mirror of https://github.com/CesiumGS/cesium.git
Compare commits
11 Commits
f29d7694a7
...
c00f701ce4
| Author | SHA1 | Date |
|---|---|---|
|
|
c00f701ce4 | |
|
|
fe54e66971 | |
|
|
e7bcd7d183 | |
|
|
46ac4e6170 | |
|
|
a060483d18 | |
|
|
c5d2c31096 | |
|
|
e2e7245acb | |
|
|
ad1944c5b0 | |
|
|
8a963092c8 | |
|
|
93fa6df9f4 | |
|
|
043d87ea5a |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
|
@ -30,9 +30,9 @@
|
|||
"use strict";
|
||||
//Sandcastle_Begin
|
||||
const viewer = new Cesium.Viewer("cesiumContainer", {
|
||||
baseLayer: Cesium.ImageryLayer.fromWorldImagery({
|
||||
style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS,
|
||||
}),
|
||||
baseLayer: Cesium.ImageryLayer.fromProviderAsync(
|
||||
Cesium.IonImageryProvider.fromAssetId(3830183),
|
||||
),
|
||||
baseLayerPicker: false,
|
||||
});
|
||||
const layers = viewer.scene.imageryLayers;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import Check from "../Core/Check.js";
|
||||
import Frozen from "../Core/Frozen.js";
|
||||
import Credit from "../Core/Credit.js";
|
||||
import defined from "../Core/defined.js";
|
||||
import Resource from "../Core/Resource.js";
|
||||
|
|
@ -29,7 +30,6 @@ const trailingSlashRegex = /\/$/;
|
|||
*
|
||||
* @alias Azure2DImageryProvider
|
||||
* @constructor
|
||||
* @private
|
||||
* @param {Azure2DImageryProvider.ConstructorOptions} options Object describing initialization options
|
||||
*
|
||||
* @example
|
||||
|
|
@ -41,16 +41,18 @@ const trailingSlashRegex = /\/$/;
|
|||
*/
|
||||
function Azure2DImageryProvider(options) {
|
||||
options = options ?? {};
|
||||
const maximumLevel = options.maximumLevel ?? 22;
|
||||
const minimumLevel = options.minimumLevel ?? 0;
|
||||
const tilesetId = options.tilesetId ?? "microsoft.imagery";
|
||||
this._maximumLevel = options.maximumLevel ?? 22;
|
||||
this._minimumLevel = options.minimumLevel ?? 0;
|
||||
|
||||
const subscriptionKey =
|
||||
this._subscriptionKey =
|
||||
options.subscriptionKey ?? options["subscription-key"];
|
||||
//>>includeStart('debug', pragmas.debug);
|
||||
Check.defined("options.subscriptionKey", subscriptionKey);
|
||||
Check.defined("options.subscriptionKey", this._subscriptionKey);
|
||||
//>>includeEnd('debug');
|
||||
|
||||
this._tilesetId = options.tilesetId;
|
||||
|
||||
const resource =
|
||||
options.url instanceof IonResource
|
||||
? options.url
|
||||
|
|
@ -60,19 +62,23 @@ function Azure2DImageryProvider(options) {
|
|||
if (!trailingSlashRegex.test(templateUrl)) {
|
||||
templateUrl += "/";
|
||||
}
|
||||
templateUrl += `map/tile`;
|
||||
|
||||
resource.url = templateUrl;
|
||||
const tilesUrl = `${templateUrl}map/tile`;
|
||||
this._viewportUrl = `${templateUrl}map/attribution`;
|
||||
|
||||
resource.url = tilesUrl;
|
||||
|
||||
resource.setQueryParameters({
|
||||
"api-version": "2024-04-01",
|
||||
tilesetId: tilesetId,
|
||||
"subscription-key": this._subscriptionKey,
|
||||
zoom: `{z}`,
|
||||
x: `{x}`,
|
||||
y: `{y}`,
|
||||
"subscription-key": subscriptionKey,
|
||||
});
|
||||
|
||||
this._resource = resource;
|
||||
|
||||
let credit;
|
||||
if (defined(options.credit)) {
|
||||
credit = options.credit;
|
||||
|
|
@ -83,8 +89,8 @@ function Azure2DImageryProvider(options) {
|
|||
|
||||
const provider = new UrlTemplateImageryProvider({
|
||||
...options,
|
||||
maximumLevel,
|
||||
minimumLevel,
|
||||
maximumLevel: this._maximumLevel,
|
||||
minimumLevel: this._minimumLevel,
|
||||
url: resource,
|
||||
credit: credit,
|
||||
});
|
||||
|
|
@ -93,6 +99,7 @@ function Azure2DImageryProvider(options) {
|
|||
|
||||
// This will be defined for ion resources
|
||||
this._tileCredits = resource.credits;
|
||||
this._attributionsByLevel = undefined;
|
||||
}
|
||||
|
||||
Object.defineProperties(Azure2DImageryProvider.prototype, {
|
||||
|
|
@ -263,7 +270,18 @@ Object.defineProperties(Azure2DImageryProvider.prototype, {
|
|||
* @returns {Credit[]|undefined} The credits to be displayed when the tile is displayed.
|
||||
*/
|
||||
Azure2DImageryProvider.prototype.getTileCredits = function (x, y, level) {
|
||||
return this._imageryProvider.getTileCredits(x, y, level);
|
||||
const hasAttributions = defined(this._attributionsByLevel);
|
||||
|
||||
if (!hasAttributions || !defined(this._tileCredits)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const innerCredits = this._attributionsByLevel.get(level);
|
||||
if (!defined(this._tileCredits)) {
|
||||
return innerCredits;
|
||||
}
|
||||
|
||||
return this._tileCredits.concat(innerCredits);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -282,7 +300,21 @@ Azure2DImageryProvider.prototype.requestImage = function (
|
|||
level,
|
||||
request,
|
||||
) {
|
||||
return this._imageryProvider.requestImage(x, y, level, request);
|
||||
const promise = this._imageryProvider.requestImage(x, y, level, request);
|
||||
|
||||
// If the requestImage call returns undefined, it couldn't be scheduled this frame. Make sure to return undefined so this can be handled upstream.
|
||||
if (!defined(promise)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Asynchronously request and populate _attributionsByLevel if it hasn't been already. We do this here so that the promise can be properly awaited.
|
||||
if (promise && !defined(this._attributionsByLevel)) {
|
||||
return Promise.all([promise, this.getViewportCredits()]).then(
|
||||
(results) => results[0],
|
||||
);
|
||||
}
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -306,5 +338,57 @@ Azure2DImageryProvider.prototype.pickFeatures = function (
|
|||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get attribution for imagery from Azure Maps to display in the credits
|
||||
* @private
|
||||
* @return {Promise<Map<Credit[]>>} The list of attribution sources to display in the credits.
|
||||
*/
|
||||
Azure2DImageryProvider.prototype.getViewportCredits = async function () {
|
||||
const maximumLevel = this._maximumLevel;
|
||||
|
||||
const promises = [];
|
||||
for (let level = 0; level < maximumLevel + 1; level++) {
|
||||
promises.push(
|
||||
fetchViewportAttribution(
|
||||
this._resource,
|
||||
this._viewportUrl,
|
||||
this._subscriptionKey,
|
||||
this._tilesetId,
|
||||
level,
|
||||
),
|
||||
);
|
||||
}
|
||||
const results = await Promise.all(promises);
|
||||
|
||||
const attributionsByLevel = new Map();
|
||||
for (let level = 0; level < maximumLevel + 1; level++) {
|
||||
const credits = [];
|
||||
const attributions = results[level].join(",");
|
||||
if (attributions) {
|
||||
const levelCredits = new Credit(attributions);
|
||||
credits.push(levelCredits);
|
||||
}
|
||||
attributionsByLevel.set(level, credits);
|
||||
}
|
||||
|
||||
this._attributionsByLevel = attributionsByLevel;
|
||||
|
||||
return attributionsByLevel;
|
||||
};
|
||||
|
||||
async function fetchViewportAttribution(resource, url, key, tilesetId, level) {
|
||||
const viewportResource = resource.getDerivedResource({
|
||||
url,
|
||||
queryParameters: {
|
||||
zoom: level,
|
||||
bounds: "-180,-90,180,90",
|
||||
},
|
||||
data: JSON.stringify(Frozen.EMPTY_OBJECT),
|
||||
});
|
||||
|
||||
const viewportJson = await viewportResource.fetchJson();
|
||||
return viewportJson.copyrights;
|
||||
}
|
||||
|
||||
// Exposed for tests
|
||||
export default Azure2DImageryProvider;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ function Google2DImageryProvider(options) {
|
|||
key: encodeURIComponent(options.key),
|
||||
});
|
||||
|
||||
this._resource = resource.clone();
|
||||
|
||||
let credit;
|
||||
if (defined(options.credit)) {
|
||||
credit = options.credit;
|
||||
|
|
@ -312,7 +314,7 @@ Object.defineProperties(Google2DImageryProvider.prototype, {
|
|||
* });
|
||||
* @example
|
||||
* // Google 2D roadmap overlay with custom styles
|
||||
* const googleTileProvider = Cesium.Google2DImageryProvider.fromIonAssetId({
|
||||
* const googleTilesProvider = Cesium.Google2DImageryProvider.fromIonAssetId({
|
||||
* assetId: 3830184,
|
||||
* overlayLayerType: "layerRoadmap",
|
||||
* styles: [
|
||||
|
|
@ -403,7 +405,7 @@ Google2DImageryProvider.fromIonAssetId = async function (options) {
|
|||
* // Google 2D roadmap overlay with custom styles
|
||||
* Cesium.GoogleMaps.defaultApiKey = "your-api-key";
|
||||
*
|
||||
* const googleTileProvider = Cesium.Google2DImageryProvider.fromUrl({
|
||||
* const googleTilesProvider = Cesium.Google2DImageryProvider.fromUrl({
|
||||
* overlayLayerType: "layerRoadmap",
|
||||
* styles: [
|
||||
* {
|
||||
|
|
@ -533,12 +535,7 @@ Google2DImageryProvider.prototype.getViewportCredits = async function () {
|
|||
const promises = [];
|
||||
for (let level = 0; level < maximumLevel + 1; level++) {
|
||||
promises.push(
|
||||
fetchViewportAttribution(
|
||||
this._viewportUrl,
|
||||
this._key,
|
||||
this._session,
|
||||
level,
|
||||
),
|
||||
fetchViewportAttribution(this._resource, this._viewportUrl, level),
|
||||
);
|
||||
}
|
||||
const results = await Promise.all(promises);
|
||||
|
|
@ -559,12 +556,10 @@ Google2DImageryProvider.prototype.getViewportCredits = async function () {
|
|||
return attributionsByLevel;
|
||||
};
|
||||
|
||||
async function fetchViewportAttribution(url, key, session, level) {
|
||||
const viewport = await Resource.fetch({
|
||||
url: url,
|
||||
async function fetchViewportAttribution(resource, url, level) {
|
||||
const viewportResource = resource.getDerivedResource({
|
||||
url,
|
||||
queryParameters: {
|
||||
key,
|
||||
session,
|
||||
zoom: level,
|
||||
north: 90,
|
||||
south: -90,
|
||||
|
|
@ -573,7 +568,7 @@ async function fetchViewportAttribution(url, key, session, level) {
|
|||
},
|
||||
data: JSON.stringify(Frozen.EMPTY_OBJECT),
|
||||
});
|
||||
const viewportJson = JSON.parse(viewport);
|
||||
const viewportJson = await viewportResource.fetchJson();
|
||||
return viewportJson.copyright;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,10 @@ describe("Scene/Azure2DImageryProvider", function () {
|
|||
tilesetId: "a-tileset-id",
|
||||
});
|
||||
|
||||
provider._attributionsByLevel = {};
|
||||
|
||||
expect(provider.url).toEqual(
|
||||
"https://atlas.microsoft.com/map/tile?api-version=2024-04-01&tilesetId=a-tileset-id&zoom={z}&x={x}&y={y}&subscription-key=test-subscriptionKey",
|
||||
"https://atlas.microsoft.com/map/tile?api-version=2024-04-01&tilesetId=a-tileset-id&subscription-key=test-subscriptionKey&zoom={z}&x={x}&y={y}",
|
||||
);
|
||||
expect(provider.tileWidth).toEqual(256);
|
||||
expect(provider.tileHeight).toEqual(256);
|
||||
|
|
@ -74,6 +76,8 @@ describe("Scene/Azure2DImageryProvider", function () {
|
|||
rectangle: rectangle,
|
||||
});
|
||||
|
||||
provider._attributionsByLevel = {};
|
||||
|
||||
expect(provider.tileWidth).toEqual(256);
|
||||
expect(provider.tileHeight).toEqual(256);
|
||||
expect(provider.maximumLevel).toBe(22);
|
||||
|
|
@ -133,6 +137,7 @@ describe("Scene/Azure2DImageryProvider", function () {
|
|||
subscriptionKey: "test-subscriptionKey",
|
||||
tilesetId: "a-tileset-id",
|
||||
});
|
||||
provider._attributionsByLevel = {};
|
||||
|
||||
const layer = new ImageryLayer(provider);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import * as Cesium from "cesium";
|
||||
|
||||
const viewer = new Cesium.Viewer("cesiumContainer", {
|
||||
baseLayer: Cesium.ImageryLayer.fromWorldImagery({
|
||||
style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS,
|
||||
}),
|
||||
baseLayer: Cesium.ImageryLayer.fromProviderAsync(
|
||||
Cesium.IonImageryProvider.fromAssetId(3830183),
|
||||
),
|
||||
baseLayerPicker: false,
|
||||
});
|
||||
const layers = viewer.scene.imageryLayers;
|
||||
|
|
|
|||
|
|
@ -345,21 +345,6 @@ of the world.\nhttp://www.openstreetmap.org",
|
|||
}),
|
||||
);
|
||||
|
||||
providerViewModels.push(
|
||||
new ProviderViewModel({
|
||||
name: "Google Maps Labels Only",
|
||||
iconUrl: buildModuleUrl(
|
||||
"Widgets/Images/ImageryProviders/googleLabels.png",
|
||||
),
|
||||
tooltip:
|
||||
"Place labels from Google Maps to combine with other imagery such as Sentinel-2",
|
||||
category: "Cesium ion",
|
||||
creationFunction: function () {
|
||||
return IonImageryProvider.fromAssetId(3830185);
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
providerViewModels.push(
|
||||
new ProviderViewModel({
|
||||
name: "Google Maps Contour",
|
||||
|
|
@ -375,6 +360,33 @@ of the world.\nhttp://www.openstreetmap.org",
|
|||
}),
|
||||
);
|
||||
|
||||
providerViewModels.push(
|
||||
new ProviderViewModel({
|
||||
name: "Azure Maps Aerial",
|
||||
iconUrl: buildModuleUrl(
|
||||
"Widgets/Images/ImageryProviders/azureAerial.png",
|
||||
),
|
||||
tooltip: "Imagery from Azure Maps",
|
||||
category: "Cesium ion",
|
||||
creationFunction: function () {
|
||||
return IonImageryProvider.fromAssetId(3891168);
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
providerViewModels.push(
|
||||
new ProviderViewModel({
|
||||
name: "Azure Maps Roads",
|
||||
iconUrl: buildModuleUrl("Widgets/Images/ImageryProviders/azureRoads.png"),
|
||||
tooltip:
|
||||
"Labeled roads and other features on a base landscape from Azure Maps",
|
||||
category: "Cesium ion",
|
||||
creationFunction: function () {
|
||||
return IonImageryProvider.fromAssetId(3891169);
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
return providerViewModels;
|
||||
}
|
||||
export default createDefaultImageryProviderViewModels;
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Loading…
Reference in New Issue