import i18next from "i18next"; import { computed, runInAction, makeObservable } from "mobx"; import URI from "urijs"; import isDefined from "../../../Core/isDefined"; import { JsonObject } from "../../../Core/Json"; import loadJson from "../../../Core/loadJson"; import TerriaError from "../../../Core/TerriaError"; import MappableMixin from "../../../ModelMixins/MappableMixin"; import CatalogMemberMixin from "../../../ModelMixins/CatalogMemberMixin"; import UrlMixin from "../../../ModelMixins/UrlMixin"; import { FeatureInfoTemplateTraits } from "../../../Traits/TraitsClasses/FeatureInfoTraits"; import SenapsLocationsCatalogItemTraits from "../../../Traits/TraitsClasses/SenapsLocationsCatalogItemTraits"; import CommonStrata from "../../Definition/CommonStrata"; import CreateModel from "../../Definition/CreateModel"; import createStratumInstance from "../../Definition/createStratumInstance"; import GeoJsonCatalogItem from "./GeoJsonCatalogItem"; import LoadableStratum from "../../Definition/LoadableStratum"; import { BaseModel } from "../../Definition/Model"; import proxyCatalogItemUrl from "../proxyCatalogItemUrl"; import { ModelConstructorParameters } from "../../Definition/Model"; import StratumOrder from "../../Definition/StratumOrder"; export interface SenapsFeature { type: string; properties: { id: string; description: string; endpoint: string; hasStreams: boolean | null; streamIds: string[]; }; geometry: JsonObject; } export interface SenapsFeatureCollection { type: string; features: SenapsFeature[]; } interface SenapsStream { id: string; } interface SenapsStreamResponse { _embedded?: { streams: SenapsStream[]; }; count: number; } interface SenapsLocation { id: string; description: string; streamIds: string[]; geojson: JsonObject; _links: { self: { href: string; }; }; } interface LocationsData { _embedded: { locations: SenapsLocation[]; }; } export class SenapsLocationsStratum extends LoadableStratum( SenapsLocationsCatalogItemTraits ) { static stratumName = "SenapsLocations"; constructor( private readonly senapsLocationsCatalogItem: SenapsLocationsCatalogItem, private readonly geojsonItem: GeoJsonCatalogItem ) { super(); this.geojsonItem = geojsonItem; } duplicateLoadableStratum(newModel: BaseModel): this { return new SenapsLocationsStratum( newModel as SenapsLocationsCatalogItem, this.geojsonItem ) as this; } static async load(senapsLocationsCatalogItem: SenapsLocationsCatalogItem) { const locationsUrl = senapsLocationsCatalogItem._constructLocationsUrl(); function addStreamIds(f: SenapsFeature, index: number, streamData: any) { const sd: SenapsStreamResponse = streamData[index]; if (sd.count === 0) { f.properties.hasStreams = false; } else if (sd._embedded !== undefined) { f.properties.streamIds = sd._embedded.streams.map( (s: SenapsStream) => s.id ); f.properties.hasStreams = true; } } try { const locationsResponse: LocationsData = await loadJson( proxyCatalogItemUrl(senapsLocationsCatalogItem, locationsUrl, "0d") ); const locations = locationsResponse._embedded.locations; const streamPromises = []; for (let i = 0; i < locations.length; i++) { const location = locations[i]; const locationId = location.id; const streamUrl = proxyCatalogItemUrl( senapsLocationsCatalogItem, senapsLocationsCatalogItem._constructStreamsUrl(locationId), "0d" ); streamPromises.push(loadJson(streamUrl)); } const streamData = await Promise.all(streamPromises); const fc: SenapsFeatureCollection = { type: "FeatureCollection", features: locations.map((site: SenapsLocation, i: number) => { const f: SenapsFeature = { type: "Feature", properties: { id: site.id, description: site.description, endpoint: site._links.self.href, hasStreams: null, streamIds: [] }, geometry: site.geojson }; addStreamIds(f, i, streamData); return f; }) }; const geojsonCatalogItem = new GeoJsonCatalogItem( undefined, senapsLocationsCatalogItem.terria ); geojsonCatalogItem.setTrait( CommonStrata.definition, "geoJsonData", fc as any as JsonObject ); geojsonCatalogItem.setTrait( CommonStrata.definition, "clampToGround", true ); if (isDefined(senapsLocationsCatalogItem.style)) { geojsonCatalogItem.setTrait( CommonStrata.definition, "style", senapsLocationsCatalogItem.style ); } if (!senapsLocationsCatalogItem.url) { throw new TerriaError({ title: i18next.t("models.senaps.retrieveErrorTitle"), message: i18next.t("models.senaps.missingSenapsBaseUrl") }); } const proxiedBaseUrl = proxyCatalogItemUrl( senapsLocationsCatalogItem, senapsLocationsCatalogItem.url, "0d" ); const featureInfo = createStratumInstance(FeatureInfoTemplateTraits, { template: `