Skip to content

Commit

Permalink
Increase maxRefreshIntervals to 10000 + get ImageServer time working …
Browse files Browse the repository at this point in the history
…+ get ImageServer tiles working
  • Loading branch information
nf-s committed May 9, 2024
1 parent d118f37 commit 3a39d35
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 84 deletions.
63 changes: 34 additions & 29 deletions lib/Map/ImageryProvider/ArcGisImageServerImageryProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { makeObservable } from "mobx";
import Cartesian2 from "terriajs-cesium/Source/Core/Cartesian2";
import Cartesian3 from "terriajs-cesium/Source/Core/Cartesian3";
import Cartographic from "terriajs-cesium/Source/Core/Cartographic";
import Credit from "terriajs-cesium/Source/Core/Credit";
import Ellipsoid from "terriajs-cesium/Source/Core/Ellipsoid";
Expand All @@ -11,7 +10,6 @@ import Math from "terriajs-cesium/Source/Core/Math";
import Rectangle from "terriajs-cesium/Source/Core/Rectangle";
import Resource from "terriajs-cesium/Source/Core/Resource";
import TilingScheme from "terriajs-cesium/Source/Core/TilingScheme";
import WebMercatorProjection from "terriajs-cesium/Source/Core/WebMercatorProjection";
import DiscardMissingTileImagePolicy from "terriajs-cesium/Source/Scene/DiscardMissingTileImagePolicy";
import ImageryLayerFeatureInfo from "terriajs-cesium/Source/Scene/ImageryLayerFeatureInfo";
import ImageryProvider from "terriajs-cesium/Source/Scene/ImageryProvider";
Expand All @@ -29,6 +27,7 @@ interface Options {
credit: Credit | string;
tileCredits?: Credit[];
enablePickFeatures?: boolean;
usePreCachedTiles?: boolean;
tileWidth?: number;
tileHeight?: number;
ellipsoid?: Ellipsoid;
Expand Down Expand Up @@ -56,6 +55,7 @@ export default class ArcGisImageServerImageryProvider {
readonly credit: Credit;
readonly tileCredits: Credit[] | undefined;
enablePickFeatures: boolean;
readonly usePreCachedTiles: boolean;
readonly tileDiscardPolicy: TileDiscardPolicy;
readonly baseResource: Resource;

Expand Down Expand Up @@ -105,6 +105,7 @@ export default class ArcGisImageServerImageryProvider {
: (options.credit as Credit);

this.enablePickFeatures = options.enablePickFeatures ?? true;
this.usePreCachedTiles = options.usePreCachedTiles ?? false;

this.baseResource = new Resource(options.url);
this.baseResource.appendForwardSlash();
Expand Down Expand Up @@ -141,33 +142,39 @@ export default class ArcGisImageServerImageryProvider {
}

buildImageResource(x: number, y: number, level: number) {
const nativeRectangle = this.tilingScheme.tileXYToNativeRectangle(
x,
y,
level
);
const bbox = `${nativeRectangle.west},${nativeRectangle.south},${nativeRectangle.east},${nativeRectangle.north}`;

const query: JsonObject = {
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;
if (this.usePreCachedTiles) {
return this.baseResource.getDerivedResource({
url: `tile/${level}/${y}/${x}`
});
} else {
query.bboxSR = 3857;
query.imageSR = 3857;
const nativeRectangle = this.tilingScheme.tileXYToNativeRectangle(
x,
y,
level
);
const bbox = `${nativeRectangle.west},${nativeRectangle.south},${nativeRectangle.east},${nativeRectangle.north}`;

const query: JsonObject = {
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
});
}

return this.baseResource.getDerivedResource({
url: "exportImage",
queryParameters: query
});
}

getTileCredits(): Credit[] {
Expand All @@ -192,8 +199,6 @@ export default class ArcGisImageServerImageryProvider {
return [];
}

const rectangle = this.tilingScheme.tileXYToNativeRectangle(x, y, level);

let horizontal;
let vertical;
let sr;
Expand Down
8 changes: 8 additions & 0 deletions lib/ModelMixins/DiscretelyTimeVaryingMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,14 @@ function DiscretelyTimeVaryingMixin<
: this.discreteTimesAsSortedJulianDates![index].time;
}

@computed({ equals: JulianDate.equals })
get nextDiscreteJulianDate() {
const index = this.nextDiscreteTimeIndex;
return index === undefined
? undefined
: this.discreteTimesAsSortedJulianDates![index].time;
}

@computed
get currentDiscreteTimeTag() {
const index = this.currentDiscreteTimeIndex;
Expand Down
101 changes: 58 additions & 43 deletions lib/Models/Catalog/Esri/ArcGisImageServerCatalogItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import i18next from "i18next";
import uniqWith from "lodash-es/uniqWith";
import { computed, makeObservable, override, runInAction } from "mobx";
import GeographicTilingScheme from "terriajs-cesium/Source/Core/GeographicTilingScheme";
import JulianDate from "terriajs-cesium/Source/Core/JulianDate";
import WebMercatorTilingScheme from "terriajs-cesium/Source/Core/WebMercatorTilingScheme";
import URI from "urijs";
import AsyncLoader from "../../../Core/AsyncLoader";
import { JsonObject, isJsonObject } from "../../../Core/Json";
import TerriaError, { networkRequestError } from "../../../Core/TerriaError";
import createDiscreteTimesFromIsoSegments from "../../../Core/createDiscreteTimes";
import createTransformerAllowUndefined from "../../../Core/createTransformerAllowUndefined";
import filterOutUndefined from "../../../Core/filterOutUndefined";
import isDefined from "../../../Core/isDefined";
import loadJson from "../../../Core/loadJson";
import replaceUnderscores from "../../../Core/replaceUnderscores";
Expand All @@ -24,7 +24,6 @@ import MappableMixin, {
import MinMaxLevelMixin from "../../../ModelMixins/MinMaxLevelMixin";
import UrlMixin from "../../../ModelMixins/UrlMixin";
import ArcGisImageServerCatalogItemTraits from "../../../Traits/TraitsClasses/ArcGisImageServerCatalogItemTraits";
import { InfoSectionTraits } from "../../../Traits/TraitsClasses/CatalogMemberTraits";
import DiscreteTimeTraits from "../../../Traits/TraitsClasses/DiscreteTimeTraits";
import LegendTraits, {
LegendItemTraits
Expand Down Expand Up @@ -84,7 +83,6 @@ class ImageServerStratum extends LoadableStratum(
serviceUri = serviceUri.addQuery("token", token);
}

// TODO: if tokenUrl, fetch and pass token as parameter
const serviceMetadata: ImageServer | undefined = await getJson(
item,
serviceUri
Expand Down Expand Up @@ -121,15 +119,15 @@ class ImageServerStratum extends LoadableStratum(
return stratum;
}

@computed get maximumScale() {
get maximumScale() {
return this.imageServer.maxScale;
}

@computed get name() {
get name() {
return replaceUnderscores(this.imageServer.name);
}

@computed get rectangle() {
get rectangle() {
const rectangle: RectangleCoordinates = {
west: Infinity,
south: Infinity,
Expand All @@ -142,41 +140,63 @@ class ImageServerStratum extends LoadableStratum(
return rectangle;
}

@computed get info() {
return filterOutUndefined([
createStratumInstance(InfoSectionTraits, {
name: i18next.t(
"models.arcGisImageServerCatalogItem.serviceDescription"
),
content: this.imageServer.serviceDescription
}),
createStratumInstance(InfoSectionTraits, {
name: i18next.t("models.arcGisImageServerCatalogItem.description"),
content: this.imageServer.description
})
]);
get description() {
return this.imageServer.description;
}

@computed get attribution() {
get attribution() {
return this.imageServer.copyrightText;
}

get token() {
return this._token;
}

// get tileHeight() {
// return this.imageServer.tileInfo?.rows
// }
@computed get usePreCachedTiles() {
if (this._item.parameters || this._item.currentDiscreteJulianDate)
return false;

return isDefined(this.imageServer.tileInfo);
}

get wkid() {
if (this._item.usePreCachedTiles) {
const wkid = this.imageServer.tileInfo?.spatialReference.wkid;
if (wkid === 102100 || wkid === 102113) return wkid;
}
}

get tileHeight() {
if (this.usePreCachedTiles) return this.imageServer.tileInfo?.rows;
}

// get tileWidth() {
// return this.imageServer.tileInfo?.cols
// }
get tileWidth() {
if (this.usePreCachedTiles) return this.imageServer.tileInfo?.cols;
}

// get maximumLevel() {
// if (this.imageServer.tileInfo?.lods)
// return this.imageServer.tileInfo.lods.length - 1
// }
get maximumLevel() {
const maximumLevelFromScale = scaleDenominatorToLevel(
this.maximumScale,
true,
false
);

// Make sure the maximum level is not higher than the maximum level of the server tiles
if (this.usePreCachedTiles && this.imageServer.tileInfo?.lods)
return Math.min(
this.imageServer.tileInfo.lods[
this.imageServer.tileInfo.lods.length - 1
].level,
maximumLevelFromScale ?? Infinity
);

return maximumLevelFromScale;
}

get minimumLevel() {
if (this.usePreCachedTiles && this.imageServer.tileInfo?.lods)
return this.imageServer.tileInfo.lods[0].level;
}
}

StratumOrder.addLoadStratum(ImageServerStratum.stratumName);
Expand Down Expand Up @@ -324,7 +344,7 @@ export default class ArcGisImageServerCatalogItem extends UrlMixin(

if (imageServerStratum?.imageServer.timeInfo === undefined)
return undefined;
// Add union type - as `time` is always defined

const result: (StratumFromTraits<DiscreteTimeTraits> & {
time: string;
})[] = [];
Expand All @@ -348,7 +368,7 @@ export default class ArcGisImageServerCatalogItem extends UrlMixin(
this._legendStratumLoader.load();

const imageryProvider = this._createImageryProvider(
this.currentDiscreteTimeTag
this.currentDiscreteJulianDate
);

if (imageryProvider) {
Expand All @@ -371,7 +391,7 @@ export default class ArcGisImageServerCatalogItem extends UrlMixin(
this.nextDiscreteTimeTag
) {
const imageryProvider = this._createImageryProvider(
this.nextDiscreteTimeTag
this.nextDiscreteJulianDate
);

if (imageryProvider) {
Expand Down Expand Up @@ -404,20 +424,14 @@ export default class ArcGisImageServerCatalogItem extends UrlMixin(

private _createImageryProvider = createTransformerAllowUndefined(
(
time: string | undefined
time: JulianDate | undefined
): ArcGisImageServerImageryProvider | undefined => {
if (!isDefined(this.url)) {
return undefined;
}

const params = { ...this.flattenedParameters };
if (time) params.time = time;

const maximumLevel = scaleDenominatorToLevel(
this.maximumScale,
true,
false
);
if (time) params.time = JulianDate.toDate(time).getTime();

let tilingScheme: WebMercatorTilingScheme | GeographicTilingScheme;

Expand All @@ -434,12 +448,13 @@ export default class ArcGisImageServerCatalogItem extends UrlMixin(
return new ArcGisImageServerImageryProvider({
url: cleanAndProxyUrl(this, this.url),
tilingScheme: tilingScheme,
maximumLevel: maximumLevel,
maximumLevel: this.maximumLevel,
minimumLevel: this.minimumLevel,
tileHeight: this.tileHeight,
tileWidth: this.tileWidth,
parameters: params,
enablePickFeatures: this.allowFeaturePicking,
// usePreCachedTilesIfAvailable: this.usePreCachedTilesIfAvailable,
usePreCachedTiles: this.usePreCachedTiles,
token: this.token,
credit: this.attribution ?? ""
});
Expand Down
12 changes: 5 additions & 7 deletions lib/Models/Catalog/Esri/ArcGisInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,17 @@ interface TileInfo {
rows: number;
cols: number;
dpi: number;
format: "Mixed";
compressionQuality: number;
format: string;
compressionQuality?: number;
origin: {
x: number;
y: number;
};
storageInfo: {
storageFormat: "esriMapCacheStorageModeCompact";
storageInfo?: {
storageFormat: string;
packetSize: number;
};
spatialReference: {
wkt: string;
};
spatialReference: SpatialReference;
lods: {
level: number;
resolution: number;
Expand Down
12 changes: 10 additions & 2 deletions lib/Traits/TraitsClasses/ArcGisImageServerCatalogItemTraits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class ArcGisImageServerCatalogItemTraits extends mixTraits(
type: "number",
name: "Maximum scale",
description:
"Gets or sets the denominator of the largest scale (smallest denominator) for which tiles should be requested. For example, if this value is 1000, then tiles representing a scale larger than 1:1000 (i.e. numerically smaller denominator, when zooming in closer) will not be requested. Instead, tiles of the largest-available scale, as specified by this property, will be used and will simply get blurier as the user zooms in closer."
"Gets or sets the denominator of the largest scale (smallest denominator) for which tiles should be requested. For example, if this value is 1000, then tiles representing a scale larger than 1:1000 (i.e. numerically smaller denominator, when zooming in closer) will not be requested. Instead, tiles of the largest-available scale, as specified by this property, will be used and will simply get blurier as the user zooms in closer. Note: maximumLevel overrides this property."
})
maximumScale?: number;

Expand Down Expand Up @@ -65,7 +65,7 @@ export default class ArcGisImageServerCatalogItemTraits extends mixTraits(
"The maximum number of discrete times that can be created by a single " +
"date range when layer in time-enabled."
})
maxRefreshIntervals: number = 1000;
maxRefreshIntervals: number = 10000;

@primitiveTrait({
type: "number",
Expand All @@ -74,4 +74,12 @@ export default class ArcGisImageServerCatalogItemTraits extends mixTraits(
"The well-known ID of the spatial reference of the image server. Only Web Mercator (102100 or 102113) and WGS84 (4326) are supported."
})
wkid?: number = 102100;

@primitiveTrait({
name: "Use Pre-Cached Tiles",
description:
"If true, the server's pre-cached tiles are used. If false, then the ImageServer exportImage endpoint will be used. This will default to false if parameters (including time) have been specified, otherwise it will default to true if a server supports pre-cached tiles.",
type: "boolean"
})
usePreCachedTiles?: boolean;
}

0 comments on commit 3a39d35

Please sign in to comment.