智慧水务管理系统 - 精河县供水工程综合管理平台

WebMapTileServiceImageryProvider.js 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. import combine from "../Core/combine.js";
  2. import Frozen from "../Core/Frozen.js";
  3. import defined from "../Core/defined.js";
  4. import DeveloperError from "../Core/DeveloperError.js";
  5. import Event from "../Core/Event.js";
  6. import Resource from "../Core/Resource.js";
  7. import WebMercatorTilingScheme from "../Core/WebMercatorTilingScheme.js";
  8. import TimeDynamicImagery from "./TimeDynamicImagery.js";
  9. import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js";
  10. import GetFeatureInfoFormat from "./GetFeatureInfoFormat.js";
  11. /**
  12. * @typedef {object} WebMapTileServiceImageryProvider.ConstructorOptions
  13. *
  14. * Initialization options for the WebMapTileServiceImageryProvider constructor
  15. *
  16. * @property {Resource|string} url The base URL for the WMTS GetTile operation (for KVP-encoded requests) or the tile-URL template (for RESTful requests). The tile-URL template should contain the following variables: {style}, {TileMatrixSet}, {TileMatrix}, {TileRow}, {TileCol}. The first two are optional if actual values are hardcoded or not required by the server. The {s} keyword may be used to specify subdomains.
  17. * @property {string} [format='image/jpeg'] The MIME type for images to retrieve from the server.
  18. * @property {string} layer The layer name for WMTS requests.
  19. * @property {string} style The style name for WMTS requests.
  20. * @property {string} tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests.
  21. * @property {boolean} [enablePickFeatures] If true, {@link WebMapTileServiceImageryProvider#pickFeatures} will invoke
  22. * the GetFeatureInfo operation on the WMTS server and return the features included in the response. If false,
  23. * {@link WebMapTileServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features)
  24. * without communicating with the server. Set this property to false if you know your WMTS server does not support
  25. * GetFeatureInfo or if you don't want this provider's features to be pickable.
  26. * Defaults to true for KVP encoding. For RESTful encoding, defaults to true only when
  27. * {@link WebMapTileServiceImageryProvider.ConstructorOptions#getFeatureInfoUrl} is specified, and false otherwise.
  28. * @property {object} [getFeatureInfoParameters] Additional parameters to include in GetFeatureInfo requests. Keys are lowercased internally.
  29. * @property {Resource|string} [getFeatureInfoUrl] The GetFeatureInfo URL of the WMTS service. If not specified, the value of <code>url</code> is used.
  30. * @property {GetFeatureInfoFormat[]} [getFeatureInfoFormats=WebMapTileServiceImageryProvider.DefaultGetFeatureInfoFormats] The formats
  31. * in which to try WMTS GetFeatureInfo requests.
  32. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle covered by the layer.
  33. * @property {TilingScheme} [tilingScheme] The tiling scheme corresponding to the organization of the tiles in the TileMatrixSet.
  34. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
  35. * @property {number} [tileWidth=256] The tile width in pixels.
  36. * @property {number} [tileHeight=256] The tile height in pixels.
  37. * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
  38. * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
  39. * @property {Array} [tileMatrixLabels] A list of identifiers in the TileMatrix to use for WMTS requests, one per TileMatrix level.
  40. * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas.
  41. * @property {string|string[]} [subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template.
  42. * If this parameter is a single string, each character in the string is a subdomain. If it is
  43. * an array, each element in the array is a subdomain.
  44. * @property {Clock} [clock] A Clock instance that is used when determining the value for the time dimension. Required when `times` is specified.
  45. * @property {TimeIntervalCollection} [times] TimeIntervalCollection with its <code>data</code> property being an object containing time dynamic dimension and their values.
  46. * @property {object} [dimensions] A object containing static dimensions and their values.
  47. */
  48. /**
  49. * Provides tiled imagery served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers.
  50. * This provider supports HTTP KVP-encoded and RESTful GetTile requests, but does not yet support the SOAP encoding.
  51. *
  52. * @alias WebMapTileServiceImageryProvider
  53. * @constructor
  54. *
  55. * @param {WebMapTileServiceImageryProvider.ConstructorOptions} options Object describing initialization options
  56. *
  57. * @demo {@link https://sandcastle.cesium.com/index.html?id=web-map-tile-service-with-time|Cesium Sandcastle Web Map Tile Service with Time Demo}
  58. *
  59. * @example
  60. * // Example 1. USGS shaded relief tiles (KVP)
  61. * const shadedRelief1 = new Cesium.WebMapTileServiceImageryProvider({
  62. * url : 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS',
  63. * layer : 'USGSShadedReliefOnly',
  64. * style : 'default',
  65. * format : 'image/jpeg',
  66. * tileMatrixSetID : 'default028mm',
  67. * // tileMatrixLabels : ['default028mm:0', 'default028mm:1', 'default028mm:2' ...],
  68. * maximumLevel: 19,
  69. * credit : new Cesium.Credit('U. S. Geological Survey')
  70. * });
  71. * viewer.imageryLayers.addImageryProvider(shadedRelief1);
  72. *
  73. * @example
  74. * // Example 2. USGS shaded relief tiles (RESTful)
  75. * const shadedRelief2 = new Cesium.WebMapTileServiceImageryProvider({
  76. * url : 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS/tile/1.0.0/USGSShadedReliefOnly/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
  77. * layer : 'USGSShadedReliefOnly',
  78. * style : 'default',
  79. * format : 'image/jpeg',
  80. * tileMatrixSetID : 'default028mm',
  81. * maximumLevel: 19,
  82. * credit : new Cesium.Credit('U. S. Geological Survey')
  83. * });
  84. * viewer.imageryLayers.addImageryProvider(shadedRelief2);
  85. *
  86. * @example
  87. * // Example 3: NASA time dynamic snowpack data (RESTful)
  88. * // Define time intervals for the layer based on the capabilities XML
  89. * const times = Cesium.TimeIntervalCollection.fromIso8601({
  90. * iso8601: '2025-01-01/2025-09-01/P5D', // Use the valid interval(s) from the Dimension section
  91. * dataCallback: function(interval, index) {
  92. * // Return an object with the Time variable used in the URL template
  93. * return {
  94. * Time: Cesium.JulianDate.toIso8601(interval.start, 0)
  95. * };
  96. * }
  97. * });
  98. * // Get the internal clock, set desired start, stop, and multiplier
  99. * const clock = viewer.clock;
  100. * clock.startTime = Cesium.JulianDate.fromIso8601('2025-01-01');
  101. * clock.currentTime = Cesium.JulianDate.fromIso8601('2025-01-01');
  102. * clock.stopTime = Cesium.JulianDate.fromIso8601('2025-09-01');
  103. * clock.clockRange = Cesium.ClockRange.LOOP_STOP;
  104. * clock.multiplier = 1; // 1 day per second
  105. * clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER;
  106. *
  107. * viewer.timeline.zoomTo(clock.startTime, clock.stopTime);
  108. *
  109. * const weather = new Cesium.WebMapTileServiceImageryProvider({
  110. * url: 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/AMSRU2_Snow_Water_Equivalent_5Day/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png',
  111. * layer: 'AMSRU2_Snow_Water_Equivalent_5Day',
  112. * style: 'default',
  113. * tileMatrixSetID: 'GoogleMapsCompatible_Level6',
  114. * format: 'image/png',
  115. * clock: clock,
  116. * times: times,
  117. * credit: new Cesium.Credit('NASA Global Imagery Browse Services for EOSDIS')
  118. * });
  119. * viewer.imageryLayers.addImageryProvider(weather);
  120. *
  121. * @example
  122. * // Example 4. Digital Earth AfricA waterbodies with GetFeatureInfo support (RESTful)
  123. * const waterbodies = new Cesium.WebMapTileServiceImageryProvider({
  124. * url: "https://geoserver.digitalearth.africa/geoserver/gwc/service/wmts/rest/{layer}/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format={format}",
  125. * layer: "waterbodies:DEAfrica_Waterbodies",
  126. * style: "waterbodies:waterbodies_v0_0_4",
  127. * tileMatrixSetID: "EPSG:3857",
  128. * tileMatrixLabels: [
  129. * "EPSG:3857:0",
  130. * "EPSG:3857:1",
  131. * "EPSG:3857:2",
  132. * "EPSG:3857:3",
  133. * "EPSG:3857:4",
  134. * "EPSG:3857:5",
  135. * "EPSG:3857:6",
  136. * "EPSG:3857:7",
  137. * "EPSG:3857:8",
  138. * "EPSG:3857:9",
  139. * "EPSG:3857:10",
  140. * "EPSG:3857:11",
  141. * "EPSG:3857:12",
  142. * "EPSG:3857:13",
  143. * "EPSG:3857:14",
  144. * "EPSG:3857:15",
  145. * "EPSG:3857:16",
  146. * "EPSG:3857:17",
  147. * "EPSG:3857:18",
  148. * "EPSG:3857:19",
  149. * "EPSG:3857:20",
  150. * "EPSG:3857:21",
  151. * "EPSG:3857:22",
  152. * "EPSG:3857:23",
  153. * "EPSG:3857:24",
  154. * "EPSG:3857:25",
  155. * "EPSG:3857:26",
  156. * "EPSG:3857:27",
  157. * "EPSG:3857:28",
  158. * "EPSG:3857:29",
  159. * "EPSG:3857:30",
  160. * ],
  161. * format: "image/png",
  162. * enablePickFeatures: true,
  163. * getFeatureInfoUrl: "https://geoserver.digitalearth.africa/geoserver/gwc/service/wmts/rest/{layer}/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{j}/{i}?format={format}",
  164. * });
  165. *
  166. * viewer.imageryLayers.addImageryProvider(waterbodies);
  167. *
  168. * @see ArcGisMapServerImageryProvider
  169. * @see BingMapsImageryProvider
  170. * @see GoogleEarthEnterpriseMapsProvider
  171. * @see OpenStreetMapImageryProvider
  172. * @see SingleTileImageryProvider
  173. * @see TileMapServiceImageryProvider
  174. * @see WebMapServiceImageryProvider
  175. * @see UrlTemplateImageryProvider
  176. */
  177. function WebMapTileServiceImageryProvider(options) {
  178. options = options ?? Frozen.EMPTY_OBJECT;
  179. //>>includeStart('debug', pragmas.debug);
  180. if (!defined(options.url)) {
  181. throw new DeveloperError("options.url is required.");
  182. }
  183. if (!defined(options.layer)) {
  184. throw new DeveloperError("options.layer is required.");
  185. }
  186. if (!defined(options.style)) {
  187. throw new DeveloperError("options.style is required.");
  188. }
  189. if (!defined(options.tileMatrixSetID)) {
  190. throw new DeveloperError("options.tileMatrixSetID is required.");
  191. }
  192. if (defined(options.times) && !defined(options.clock)) {
  193. throw new DeveloperError(
  194. "options.times was specified, so options.clock is required.",
  195. );
  196. }
  197. //>>includeEnd('debug');
  198. this._defaultAlpha = undefined;
  199. this._defaultNightAlpha = undefined;
  200. this._defaultDayAlpha = undefined;
  201. this._defaultBrightness = undefined;
  202. this._defaultContrast = undefined;
  203. this._defaultHue = undefined;
  204. this._defaultSaturation = undefined;
  205. this._defaultGamma = undefined;
  206. this._defaultMinificationFilter = undefined;
  207. this._defaultMagnificationFilter = undefined;
  208. this._getFeatureInfoUrl = options.getFeatureInfoUrl ?? options.url;
  209. const resource = Resource.createIfNeeded(options.url);
  210. const pickFeatureResource = Resource.createIfNeeded(this._getFeatureInfoUrl);
  211. const style = options.style;
  212. const tileMatrixSetID = options.tileMatrixSetID;
  213. const url = resource.url;
  214. const format = options.format ?? "image/jpeg";
  215. const bracketMatch = url.match(/{/g);
  216. if (
  217. !defined(bracketMatch) ||
  218. (bracketMatch.length === 1 && /{s}/.test(url))
  219. ) {
  220. resource.setQueryParameters(
  221. WebMapTileServiceImageryProvider.DefaultParameters,
  222. true,
  223. );
  224. this._useKvp = true;
  225. } else {
  226. resource.setTemplateValues(
  227. WebMapTileServiceImageryProvider.DefaultParameters,
  228. true,
  229. );
  230. this._useKvp = false;
  231. }
  232. if (this._useKvp) {
  233. pickFeatureResource.setQueryParameters(
  234. WebMapTileServiceImageryProvider.GetFeatureInfoDefaultParameters,
  235. true,
  236. );
  237. if (defined(options.getFeatureInfoParameters)) {
  238. pickFeatureResource.setQueryParameters(
  239. objectToLowercase(options.getFeatureInfoParameters),
  240. );
  241. }
  242. const pickFeatureParams = {
  243. infoformat: "{format}",
  244. i: "{i}",
  245. j: "{j}",
  246. };
  247. pickFeatureResource.setQueryParameters(pickFeatureParams, true);
  248. } else {
  249. pickFeatureResource.setTemplateValues(
  250. WebMapTileServiceImageryProvider.GetFeatureInfoDefaultParameters,
  251. true,
  252. );
  253. if (defined(options.getFeatureInfoParameters)) {
  254. pickFeatureResource.setTemplateValues(
  255. objectToLowercase(options.getFeatureInfoParameters),
  256. );
  257. }
  258. }
  259. this._resource = resource;
  260. this._tileMatrixLabels = options.tileMatrixLabels;
  261. this._format = format;
  262. this._dimensions = options.dimensions;
  263. this._tilematrixset = tileMatrixSetID;
  264. const parameters = {};
  265. parameters.tilematrix = "{TileMatrix}";
  266. parameters.layer = options.layer;
  267. parameters.style = style;
  268. parameters.tilerow = "{TileRow}";
  269. parameters.tilecol = "{TileCol}";
  270. parameters.tilematrixset = tileMatrixSetID;
  271. if (this._useKvp) {
  272. resource.setQueryParameters(parameters, true);
  273. resource.setQueryParameters({ format: format }, true);
  274. pickFeatureResource.setQueryParameters({ format: format }, true);
  275. pickFeatureResource.setQueryParameters(parameters, true);
  276. } else {
  277. parameters.Style = style;
  278. resource.setTemplateValues(parameters);
  279. resource.setTemplateValues({ format: format });
  280. pickFeatureResource.setTemplateValues(parameters);
  281. }
  282. const that = this;
  283. this._reload = undefined;
  284. if (defined(options.times)) {
  285. this._timeDynamicImagery = new TimeDynamicImagery({
  286. clock: options.clock,
  287. times: options.times,
  288. requestImageFunction: function (x, y, level, request, interval) {
  289. return requestImage(that, x, y, level, request, interval);
  290. },
  291. reloadFunction: function () {
  292. if (defined(that._reload)) {
  293. that._reload();
  294. }
  295. },
  296. });
  297. }
  298. this._errorEvent = new Event();
  299. // Let UrlTemplateImageryProvider do the actual URL building.
  300. this._tileProvider = new UrlTemplateImageryProvider({
  301. url: resource,
  302. pickFeaturesUrl: pickFeatureResource,
  303. tilingScheme:
  304. options.tilingScheme ??
  305. new WebMercatorTilingScheme({ ellipsoid: options.ellipsoid }),
  306. rectangle: options.rectangle,
  307. tileWidth: options.tileWidth,
  308. tileHeight: options.tileHeight,
  309. minimumLevel: options.minimumLevel,
  310. maximumLevel: options.maximumLevel,
  311. subdomains: options.subdomains,
  312. tileDiscardPolicy: options.tileDiscardPolicy,
  313. credit: options.credit,
  314. getFeatureInfoFormats:
  315. options.getFeatureInfoFormats ??
  316. WebMapTileServiceImageryProvider.DefaultGetFeatureInfoFormats,
  317. enablePickFeatures:
  318. options.enablePickFeatures ??
  319. (this._useKvp || defined(options.getFeatureInfoUrl)),
  320. customTags: createCustomTags(this),
  321. });
  322. }
  323. function requestImage(imageryProvider, col, row, level, request, interval) {
  324. const tileProvider = imageryProvider._tileProvider;
  325. applyDimensions(imageryProvider, tileProvider._resource, interval);
  326. return tileProvider.requestImage(col, row, level, request);
  327. }
  328. function pickFeatures(
  329. imageryProvider,
  330. x,
  331. y,
  332. level,
  333. longitude,
  334. latitude,
  335. interval,
  336. ) {
  337. const tileProvider = imageryProvider._tileProvider;
  338. applyDimensions(
  339. imageryProvider,
  340. tileProvider._pickFeaturesResource,
  341. interval,
  342. );
  343. return tileProvider.pickFeatures(x, y, level, longitude, latitude);
  344. }
  345. Object.defineProperties(WebMapTileServiceImageryProvider.prototype, {
  346. /**
  347. * Gets the URL of the service hosting the imagery.
  348. * @memberof WebMapTileServiceImageryProvider.prototype
  349. * @type {string}
  350. * @readonly
  351. */
  352. url: {
  353. get: function () {
  354. return this._resource.url;
  355. },
  356. },
  357. /**
  358. * Gets the proxy used by this provider.
  359. * @memberof WebMapTileServiceImageryProvider.prototype
  360. * @type {Proxy}
  361. * @readonly
  362. */
  363. proxy: {
  364. get: function () {
  365. return this._resource.proxy;
  366. },
  367. },
  368. /**
  369. * Gets the width of each tile, in pixels.
  370. * @memberof WebMapTileServiceImageryProvider.prototype
  371. * @type {number}
  372. * @readonly
  373. */
  374. tileWidth: {
  375. get: function () {
  376. return this._tileProvider.tileWidth;
  377. },
  378. },
  379. /**
  380. * Gets the height of each tile, in pixels.
  381. * @memberof WebMapTileServiceImageryProvider.prototype
  382. * @type {number}
  383. * @readonly
  384. */
  385. tileHeight: {
  386. get: function () {
  387. return this._tileProvider.tileHeight;
  388. },
  389. },
  390. /**
  391. * Gets the maximum level-of-detail that can be requested.
  392. * @memberof WebMapTileServiceImageryProvider.prototype
  393. * @type {number|undefined}
  394. * @readonly
  395. */
  396. maximumLevel: {
  397. get: function () {
  398. return this._tileProvider.maximumLevel;
  399. },
  400. },
  401. /**
  402. * Gets the minimum level-of-detail that can be requested.
  403. * @memberof WebMapTileServiceImageryProvider.prototype
  404. * @type {number}
  405. * @readonly
  406. */
  407. minimumLevel: {
  408. get: function () {
  409. return this._tileProvider.minimumLevel;
  410. },
  411. },
  412. /**
  413. * Gets the tiling scheme used by this provider.
  414. * @memberof WebMapTileServiceImageryProvider.prototype
  415. * @type {TilingScheme}
  416. * @readonly
  417. */
  418. tilingScheme: {
  419. get: function () {
  420. return this._tileProvider.tilingScheme;
  421. },
  422. },
  423. /**
  424. * Gets the rectangle, in radians, of the imagery provided by this instance.
  425. * @memberof WebMapTileServiceImageryProvider.prototype
  426. * @type {Rectangle}
  427. * @readonly
  428. */
  429. rectangle: {
  430. get: function () {
  431. return this._tileProvider.rectangle;
  432. },
  433. },
  434. /**
  435. * Gets the tile discard policy. If not undefined, the discard policy is responsible
  436. * for filtering out "missing" tiles via its shouldDiscardImage function. If this function
  437. * returns undefined, no tiles are filtered.
  438. * @memberof WebMapTileServiceImageryProvider.prototype
  439. * @type {TileDiscardPolicy}
  440. * @readonly
  441. */
  442. tileDiscardPolicy: {
  443. get: function () {
  444. return this._tileProvider.tileDiscardPolicy;
  445. },
  446. },
  447. /**
  448. * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing
  449. * to the event, you will be notified of the error and can potentially recover from it. Event listeners
  450. * are passed an instance of {@link TileProviderError}.
  451. * @memberof WebMapTileServiceImageryProvider.prototype
  452. * @type {Event}
  453. * @readonly
  454. */
  455. errorEvent: {
  456. get: function () {
  457. return this._tileProvider.errorEvent;
  458. },
  459. },
  460. /**
  461. * Gets the mime type of images returned by this imagery provider.
  462. * @memberof WebMapTileServiceImageryProvider.prototype
  463. * @type {string}
  464. * @readonly
  465. */
  466. format: {
  467. get: function () {
  468. return this._format;
  469. },
  470. },
  471. /**
  472. * Gets the credit to display when this imagery provider is active. Typically this is used to credit
  473. * the source of the imagery.
  474. * @memberof WebMapTileServiceImageryProvider.prototype
  475. * @type {Credit}
  476. * @readonly
  477. */
  478. credit: {
  479. get: function () {
  480. return this._tileProvider.credit;
  481. },
  482. },
  483. /**
  484. * Gets a value indicating whether or not the images provided by this imagery provider
  485. * include an alpha channel. If this property is false, an alpha channel, if present, will
  486. * be ignored. If this property is true, any images without an alpha channel will be treated
  487. * as if their alpha is 1.0 everywhere. When this property is false, memory usage
  488. * and texture upload time are reduced.
  489. * @memberof WebMapTileServiceImageryProvider.prototype
  490. * @type {boolean}
  491. * @readonly
  492. */
  493. hasAlphaChannel: {
  494. get: function () {
  495. return true;
  496. },
  497. },
  498. /**
  499. * Gets or sets a value indicating whether feature picking is enabled. If true, {@link WebMapTileServiceImageryProvider#pickFeatures} will
  500. * invoke the <code>GetFeatureInfo</code> service on the WMTS server and attempt to interpret the features included in the response. If false,
  501. * {@link WebMapTileServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable
  502. * features) without communicating with the server. Set this property to false if you know your data
  503. * source does not support picking features or if you don't want this provider's features to be pickable.
  504. * Defaults to true for KVP encoding. For RESTful encoding, defaults to true only when
  505. * {@link WebMapTileServiceImageryProvider.ConstructorOptions#getFeatureInfoUrl} is specified, and false otherwise.
  506. * @memberof WebMapTileServiceImageryProvider.prototype
  507. * @type {boolean}
  508. */
  509. enablePickFeatures: {
  510. get: function () {
  511. return this._tileProvider.enablePickFeatures;
  512. },
  513. set: function (enablePickFeatures) {
  514. this._tileProvider.enablePickFeatures = enablePickFeatures;
  515. },
  516. },
  517. /**
  518. * Gets or sets a clock that is used to get keep the time used for time dynamic parameters.
  519. * @memberof WebMapTileServiceImageryProvider.prototype
  520. * @type {Clock}
  521. */
  522. clock: {
  523. get: function () {
  524. return this._timeDynamicImagery.clock;
  525. },
  526. set: function (value) {
  527. this._timeDynamicImagery.clock = value;
  528. },
  529. },
  530. /**
  531. * Gets or sets a time interval collection that is used to get time dynamic parameters. The data of each
  532. * TimeInterval is an object containing the keys and values of the properties that are used during
  533. * tile requests.
  534. * @memberof WebMapTileServiceImageryProvider.prototype
  535. * @type {TimeIntervalCollection}
  536. */
  537. times: {
  538. get: function () {
  539. return this._timeDynamicImagery.times;
  540. },
  541. set: function (value) {
  542. this._timeDynamicImagery.times = value;
  543. },
  544. },
  545. /**
  546. * Gets or sets an object that contains static dimensions and their values.
  547. * @memberof WebMapTileServiceImageryProvider.prototype
  548. * @type {object}
  549. */
  550. dimensions: {
  551. get: function () {
  552. return this._dimensions;
  553. },
  554. set: function (value) {
  555. if (this._dimensions !== value) {
  556. this._dimensions = value;
  557. if (defined(this._reload)) {
  558. this._reload();
  559. }
  560. }
  561. },
  562. },
  563. /**
  564. * Gets the getFeatureInfo URL of the WMTS server.
  565. * @memberof WebMapTileServiceImageryProvider.prototype
  566. * @type {Resource|string}
  567. * @readonly
  568. */
  569. getFeatureInfoUrl: {
  570. get: function () {
  571. return this._getFeatureInfoUrl;
  572. },
  573. },
  574. });
  575. /**
  576. * Gets the credits to be displayed when a given tile is displayed.
  577. *
  578. * @param {number} x The tile X coordinate.
  579. * @param {number} y The tile Y coordinate.
  580. * @param {number} level The tile level;
  581. * @returns {Credit[]} The credits to be displayed when the tile is displayed.
  582. */
  583. WebMapTileServiceImageryProvider.prototype.getTileCredits = function (
  584. x,
  585. y,
  586. level,
  587. ) {
  588. return this._tileProvider.getTileCredits(x, y, level);
  589. };
  590. /**
  591. * Requests the image for a given tile.
  592. *
  593. * @param {number} x The tile X coordinate.
  594. * @param {number} y The tile Y coordinate.
  595. * @param {number} level The tile level.
  596. * @param {Request} [request] The request object. Intended for internal use only.
  597. * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or
  598. * undefined if there are too many active requests to the server, and the request should be retried later.
  599. */
  600. WebMapTileServiceImageryProvider.prototype.requestImage = function (
  601. x,
  602. y,
  603. level,
  604. request,
  605. ) {
  606. let result;
  607. const timeDynamicImagery = this._timeDynamicImagery;
  608. let currentInterval;
  609. // Try and load from cache
  610. if (defined(timeDynamicImagery)) {
  611. currentInterval = timeDynamicImagery.currentInterval;
  612. result = timeDynamicImagery.getFromCache(x, y, level, request);
  613. }
  614. // Couldn't load from cache
  615. if (!defined(result)) {
  616. result = requestImage(this, x, y, level, request, currentInterval);
  617. }
  618. // If we are approaching an interval, preload this tile in the next interval
  619. if (defined(result) && defined(timeDynamicImagery)) {
  620. timeDynamicImagery.checkApproachingInterval(x, y, level, request);
  621. }
  622. return result;
  623. };
  624. /**
  625. * Asynchronously determines what features, if any, are located at a given longitude and latitude within
  626. * a tile.
  627. *
  628. * @param {number} x The tile X coordinate.
  629. * @param {number} y The tile Y coordinate.
  630. * @param {number} level The tile level.
  631. * @param {number} longitude The longitude at which to pick features.
  632. * @param {number} latitude The latitude at which to pick features.
  633. * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous
  634. * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo}
  635. * instances. The array may be empty if no features are found at the given location.
  636. */
  637. WebMapTileServiceImageryProvider.prototype.pickFeatures = function (
  638. x,
  639. y,
  640. level,
  641. longitude,
  642. latitude,
  643. ) {
  644. const timeDynamicImagery = this._timeDynamicImagery;
  645. const currentInterval = defined(timeDynamicImagery)
  646. ? timeDynamicImagery.currentInterval
  647. : undefined;
  648. return pickFeatures(this, x, y, level, longitude, latitude, currentInterval);
  649. };
  650. /**
  651. * The default parameters to include in the WMTS URL to obtain images. The values are as follows:
  652. * service=WMTS
  653. * version=1.0.0
  654. * request=GetTile
  655. *
  656. * @constant
  657. * @type {object}
  658. */
  659. WebMapTileServiceImageryProvider.DefaultParameters = Object.freeze({
  660. service: "WMTS",
  661. version: "1.0.0",
  662. request: "GetTile",
  663. });
  664. /**
  665. * The default parameters to include in the WMTS URL to get feature information. The values are as follows:
  666. * service=WMTS
  667. * version=1.0.0
  668. * request=GetFeatureInfo
  669. *
  670. * @constant
  671. * @type {object}
  672. */
  673. WebMapTileServiceImageryProvider.GetFeatureInfoDefaultParameters =
  674. Object.freeze({
  675. service: "WMTS",
  676. version: "1.0.0",
  677. request: "GetFeatureInfo",
  678. });
  679. WebMapTileServiceImageryProvider.DefaultGetFeatureInfoFormats = Object.freeze([
  680. Object.freeze(new GetFeatureInfoFormat("json", "application/json")),
  681. Object.freeze(new GetFeatureInfoFormat("xml", "text/xml")),
  682. Object.freeze(new GetFeatureInfoFormat("text", "text/html")),
  683. ]);
  684. function applyDimensions(imageryProvider, resource, interval) {
  685. const staticDimensions = imageryProvider._dimensions;
  686. const dynamicIntervalData = defined(interval) ? interval.data : undefined;
  687. if (!imageryProvider._useKvp) {
  688. if (defined(staticDimensions)) {
  689. resource.setTemplateValues(staticDimensions);
  690. }
  691. if (defined(dynamicIntervalData)) {
  692. resource.setTemplateValues(dynamicIntervalData);
  693. }
  694. } else {
  695. // build KVP request
  696. let query = {};
  697. if (defined(staticDimensions)) {
  698. query = combine(query, staticDimensions);
  699. }
  700. if (defined(dynamicIntervalData)) {
  701. query = combine(query, dynamicIntervalData);
  702. }
  703. resource.setQueryParameters(query);
  704. }
  705. }
  706. function createCustomTags(imageryProvider) {
  707. function getTileMatrix(level) {
  708. const labels = imageryProvider._tileMatrixLabels;
  709. return defined(labels) ? labels[level] : level.toString();
  710. }
  711. // We provide both uppercase and lowercase to make it more convenient for users when creating URL templates.
  712. return {
  713. TileMatrix: function (provider, x, y, level) {
  714. return getTileMatrix(level);
  715. },
  716. tilematrix: function (provider, x, y, level) {
  717. return getTileMatrix(level);
  718. },
  719. TileRow: function (provider, x, y) {
  720. return y.toString();
  721. },
  722. tilerow: function (provider, x, y) {
  723. return y.toString();
  724. },
  725. TileCol: function (provider, x, y) {
  726. return x.toString();
  727. },
  728. tilecol: function (provider, x, y) {
  729. return x.toString();
  730. },
  731. TileMatrixSet: function (provider) {
  732. return imageryProvider._tilematrixset;
  733. },
  734. tilematrixset: function (provider) {
  735. return imageryProvider._tilematrixset;
  736. },
  737. };
  738. }
  739. function objectToLowercase(obj) {
  740. const result = {};
  741. for (const key in obj) {
  742. if (obj.hasOwnProperty(key)) {
  743. result[key.toLowerCase()] = obj[key];
  744. }
  745. }
  746. return result;
  747. }
  748. export default WebMapTileServiceImageryProvider;