terriajs
Version:
Geospatial data visualization platform.
346 lines • 14.5 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import DOMPurify from "dompurify";
import i18next from "i18next";
import { computed, runInAction, makeObservable, override } from "mobx";
import { createTransformer } from "mobx-utils";
import URI from "urijs";
import isDefined from "../../../Core/isDefined";
import loadJson from "../../../Core/loadJson";
import AccessControlMixin from "../../../ModelMixins/AccessControlMixin";
import ReferenceMixin from "../../../ModelMixins/ReferenceMixin";
import UrlMixin from "../../../ModelMixins/UrlMixin";
import ArcGisPortalItemFormatTraits from "../../../Traits/TraitsClasses/ArcGisPortalItemFormatTraits";
import ArcGisPortalItemTraits from "../../../Traits/TraitsClasses/ArcGisPortalItemTraits";
import { InfoSectionTraits } from "../../../Traits/TraitsClasses/CatalogMemberTraits";
import CatalogMemberFactory from "../CatalogMemberFactory";
import CommonStrata from "../../Definition/CommonStrata";
import CreateModel from "../../Definition/CreateModel";
import createStratumInstance from "../../Definition/createStratumInstance";
import LoadableStratum from "../../Definition/LoadableStratum";
import proxyCatalogItemUrl from "../proxyCatalogItemUrl";
import StratumOrder from "../../Definition/StratumOrder";
export class ArcGisPortalItemStratum extends LoadableStratum(ArcGisPortalItemTraits) {
arcgisPortalItemReference;
arcgisPortalCatalogGroup;
static stratumName = "arcGisPortalDataset";
constructor(arcgisPortalItemReference, arcgisPortalCatalogGroup) {
super();
this.arcgisPortalItemReference = arcgisPortalItemReference;
this.arcgisPortalCatalogGroup = arcgisPortalCatalogGroup;
makeObservable(this);
}
duplicateLoadableStratum(_newModel) {
return new ArcGisPortalItemStratum(this.arcgisPortalItemReference, this.arcgisPortalCatalogGroup);
}
static async load(arcgisPortalItemReference, arcgisPortalCatalogGroup) {
if (arcgisPortalItemReference._arcgisItem === undefined) {
if (arcgisPortalItemReference.uniqueId !== undefined) {
arcgisPortalItemReference._portalRootUrl =
arcgisPortalItemReference.url;
arcgisPortalItemReference._arcgisItem = await loadPortalItem(arcgisPortalItemReference);
arcgisPortalItemReference.setSupportedFormatFromItem(arcgisPortalItemReference._arcgisItem);
}
}
else if (arcgisPortalCatalogGroup !== undefined) {
arcgisPortalItemReference._portalRootUrl = arcgisPortalCatalogGroup.url;
}
return new ArcGisPortalItemStratum(arcgisPortalItemReference, arcgisPortalCatalogGroup);
}
get arcgisPortalItem() {
if (this.arcgisPortalItemReference._arcgisItem === undefined)
return undefined;
return this.arcgisPortalItemReference._arcgisItem;
}
get portalItemUrl() {
if (this.arcgisPortalItem === undefined ||
this.arcgisPortalItemReference._portalRootUrl === undefined)
return undefined;
const uri = new URI(this.arcgisPortalItemReference._portalRootUrl)
.segment(`/home/item.html`)
.addQuery("id", this.arcgisPortalItem.id);
return uri.toString();
}
get url() {
if (this.arcgisPortalItem === undefined)
return undefined;
if (this.arcgisPortalItem.type === "Scene Service")
return `/i3s-to-3dtiles/${this.arcgisPortalItem.url}`;
return this.arcgisPortalItem.url;
}
get name() {
if (this.arcgisPortalItem === undefined)
return undefined;
return this.arcgisPortalItem.title;
}
get description() {
if (this.arcgisPortalItem === undefined)
return undefined;
// return this.arcgisPortalItem.description
return DOMPurify.sanitize(this.arcgisPortalItem.description, {
FORBID_ATTR: ["style"],
FORBID_TAGS: ["font"]
});
}
get info() {
const outArray = [];
if (this.arcgisPortalItem === undefined)
return outArray;
if (this.arcgisPortalItem.licenseInfo !== undefined) {
outArray.push(createStratumInstance(InfoSectionTraits, {
name: i18next.t("models.arcgisPortal.licence"),
content: DOMPurify.sanitize(this.arcgisPortalItem.licenseInfo, {
FORBID_ATTR: ["style"],
FORBID_TAGS: ["font"]
})
}));
}
outArray.push(createStratumInstance(InfoSectionTraits, {
name: i18next.t("models.arcgisPortal.openInPortal"),
content: `<a href="${this.portalItemUrl}"><button>${i18next.t("models.arcgisPortal.openInPortal")}</button></a>`
}));
return outArray;
}
}
__decorate([
computed
], ArcGisPortalItemStratum.prototype, "arcgisPortalItem", null);
__decorate([
computed
], ArcGisPortalItemStratum.prototype, "portalItemUrl", null);
__decorate([
computed
], ArcGisPortalItemStratum.prototype, "url", null);
__decorate([
computed
], ArcGisPortalItemStratum.prototype, "name", null);
__decorate([
computed
], ArcGisPortalItemStratum.prototype, "description", null);
__decorate([
computed
], ArcGisPortalItemStratum.prototype, "info", null);
StratumOrder.addLoadStratum(ArcGisPortalItemStratum.stratumName);
export default class ArcGisPortalItemReference extends AccessControlMixin(UrlMixin(ReferenceMixin(CreateModel(ArcGisPortalItemTraits)))) {
static defaultSupportedFormats = [
createStratumInstance(ArcGisPortalItemFormatTraits, {
id: "I3S",
formatRegex: "Scene Service",
urlRegex: "SceneServer$|SceneServer/$",
definition: {
type: "3d-tiles"
}
}),
// createStratumInstance(ArcGisPortalItemFormatTraits, {
// id: "WFS",
// formatRegex: "WFS",
// urlRegex: "WFSServer",
// definition: {
// type: "wfs"
// }
// }),
createStratumInstance(ArcGisPortalItemFormatTraits, {
id: "WMS",
formatRegex: "WMS",
urlRegex: "WMSServer",
definition: {
type: "wms"
}
}),
createStratumInstance(ArcGisPortalItemFormatTraits, {
id: "ArcGIS MapServer Group",
formatRegex: "Map Service",
urlRegex: "MapServer$|MapServer/$",
definition: {
type: "esri-mapServer-group"
}
}),
createStratumInstance(ArcGisPortalItemFormatTraits, {
id: "ArcGIS MapServer",
formatRegex: "Map Service",
urlRegex: /MapServer\/\d/,
definition: {
type: "esri-mapServer"
}
}),
createStratumInstance(ArcGisPortalItemFormatTraits, {
id: "ArcGIS FeatureServer Group",
formatRegex: "Feature Service",
urlRegex: "FeatureServer$|FeatureServer/$",
definition: {
type: "esri-featureServer-group"
}
}),
createStratumInstance(ArcGisPortalItemFormatTraits, {
id: "ArcGIS FeatureServer",
formatRegex: "Feature Service",
urlRegex: /FeatureServer\/\d/,
definition: {
type: "esri-featureServer"
}
}),
createStratumInstance(ArcGisPortalItemFormatTraits, {
id: "Kml",
formatRegex: "KML",
definition: {
type: "kml"
}
})
];
static type = "arcgis-portal-item";
get type() {
return ArcGisPortalItemReference.type;
}
get typeName() {
return i18next.t("models.arcgisPortal.name");
}
_arcgisItem = undefined;
_arcgisPortalCatalogGroup = undefined;
_supportedFormat = undefined;
_portalRootUrl = undefined;
constructor(id, terria, sourceReference, strata) {
super(id, terria, sourceReference, strata);
makeObservable(this);
this.setTrait(CommonStrata.defaults, "supportedFormats", ArcGisPortalItemReference.defaultSupportedFormats);
}
get cacheDuration() {
if (isDefined(super.cacheDuration)) {
return super.cacheDuration;
}
else if (isDefined(this._arcgisPortalCatalogGroup)) {
return this._arcgisPortalCatalogGroup.cacheDuration;
}
return "0d";
}
get preparedSupportedFormats() {
return (this.supportedFormats && this.supportedFormats.map(prepareSupportedFormat));
}
isItemInSupportedFormats(item) {
if (item === undefined)
return undefined;
for (let i = 0; i < this.preparedSupportedFormats.length; ++i) {
const format = this.preparedSupportedFormats[i];
// This is a bit clunky but format handling for non-Esri stuff in portal is a bit unpredictable
if (format.formatRegex === undefined || format.urlRegex === undefined) {
// eg KML we can match using format regex but not the URL
if (format.formatRegex) {
if (format.formatRegex.test(item.type))
return format;
}
else if (format.urlRegex) {
if (format.urlRegex.test(item.url))
return format;
}
}
else {
if (format.formatRegex.test(item.type) &&
format.urlRegex.test(item.url)) {
return format;
}
}
}
return undefined;
}
setDataset(item) {
this._arcgisItem = item;
}
setArcgisPortalCatalog(arcgisCatalogGroup) {
this._arcgisPortalCatalogGroup = arcgisCatalogGroup;
}
setSupportedFormatFromItem(item) {
this._supportedFormat = this.isItemInSupportedFormats(item);
}
async setArcgisStrata(model) {
const stratum = await ArcGisPortalItemStratum.load(this, this._arcgisPortalCatalogGroup);
if (stratum === undefined)
return;
runInAction(() => {
model.strata.set(ArcGisPortalItemStratum.stratumName, stratum);
});
}
async forceLoadReference(_previousTarget) {
// So when we first crawl we'll get this far
await this.setArcgisStrata(this);
// this.setSupportedFormatFromItem(this._arcgisItem);
if (this._supportedFormat === undefined)
return undefined;
// See comments below re this sequence
const itemDataInfo = await loadAdditionalPortalInfo(this);
if (itemDataInfo !== undefined && this._arcgisItem !== undefined) {
if (!itemDataInfo.error && itemDataInfo.layers) {
if (itemDataInfo.layers.length === 1) {
this._arcgisItem.url = `${this._arcgisItem.url}/${itemDataInfo.layers[0].id}`;
}
}
this.setSupportedFormatFromItem(this._arcgisItem);
}
// One final catch to handing types
// Tiled MapServices dont use a single layer
if (this._arcgisItem !== undefined &&
this._arcgisItem.type === "Map Service" &&
this._arcgisItem.typeKeywords.indexOf("Tiled") > -1) {
const mapServerFormat = this.preparedSupportedFormats.filter((f) => f.definition.type === "esri-mapServer");
if (mapServerFormat.length === 1)
this._supportedFormat = mapServerFormat[0];
}
const model = CatalogMemberFactory.create(this._supportedFormat.definition.type, this.uniqueId, this.terria, this);
if (model === undefined)
return;
await this.setArcgisStrata(model);
const defintionStratum = this.strata.get(CommonStrata.definition);
if (defintionStratum) {
model.strata.set(CommonStrata.definition, defintionStratum);
model.setTrait(CommonStrata.definition, "url", undefined);
}
return model;
}
}
__decorate([
override
], ArcGisPortalItemReference.prototype, "cacheDuration", null);
__decorate([
computed
], ArcGisPortalItemReference.prototype, "preparedSupportedFormats", null);
async function loadPortalItem(portalItem) {
const uri = new URI(portalItem._portalRootUrl)
.segment(`/sharing/rest/content/items/${portalItem.itemId}`)
.addQuery({ f: "json" });
const response = await loadJson(proxyCatalogItemUrl(portalItem, uri.toString(), portalItem.cacheDuration));
return response;
}
// Portal has this weird habit of storing useful additional info about an item
// such as which layers to use from a group of layers at the /data endpoint
// But this only relevant on some layers
async function loadAdditionalPortalInfo(portalItem) {
if (portalItem._arcgisItem === undefined)
return undefined;
const baseUrl = portalItem._portalRootUrl;
const uri = new URI(baseUrl)
.segment(`/sharing/rest/content/items/${portalItem._arcgisItem.id}/data`)
.addQuery({ f: "json" });
// The request also returns 200 even if the page is blank causing json errors
// Sometimes it actually returns json containing an error, but not always
try {
const response = await loadJson(proxyCatalogItemUrl(portalItem, uri.toString(), portalItem.cacheDuration));
return response;
}
catch (_err) {
return undefined;
}
}
const prepareSupportedFormat = createTransformer((format) => {
return {
urlRegex: format.urlRegex
? new RegExp(format.urlRegex, "i")
: undefined,
formatRegex: format.formatRegex
? new RegExp(format.formatRegex, "i")
: undefined,
definition: format.definition || {}
};
});
//# sourceMappingURL=ArcGisPortalItemReference.js.map