terriajs
Version:
Geospatial data visualization platform.
169 lines • 6.72 kB
JavaScript
import { makeObservable } from "mobx";
import Cartesian2 from "terriajs-cesium/Source/Core/Cartesian2";
import Cartographic from "terriajs-cesium/Source/Core/Cartographic";
import Credit from "terriajs-cesium/Source/Core/Credit";
import Ellipsoid from "terriajs-cesium/Source/Core/Ellipsoid";
import CesiumEvent from "terriajs-cesium/Source/Core/Event";
import GeographicProjection from "terriajs-cesium/Source/Core/GeographicProjection";
import GeographicTilingScheme from "terriajs-cesium/Source/Core/GeographicTilingScheme";
import Math from "terriajs-cesium/Source/Core/Math";
import Resource from "terriajs-cesium/Source/Core/Resource";
import DiscardMissingTileImagePolicy from "terriajs-cesium/Source/Scene/DiscardMissingTileImagePolicy";
import ImageryLayerFeatureInfo from "terriajs-cesium/Source/Scene/ImageryLayerFeatureInfo";
import ImageryProvider from "terriajs-cesium/Source/Scene/ImageryProvider";
/** This is adapted from Cesium's ArcGisMapServerImageryProvider
* https://github.com/CesiumGS/cesium/blob/51aae2d21014cfc28e948b1719d07f1912df9434/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js
* Code licensed under the Apache License v2.0.
* For details, see https://github.com/CesiumGS/cesium/blob/main/LICENSE.md
*/
export default class ArcGisImageServerImageryProvider {
tilingScheme;
ellipsoid;
tileWidth;
tileHeight;
minimumLevel;
maximumLevel;
rectangle;
errorEvent = new CesiumEvent();
ready = true;
credit;
/** Note: this can be set dynamically */
enablePickFeatures;
usePreCachedTiles;
tileDiscardPolicy;
baseResource;
defaultNightAlpha = undefined;
defaultDayAlpha = undefined;
hasAlphaChannel = true;
defaultAlpha = undefined;
defaultBrightness = undefined;
defaultContrast = undefined;
defaultGamma = undefined;
defaultHue = undefined;
defaultSaturation = undefined;
defaultMagnificationFilter = undefined;
defaultMinificationFilter = undefined;
readyPromise = Promise.resolve(true);
constructor(options) {
makeObservable(this);
this.tilingScheme = options.tilingScheme ?? new GeographicTilingScheme();
this.rectangle = options.rectangle ?? this.tilingScheme.rectangle;
this.ellipsoid = Ellipsoid.WGS84;
this.tileWidth = options.tileWidth ?? 256;
this.tileHeight = options.tileHeight ?? 256;
this.minimumLevel = options.minimumLevel ?? 0;
this.maximumLevel = options.maximumLevel ?? 25;
this.ready = true;
this.credit =
typeof options.credit === "string"
? new Credit(options.credit)
: options.credit;
this.enablePickFeatures = options.enablePickFeatures ?? true;
this.usePreCachedTiles = options.usePreCachedTiles ?? false;
this.baseResource = new Resource(options.url);
this.baseResource.appendForwardSlash();
if (options.parameters) {
this.baseResource.appendQueryParameters(options.parameters);
}
if (options.token) {
this.baseResource.appendQueryParameters({
token: options.token
});
}
this.tileDiscardPolicy = new DiscardMissingTileImagePolicy({
missingImageUrl: this.buildImageResource(0, 0, this.maximumLevel).url,
pixelsToCheck: [
new Cartesian2(0, 0),
new Cartesian2(200, 20),
new Cartesian2(20, 200),
new Cartesian2(80, 110),
new Cartesian2(160, 130)
],
disableCheckIfAllPixelsAreTransparent: true
});
}
get proxy() {
return this.baseResource.proxy;
}
buildImageResource(x, y, level, request) {
if (this.usePreCachedTiles) {
return this.baseResource.getDerivedResource({
url: `tile/${level}/${y}/${x}`,
request: request
});
}
else {
const nativeRectangle = this.tilingScheme.tileXYToNativeRectangle(x, y, level);
const bbox = `${nativeRectangle.west},${nativeRectangle.south},${nativeRectangle.east},${nativeRectangle.north}`;
const query = {
bbox: bbox,
size: `${this.tileWidth},${this.tileHeight}`,
format: "png32",
transparent: true,
f: "image"
};
if (this.tilingScheme.projection instanceof GeographicProjection) {
query.bboxSR = 4326;
query.imageSR = 4326;
}
else {
query.bboxSR = 3857;
query.imageSR = 3857;
}
return this.baseResource.getDerivedResource({
url: "exportImage",
queryParameters: query,
request: request
});
}
}
getTileCredits() {
return [];
}
requestImage(x, y, level, request) {
return ImageryProvider.loadImage(this, this.buildImageResource(x, y, level, request));
}
async pickFeatures(_x, _y, _level, longitude, latitude) {
if (!this.enablePickFeatures) {
return [];
}
let horizontal;
let vertical;
let sr;
if (this.tilingScheme.projection instanceof GeographicProjection) {
horizontal = Math.toDegrees(longitude);
vertical = Math.toDegrees(latitude);
sr = "4326";
}
else {
const projected = this.tilingScheme.projection.project(new Cartographic(longitude, latitude, 0.0));
horizontal = projected.x;
vertical = projected.y;
sr = "3857";
}
const query = {
f: "json",
geometryType: "esriGeometryPoint",
geometry: `{x: ${horizontal}, y: ${vertical}, spatialReference: {wkid: ${sr}}}`,
// Disable catalog items - as we don't use them
returnCatalogItems: false
};
const resource = this.baseResource.getDerivedResource({
url: "identify",
queryParameters: query
});
const json = (await resource.fetchJson());
const result = [];
if (json.value) {
const featureInfo = new ImageryLayerFeatureInfo();
featureInfo.data = json;
featureInfo.name = json.name;
featureInfo.properties = json.properties;
featureInfo.description = json.value;
result.push(featureInfo);
}
// Todo: handle json.catalogItems
return result;
}
}
//# sourceMappingURL=ArcGisImageServerImageryProvider.js.map