terriajs
Version:
Geospatial data visualization platform.
261 lines (230 loc) • 7.72 kB
text/typescript
import i18next from "i18next";
import { action, computed, runInAction, makeObservable } from "mobx";
import URI from "urijs";
import filterOutUndefined from "../../../Core/filterOutUndefined";
import isDefined from "../../../Core/isDefined";
import loadJson from "../../../Core/loadJson";
import replaceUnderscores from "../../../Core/replaceUnderscores";
import runLater from "../../../Core/runLater";
import { networkRequestError } from "../../../Core/TerriaError";
import CatalogMemberMixin from "../../../ModelMixins/CatalogMemberMixin";
import GroupMixin from "../../../ModelMixins/GroupMixin";
import UrlMixin from "../../../ModelMixins/UrlMixin";
import ArcGisFeatureServerCatalogGroupTraits from "../../../Traits/TraitsClasses/ArcGisFeatureServerCatalogGroupTraits";
import { InfoSectionTraits } from "../../../Traits/TraitsClasses/CatalogMemberTraits";
import ModelReference from "../../../Traits/ModelReference";
import ArcGisCatalogGroup from "./ArcGisCatalogGroup";
import ArcGisFeatureServerCatalogItem from "./ArcGisFeatureServerCatalogItem";
import CommonStrata from "../../Definition/CommonStrata";
import CreateModel from "../../Definition/CreateModel";
import createStratumInstance from "../../Definition/createStratumInstance";
import LoadableStratum from "../../Definition/LoadableStratum";
import { BaseModel } from "../../Definition/Model";
import proxyCatalogItemUrl from "../proxyCatalogItemUrl";
import StratumOrder from "../../Definition/StratumOrder";
interface DocumentInfo {
Title?: string;
Author?: string;
}
interface Layer {
id: number;
name?: string;
description?: string;
copyrightText?: string;
}
interface FeatureServer {
documentInfo?: DocumentInfo;
name?: string;
serviceDescription?: string;
description?: string;
copyrightText?: string;
layers: Layer[];
}
export class FeatureServerStratum extends LoadableStratum(
ArcGisFeatureServerCatalogGroupTraits
) {
static stratumName = "featureServer";
constructor(
private readonly _catalogGroup:
| ArcGisFeatureServerCatalogGroup
| ArcGisCatalogGroup,
private readonly _featureServer: FeatureServer
) {
super();
makeObservable(this);
}
duplicateLoadableStratum(model: BaseModel): this {
return new FeatureServerStratum(
model as ArcGisFeatureServerCatalogGroup,
this._featureServer
) as this;
}
get featureServerData() {
return this._featureServer;
}
get name() {
if (
this._featureServer.documentInfo &&
this._featureServer.documentInfo.Title &&
this._featureServer.documentInfo.Title.length > 0
) {
return replaceUnderscores(this._featureServer.documentInfo.Title);
}
}
get info() {
return [
createStratumInstance(InfoSectionTraits, {
name: i18next.t(
"models.arcGisFeatureServerCatalogGroup.serviceDescription"
),
content: this._featureServer.serviceDescription
}),
createStratumInstance(InfoSectionTraits, {
name: i18next.t(
"models.arcGisFeatureServerCatalogGroup.dataDescription"
),
content: this._featureServer.description
}),
createStratumInstance(InfoSectionTraits, {
name: i18next.t("models.arcGisFeatureServerCatalogGroup.copyrightText"),
content: this._featureServer.copyrightText
})
];
}
get cacheDuration(): string {
if (isDefined(super.cacheDuration)) {
return super.cacheDuration;
}
return "1d";
}
get dataCustodian() {
if (
this._featureServer.documentInfo &&
this._featureServer.documentInfo.Author &&
this._featureServer.documentInfo.Author.length > 0
) {
return this._featureServer.documentInfo.Author;
}
}
static async load(
catalogGroup: ArcGisFeatureServerCatalogGroup | ArcGisCatalogGroup
): Promise<FeatureServerStratum> {
const uri = new URI(catalogGroup.url).addQuery("f", "json");
if (catalogGroup.token) {
uri.addQuery("token", catalogGroup.token);
}
return loadJson(proxyCatalogItemUrl(catalogGroup, uri.toString()))
.then((featureServer: FeatureServer) => {
// Is this really a FeatureServer REST response?
if (!featureServer || !featureServer.layers) {
throw networkRequestError({
title: i18next.t(
"models.arcGisFeatureServerCatalogGroup.invalidServiceTitle"
),
message: i18next.t(
"models.arcGisFeatureServerCatalogGroup.invalidServiceMessage"
)
});
}
const stratum = new FeatureServerStratum(catalogGroup, featureServer);
return stratum;
})
.catch(() => {
throw networkRequestError({
sender: catalogGroup,
title: i18next.t(
"models.arcGisFeatureServerCatalogGroup.groupNotAvailableTitle"
),
message: i18next.t(
"models.arcGisFeatureServerCatalogGroup.groupNotAvailableMessage"
)
});
});
}
get members(): ModelReference[] {
return filterOutUndefined(
this.layers.map((layer) => {
if (!isDefined(layer.id)) {
return undefined;
}
return this._catalogGroup.uniqueId + "/" + layer.id;
})
);
}
get layers(): readonly Layer[] {
return this._featureServer.layers;
}
createMembersFromLayers() {
this.layers.forEach((layer) => this.createMemberFromLayer(layer));
}
createMemberFromLayer(layer: Layer) {
if (!isDefined(layer.id)) {
return;
}
const id = this._catalogGroup.uniqueId;
const layerId = id + "/" + layer.id;
const existingModel = this._catalogGroup.terria.getModelById(
ArcGisFeatureServerCatalogItem,
layerId
);
let model: ArcGisFeatureServerCatalogItem;
if (existingModel === undefined) {
model = new ArcGisFeatureServerCatalogItem(
layerId,
this._catalogGroup.terria
);
this._catalogGroup.terria.addModel(model);
} else {
model = existingModel;
}
// Replace the stratum inherited from the parent group.
model.strata.delete(CommonStrata.definition);
model.setTrait(
CommonStrata.definition,
"name",
replaceUnderscores(layer.name)
);
const uri = new URI(this._catalogGroup.url).segment(layer.id + ""); // Convert layer id to string as segment(0) means sthg different.
model.setTrait(CommonStrata.definition, "url", uri.toString());
if (this._catalogGroup.token) {
model.setTrait(
CommonStrata.definition,
"token",
this._catalogGroup.token
);
}
}
}
StratumOrder.addLoadStratum(FeatureServerStratum.stratumName);
export default class ArcGisFeatureServerCatalogGroup extends UrlMixin(
GroupMixin(
CatalogMemberMixin(CreateModel(ArcGisFeatureServerCatalogGroupTraits))
)
) {
static readonly type = "esri-featureServer-group";
get type() {
return ArcGisFeatureServerCatalogGroup.type;
}
get typeName() {
return i18next.t("models.arcGisFeatureServerCatalogGroup.name");
}
protected forceLoadMetadata(): Promise<void> {
return FeatureServerStratum.load(this).then((stratum) => {
runInAction(() => {
this.strata.set(FeatureServerStratum.stratumName, stratum);
});
});
}
protected async forceLoadMembers() {
const featureServerStratum = this.strata.get(
FeatureServerStratum.stratumName
) as FeatureServerStratum | undefined;
if (featureServerStratum) {
await runLater(() => featureServerStratum.createMembersFromLayers());
}
}
}