WebMapTileServiceImageryProvider.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*global define*/
  2. define([
  3. '../Core/combine',
  4. '../Core/Credit',
  5. '../Core/defaultValue',
  6. '../Core/defined',
  7. '../Core/defineProperties',
  8. '../Core/DeveloperError',
  9. '../Core/Event',
  10. '../Core/freezeObject',
  11. '../Core/objectToQuery',
  12. '../Core/queryToObject',
  13. '../Core/Rectangle',
  14. '../Core/WebMercatorTilingScheme',
  15. '../ThirdParty/Uri',
  16. './ImageryProvider'
  17. ], function(
  18. combine,
  19. Credit,
  20. defaultValue,
  21. defined,
  22. defineProperties,
  23. DeveloperError,
  24. Event,
  25. freezeObject,
  26. objectToQuery,
  27. queryToObject,
  28. Rectangle,
  29. WebMercatorTilingScheme,
  30. Uri,
  31. ImageryProvider) {
  32. "use strict";
  33. /**
  34. * Provides tiled imagery served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers.
  35. * This provider supports HTTP KVP-encoded GetTile requests, but does not yet support SOAP and RESTful encoding.
  36. *
  37. * @alias WebMapTileServiceImageryProvider
  38. * @constructor
  39. *
  40. * @param {Object} options Object with the following properties:
  41. * @param {String} options.url The WMTS server url.
  42. * @param {String} [options.format='image/jpeg'] The MIME type for images to retrieve from the server.
  43. * @param {String} options.layer The layer name for WMTS requests.
  44. * @param {String} options.style The style name for WMTS requests.
  45. * @param {String} options.tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests.
  46. * @param {Array} [options.tileMatrixLabels] A list of identifiers in the TileMatrix to use for WMTS requests, one per TileMatrix level.
  47. * @param {Number} [options.tileWidth=256] The tile width in pixels.
  48. * @param {Number} [options.tileHeight=256] The tile height in pixels.
  49. * @param {TilingScheme} [options.tilingScheme] The tiling scheme corresponding to the organization of the tiles in the TileMatrixSet.
  50. * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL.
  51. * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle covered by the layer.
  52. * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
  53. * @param {Number} [options.maximumLevel=18] The maximum level-of-detail supported by the imagery provider.
  54. * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
  55. *
  56. * @see ArcGisMapServerImageryProvider
  57. * @see BingMapsImageryProvider
  58. * @see SingleTileImageryProvider
  59. * @see TileMapServiceImageryProvider
  60. * @see WebMapServiceImageryProvider
  61. *
  62. * @example
  63. * // USGS shaded relief tile provider
  64. * var shadedRelief = new Cesium.WebMapTileServiceImageryProvider({
  65. * url : 'http://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS',
  66. * layer : 'USGSShadedReliefOnly',
  67. * style : 'default',
  68. * format : 'image/jpeg',
  69. * tileMatrixSetID : 'default028mm',
  70. * // tileMatrixLabels : ['default028mm:0', 'default028mm:1', 'default028mm:2' ...],
  71. * maximumLevel: 19,
  72. * credit : new Cesium.Credit('U. S. Geological Survey')
  73. * });
  74. * viewer.imageryLayers.addImageryProvider(shadedRelief);
  75. */
  76. var WebMapTileServiceImageryProvider = function WebMapTileServiceImageryProvider(options) {
  77. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  78. if (!defined(options.url)) {
  79. throw new DeveloperError('options.url is required.');
  80. }
  81. if (!defined(options.layer)) {
  82. throw new DeveloperError('options.layer is required.');
  83. }
  84. if (!defined(options.style)) {
  85. throw new DeveloperError('options.style is required.');
  86. }
  87. if (!defined(options.tileMatrixSetID)) {
  88. throw new DeveloperError('options.tileMatrixSetID is required.');
  89. }
  90. this._url = options.url;
  91. this._layer = options.layer;
  92. this._style = options.style;
  93. this._tileMatrixSetID = options.tileMatrixSetID;
  94. this._tileMatrixLabels = options.tileMatrixLabels;
  95. this._format = defaultValue(options.format, 'image/jpeg');
  96. this._proxy = options.proxy;
  97. this._tileDiscardPolicy = options.tileDiscardPolicy;
  98. this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new WebMercatorTilingScheme();
  99. this._tileWidth = defaultValue(options.tileWidth, 256);
  100. this._tileHeight = defaultValue(options.tileHeight, 256);
  101. this._minimumLevel = defaultValue(options.minimumLevel, 0);
  102. this._maximumLevel = defaultValue(options.maximumLevel, 18);
  103. this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle);
  104. // Check the number of tiles at the minimum level. If it's more than four,
  105. // throw an exception, because starting at the higher minimum
  106. // level will cause too many tiles to be downloaded and rendered.
  107. var swTile = this._tilingScheme.positionToTileXY(Rectangle.southwest(this._rectangle), this._minimumLevel);
  108. var neTile = this._tilingScheme.positionToTileXY(Rectangle.northeast(this._rectangle), this._minimumLevel);
  109. var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
  110. if (tileCount > 4) {
  111. throw new DeveloperError('The imagery provider\'s rectangle and minimumLevel indicate that there are ' + tileCount + ' tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.');
  112. }
  113. this._errorEvent = new Event();
  114. var credit = options.credit;
  115. this._credit = typeof credit === 'string' ? new Credit(credit) : credit;
  116. };
  117. var defaultParameters = freezeObject({
  118. service : 'WMTS',
  119. version : '1.0.0',
  120. request : 'GetTile'
  121. });
  122. function buildImageUrl(imageryProvider, col, row, level) {
  123. var uri = new Uri(imageryProvider._url);
  124. var queryOptions = queryToObject(defaultValue(uri.query, ''));
  125. var labels;
  126. queryOptions = combine(defaultParameters, queryOptions);
  127. labels = imageryProvider._tileMatrixLabels;
  128. queryOptions.tilematrix = defined(labels) ? labels[level] : level;
  129. queryOptions.layer = imageryProvider._layer;
  130. queryOptions.style = imageryProvider._style;
  131. queryOptions.tilerow = row;
  132. queryOptions.tilecol = col;
  133. queryOptions.tilematrixset = imageryProvider._tileMatrixSetID;
  134. queryOptions.format = imageryProvider._format;
  135. uri.query = objectToQuery(queryOptions);
  136. var url = uri.toString();
  137. var proxy = imageryProvider._proxy;
  138. if (defined(proxy)) {
  139. url = proxy.getURL(url);
  140. }
  141. return url;
  142. }
  143. defineProperties(WebMapTileServiceImageryProvider.prototype, {
  144. /**
  145. * Gets the URL of the service hosting the imagery.
  146. * @memberof WebMapTileServiceImageryProvider.prototype
  147. * @type {String}
  148. * @readonly
  149. */
  150. url : {
  151. get : function() {
  152. return this._url;
  153. }
  154. },
  155. /**
  156. * Gets the proxy used by this provider.
  157. * @memberof WebMapTileServiceImageryProvider.prototype
  158. * @type {Proxy}
  159. * @readonly
  160. */
  161. proxy : {
  162. get : function() {
  163. return this._proxy;
  164. }
  165. },
  166. /**
  167. * Gets the width of each tile, in pixels. This function should
  168. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  169. * @memberof WebMapTileServiceImageryProvider.prototype
  170. * @type {Number}
  171. * @readonly
  172. */
  173. tileWidth : {
  174. get : function() {
  175. return this._tileWidth;
  176. }
  177. },
  178. /**
  179. * Gets the height of each tile, in pixels. This function should
  180. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  181. * @memberof WebMapTileServiceImageryProvider.prototype
  182. * @type {Number}
  183. * @readonly
  184. */
  185. tileHeight : {
  186. get : function() {
  187. return this._tileHeight;
  188. }
  189. },
  190. /**
  191. * Gets the maximum level-of-detail that can be requested. This function should
  192. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  193. * @memberof WebMapTileServiceImageryProvider.prototype
  194. * @type {Number}
  195. * @readonly
  196. */
  197. maximumLevel : {
  198. get : function() {
  199. return this._maximumLevel;
  200. }
  201. },
  202. /**
  203. * Gets the minimum level-of-detail that can be requested. This function should
  204. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  205. * @memberof WebMapTileServiceImageryProvider.prototype
  206. * @type {Number}
  207. * @readonly
  208. */
  209. minimumLevel : {
  210. get : function() {
  211. return this._minimumLevel;
  212. }
  213. },
  214. /**
  215. * Gets the tiling scheme used by this provider. This function should
  216. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  217. * @memberof WebMapTileServiceImageryProvider.prototype
  218. * @type {TilingScheme}
  219. * @readonly
  220. */
  221. tilingScheme : {
  222. get : function() {
  223. return this._tilingScheme;
  224. }
  225. },
  226. /**
  227. * Gets the rectangle, in radians, of the imagery provided by this instance. This function should
  228. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  229. * @memberof WebMapTileServiceImageryProvider.prototype
  230. * @type {Rectangle}
  231. * @readonly
  232. */
  233. rectangle : {
  234. get : function() {
  235. return this._rectangle;
  236. }
  237. },
  238. /**
  239. * Gets the tile discard policy. If not undefined, the discard policy is responsible
  240. * for filtering out "missing" tiles via its shouldDiscardImage function. If this function
  241. * returns undefined, no tiles are filtered. This function should
  242. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  243. * @memberof WebMapTileServiceImageryProvider.prototype
  244. * @type {TileDiscardPolicy}
  245. * @readonly
  246. */
  247. tileDiscardPolicy : {
  248. get : function() {
  249. return this._tileDiscardPolicy;
  250. }
  251. },
  252. /**
  253. * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing
  254. * to the event, you will be notified of the error and can potentially recover from it. Event listeners
  255. * are passed an instance of {@link TileProviderError}.
  256. * @memberof WebMapTileServiceImageryProvider.prototype
  257. * @type {Event}
  258. * @readonly
  259. */
  260. errorEvent : {
  261. get : function() {
  262. return this._errorEvent;
  263. }
  264. },
  265. /**
  266. * Gets the mime type of images returned by this imagery provider.
  267. * @memberof WebMapTileServiceImageryProvider.prototype
  268. * @type {String}
  269. * @readonly
  270. */
  271. format : {
  272. get : function() {
  273. return this._format;
  274. }
  275. },
  276. /**
  277. * Gets a value indicating whether or not the provider is ready for use.
  278. * @memberof WebMapTileServiceImageryProvider.prototype
  279. * @type {Boolean}
  280. * @readonly
  281. */
  282. ready : {
  283. value: true
  284. },
  285. /**
  286. * Gets the credit to display when this imagery provider is active. Typically this is used to credit
  287. * the source of the imagery. This function should not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  288. * @memberof WebMapTileServiceImageryProvider.prototype
  289. * @type {Credit}
  290. * @readonly
  291. */
  292. credit : {
  293. get : function() {
  294. return this._credit;
  295. }
  296. },
  297. /**
  298. * Gets a value indicating whether or not the images provided by this imagery provider
  299. * include an alpha channel. If this property is false, an alpha channel, if present, will
  300. * be ignored. If this property is true, any images without an alpha channel will be treated
  301. * as if their alpha is 1.0 everywhere. When this property is false, memory usage
  302. * and texture upload time are reduced.
  303. * @memberof WebMapTileServiceImageryProvider.prototype
  304. * @type {Boolean}
  305. * @readonly
  306. */
  307. hasAlphaChannel : {
  308. get : function() {
  309. return true;
  310. }
  311. }
  312. });
  313. /**
  314. * Gets the credits to be displayed when a given tile is displayed.
  315. *
  316. * @param {Number} x The tile X coordinate.
  317. * @param {Number} y The tile Y coordinate.
  318. * @param {Number} level The tile level;
  319. * @returns {Credit[]} The credits to be displayed when the tile is displayed.
  320. *
  321. * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready.
  322. */
  323. WebMapTileServiceImageryProvider.prototype.getTileCredits = function(x, y, level) {
  324. return undefined;
  325. };
  326. /**
  327. * Requests the image for a given tile. This function should
  328. * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
  329. *
  330. * @param {Number} x The tile X coordinate.
  331. * @param {Number} y The tile Y coordinate.
  332. * @param {Number} level The tile level.
  333. * @returns {Promise} A promise for the image that will resolve when the image is available, or
  334. * undefined if there are too many active requests to the server, and the request
  335. * should be retried later. The resolved image may be either an
  336. * Image or a Canvas DOM object.
  337. *
  338. * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready.
  339. */
  340. WebMapTileServiceImageryProvider.prototype.requestImage = function(x, y, level) {
  341. var url = buildImageUrl(this, x, y, level);
  342. return ImageryProvider.loadImage(this, url);
  343. };
  344. /**
  345. * Picking features is not currently supported by this imagery provider, so this function simply returns
  346. * undefined.
  347. *
  348. * @param {Number} x The tile X coordinate.
  349. * @param {Number} y The tile Y coordinate.
  350. * @param {Number} level The tile level.
  351. * @param {Number} longitude The longitude at which to pick features.
  352. * @param {Number} latitude The latitude at which to pick features.
  353. * @return {Promise} A promise for the picked features that will resolve when the asynchronous
  354. * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo}
  355. * instances. The array may be empty if no features are found at the given location.
  356. * It may also be undefined if picking is not supported.
  357. */
  358. WebMapTileServiceImageryProvider.prototype.pickFeatures = function() {
  359. return undefined;
  360. };
  361. return WebMapTileServiceImageryProvider;
  362. });