ArcGisMapServerImageryProvider.js 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  1. import Cartesian2 from "../Core/Cartesian2.js";
  2. import Cartesian3 from "../Core/Cartesian3.js";
  3. import Cartographic from "../Core/Cartographic.js";
  4. import Check from "../Core/Check.js";
  5. import Credit from "../Core/Credit.js";
  6. import defaultValue from "../Core/defaultValue.js";
  7. import defined from "../Core/defined.js";
  8. import deprecationWarning from "../Core/deprecationWarning.js";
  9. import Event from "../Core/Event.js";
  10. import GeographicProjection from "../Core/GeographicProjection.js";
  11. import GeographicTilingScheme from "../Core/GeographicTilingScheme.js";
  12. import CesiumMath from "../Core/Math.js";
  13. import Rectangle from "../Core/Rectangle.js";
  14. import Resource from "../Core/Resource.js";
  15. import RuntimeError from "../Core/RuntimeError.js";
  16. import TileProviderError from "../Core/TileProviderError.js";
  17. import WebMercatorProjection from "../Core/WebMercatorProjection.js";
  18. import WebMercatorTilingScheme from "../Core/WebMercatorTilingScheme.js";
  19. import ArcGisMapService from "./ArcGisMapService.js";
  20. import DiscardMissingTileImagePolicy from "./DiscardMissingTileImagePolicy.js";
  21. import ImageryLayerFeatureInfo from "./ImageryLayerFeatureInfo.js";
  22. import ImageryProvider from "./ImageryProvider.js";
  23. import ArcGisBaseMapType from "./ArcGisBaseMapType.js";
  24. import DeveloperError from "../Core/DeveloperError.js";
  25. /**
  26. * @typedef {object} ArcGisMapServerImageryProvider.ConstructorOptions
  27. *
  28. * Initialization options for the ArcGisMapServerImageryProvider constructor
  29. *
  30. * @property {Resource|string} [url] The URL of the ArcGIS MapServer service. Deprecated.
  31. * @property {string} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. Deprecated.
  32. * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile
  33. * is invalid and should be discarded. If this value is not specified, a default
  34. * {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a
  35. * {@link NeverTileDiscardPolicy} is used for non-tiled map servers. In the former case,
  36. * we request tile 0,0 at the maximum tile level and check pixels (0,0), (200,20), (20,200),
  37. * (80,110), and (160, 130). If all of these pixels are transparent, the discard check is
  38. * disabled and no tiles are discarded. If any of them have a non-transparent color, any
  39. * tile that has the same values in these pixel locations is discarded. The end result of
  40. * these defaults should be correct tile discarding for a standard ArcGIS Server. To ensure
  41. * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this
  42. * parameter.
  43. * @property {boolean} [usePreCachedTilesIfAvailable=true] If true, the server's pre-cached
  44. * tiles are used if they are available. Exporting Tiles is only supported with deprecated APIs.
  45. * @property {string} [layers] A comma-separated list of the layers to show, or undefined if all layers should be shown.
  46. * @property {boolean} [enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke
  47. * the Identify service on the MapServer and return the features included in the response. If false,
  48. * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features)
  49. * without communicating with the server. Set this property to false if you don't want this provider's features to
  50. * be pickable. Can be overridden by setting the {@link ArcGisMapServerImageryProvider#enablePickFeatures} property on the object.
  51. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. This parameter is ignored when accessing
  52. * a tiled layer.
  53. * @property {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles.
  54. * This parameter is ignored when accessing a tiled server.
  55. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified and used,
  56. * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
  57. * parameter is specified, the WGS84 ellipsoid is used.
  58. * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. This parameter is ignored when accessing a tiled server.
  59. * @property {number} [tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server.
  60. * @property {number} [tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server.
  61. * @property {number} [maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing
  62. * a tiled server.
  63. *
  64. *
  65. */
  66. /**
  67. * Used to track creation details while fetching initial metadata
  68. *
  69. * @constructor
  70. * @private
  71. *
  72. * @param {ArcGisMapServerImageryProvider.ConstructorOptions} options An object describing initialization options
  73. */
  74. function ImageryProviderBuilder(options) {
  75. this.useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true);
  76. const ellipsoid = options.ellipsoid;
  77. this.tilingScheme = defaultValue(
  78. options.tilingScheme,
  79. new GeographicTilingScheme({ ellipsoid: ellipsoid })
  80. );
  81. this.rectangle = defaultValue(options.rectangle, this.tilingScheme.rectangle);
  82. this.ellipsoid = ellipsoid;
  83. let credit = options.credit;
  84. if (typeof credit === "string") {
  85. credit = new Credit(credit);
  86. }
  87. this.credit = credit;
  88. this.tileCredits = undefined;
  89. this.tileDiscardPolicy = options.tileDiscardPolicy;
  90. this.tileWidth = defaultValue(options.tileWidth, 256);
  91. this.tileHeight = defaultValue(options.tileHeight, 256);
  92. this.maximumLevel = options.maximumLevel;
  93. }
  94. /**
  95. * Complete ArcGisMapServerImageryProvider creation based on builder values.
  96. *
  97. * @private
  98. *
  99. * @param {ArcGisMapServerImageryProvider} provider
  100. */
  101. ImageryProviderBuilder.prototype.build = function (provider) {
  102. provider._useTiles = this.useTiles;
  103. provider._tilingScheme = this.tilingScheme;
  104. provider._rectangle = this.rectangle;
  105. provider._credit = this.credit;
  106. provider._tileCredits = this.tileCredits;
  107. provider._tileDiscardPolicy = this.tileDiscardPolicy;
  108. provider._tileWidth = this.tileWidth;
  109. provider._tileHeight = this.tileHeight;
  110. provider._maximumLevel = this.maximumLevel;
  111. // Install the default tile discard policy if none has been supplied.
  112. if (this.useTiles && !defined(this.tileDiscardPolicy)) {
  113. provider._tileDiscardPolicy = new DiscardMissingTileImagePolicy({
  114. missingImageUrl: buildImageResource(provider, 0, 0, this.maximumLevel)
  115. .url,
  116. pixelsToCheck: [
  117. new Cartesian2(0, 0),
  118. new Cartesian2(200, 20),
  119. new Cartesian2(20, 200),
  120. new Cartesian2(80, 110),
  121. new Cartesian2(160, 130),
  122. ],
  123. disableCheckIfAllPixelsAreTransparent: true,
  124. });
  125. }
  126. provider._ready = true;
  127. };
  128. function metadataSuccess(data, imageryProviderBuilder) {
  129. const tileInfo = data.tileInfo;
  130. if (!defined(tileInfo)) {
  131. imageryProviderBuilder.useTiles = false;
  132. } else {
  133. imageryProviderBuilder.tileWidth = tileInfo.rows;
  134. imageryProviderBuilder.tileHeight = tileInfo.cols;
  135. if (
  136. tileInfo.spatialReference.wkid === 102100 ||
  137. tileInfo.spatialReference.wkid === 102113
  138. ) {
  139. imageryProviderBuilder.tilingScheme = new WebMercatorTilingScheme({
  140. ellipsoid: imageryProviderBuilder.ellipsoid,
  141. });
  142. } else if (data.tileInfo.spatialReference.wkid === 4326) {
  143. imageryProviderBuilder.tilingScheme = new GeographicTilingScheme({
  144. ellipsoid: imageryProviderBuilder.ellipsoid,
  145. });
  146. } else {
  147. const message = `Tile spatial reference WKID ${data.tileInfo.spatialReference.wkid} is not supported.`;
  148. throw new RuntimeError(message);
  149. }
  150. imageryProviderBuilder.maximumLevel = data.tileInfo.lods.length - 1;
  151. if (defined(data.fullExtent)) {
  152. if (
  153. defined(data.fullExtent.spatialReference) &&
  154. defined(data.fullExtent.spatialReference.wkid)
  155. ) {
  156. if (
  157. data.fullExtent.spatialReference.wkid === 102100 ||
  158. data.fullExtent.spatialReference.wkid === 102113
  159. ) {
  160. const projection = new WebMercatorProjection();
  161. const extent = data.fullExtent;
  162. const sw = projection.unproject(
  163. new Cartesian3(
  164. Math.max(
  165. extent.xmin,
  166. -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
  167. Math.PI
  168. ),
  169. Math.max(
  170. extent.ymin,
  171. -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
  172. Math.PI
  173. ),
  174. 0.0
  175. )
  176. );
  177. const ne = projection.unproject(
  178. new Cartesian3(
  179. Math.min(
  180. extent.xmax,
  181. imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
  182. Math.PI
  183. ),
  184. Math.min(
  185. extent.ymax,
  186. imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius *
  187. Math.PI
  188. ),
  189. 0.0
  190. )
  191. );
  192. imageryProviderBuilder.rectangle = new Rectangle(
  193. sw.longitude,
  194. sw.latitude,
  195. ne.longitude,
  196. ne.latitude
  197. );
  198. } else if (data.fullExtent.spatialReference.wkid === 4326) {
  199. imageryProviderBuilder.rectangle = Rectangle.fromDegrees(
  200. data.fullExtent.xmin,
  201. data.fullExtent.ymin,
  202. data.fullExtent.xmax,
  203. data.fullExtent.ymax
  204. );
  205. } else {
  206. const extentMessage = `fullExtent.spatialReference WKID ${data.fullExtent.spatialReference.wkid} is not supported.`;
  207. throw new RuntimeError(extentMessage);
  208. }
  209. }
  210. } else {
  211. imageryProviderBuilder.rectangle =
  212. imageryProviderBuilder.tilingScheme.rectangle;
  213. }
  214. imageryProviderBuilder.useTiles = true;
  215. }
  216. if (defined(data.copyrightText) && data.copyrightText.length > 0) {
  217. if (defined(imageryProviderBuilder.credit)) {
  218. imageryProviderBuilder.tileCredits = [new Credit(data.copyrightText)];
  219. } else {
  220. imageryProviderBuilder.credit = new Credit(data.copyrightText);
  221. }
  222. }
  223. }
  224. function metadataFailure(resource, error, provider) {
  225. let message = `An error occurred while accessing ${resource.url}`;
  226. if (defined(error) && defined(error.message)) {
  227. message += `: ${error.message}`;
  228. }
  229. // When readyPromise is deprecated, TileProviderError.reportError,
  230. // and related parameters can be removed
  231. TileProviderError.reportError(
  232. undefined,
  233. provider,
  234. defined(provider) ? provider._errorEvent : undefined,
  235. message,
  236. undefined,
  237. undefined,
  238. undefined,
  239. error
  240. );
  241. throw new RuntimeError(message);
  242. }
  243. async function requestMetadata(resource, imageryProviderBuilder, provider) {
  244. const jsonResource = resource.getDerivedResource({
  245. queryParameters: {
  246. f: "json",
  247. },
  248. });
  249. try {
  250. const data = await jsonResource.fetchJson();
  251. metadataSuccess(data, imageryProviderBuilder);
  252. } catch (error) {
  253. metadataFailure(resource, error, provider);
  254. }
  255. }
  256. /**
  257. * <div class="notice">
  258. * This object is normally not instantiated directly, use {@link ArcGisMapServerImageryProvider.fromBasemapType} or {@link ArcGisMapServerImageryProvider.fromUrl}.
  259. * </div>
  260. *
  261. * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are
  262. * used, if available.
  263. *
  264. * <br/>
  265. *
  266. * An {@link https://developers.arcgis.com/documentation/mapping-apis-and-services/security| ArcGIS Access Token } is required to authenticate requests to an ArcGIS Image Tile service.
  267. * To access secure ArcGIS resources, it's required to create an ArcGIS developer
  268. * account or an ArcGIS online account, then implement an authentication method to obtain an access token.
  269. *
  270. * @alias ArcGisMapServerImageryProvider
  271. * @constructor
  272. *
  273. * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options
  274. *
  275. * @see ArcGisMapServerImageryProvider.fromBasemapType
  276. * @see ArcGisMapServerImageryProvider.fromUrl
  277. *
  278. * @example
  279. * // Set the default access token for accessing ArcGIS Image Tile service
  280. * Cesium.ArcGisMapService.defaultAccessToken = "<ArcGIS Access Token>";
  281. *
  282. * // Add a base layer from a default ArcGIS basemap
  283. * const viewer = new Cesium.Viewer("cesiumContainer", {
  284. * baseLayer: Cesium.ImageryLayer.fromProviderAsync(
  285. * Cesium.ArcGisMapServerImageryProvider.fromBasemapType(
  286. * Cesium.ArcGisBaseMapType.SATELLITE
  287. * )
  288. * ),
  289. * });
  290. *
  291. * @example
  292. * // Create an imagery provider from the url directly
  293. * const esri = await Cesium.ArcGisMapServerImageryProvider.fromUrl(
  294. * "https://ibasemaps-api.arcgis.com/arcgis/rest/services/World_Imagery/MapServer", {
  295. * token: "<ArcGIS Access Token>"
  296. * });
  297. *
  298. * @see {@link https://developers.arcgis.com/rest/|ArcGIS Server REST API}
  299. * @see {@link https://developers.arcgis.com/documentation/mapping-apis-and-services/security| ArcGIS Access Token }
  300. */
  301. function ArcGisMapServerImageryProvider(options) {
  302. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  303. this._defaultAlpha = undefined;
  304. this._defaultNightAlpha = undefined;
  305. this._defaultDayAlpha = undefined;
  306. this._defaultBrightness = undefined;
  307. this._defaultContrast = undefined;
  308. this._defaultHue = undefined;
  309. this._defaultSaturation = undefined;
  310. this._defaultGamma = undefined;
  311. this._defaultMinificationFilter = undefined;
  312. this._defaultMagnificationFilter = undefined;
  313. this._tileDiscardPolicy = options.tileDiscardPolicy;
  314. this._tileWidth = defaultValue(options.tileWidth, 256);
  315. this._tileHeight = defaultValue(options.tileHeight, 256);
  316. this._maximumLevel = options.maximumLevel;
  317. this._tilingScheme = defaultValue(
  318. options.tilingScheme,
  319. new GeographicTilingScheme({ ellipsoid: options.ellipsoid })
  320. );
  321. this._useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true);
  322. this._rectangle = defaultValue(
  323. options.rectangle,
  324. this._tilingScheme.rectangle
  325. );
  326. this._layers = options.layers;
  327. this._credit = options.credit;
  328. this._tileCredits = undefined;
  329. let credit = options.credit;
  330. if (typeof credit === "string") {
  331. credit = new Credit(credit);
  332. }
  333. /**
  334. * Gets or sets a value indicating whether feature picking is enabled. If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will
  335. * invoke the "identify" operation on the ArcGIS server and return the features included in the response. If false,
  336. * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features)
  337. * without communicating with the server.
  338. * @type {boolean}
  339. * @default true
  340. */
  341. this.enablePickFeatures = defaultValue(options.enablePickFeatures, true);
  342. this._errorEvent = new Event();
  343. this._ready = false;
  344. if (defined(options.url)) {
  345. deprecationWarning(
  346. "ArcGisMapServerImageryProvider options.url",
  347. "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead."
  348. );
  349. const resource = Resource.createIfNeeded(options.url);
  350. resource.appendForwardSlash();
  351. this._tileDiscardPolicy = options.tileDiscardPolicy;
  352. if (defined(options.token)) {
  353. resource.setQueryParameters({
  354. token: options.token,
  355. });
  356. }
  357. this._resource = resource;
  358. const imageryProviderBuilder = new ImageryProviderBuilder(options);
  359. if (imageryProviderBuilder.useTiles) {
  360. this._readyPromise = requestMetadata(
  361. resource,
  362. imageryProviderBuilder,
  363. this
  364. ).then(() => {
  365. imageryProviderBuilder.build(this);
  366. return true;
  367. });
  368. } else {
  369. imageryProviderBuilder.build(this);
  370. this._readyPromise = Promise.resolve(true);
  371. }
  372. }
  373. }
  374. /**
  375. * Creates an {@link ImageryProvider} which provides tiled imagery from an ArcGIS base map.
  376. * @param {ArcGisBaseMapType} style The style of the ArcGIS base map imagery. Valid options are {@link ArcGisBaseMapType.SATELLITE}, {@link ArcGisBaseMapType.OCEANS}, and {@link ArcGisBaseMapType.HILLSHADE}.
  377. * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options.
  378. * @returns {Promise<ArcGisMapServerImageryProvider>} A promise that resolves to the created ArcGisMapServerImageryProvider.
  379. *
  380. * @example
  381. * // Set the default access token for accessing ArcGIS Image Tile service
  382. * Cesium.ArcGisMapService.defaultAccessToken = "<ArcGIS Access Token>";
  383. *
  384. * // Add a base layer from a default ArcGIS basemap
  385. * const provider = await Cesium.ArcGisMapServerImageryProvider.fromBasemapType(
  386. * Cesium.ArcGisBaseMapType.SATELLITE);
  387. *
  388. * @example
  389. * // Add a base layer from a default ArcGIS Basemap
  390. * const viewer = new Cesium.Viewer("cesiumContainer", {
  391. * baseLayer: Cesium.ImageryLayer.fromProviderAsync(
  392. * Cesium.ArcGisMapServerImageryProvider.fromBasemapType(
  393. * Cesium.ArcGisBaseMapType.HILLSHADE, {
  394. * token: "<ArcGIS Access Token>"
  395. * }
  396. * )
  397. * ),
  398. * });
  399. */
  400. ArcGisMapServerImageryProvider.fromBasemapType = async function (
  401. style,
  402. options
  403. ) {
  404. //>>includeStart('debug', pragmas.debug);
  405. Check.defined("style", style);
  406. //>>includeEnd('debug');
  407. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  408. let accessToken;
  409. let server;
  410. let warningCredit;
  411. switch (style) {
  412. case ArcGisBaseMapType.SATELLITE:
  413. {
  414. accessToken = defaultValue(
  415. options.token,
  416. ArcGisMapService.defaultAccessToken
  417. );
  418. server = Resource.createIfNeeded(
  419. defaultValue(options.url, ArcGisMapService.defaultWorldImageryServer)
  420. );
  421. server.appendForwardSlash();
  422. const defaultTokenCredit = ArcGisMapService.getDefaultTokenCredit(
  423. accessToken
  424. );
  425. if (defined(defaultTokenCredit)) {
  426. warningCredit = Credit.clone(defaultTokenCredit);
  427. }
  428. }
  429. break;
  430. case ArcGisBaseMapType.OCEANS:
  431. {
  432. accessToken = defaultValue(
  433. options.token,
  434. ArcGisMapService.defaultAccessToken
  435. );
  436. server = Resource.createIfNeeded(
  437. defaultValue(options.url, ArcGisMapService.defaultWorldOceanServer)
  438. );
  439. server.appendForwardSlash();
  440. const defaultTokenCredit = ArcGisMapService.getDefaultTokenCredit(
  441. accessToken
  442. );
  443. if (defined(defaultTokenCredit)) {
  444. warningCredit = Credit.clone(defaultTokenCredit);
  445. }
  446. }
  447. break;
  448. case ArcGisBaseMapType.HILLSHADE:
  449. {
  450. accessToken = defaultValue(
  451. options.token,
  452. ArcGisMapService.defaultAccessToken
  453. );
  454. server = Resource.createIfNeeded(
  455. defaultValue(
  456. options.url,
  457. ArcGisMapService.defaultWorldHillshadeServer
  458. )
  459. );
  460. server.appendForwardSlash();
  461. const defaultTokenCredit = ArcGisMapService.getDefaultTokenCredit(
  462. accessToken
  463. );
  464. if (defined(defaultTokenCredit)) {
  465. warningCredit = Credit.clone(defaultTokenCredit);
  466. }
  467. }
  468. break;
  469. default:
  470. //>>includeStart('debug', pragmas.debug);
  471. throw new DeveloperError(`Unsupported basemap type: ${style}`);
  472. //>>includeEnd('debug');
  473. }
  474. return ArcGisMapServerImageryProvider.fromUrl(server, {
  475. ...options,
  476. token: accessToken,
  477. credit: warningCredit,
  478. usePreCachedTilesIfAvailable: true, // ArcGIS Base Map Service Layers only support Tiled views
  479. });
  480. };
  481. function buildImageResource(imageryProvider, x, y, level, request) {
  482. let resource;
  483. if (imageryProvider._useTiles) {
  484. resource = imageryProvider._resource.getDerivedResource({
  485. url: `tile/${level}/${y}/${x}`,
  486. request: request,
  487. });
  488. } else {
  489. const nativeRectangle = imageryProvider._tilingScheme.tileXYToNativeRectangle(
  490. x,
  491. y,
  492. level
  493. );
  494. const bbox = `${nativeRectangle.west},${nativeRectangle.south},${nativeRectangle.east},${nativeRectangle.north}`;
  495. const query = {
  496. bbox: bbox,
  497. size: `${imageryProvider._tileWidth},${imageryProvider._tileHeight}`,
  498. format: "png32",
  499. transparent: true,
  500. f: "image",
  501. };
  502. if (
  503. imageryProvider._tilingScheme.projection instanceof GeographicProjection
  504. ) {
  505. query.bboxSR = 4326;
  506. query.imageSR = 4326;
  507. } else {
  508. query.bboxSR = 3857;
  509. query.imageSR = 3857;
  510. }
  511. if (imageryProvider.layers) {
  512. query.layers = `show:${imageryProvider.layers}`;
  513. }
  514. resource = imageryProvider._resource.getDerivedResource({
  515. url: "export",
  516. request: request,
  517. queryParameters: query,
  518. });
  519. }
  520. return resource;
  521. }
  522. Object.defineProperties(ArcGisMapServerImageryProvider.prototype, {
  523. /**
  524. * Gets the URL of the ArcGIS MapServer.
  525. * @memberof ArcGisMapServerImageryProvider.prototype
  526. * @type {string}
  527. * @readonly
  528. */
  529. url: {
  530. get: function () {
  531. return this._resource._url;
  532. },
  533. },
  534. /**
  535. * Gets the ArcGIS token used to authenticate with the ArcGis MapServer service.
  536. * @memberof ArcGisMapServerImageryProvider.prototype
  537. * @type {string}
  538. * @readonly
  539. */
  540. token: {
  541. get: function () {
  542. return this._resource.queryParameters.token;
  543. },
  544. },
  545. /**
  546. * Gets the proxy used by this provider.
  547. * @memberof ArcGisMapServerImageryProvider.prototype
  548. * @type {Proxy}
  549. * @readonly
  550. */
  551. proxy: {
  552. get: function () {
  553. return this._resource.proxy;
  554. },
  555. },
  556. /**
  557. * Gets the width of each tile, in pixels.
  558. * @memberof ArcGisMapServerImageryProvider.prototype
  559. * @type {number}
  560. * @readonly
  561. */
  562. tileWidth: {
  563. get: function () {
  564. return this._tileWidth;
  565. },
  566. },
  567. /**
  568. * Gets the height of each tile, in pixels.
  569. * @memberof ArcGisMapServerImageryProvider.prototype
  570. * @type {number}
  571. * @readonly
  572. */
  573. tileHeight: {
  574. get: function () {
  575. return this._tileHeight;
  576. },
  577. },
  578. /**
  579. * Gets the maximum level-of-detail that can be requested.
  580. * @memberof ArcGisMapServerImageryProvider.prototype
  581. * @type {number|undefined}
  582. * @readonly
  583. */
  584. maximumLevel: {
  585. get: function () {
  586. return this._maximumLevel;
  587. },
  588. },
  589. /**
  590. * Gets the minimum level-of-detail that can be requested.
  591. * @memberof ArcGisMapServerImageryProvider.prototype
  592. * @type {number}
  593. * @readonly
  594. */
  595. minimumLevel: {
  596. get: function () {
  597. return 0;
  598. },
  599. },
  600. /**
  601. * Gets the tiling scheme used by this provider.
  602. * @memberof ArcGisMapServerImageryProvider.prototype
  603. * @type {TilingScheme}
  604. * @readonly
  605. */
  606. tilingScheme: {
  607. get: function () {
  608. return this._tilingScheme;
  609. },
  610. },
  611. /**
  612. * Gets the rectangle, in radians, of the imagery provided by this instance.
  613. * @memberof ArcGisMapServerImageryProvider.prototype
  614. * @type {Rectangle}
  615. * @readonly
  616. */
  617. rectangle: {
  618. get: function () {
  619. return this._rectangle;
  620. },
  621. },
  622. /**
  623. * Gets the tile discard policy. If not undefined, the discard policy is responsible
  624. * for filtering out "missing" tiles via its shouldDiscardImage function. If this function
  625. * returns undefined, no tiles are filtered.
  626. * @memberof ArcGisMapServerImageryProvider.prototype
  627. * @type {TileDiscardPolicy}
  628. * @readonly
  629. */
  630. tileDiscardPolicy: {
  631. get: function () {
  632. return this._tileDiscardPolicy;
  633. },
  634. },
  635. /**
  636. * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing
  637. * to the event, you will be notified of the error and can potentially recover from it. Event listeners
  638. * are passed an instance of {@link TileProviderError}.
  639. * @memberof ArcGisMapServerImageryProvider.prototype
  640. * @type {Event}
  641. * @readonly
  642. */
  643. errorEvent: {
  644. get: function () {
  645. return this._errorEvent;
  646. },
  647. },
  648. /**
  649. * Gets a value indicating whether or not the provider is ready for use.
  650. * @memberof ArcGisMapServerImageryProvider.prototype
  651. * @type {boolean}
  652. * @readonly
  653. * @deprecated
  654. */
  655. ready: {
  656. get: function () {
  657. deprecationWarning(
  658. "ArcGisMapServerImageryProvider.ready",
  659. "ArcGisMapServerImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead."
  660. );
  661. return this._ready;
  662. },
  663. },
  664. /**
  665. * Gets a promise that resolves to true when the provider is ready for use.
  666. * @memberof ArcGisMapServerImageryProvider.prototype
  667. * @type {Promise<boolean>}
  668. * @readonly
  669. * @deprecated
  670. */
  671. readyPromise: {
  672. get: function () {
  673. deprecationWarning(
  674. "ArcGisMapServerImageryProvider.readyPromise",
  675. "ArcGisMapServerImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead."
  676. );
  677. return this._readyPromise;
  678. },
  679. },
  680. /**
  681. * Gets the credit to display when this imagery provider is active. Typically this is used to credit
  682. * the source of the imagery. This function should not be called before {@link ArcGisMapServerImageryProvider#ready} returns true.
  683. * @memberof ArcGisMapServerImageryProvider.prototype
  684. * @type {Credit}
  685. * @readonly
  686. */
  687. credit: {
  688. get: function () {
  689. return this._credit;
  690. },
  691. },
  692. /**
  693. * Gets a value indicating whether this imagery provider is using pre-cached tiles from the
  694. * ArcGIS MapServer.
  695. * @memberof ArcGisMapServerImageryProvider.prototype
  696. *
  697. * @type {boolean}
  698. * @readonly
  699. * @default true
  700. */
  701. usingPrecachedTiles: {
  702. get: function () {
  703. return this._useTiles;
  704. },
  705. },
  706. /**
  707. * Gets a value indicating whether or not the images provided by this imagery provider
  708. * include an alpha channel. If this property is false, an alpha channel, if present, will
  709. * be ignored. If this property is true, any images without an alpha channel will be treated
  710. * as if their alpha is 1.0 everywhere. When this property is false, memory usage
  711. * and texture upload time are reduced.
  712. * @memberof ArcGisMapServerImageryProvider.prototype
  713. *
  714. * @type {boolean}
  715. * @readonly
  716. * @default true
  717. */
  718. hasAlphaChannel: {
  719. get: function () {
  720. return true;
  721. },
  722. },
  723. /**
  724. * Gets the comma-separated list of layer IDs to show.
  725. * @memberof ArcGisMapServerImageryProvider.prototype
  726. *
  727. * @type {string}
  728. */
  729. layers: {
  730. get: function () {
  731. return this._layers;
  732. },
  733. },
  734. /**
  735. * The default alpha blending value of this provider, with 0.0 representing fully transparent and
  736. * 1.0 representing fully opaque.
  737. * @memberof ArcGisMapServerImageryProvider.prototype
  738. * @type {Number|undefined}
  739. * @deprecated
  740. */
  741. defaultAlpha: {
  742. get: function () {
  743. deprecationWarning(
  744. "ArcGisMapServerImageryProvider.defaultAlpha",
  745. "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead."
  746. );
  747. return this._defaultAlpha;
  748. },
  749. set: function (value) {
  750. deprecationWarning(
  751. "ArcGisMapServerImageryProvider.defaultAlpha",
  752. "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead."
  753. );
  754. this._defaultAlpha = value;
  755. },
  756. },
  757. /**
  758. * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
  759. * 1.0 representing fully opaque.
  760. * @memberof ArcGisMapServerImageryProvider.prototype
  761. * @type {Number|undefined}
  762. * @deprecated
  763. */
  764. defaultNightAlpha: {
  765. get: function () {
  766. deprecationWarning(
  767. "ArcGisMapServerImageryProvider.defaultNightAlpha",
  768. "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead."
  769. );
  770. return this._defaultNightAlpha;
  771. },
  772. set: function (value) {
  773. deprecationWarning(
  774. "ArcGisMapServerImageryProvider.defaultNightAlpha",
  775. "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead."
  776. );
  777. this._defaultNightAlpha = value;
  778. },
  779. },
  780. /**
  781. * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
  782. * 1.0 representing fully opaque.
  783. * @memberof ArcGisMapServerImageryProvider.prototype
  784. * @type {Number|undefined}
  785. * @deprecated
  786. */
  787. defaultDayAlpha: {
  788. get: function () {
  789. deprecationWarning(
  790. "ArcGisMapServerImageryProvider.defaultDayAlpha",
  791. "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead."
  792. );
  793. return this._defaultDayAlpha;
  794. },
  795. set: function (value) {
  796. deprecationWarning(
  797. "ArcGisMapServerImageryProvider.defaultDayAlpha",
  798. "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead."
  799. );
  800. this._defaultDayAlpha = value;
  801. },
  802. },
  803. /**
  804. * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
  805. * makes the imagery darker while greater than 1.0 makes it brighter.
  806. * @memberof ArcGisMapServerImageryProvider.prototype
  807. * @type {Number|undefined}
  808. * @deprecated
  809. */
  810. defaultBrightness: {
  811. get: function () {
  812. deprecationWarning(
  813. "ArcGisMapServerImageryProvider.defaultBrightness",
  814. "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead."
  815. );
  816. return this._defaultBrightness;
  817. },
  818. set: function (value) {
  819. deprecationWarning(
  820. "ArcGisMapServerImageryProvider.defaultBrightness",
  821. "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead."
  822. );
  823. this._defaultBrightness = value;
  824. },
  825. },
  826. /**
  827. * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
  828. * the contrast while greater than 1.0 increases it.
  829. * @memberof ArcGisMapServerImageryProvider.prototype
  830. * @type {Number|undefined}
  831. * @deprecated
  832. */
  833. defaultContrast: {
  834. get: function () {
  835. deprecationWarning(
  836. "ArcGisMapServerImageryProvider.defaultContrast",
  837. "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead."
  838. );
  839. return this._defaultContrast;
  840. },
  841. set: function (value) {
  842. deprecationWarning(
  843. "ArcGisMapServerImageryProvider.defaultContrast",
  844. "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead."
  845. );
  846. this._defaultContrast = value;
  847. },
  848. },
  849. /**
  850. * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
  851. * @memberof ArcGisMapServerImageryProvider.prototype
  852. * @type {Number|undefined}
  853. * @deprecated
  854. */
  855. defaultHue: {
  856. get: function () {
  857. deprecationWarning(
  858. "ArcGisMapServerImageryProvider.defaultHue",
  859. "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead."
  860. );
  861. return this._defaultHue;
  862. },
  863. set: function (value) {
  864. deprecationWarning(
  865. "ArcGisMapServerImageryProvider.defaultHue",
  866. "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead."
  867. );
  868. this._defaultHue = value;
  869. },
  870. },
  871. /**
  872. * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
  873. * saturation while greater than 1.0 increases it.
  874. * @memberof ArcGisMapServerImageryProvider.prototype
  875. * @type {Number|undefined}
  876. * @deprecated
  877. */
  878. defaultSaturation: {
  879. get: function () {
  880. deprecationWarning(
  881. "ArcGisMapServerImageryProvider.defaultSaturation",
  882. "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead."
  883. );
  884. return this._defaultSaturation;
  885. },
  886. set: function (value) {
  887. deprecationWarning(
  888. "ArcGisMapServerImageryProvider.defaultSaturation",
  889. "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead."
  890. );
  891. this._defaultSaturation = value;
  892. },
  893. },
  894. /**
  895. * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
  896. * @memberof ArcGisMapServerImageryProvider.prototype
  897. * @type {Number|undefined}
  898. * @deprecated
  899. */
  900. defaultGamma: {
  901. get: function () {
  902. deprecationWarning(
  903. "ArcGisMapServerImageryProvider.defaultGamma",
  904. "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead."
  905. );
  906. return this._defaultGamma;
  907. },
  908. set: function (value) {
  909. deprecationWarning(
  910. "ArcGisMapServerImageryProvider.defaultGamma",
  911. "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead."
  912. );
  913. this._defaultGamma = value;
  914. },
  915. },
  916. /**
  917. * The default texture minification filter to apply to this provider.
  918. * @memberof ArcGisMapServerImageryProvider.prototype
  919. * @type {TextureMinificationFilter}
  920. * @deprecated
  921. */
  922. defaultMinificationFilter: {
  923. get: function () {
  924. deprecationWarning(
  925. "ArcGisMapServerImageryProvider.defaultMinificationFilter",
  926. "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead."
  927. );
  928. return this._defaultMinificationFilter;
  929. },
  930. set: function (value) {
  931. deprecationWarning(
  932. "ArcGisMapServerImageryProvider.defaultMinificationFilter",
  933. "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead."
  934. );
  935. this._defaultMinificationFilter = value;
  936. },
  937. },
  938. /**
  939. * The default texture magnification filter to apply to this provider.
  940. * @memberof ArcGisMapServerImageryProvider.prototype
  941. * @type {TextureMagnificationFilter}
  942. * @deprecated
  943. */
  944. defaultMagnificationFilter: {
  945. get: function () {
  946. deprecationWarning(
  947. "ArcGisMapServerImageryProvider.defaultMagnificationFilter",
  948. "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead."
  949. );
  950. return this._defaultMagnificationFilter;
  951. },
  952. set: function (value) {
  953. deprecationWarning(
  954. "ArcGisMapServerImageryProvider.defaultMagnificationFilter",
  955. "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead."
  956. );
  957. this._defaultMagnificationFilter = value;
  958. },
  959. },
  960. });
  961. /**
  962. * Creates an {@link ImageryProvider} which provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are
  963. * used, if available.
  964. *
  965. * @param {Resource|String} url The URL of the ArcGIS MapServer service.
  966. * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options.
  967. * @returns {Promise<ArcGisMapServerImageryProvider>} A promise that resolves to the created ArcGisMapServerImageryProvider.
  968. *
  969. * @example
  970. * const esri = await Cesium.ArcGisMapServerImageryProvider.fromUrl(
  971. * "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
  972. * );
  973. *
  974. * @exception {RuntimeError} metadata spatial reference specifies an unknown WKID
  975. * @exception {RuntimeError} metadata fullExtent.spatialReference specifies an unknown WKID
  976. */
  977. ArcGisMapServerImageryProvider.fromUrl = async function (url, options) {
  978. //>>includeStart('debug', pragmas.debug);
  979. Check.defined("url", url);
  980. //>>includeEnd('debug');
  981. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  982. const resource = Resource.createIfNeeded(url);
  983. resource.appendForwardSlash();
  984. if (defined(options.token)) {
  985. resource.setQueryParameters({
  986. token: options.token,
  987. });
  988. }
  989. const provider = new ArcGisMapServerImageryProvider(options);
  990. provider._resource = resource;
  991. const imageryProviderBuilder = new ImageryProviderBuilder(options);
  992. const useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true);
  993. if (useTiles) {
  994. await requestMetadata(resource, imageryProviderBuilder);
  995. }
  996. imageryProviderBuilder.build(provider);
  997. provider._readyPromise = Promise.resolve(true);
  998. return provider;
  999. };
  1000. /**
  1001. * Gets the credits to be displayed when a given tile is displayed.
  1002. *
  1003. * @param {number} x The tile X coordinate.
  1004. * @param {number} y The tile Y coordinate.
  1005. * @param {number} level The tile level;
  1006. * @returns {Credit[]} The credits to be displayed when the tile is displayed.
  1007. */
  1008. ArcGisMapServerImageryProvider.prototype.getTileCredits = function (
  1009. x,
  1010. y,
  1011. level
  1012. ) {
  1013. return this._tileCredits;
  1014. };
  1015. /**
  1016. * Requests the image for a given tile.
  1017. *
  1018. * @param {number} x The tile X coordinate.
  1019. * @param {number} y The tile Y coordinate.
  1020. * @param {number} level The tile level.
  1021. * @param {Request} [request] The request object. Intended for internal use only.
  1022. * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or
  1023. * undefined if there are too many active requests to the server, and the request should be retried later.
  1024. */
  1025. ArcGisMapServerImageryProvider.prototype.requestImage = function (
  1026. x,
  1027. y,
  1028. level,
  1029. request
  1030. ) {
  1031. return ImageryProvider.loadImage(
  1032. this,
  1033. buildImageResource(this, x, y, level, request)
  1034. );
  1035. };
  1036. /**
  1037. /**
  1038. * Asynchronously determines what features, if any, are located at a given longitude and latitude within
  1039. * a tile.
  1040. *
  1041. * @param {number} x The tile X coordinate.
  1042. * @param {number} y The tile Y coordinate.
  1043. * @param {number} level The tile level.
  1044. * @param {number} longitude The longitude at which to pick features.
  1045. * @param {number} latitude The latitude at which to pick features.
  1046. * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous
  1047. * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo}
  1048. * instances. The array may be empty if no features are found at the given location.
  1049. */
  1050. ArcGisMapServerImageryProvider.prototype.pickFeatures = function (
  1051. x,
  1052. y,
  1053. level,
  1054. longitude,
  1055. latitude
  1056. ) {
  1057. if (!this.enablePickFeatures) {
  1058. return undefined;
  1059. }
  1060. const rectangle = this._tilingScheme.tileXYToNativeRectangle(x, y, level);
  1061. let horizontal;
  1062. let vertical;
  1063. let sr;
  1064. if (this._tilingScheme.projection instanceof GeographicProjection) {
  1065. horizontal = CesiumMath.toDegrees(longitude);
  1066. vertical = CesiumMath.toDegrees(latitude);
  1067. sr = "4326";
  1068. } else {
  1069. const projected = this._tilingScheme.projection.project(
  1070. new Cartographic(longitude, latitude, 0.0)
  1071. );
  1072. horizontal = projected.x;
  1073. vertical = projected.y;
  1074. sr = "3857";
  1075. }
  1076. let layers = "visible";
  1077. if (defined(this._layers)) {
  1078. layers += `:${this._layers}`;
  1079. }
  1080. const query = {
  1081. f: "json",
  1082. tolerance: 2,
  1083. geometryType: "esriGeometryPoint",
  1084. geometry: `${horizontal},${vertical}`,
  1085. mapExtent: `${rectangle.west},${rectangle.south},${rectangle.east},${rectangle.north}`,
  1086. imageDisplay: `${this._tileWidth},${this._tileHeight},96`,
  1087. sr: sr,
  1088. layers: layers,
  1089. };
  1090. const resource = this._resource.getDerivedResource({
  1091. url: "identify",
  1092. queryParameters: query,
  1093. });
  1094. return resource.fetchJson().then(function (json) {
  1095. const result = [];
  1096. const features = json.results;
  1097. if (!defined(features)) {
  1098. return result;
  1099. }
  1100. for (let i = 0; i < features.length; ++i) {
  1101. const feature = features[i];
  1102. const featureInfo = new ImageryLayerFeatureInfo();
  1103. featureInfo.data = feature;
  1104. featureInfo.name = feature.value;
  1105. featureInfo.properties = feature.attributes;
  1106. featureInfo.configureDescriptionFromProperties(feature.attributes);
  1107. // If this is a point feature, use the coordinates of the point.
  1108. if (feature.geometryType === "esriGeometryPoint" && feature.geometry) {
  1109. const wkid =
  1110. feature.geometry.spatialReference &&
  1111. feature.geometry.spatialReference.wkid
  1112. ? feature.geometry.spatialReference.wkid
  1113. : 4326;
  1114. if (wkid === 4326 || wkid === 4283) {
  1115. featureInfo.position = Cartographic.fromDegrees(
  1116. feature.geometry.x,
  1117. feature.geometry.y,
  1118. feature.geometry.z
  1119. );
  1120. } else if (wkid === 102100 || wkid === 900913 || wkid === 3857) {
  1121. const projection = new WebMercatorProjection();
  1122. featureInfo.position = projection.unproject(
  1123. new Cartesian3(
  1124. feature.geometry.x,
  1125. feature.geometry.y,
  1126. feature.geometry.z
  1127. )
  1128. );
  1129. }
  1130. }
  1131. result.push(featureInfo);
  1132. }
  1133. return result;
  1134. });
  1135. };
  1136. ArcGisMapServerImageryProvider._metadataCache = {};
  1137. export default ArcGisMapServerImageryProvider;