IonImageryProvider.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. import Check from "../Core/Check.js";
  2. import defaultValue from "../Core/defaultValue.js";
  3. import defined from "../Core/defined.js";
  4. import deprecationWarning from "../Core/deprecationWarning.js";
  5. import Event from "../Core/Event.js";
  6. import IonResource from "../Core/IonResource.js";
  7. import RuntimeError from "../Core/RuntimeError.js";
  8. import ArcGisMapServerImageryProvider from "./ArcGisMapServerImageryProvider.js";
  9. import BingMapsImageryProvider from "./BingMapsImageryProvider.js";
  10. import TileMapServiceImageryProvider from "./TileMapServiceImageryProvider.js";
  11. import GoogleEarthEnterpriseMapsProvider from "./GoogleEarthEnterpriseMapsProvider.js";
  12. import MapboxImageryProvider from "./MapboxImageryProvider.js";
  13. import SingleTileImageryProvider from "./SingleTileImageryProvider.js";
  14. import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js";
  15. import WebMapServiceImageryProvider from "./WebMapServiceImageryProvider.js";
  16. import WebMapTileServiceImageryProvider from "./WebMapTileServiceImageryProvider.js";
  17. function createFactory(Type) {
  18. return function (options) {
  19. return new Type(options);
  20. };
  21. }
  22. // These values are the list of supported external imagery
  23. // assets in the Cesium ion beta. They are subject to change.
  24. const ImageryProviderMapping = {
  25. ARCGIS_MAPSERVER: createFactory(ArcGisMapServerImageryProvider),
  26. BING: createFactory(BingMapsImageryProvider),
  27. GOOGLE_EARTH: createFactory(GoogleEarthEnterpriseMapsProvider),
  28. MAPBOX: createFactory(MapboxImageryProvider),
  29. SINGLE_TILE: createFactory(SingleTileImageryProvider),
  30. TMS: createFactory(TileMapServiceImageryProvider),
  31. URL_TEMPLATE: createFactory(UrlTemplateImageryProvider),
  32. WMS: createFactory(WebMapServiceImageryProvider),
  33. WMTS: createFactory(WebMapTileServiceImageryProvider),
  34. };
  35. const ImageryProviderAsyncMapping = {
  36. ARCGIS_MAPSERVER: ArcGisMapServerImageryProvider.fromUrl,
  37. BING: async (url, options) => {
  38. return BingMapsImageryProvider.fromUrl(url, options);
  39. },
  40. GOOGLE_EARTH: async (url, options) => {
  41. const channel = options.channel;
  42. delete options.channel;
  43. return GoogleEarthEnterpriseMapsProvider.fromUrl(url, channel, options);
  44. },
  45. MAPBOX: (url, options) => {
  46. return new MapboxImageryProvider({
  47. url: url,
  48. ...options,
  49. });
  50. },
  51. SINGLE_TILE: SingleTileImageryProvider.fromUrl,
  52. TMS: TileMapServiceImageryProvider.fromUrl,
  53. URL_TEMPLATE: (url, options) => {
  54. return new UrlTemplateImageryProvider({
  55. url: url,
  56. ...options,
  57. });
  58. },
  59. WMS: (url, options) => {
  60. return new WebMapServiceImageryProvider({
  61. url: url,
  62. ...options,
  63. });
  64. },
  65. WMTS: (url, options) => {
  66. return new WebMapTileServiceImageryProvider({
  67. url: url,
  68. ...options,
  69. });
  70. },
  71. };
  72. /**
  73. * @typedef {object} IonImageryProvider.ConstructorOptions
  74. *
  75. * Initialization options for the TileMapServiceImageryProvider constructor
  76. *
  77. * @property {number} [assetId] An ion imagery asset ID. Deprecated.
  78. * @property {string} [accessToken=Ion.defaultAccessToken] The access token to use.
  79. * @property {string|Resource} [server=Ion.defaultServer] The resource to the Cesium ion API server.
  80. */
  81. /**
  82. * <div class="notice">
  83. * To construct a IonImageryProvider, call {@link IonImageryProvider.fromAssetId}. Do not call the constructor directly.
  84. * </div>
  85. *
  86. * Provides tiled imagery using the Cesium ion REST API.
  87. *
  88. * @alias IonImageryProvider
  89. * @constructor
  90. *
  91. * @param {IonImageryProvider.ConstructorOptions} options Object describing initialization options
  92. *
  93. * @example
  94. * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812));
  95. * viewer.imageryLayers.add(imageryLayer);
  96. *
  97. * @see IonImageryProvider.fromAssetId
  98. */
  99. function IonImageryProvider(options) {
  100. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  101. this._defaultAlpha = undefined;
  102. this._defaultNightAlpha = undefined;
  103. this._defaultDayAlpha = undefined;
  104. this._defaultBrightness = undefined;
  105. this._defaultContrast = undefined;
  106. this._defaultHue = undefined;
  107. this._defaultSaturation = undefined;
  108. this._defaultGamma = undefined;
  109. this._defaultMinificationFilter = undefined;
  110. this._defaultMagnificationFilter = undefined;
  111. this._ready = false;
  112. this._tileCredits = undefined;
  113. this._errorEvent = new Event();
  114. const assetId = options.assetId;
  115. if (defined(assetId)) {
  116. deprecationWarning(
  117. "IonImageryProvider options.assetId",
  118. "options.assetId was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead."
  119. );
  120. IonImageryProvider._initialize(this, assetId, options);
  121. }
  122. }
  123. Object.defineProperties(IonImageryProvider.prototype, {
  124. /**
  125. * Gets a value indicating whether or not the provider is ready for use.
  126. * @memberof IonImageryProvider.prototype
  127. * @type {boolean}
  128. * @readonly
  129. * @deprecated
  130. */
  131. ready: {
  132. get: function () {
  133. deprecationWarning(
  134. "IonImageryProvider.ready",
  135. "IonImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead."
  136. );
  137. return this._ready;
  138. },
  139. },
  140. /**
  141. * Gets a promise that resolves to true when the provider is ready for use.
  142. * @memberof IonImageryProvider.prototype
  143. * @type {Promise<boolean>}
  144. * @readonly
  145. * @deprecated
  146. */
  147. readyPromise: {
  148. get: function () {
  149. deprecationWarning(
  150. "IonImageryProvider.readyPromise",
  151. "IonImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead."
  152. );
  153. return this._readyPromise;
  154. },
  155. },
  156. /**
  157. * Gets the rectangle, in radians, of the imagery provided by the instance.
  158. * @memberof IonImageryProvider.prototype
  159. * @type {Rectangle}
  160. * @readonly
  161. */
  162. rectangle: {
  163. get: function () {
  164. return this._imageryProvider.rectangle;
  165. },
  166. },
  167. /**
  168. * Gets the width of each tile, in pixels.
  169. * @memberof IonImageryProvider.prototype
  170. * @type {number}
  171. * @readonly
  172. */
  173. tileWidth: {
  174. get: function () {
  175. return this._imageryProvider.tileWidth;
  176. },
  177. },
  178. /**
  179. * Gets the height of each tile, in pixels.
  180. * @memberof IonImageryProvider.prototype
  181. * @type {number}
  182. * @readonly
  183. */
  184. tileHeight: {
  185. get: function () {
  186. return this._imageryProvider.tileHeight;
  187. },
  188. },
  189. /**
  190. * Gets the maximum level-of-detail that can be requested.
  191. * @memberof IonImageryProvider.prototype
  192. * @type {number|undefined}
  193. * @readonly
  194. */
  195. maximumLevel: {
  196. get: function () {
  197. return this._imageryProvider.maximumLevel;
  198. },
  199. },
  200. /**
  201. * Gets the minimum level-of-detail that can be requested. Generally,
  202. * a minimum level should only be used when the rectangle of the imagery is small
  203. * enough that the number of tiles at the minimum level is small. An imagery
  204. * provider with more than a few tiles at the minimum level will lead to
  205. * rendering problems.
  206. * @memberof IonImageryProvider.prototype
  207. * @type {number}
  208. * @readonly
  209. */
  210. minimumLevel: {
  211. get: function () {
  212. return this._imageryProvider.minimumLevel;
  213. },
  214. },
  215. /**
  216. * Gets the tiling scheme used by the provider.
  217. * @memberof IonImageryProvider.prototype
  218. * @type {TilingScheme}
  219. * @readonly
  220. */
  221. tilingScheme: {
  222. get: function () {
  223. return this._imageryProvider.tilingScheme;
  224. },
  225. },
  226. /**
  227. * Gets the tile discard policy. If not undefined, the discard policy is responsible
  228. * for filtering out "missing" tiles via its shouldDiscardImage function. If this function
  229. * returns undefined, no tiles are filtered.
  230. * @memberof IonImageryProvider.prototype
  231. * @type {TileDiscardPolicy}
  232. * @readonly
  233. */
  234. tileDiscardPolicy: {
  235. get: function () {
  236. return this._imageryProvider.tileDiscardPolicy;
  237. },
  238. },
  239. /**
  240. * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing
  241. * to the event, you will be notified of the error and can potentially recover from it. Event listeners
  242. * are passed an instance of {@link TileProviderError}.
  243. * @memberof IonImageryProvider.prototype
  244. * @type {Event}
  245. * @readonly
  246. */
  247. errorEvent: {
  248. get: function () {
  249. return this._errorEvent;
  250. },
  251. },
  252. /**
  253. * Gets the credit to display when this imagery provider is active. Typically this is used to credit
  254. * the source of the imagery.
  255. * @memberof IonImageryProvider.prototype
  256. * @type {Credit}
  257. * @readonly
  258. */
  259. credit: {
  260. get: function () {
  261. return this._imageryProvider.credit;
  262. },
  263. },
  264. /**
  265. * Gets a value indicating whether or not the images provided by this imagery provider
  266. * include an alpha channel. If this property is false, an alpha channel, if present, will
  267. * be ignored. If this property is true, any images without an alpha channel will be treated
  268. * as if their alpha is 1.0 everywhere. When this property is false, memory usage
  269. * and texture upload time are reduced.
  270. * @memberof IonImageryProvider.prototype
  271. * @type {boolean}
  272. * @readonly
  273. */
  274. hasAlphaChannel: {
  275. get: function () {
  276. return this._imageryProvider.hasAlphaChannel;
  277. },
  278. },
  279. /**
  280. * Gets the proxy used by this provider.
  281. * @memberof IonImageryProvider.prototype
  282. * @type {Proxy}
  283. * @readonly
  284. * @default undefined
  285. */
  286. proxy: {
  287. get: function () {
  288. return undefined;
  289. },
  290. },
  291. /**
  292. * The default alpha blending value of this provider, with 0.0 representing fully transparent and
  293. * 1.0 representing fully opaque.
  294. * @memberof IonImageryProvider.prototype
  295. * @type {Number|undefined}
  296. * @deprecated
  297. */
  298. defaultAlpha: {
  299. get: function () {
  300. deprecationWarning(
  301. "IonImageryProvider.defaultAlpha",
  302. "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead."
  303. );
  304. return this._defaultAlpha;
  305. },
  306. set: function (value) {
  307. deprecationWarning(
  308. "IonImageryProvider.defaultAlpha",
  309. "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead."
  310. );
  311. this._defaultAlpha = value;
  312. },
  313. },
  314. /**
  315. * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
  316. * 1.0 representing fully opaque.
  317. * @memberof IonImageryProvider.prototype
  318. * @type {Number|undefined}
  319. * @deprecated
  320. */
  321. defaultNightAlpha: {
  322. get: function () {
  323. deprecationWarning(
  324. "IonImageryProvider.defaultNightAlpha",
  325. "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead."
  326. );
  327. return this.defaultNightAlpha;
  328. },
  329. set: function (value) {
  330. deprecationWarning(
  331. "IonImageryProvider.defaultNightAlpha",
  332. "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead."
  333. );
  334. this.defaultNightAlpha = value;
  335. },
  336. },
  337. /**
  338. * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
  339. * 1.0 representing fully opaque.
  340. * @memberof IonImageryProvider.prototype
  341. * @type {Number|undefined}
  342. * @deprecated
  343. */
  344. defaultDayAlpha: {
  345. get: function () {
  346. deprecationWarning(
  347. "IonImageryProvider.defaultDayAlpha",
  348. "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead."
  349. );
  350. return this._defaultDayAlpha;
  351. },
  352. set: function (value) {
  353. deprecationWarning(
  354. "IonImageryProvider.defaultDayAlpha",
  355. "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead."
  356. );
  357. this._defaultDayAlpha = value;
  358. },
  359. },
  360. /**
  361. * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
  362. * makes the imagery darker while greater than 1.0 makes it brighter.
  363. * @memberof IonImageryProvider.prototype
  364. * @type {Number|undefined}
  365. * @deprecated
  366. */
  367. defaultBrightness: {
  368. get: function () {
  369. deprecationWarning(
  370. "IonImageryProvider.defaultBrightness",
  371. "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead."
  372. );
  373. return this._defaultBrightness;
  374. },
  375. set: function (value) {
  376. deprecationWarning(
  377. "IonImageryProvider.defaultBrightness",
  378. "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead."
  379. );
  380. this._defaultBrightness = value;
  381. },
  382. },
  383. /**
  384. * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
  385. * the contrast while greater than 1.0 increases it.
  386. * @memberof IonImageryProvider.prototype
  387. * @type {Number|undefined}
  388. * @deprecated
  389. */
  390. defaultContrast: {
  391. get: function () {
  392. deprecationWarning(
  393. "IonImageryProvider.defaultContrast",
  394. "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead."
  395. );
  396. return this._defaultContrast;
  397. },
  398. set: function (value) {
  399. deprecationWarning(
  400. "IonImageryProvider.defaultContrast",
  401. "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead."
  402. );
  403. this._defaultContrast = value;
  404. },
  405. },
  406. /**
  407. * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
  408. * @memberof IonImageryProvider.prototype
  409. * @type {Number|undefined}
  410. * @deprecated
  411. */
  412. defaultHue: {
  413. get: function () {
  414. deprecationWarning(
  415. "IonImageryProvider.defaultHue",
  416. "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead."
  417. );
  418. return this._defaultHue;
  419. },
  420. set: function (value) {
  421. deprecationWarning(
  422. "IonImageryProvider.defaultHue",
  423. "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead."
  424. );
  425. this._defaultHue = value;
  426. },
  427. },
  428. /**
  429. * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
  430. * saturation while greater than 1.0 increases it.
  431. * @memberof IonImageryProvider.prototype
  432. * @type {Number|undefined}
  433. * @deprecated
  434. */
  435. defaultSaturation: {
  436. get: function () {
  437. deprecationWarning(
  438. "IonImageryProvider.defaultSaturation",
  439. "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead."
  440. );
  441. return this._defaultSaturation;
  442. },
  443. set: function (value) {
  444. deprecationWarning(
  445. "IonImageryProvider.defaultSaturation",
  446. "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead."
  447. );
  448. this._defaultSaturation = value;
  449. },
  450. },
  451. /**
  452. * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
  453. * @memberof IonImageryProvider.prototype
  454. * @type {Number|undefined}
  455. * @deprecated
  456. */
  457. defaultGamma: {
  458. get: function () {
  459. deprecationWarning(
  460. "IonImageryProvider.defaultGamma",
  461. "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead."
  462. );
  463. return this._defaultGamma;
  464. },
  465. set: function (value) {
  466. deprecationWarning(
  467. "IonImageryProvider.defaultGamma",
  468. "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead."
  469. );
  470. this._defaultGamma = value;
  471. },
  472. },
  473. /**
  474. * The default texture minification filter to apply to this provider.
  475. * @memberof IonImageryProvider.prototype
  476. * @type {TextureMinificationFilter}
  477. * @deprecated
  478. */
  479. defaultMinificationFilter: {
  480. get: function () {
  481. deprecationWarning(
  482. "IonImageryProvider.defaultMinificationFilter",
  483. "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead."
  484. );
  485. return this._defaultMinificationFilter;
  486. },
  487. set: function (value) {
  488. deprecationWarning(
  489. "IonImageryProvider.defaultMinificationFilter",
  490. "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead."
  491. );
  492. this._defaultMinificationFilter = value;
  493. },
  494. },
  495. /**
  496. * The default texture magnification filter to apply to this provider.
  497. * @memberof IonImageryProvider.prototype
  498. * @type {TextureMagnificationFilter}
  499. * @deprecated
  500. */
  501. defaultMagnificationFilter: {
  502. get: function () {
  503. deprecationWarning(
  504. "IonImageryProvider.defaultMagnificationFilter",
  505. "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead."
  506. );
  507. return this._defaultMagnificationFilter;
  508. },
  509. set: function (value) {
  510. deprecationWarning(
  511. "IonImageryProvider.defaultMagnificationFilter",
  512. "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead."
  513. );
  514. this._defaultMagnificationFilter = value;
  515. },
  516. },
  517. });
  518. // This is here for backwards compatibility
  519. IonImageryProvider._initialize = function (provider, assetId, options) {
  520. const endpointResource = IonResource._createEndpointResource(
  521. assetId,
  522. options
  523. );
  524. // A simple cache to avoid making repeated requests to ion for endpoints we've
  525. // already retrieved. This exists mainly to support Bing caching to reduce
  526. // world imagery sessions, but provides a small boost of performance in general
  527. // if constantly reloading assets
  528. const cacheKey = assetId.toString() + options.accessToken + options.server;
  529. let promise = IonImageryProvider._endpointCache[cacheKey];
  530. if (!defined(promise)) {
  531. promise = endpointResource.fetchJson();
  532. IonImageryProvider._endpointCache[cacheKey] = promise;
  533. }
  534. provider._readyPromise = promise.then(function (endpoint) {
  535. if (endpoint.type !== "IMAGERY") {
  536. return Promise.reject(
  537. new RuntimeError(`Cesium ion asset ${assetId} is not an imagery asset.`)
  538. );
  539. }
  540. let imageryProvider;
  541. const externalType = endpoint.externalType;
  542. if (!defined(externalType)) {
  543. imageryProvider = new TileMapServiceImageryProvider({
  544. url: new IonResource(endpoint, endpointResource),
  545. });
  546. } else {
  547. const factory = ImageryProviderMapping[externalType];
  548. if (!defined(factory)) {
  549. return Promise.reject(
  550. new RuntimeError(
  551. `Unrecognized Cesium ion imagery type: ${externalType}`
  552. )
  553. );
  554. }
  555. imageryProvider = factory(endpoint.options);
  556. }
  557. provider._tileCredits = IonResource.getCreditsFromEndpoint(
  558. endpoint,
  559. endpointResource
  560. );
  561. imageryProvider.errorEvent.addEventListener(function (tileProviderError) {
  562. //Propagate the errorEvent but set the provider to this instance instead
  563. //of the inner instance.
  564. tileProviderError.provider = provider;
  565. provider._errorEvent.raiseEvent(tileProviderError);
  566. });
  567. provider._imageryProvider = imageryProvider;
  568. // readyPromise is deprecated. This is here for backwards compatibility
  569. return Promise.resolve(imageryProvider._readyPromise).then(function () {
  570. provider._ready = true;
  571. return true;
  572. });
  573. });
  574. };
  575. /**
  576. * Creates a provider for tiled imagery using the Cesium ion REST API.
  577. *
  578. * @param {Number} assetId An ion imagery asset ID.
  579. * @param {IonImageryProvider.ConstructorOptions} options Object describing initialization options.
  580. * @returns {Promise<IonImageryProvider>} A promise which resolves to the created IonImageryProvider.
  581. *
  582. * @example
  583. * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812));
  584. * viewer.imageryLayers.add(imageryLayer);
  585. *
  586. * @exception {RuntimeError} Cesium ion assetId is not an imagery asset
  587. * @exception {RuntimeError} Unrecognized Cesium ion imagery type
  588. */
  589. IonImageryProvider.fromAssetId = async function (assetId, options) {
  590. //>>includeStart('debug', pragmas.debug);
  591. Check.typeOf.number("assetId", assetId);
  592. //>>includeEnd('debug');
  593. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  594. const endpointResource = IonResource._createEndpointResource(
  595. assetId,
  596. options
  597. );
  598. // A simple cache to avoid making repeated requests to ion for endpoints we've
  599. // already retrieved. This exists mainly to support Bing caching to reduce
  600. // world imagery sessions, but provides a small boost of performance in general
  601. // if constantly reloading assets
  602. const cacheKey = assetId.toString() + options.accessToken + options.server;
  603. let promise = IonImageryProvider._endpointCache[cacheKey];
  604. if (!defined(promise)) {
  605. promise = endpointResource.fetchJson();
  606. IonImageryProvider._endpointCache[cacheKey] = promise;
  607. }
  608. const endpoint = await promise;
  609. if (endpoint.type !== "IMAGERY") {
  610. throw new RuntimeError(
  611. `Cesium ion asset ${assetId} is not an imagery asset.`
  612. );
  613. }
  614. let imageryProvider;
  615. const externalType = endpoint.externalType;
  616. if (!defined(externalType)) {
  617. imageryProvider = await TileMapServiceImageryProvider.fromUrl(
  618. new IonResource(endpoint, endpointResource)
  619. );
  620. } else {
  621. const factory = ImageryProviderAsyncMapping[externalType];
  622. if (!defined(factory)) {
  623. throw new RuntimeError(
  624. `Unrecognized Cesium ion imagery type: ${externalType}`
  625. );
  626. }
  627. // Make a copy before editing since this object reference is cached;
  628. const options = { ...endpoint.options };
  629. const url = options.url;
  630. delete options.url;
  631. imageryProvider = await factory(url, options);
  632. }
  633. const provider = new IonImageryProvider(options);
  634. imageryProvider.errorEvent.addEventListener(function (tileProviderError) {
  635. //Propagate the errorEvent but set the provider to this instance instead
  636. //of the inner instance.
  637. tileProviderError.provider = provider;
  638. provider._errorEvent.raiseEvent(tileProviderError);
  639. });
  640. provider._tileCredits = IonResource.getCreditsFromEndpoint(
  641. endpoint,
  642. endpointResource
  643. );
  644. provider._imageryProvider = imageryProvider;
  645. provider._ready = true;
  646. provider._readyPromise = Promise.resolve(true);
  647. return provider;
  648. };
  649. /**
  650. * Gets the credits to be displayed when a given tile is displayed.
  651. * @function
  652. *
  653. * @param {number} x The tile X coordinate.
  654. * @param {number} y The tile Y coordinate.
  655. * @param {number} level The tile level;
  656. * @returns {Credit[]} The credits to be displayed when the tile is displayed.
  657. */
  658. IonImageryProvider.prototype.getTileCredits = function (x, y, level) {
  659. const innerCredits = this._imageryProvider.getTileCredits(x, y, level);
  660. if (!defined(innerCredits)) {
  661. return this._tileCredits;
  662. }
  663. return this._tileCredits.concat(innerCredits);
  664. };
  665. /**
  666. * Requests the image for a given tile.
  667. * @function
  668. *
  669. * @param {number} x The tile X coordinate.
  670. * @param {number} y The tile Y coordinate.
  671. * @param {number} level The tile level.
  672. * @param {Request} [request] The request object. Intended for internal use only.
  673. * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or
  674. * undefined if there are too many active requests to the server, and the request should be retried later.
  675. */
  676. IonImageryProvider.prototype.requestImage = function (x, y, level, request) {
  677. return this._imageryProvider.requestImage(x, y, level, request);
  678. };
  679. /**
  680. * Asynchronously determines what features, if any, are located at a given longitude and latitude within
  681. * a tile. This function is optional, so it may not exist on all ImageryProviders.
  682. *
  683. * @function
  684. *
  685. * @param {number} x The tile X coordinate.
  686. * @param {number} y The tile Y coordinate.
  687. * @param {number} level The tile level.
  688. * @param {number} longitude The longitude at which to pick features.
  689. * @param {number} latitude The latitude at which to pick features.
  690. * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous
  691. * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo}
  692. * instances. The array may be empty if no features are found at the given location.
  693. * It may also be undefined if picking is not supported.
  694. */
  695. IonImageryProvider.prototype.pickFeatures = function (
  696. x,
  697. y,
  698. level,
  699. longitude,
  700. latitude
  701. ) {
  702. return this._imageryProvider.pickFeatures(x, y, level, longitude, latitude);
  703. };
  704. //exposed for testing
  705. IonImageryProvider._endpointCache = {};
  706. export default IonImageryProvider;