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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. import Credit from "../Core/Credit.js";
  2. import Frozen from "../Core/Frozen.js";
  3. import defined from "../Core/defined.js";
  4. import DeveloperError from "../Core/DeveloperError.js";
  5. import Resource from "../Core/Resource.js";
  6. import IonResource from "../Core/IonResource.js";
  7. import Check from "../Core/Check.js";
  8. import GoogleMaps from "../Core/GoogleMaps.js";
  9. import { GOOGLE_2D_MAPS as createFromIonEndpoint } from "./IonImageryProviderFactory.js";
  10. import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js";
  11. const trailingSlashRegex = /\/$/;
  12. /**
  13. * @typedef {object} Google2DImageryProvider.ConstructorOptions
  14. *
  15. * Initialization options for the Google2DImageryProvider constructor
  16. *
  17. * @property {string} key The Google api key to send with tile requests.
  18. * @property {string} session The Google session token that tracks the current state of your map and viewport.
  19. * @property {string|Resource|IonResource} url The Google 2D maps endpoint.
  20. * @property {string} tileWidth The width of each tile in pixels.
  21. * @property {string} tileHeight The height of each tile in pixels.
  22. * @property {Ellipsoid} [ellipsoid=Ellipsoid.default] The ellipsoid. If not specified, the default ellipsoid is used.
  23. * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
  24. * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely
  25. * to result in rendering problems.
  26. * @property {number} [maximumLevel=22] The maximum level-of-detail supported by the imagery provider.
  27. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
  28. */
  29. /**
  30. * <div class="notice">
  31. * This object is normally not instantiated directly, use {@link Google2DImageryProvider.fromIonAssetId} or {@link Google2DImageryProvider.fromUrl}.
  32. * </div>
  33. *
  34. *
  35. * Provides 2D image tiles from {@link https://developers.google.com/maps/documentation/tile/2d-tiles-overview|Google 2D Tiles}.
  36. *
  37. * Google 2D Tiles can only be used with the Google geocoder.
  38. *
  39. * @alias Google2DImageryProvider
  40. * @constructor
  41. *
  42. * @param {Google2DImageryProvider.ConstructorOptions} options Object describing initialization options
  43. *
  44. * @example
  45. * // Google 2D imagery provider
  46. * const googleTilesProvider = Cesium.Google2DImageryProvider.fromIonAssetId({
  47. * assetId: 3830184
  48. * });
  49. * @example
  50. * // Use your own Google api key
  51. * Cesium.GoogleMaps.defaultApiKey = "your-api-key";
  52. *
  53. * const googleTilesProvider = Cesium.Google2DImageryProvider.fromUrl({
  54. * mapType: "SATELLITE"
  55. * });
  56. *
  57. *
  58. * @see {@link https://developers.google.com/maps/documentation/tile/2d-tiles-overview}
  59. * @see {@link https://developers.google.com/maps/documentation/tile/session_tokens}
  60. * @see {@link https://en.wikipedia.org/wiki/IETF_language_tag|IETF Language Tags}
  61. * @see {@link https://cldr.unicode.org/|Common Locale Data Repository region identifiers}
  62. */
  63. function Google2DImageryProvider(options) {
  64. options = options ?? Frozen.EMPTY_OBJECT;
  65. this._maximumLevel = options.maximumLevel ?? 22;
  66. this._minimumLevel = options.minimumLevel ?? 0;
  67. //>>includeStart("debug", pragmas.debug);
  68. Check.defined("options.session", options.session);
  69. Check.defined("options.tileWidth", options.tileWidth);
  70. Check.defined("options.tileHeight", options.tileHeight);
  71. Check.defined("options.key", options.key);
  72. //>>includeEnd("debug");
  73. this._session = options.session;
  74. this._key = options.key;
  75. this._tileWidth = options.tileWidth;
  76. this._tileHeight = options.tileHeight;
  77. const resource =
  78. options.url instanceof IonResource
  79. ? options.url
  80. : Resource.createIfNeeded(options.url ?? GoogleMaps.mapTilesApiEndpoint);
  81. let templateUrl = resource.getUrlComponent();
  82. if (!trailingSlashRegex.test(templateUrl)) {
  83. templateUrl += "/";
  84. }
  85. const tilesUrl = `${templateUrl}v1/2dtiles/{z}/{x}/{y}`;
  86. this._viewportUrl = `${templateUrl}tile/v1/viewport`;
  87. resource.url = tilesUrl;
  88. resource.setQueryParameters({
  89. session: encodeURIComponent(options.session),
  90. key: encodeURIComponent(options.key),
  91. });
  92. this._resource = resource.clone();
  93. let credit;
  94. if (defined(options.credit)) {
  95. credit = options.credit;
  96. if (typeof credit === "string") {
  97. credit = new Credit(credit);
  98. }
  99. }
  100. const provider = new UrlTemplateImageryProvider({
  101. url: resource,
  102. credit: credit,
  103. tileWidth: options.tileWidth,
  104. tileHeight: options.tileHeight,
  105. ellipsoid: options.ellipsoid,
  106. rectangle: options.rectangle,
  107. maximumLevel: this._maximumLevel,
  108. minimumLevel: this._minimumLevel,
  109. });
  110. provider._resource = resource;
  111. this._imageryProvider = provider;
  112. // This will be defined for ion resources
  113. this._tileCredits = resource.credits;
  114. this._attributionsByLevel = undefined;
  115. }
  116. Object.defineProperties(Google2DImageryProvider.prototype, {
  117. /**
  118. * Gets the URL of the Google 2D Imagery server.
  119. * @memberof Google2DImageryProvider.prototype
  120. * @type {string}
  121. * @readonly
  122. */
  123. url: {
  124. get: function () {
  125. return this._imageryProvider.url;
  126. },
  127. },
  128. /**
  129. * Gets the rectangle, in radians, of the imagery provided by the instance.
  130. * @memberof Google2DImageryProvider.prototype
  131. * @type {Rectangle}
  132. * @readonly
  133. */
  134. rectangle: {
  135. get: function () {
  136. return this._imageryProvider.rectangle;
  137. },
  138. },
  139. /**
  140. * Gets the width of each tile, in pixels.
  141. * @memberof Google2DImageryProvider.prototype
  142. * @type {number}
  143. * @readonly
  144. */
  145. tileWidth: {
  146. get: function () {
  147. return this._imageryProvider.tileWidth;
  148. },
  149. },
  150. /**
  151. * Gets the height of each tile, in pixels.
  152. * @memberof Google2DImageryProvider.prototype
  153. * @type {number}
  154. * @readonly
  155. */
  156. tileHeight: {
  157. get: function () {
  158. return this._imageryProvider.tileHeight;
  159. },
  160. },
  161. /**
  162. * Gets the maximum level-of-detail that can be requested.
  163. * @memberof Google2DImageryProvider.prototype
  164. * @type {number|undefined}
  165. * @readonly
  166. */
  167. maximumLevel: {
  168. get: function () {
  169. return this._imageryProvider.maximumLevel;
  170. },
  171. },
  172. /**
  173. * Gets the minimum level-of-detail that can be requested. Generally,
  174. * a minimum level should only be used when the rectangle of the imagery is small
  175. * enough that the number of tiles at the minimum level is small. An imagery
  176. * provider with more than a few tiles at the minimum level will lead to
  177. * rendering problems.
  178. * @memberof Google2DImageryProvider.prototype
  179. * @type {number}
  180. * @readonly
  181. */
  182. minimumLevel: {
  183. get: function () {
  184. return this._imageryProvider.minimumLevel;
  185. },
  186. },
  187. /**
  188. * Gets the tiling scheme used by the provider.
  189. * @memberof Google2DImageryProvider.prototype
  190. * @type {TilingScheme}
  191. * @readonly
  192. */
  193. tilingScheme: {
  194. get: function () {
  195. return this._imageryProvider.tilingScheme;
  196. },
  197. },
  198. /**
  199. * Gets the tile discard policy. If not undefined, the discard policy is responsible
  200. * for filtering out "missing" tiles via its shouldDiscardImage function. If this function
  201. * returns undefined, no tiles are filtered.
  202. * @memberof Google2DImageryProvider.prototype
  203. * @type {TileDiscardPolicy}
  204. * @readonly
  205. */
  206. tileDiscardPolicy: {
  207. get: function () {
  208. return this._imageryProvider.tileDiscardPolicy;
  209. },
  210. },
  211. /**
  212. * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing
  213. * to the event, you will be notified of the error and can potentially recover from it. Event listeners
  214. * are passed an instance of {@link TileProviderError}.
  215. * @memberof Google2DImageryProvider.prototype
  216. * @type {Event}
  217. * @readonly
  218. */
  219. errorEvent: {
  220. get: function () {
  221. return this._imageryProvider.errorEvent;
  222. },
  223. },
  224. /**
  225. * Gets the credit to display when this imagery provider is active. Typically this is used to credit
  226. * the source of the imagery.
  227. * @memberof Google2DImageryProvider.prototype
  228. * @type {Credit}
  229. * @readonly
  230. */
  231. credit: {
  232. get: function () {
  233. return this._imageryProvider.credit;
  234. },
  235. },
  236. /**
  237. * Gets the proxy used by this provider.
  238. * @memberof Google2DImageryProvider.prototype
  239. * @type {Proxy}
  240. * @readonly
  241. */
  242. proxy: {
  243. get: function () {
  244. return this._imageryProvider.proxy;
  245. },
  246. },
  247. /**
  248. * Gets a value indicating whether or not the images provided by this imagery provider
  249. * include an alpha channel. If this property is false, an alpha channel, if present, will
  250. * be ignored. If this property is true, any images without an alpha channel will be treated
  251. * as if their alpha is 1.0 everywhere. When this property is false, memory usage
  252. * and texture upload time are reduced.
  253. * @memberof Google2DImageryProvider.prototype
  254. * @type {boolean}
  255. * @readonly
  256. */
  257. hasAlphaChannel: {
  258. get: function () {
  259. return this._imageryProvider.hasAlphaChannel;
  260. },
  261. },
  262. });
  263. /**
  264. * Creates an {@link ImageryProvider} which provides 2D global tiled imagery from {@link https://developers.google.com/maps/documentation/tile/2d-tiles-overview|Google 2D Tiles}, streamed using the Cesium ion REST API.
  265. * @param {object} options Object with the following properties:
  266. * @param {string} options.assetId The Cesium ion asset id.
  267. * @param {"satellite" | "terrain" | "roadmap"} [options.mapType="satellite"] The map type of the Google map imagery. Valid options are satellite, terrain, and roadmap. If overlayLayerType is set, mapType is ignored and a transparent overlay is returned. If overlayMapType is undefined, then a basemap of mapType is returned. layerRoadmap overlayLayerType is included in terrain and roadmap mapTypes.
  268. * @param {string} [options.language="en_US"] an IETF language tag that specifies the language used to display information on the tiles
  269. * @param {string} [options.region="US"] A Common Locale Data Repository region identifier (two uppercase letters) that represents the physical location of the user.
  270. * @param {"layerRoadmap" | "layerStreetview" | "layerTraffic"} [options.overlayLayerType] Returns a transparent overlay map with the specified layerType. If no value is provided, a basemap of mapType is returned. Use multiple instances of Google2DImageryProvider to add multiple Google Maps overlays to a scene. layerRoadmap is included in terrain and roadmap mapTypes, so adding as overlay to terrain or roadmap has no effect.
  271. * @param {object} [options.styles] An array of JSON style objects that specify the appearance and detail level of map features such as roads, parks, and built-up areas. Styling is used to customize the standard Google base map. The styles parameter is valid only if the mapType is roadmap. For the complete style syntax, see the ({@link https://developers.google.com/maps/documentation/tile/style-reference|Google Style Reference}).
  272. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.default] The ellipsoid. If not specified, the default ellipsoid is used.
  273. * @param {number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
  274. * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely
  275. * to result in rendering problems.
  276. * @param {number} [options.maximumLevel=22] The maximum level-of-detail supported by the imagery provider.
  277. * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
  278. * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas.
  279. *
  280. * @returns {Promise<Google2DImageryProvider>} A promise that resolves to the created Google2DImageryProvider.
  281. *
  282. * @example
  283. * // Google 2D imagery provider
  284. * const googleTilesProvider = Cesium.Google2DImageryProvider.fromIonAssetId({
  285. * assetId: 3830184
  286. * });
  287. * @example
  288. * // Google 2D roadmap overlay with custom styles
  289. * const googleTilesProvider = Cesium.Google2DImageryProvider.fromIonAssetId({
  290. * assetId: 3830184,
  291. * overlayLayerType: "layerRoadmap",
  292. * styles: [
  293. * {
  294. * stylers: [{ hue: "#00ffe6" }, { saturation: -20 }],
  295. * },
  296. * {
  297. * featureType: "road",
  298. * elementType: "geometry",
  299. * stylers: [{ lightness: 100 }, { visibility: "simplified" }],
  300. * },
  301. * ],
  302. * });
  303. */
  304. Google2DImageryProvider.fromIonAssetId = async function (options) {
  305. options = options ?? {};
  306. options.mapType = options.mapType ?? "satellite";
  307. options.language = options.language ?? "en_US";
  308. options.region = options.region ?? "US";
  309. const overlayLayerType = options.overlayLayerType;
  310. //>>includeStart("debug", pragmas.debug);
  311. if (defined(overlayLayerType)) {
  312. Check.typeOf.string("options.overlayLayerType", overlayLayerType);
  313. }
  314. Check.defined("options.assetId", options.assetId);
  315. //>>includeEnd("debug");
  316. const queryOptions = buildQueryOptions(options);
  317. const endpointResource = IonResource._createEndpointResource(
  318. options.assetId,
  319. {
  320. queryParameters: {
  321. options: JSON.stringify(queryOptions),
  322. },
  323. },
  324. );
  325. const providerOptions = {
  326. language: options.language,
  327. region: options.region,
  328. ellipsoid: options.ellipsoid,
  329. minimumLevel: options.minimumLevel,
  330. maximumLevel: options.maximumLevel,
  331. rectangle: options.rectangle,
  332. credit: options.credit,
  333. };
  334. const endpoint = await endpointResource.fetchJson();
  335. const url = endpoint.options.url;
  336. delete endpoint.options.url;
  337. endpoint.options = {
  338. ...endpoint.options,
  339. ...providerOptions,
  340. };
  341. return createFromIonEndpoint(url, endpoint, endpointResource);
  342. };
  343. /**
  344. * Creates an {@link ImageryProvider} which provides 2D global tiled imagery from {@link https://developers.google.com/maps/documentation/tile/2d-tiles-overview|Google 2D Tiles}.
  345. * @param {object} options Object with the following properties:
  346. * @param {string} [options.key=GoogleMaps.defaultApiKey] Your API key to access Google 2D Tiles. See {@link https://developers.google.com/maps/documentation/javascript/get-api-key} for instructions on how to create your own key.
  347. * @param {"satellite" | "terrain" | "roadmap"} [options.mapType="satellite"] The map type of the Google map imagery. Valid options are satellite, terrain, and roadmap. If overlayLayerType is set, mapType is ignored and a transparent overlay is returned. If overlayMapType is undefined, then a basemap of mapType is returned. layerRoadmap overlayLayerType is included in terrain and roadmap mapTypes.
  348. * @param {string} [options.language="en_US"] an IETF language tag that specifies the language used to display information on the tiles
  349. * @param {string} [options.region="US"] A Common Locale Data Repository region identifier (two uppercase letters) that represents the physical location of the user.
  350. * @param {"layerRoadmap" | "layerStreetview" | "layerTraffic"} [options.overlayLayerType] Returns a transparent overlay map with the specified layerType. If no value is provided, a basemap of mapType is returned. Use multiple instances of Google2DImageryProvider to add multiple Google Maps overlays to a scene. layerRoadmap is included in terrain and roadmap mapTypes, so adding as overlay to terrain or roadmap has no effect.
  351. * @param {object} [options.styles] An array of JSON style objects that specify the appearance and detail level of map features such as roads, parks, and built-up areas. Styling is used to customize the standard Google base map. The styles parameter is valid only if the mapType is roadmap. For the complete style syntax, see the ({@link https://developers.google.com/maps/documentation/tile/style-reference|Google Style Reference}).
  352. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.default] The ellipsoid. If not specified, the default ellipsoid is used.
  353. * @param {number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
  354. * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely
  355. * to result in rendering problems.
  356. * @param {number} [options.maximumLevel=22] The maximum level-of-detail supported by the imagery provider.
  357. * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
  358. * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas.
  359. *
  360. * @returns {Promise<Google2DImageryProvider>} A promise that resolves to the created Google2DImageryProvider.
  361. *
  362. * @example
  363. * // Use your own Google api key
  364. * Cesium.GoogleMaps.defaultApiKey = "your-api-key";
  365. *
  366. * const googleTilesProvider = Cesium.Google2DImageryProvider.fromUrl({
  367. * mapType: "satellite"
  368. * });
  369. * @example
  370. * // Google 2D roadmap overlay with custom styles
  371. * Cesium.GoogleMaps.defaultApiKey = "your-api-key";
  372. *
  373. * const googleTilesProvider = Cesium.Google2DImageryProvider.fromUrl({
  374. * overlayLayerType: "layerRoadmap",
  375. * styles: [
  376. * {
  377. * stylers: [{ hue: "#00ffe6" }, { saturation: -20 }],
  378. * },
  379. * {
  380. * featureType: "road",
  381. * elementType: "geometry",
  382. * stylers: [{ lightness: 100 }, { visibility: "simplified" }],
  383. * },
  384. * ],
  385. * });
  386. */
  387. Google2DImageryProvider.fromUrl = async function (options) {
  388. options = options ?? {};
  389. options.mapType = options.mapType ?? "satellite";
  390. options.language = options.language ?? "en_US";
  391. options.region = options.region ?? "US";
  392. options.url = options.url ?? GoogleMaps.mapTilesApiEndpoint;
  393. options.key = options.key ?? GoogleMaps.defaultApiKey;
  394. const overlayLayerType = options.overlayLayerType;
  395. //>>includeStart("debug", pragmas.debug);
  396. if (defined(overlayLayerType)) {
  397. Check.typeOf.string("overlayLayerType", overlayLayerType);
  398. }
  399. if (!defined(options.key) && !defined(GoogleMaps.defaultApiKey)) {
  400. throw new DeveloperError(
  401. "options.key or GoogleMaps.defaultApiKey is required.",
  402. );
  403. }
  404. //>>includeEnd("debug");
  405. const sessionJson = await createGoogleImagerySession(options);
  406. return new Google2DImageryProvider({
  407. ...sessionJson,
  408. ...options,
  409. credit: options.credit ?? GoogleMaps.getDefaultCredit(),
  410. });
  411. };
  412. /**
  413. * Gets the credits to be displayed when a given tile is displayed.
  414. *
  415. * @param {number} x The tile X coordinate.
  416. * @param {number} y The tile Y coordinate.
  417. * @param {number} level The tile level;
  418. * @returns {Credit[]|undefined} The credits to be displayed when the tile is displayed.
  419. */
  420. Google2DImageryProvider.prototype.getTileCredits = function (x, y, level) {
  421. const hasAttributions = defined(this._attributionsByLevel);
  422. if (!hasAttributions || !defined(this._tileCredits)) {
  423. return undefined;
  424. }
  425. const innerCredits = this._attributionsByLevel.get(level);
  426. if (!defined(this._tileCredits)) {
  427. return innerCredits;
  428. }
  429. return this._tileCredits.concat(innerCredits);
  430. };
  431. /**
  432. * Requests the image for a given tile.
  433. *
  434. * @param {number} x The tile X coordinate.
  435. * @param {number} y The tile Y coordinate.
  436. * @param {number} level The tile level.
  437. * @param {Request} [request] The request object. Intended for internal use only.
  438. * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or
  439. * undefined if there are too many active requests to the server, and the request should be retried later.
  440. */
  441. Google2DImageryProvider.prototype.requestImage = function (
  442. x,
  443. y,
  444. level,
  445. request,
  446. ) {
  447. const promise = this._imageryProvider.requestImage(x, y, level, request);
  448. // If the requestImage call returns undefined, it couldn't be scheduled this frame. Make sure to return undefined so this can be handled upstream.
  449. if (!defined(promise)) {
  450. return undefined;
  451. }
  452. // Asynchronously request and populate _attributionsByLevel if it hasn't been already. We do this here so that the promise can be properly awaited.
  453. if (!defined(this._attributionsByLevel)) {
  454. return Promise.all([promise, this.getViewportCredits()]).then(
  455. (results) => results[0],
  456. );
  457. }
  458. return promise;
  459. };
  460. /**
  461. * Picking features is not currently supported by this imagery provider, so this function simply returns
  462. * undefined.
  463. *
  464. * @param {number} x The tile X coordinate.
  465. * @param {number} y The tile Y coordinate.
  466. * @param {number} level The tile level.
  467. * @param {number} longitude The longitude at which to pick features.
  468. * @param {number} latitude The latitude at which to pick features.
  469. * @return {undefined} Undefined since picking is not supported.
  470. */
  471. Google2DImageryProvider.prototype.pickFeatures = function (
  472. x,
  473. y,
  474. level,
  475. longitude,
  476. latitude,
  477. ) {
  478. return undefined;
  479. };
  480. /**
  481. * Get attribution for imagery from Google Maps to display in the credits
  482. * @private
  483. * @return {Promise<Map<Credit[]>>} The list of attribution sources to display in the credits.
  484. */
  485. Google2DImageryProvider.prototype.getViewportCredits = async function () {
  486. const maximumLevel = this._maximumLevel;
  487. const promises = [];
  488. for (let level = 0; level < maximumLevel + 1; level++) {
  489. promises.push(
  490. fetchViewportAttribution(this._resource, this._viewportUrl, level),
  491. );
  492. }
  493. const results = await Promise.all(promises);
  494. const attributionsByLevel = new Map();
  495. for (let level = 0; level < maximumLevel + 1; level++) {
  496. const credits = [];
  497. const attributions = results[level];
  498. if (attributions) {
  499. const levelCredits = new Credit(attributions);
  500. credits.push(levelCredits);
  501. }
  502. attributionsByLevel.set(level, credits);
  503. }
  504. this._attributionsByLevel = attributionsByLevel;
  505. return attributionsByLevel;
  506. };
  507. async function fetchViewportAttribution(resource, url, level) {
  508. const viewportResource = resource.getDerivedResource({
  509. url,
  510. queryParameters: {
  511. zoom: level,
  512. north: 90,
  513. south: -90,
  514. east: 180,
  515. west: -180,
  516. },
  517. data: JSON.stringify(Frozen.EMPTY_OBJECT),
  518. });
  519. const viewportJson = await viewportResource.fetchJson();
  520. return viewportJson.copyright;
  521. }
  522. function buildQueryOptions(options) {
  523. const { mapType, overlayLayerType, styles } = options;
  524. const queryOptions = {
  525. mapType,
  526. overlay: false,
  527. };
  528. if (mapType === "terrain" && !defined(overlayLayerType)) {
  529. queryOptions.layerTypes = ["layerRoadmap"];
  530. }
  531. if (defined(overlayLayerType)) {
  532. queryOptions.mapType = "satellite";
  533. queryOptions.overlay = true;
  534. queryOptions.layerTypes = [overlayLayerType];
  535. }
  536. if (defined(styles)) {
  537. queryOptions.styles = styles;
  538. }
  539. return queryOptions;
  540. }
  541. async function createGoogleImagerySession(options) {
  542. const { language, region, key, url } = options;
  543. const queryOptions = buildQueryOptions(options);
  544. let baseUrl = url.url ?? url;
  545. if (!trailingSlashRegex.test(baseUrl)) {
  546. baseUrl += "/";
  547. }
  548. const response = await Resource.post({
  549. url: `${baseUrl}v1/createSession`,
  550. queryParameters: { key: key },
  551. data: JSON.stringify({
  552. ...queryOptions,
  553. language,
  554. region,
  555. }),
  556. });
  557. const responseJson = JSON.parse(response);
  558. return responseJson;
  559. }
  560. export default Google2DImageryProvider;