terriajs
Version:
Geospatial data visualization platform.
198 lines (172 loc) • 5.95 kB
text/typescript
import i18next from "i18next";
import { action, computed, observable, toJS, makeObservable } from "mobx";
import JulianDate from "terriajs-cesium/Source/Core/JulianDate";
import CzmlDataSource from "terriajs-cesium/Source/DataSources/CzmlDataSource";
import DataSourceClock from "terriajs-cesium/Source/DataSources/DataSourceClock";
import isDefined from "../../../Core/isDefined";
import TerriaError, { networkRequestError } from "../../../Core/TerriaError";
import AutoRefreshingMixin from "../../../ModelMixins/AutoRefreshingMixin";
import CatalogMemberMixin from "../../../ModelMixins/CatalogMemberMixin";
import MappableMixin from "../../../ModelMixins/MappableMixin";
import TimeVarying from "../../../ModelMixins/TimeVarying";
import UrlMixin from "../../../ModelMixins/UrlMixin";
import CzmlCatalogItemTraits from "../../../Traits/TraitsClasses/CzmlCatalogItemTraits";
import CreateModel from "../../Definition/CreateModel";
import LoadableStratum from "../../Definition/LoadableStratum";
import { BaseModel } from "../../Definition/Model";
import StratumOrder from "../../Definition/StratumOrder";
import HasLocalData from "../../HasLocalData";
import CommonStrata from "../../Definition/CommonStrata";
import { ModelConstructorParameters } from "../../Definition/Model";
import proxyCatalogItemUrl from "../proxyCatalogItemUrl";
import CesiumIonMixin from "../../../ModelMixins/CesiumIonMixin";
/**
* A loadable stratum for CzmlCatalogItemTraits that derives TimeVaryingTraits
* from the CzmlDataSource
*/
class CzmlTimeVaryingStratum extends LoadableStratum(CzmlCatalogItemTraits) {
static stratumName = "czmlLoadableStratum";
constructor(readonly catalogItem: CzmlCatalogItem) {
super();
makeObservable(this);
}
duplicateLoadableStratum(model: BaseModel): this {
return new CzmlTimeVaryingStratum(model as CzmlCatalogItem) as this;
}
private get clock(): DataSourceClock | undefined {
return this.catalogItem._dataSource?.clock;
}
get currentTime(): string | undefined {
const currentTime = this.clock?.currentTime;
return currentTime ? JulianDate.toIso8601(currentTime) : undefined;
}
get startTime(): string | undefined {
const startTime = this.clock?.startTime;
return startTime ? JulianDate.toIso8601(startTime) : undefined;
}
get stopTime() {
const stopTime = this.clock?.stopTime;
return stopTime ? JulianDate.toIso8601(stopTime) : undefined;
}
get multiplier(): number | undefined {
return this.clock?.multiplier;
}
}
StratumOrder.addLoadStratum(CzmlTimeVaryingStratum.stratumName);
export default class CzmlCatalogItem
extends AutoRefreshingMixin(
MappableMixin(
UrlMixin(
CesiumIonMixin(CatalogMemberMixin(CreateModel(CzmlCatalogItemTraits)))
)
)
)
implements TimeVarying, HasLocalData
{
static readonly type = "czml";
constructor(...args: ModelConstructorParameters) {
super(...args);
makeObservable(this);
}
get type() {
return CzmlCatalogItem.type;
}
_dataSource: CzmlDataSource | undefined;
setFileInput(file: File) {
this.setTrait(
CommonStrata.user,
"url",
URL.createObjectURL(file) + "#" + file.name
);
}
get hasLocalData(): boolean {
return this.url?.startsWith("blob:") ?? false;
}
protected forceLoadMapItems(): Promise<void> {
const attribution = this.attribution;
let loadableData: any = undefined;
if (isDefined(this.czmlData)) {
loadableData = toJS(this.czmlData);
} else if (isDefined(this.czmlString)) {
loadableData = JSON.parse(this.czmlString);
} else if (isDefined(this.ionResource)) {
loadableData = this.ionResource;
} else if (isDefined(this.url)) {
loadableData = proxyCatalogItemUrl(this, this.url, this.cacheDuration);
}
if (loadableData === undefined) {
throw new TerriaError({
sender: this,
title: i18next.t("models.czml.unableToLoadItemTitle"),
message: i18next.t("models.czml.unableToLoadItemMessage")
});
}
return CzmlDataSource.load(loadableData, {
credit: attribution
})
.then(
action((czmlDataSource) => {
this._dataSource = czmlDataSource;
this.strata.set(
CzmlTimeVaryingStratum.stratumName,
new CzmlTimeVaryingStratum(this)
);
})
)
.catch((e) => {
if (e instanceof TerriaError) {
throw e;
} else {
throw networkRequestError({
sender: this,
title: i18next.t("models.czml.errorLoadingTitle"),
message: i18next.t("models.czml.errorLoadingMessage")
});
}
});
}
protected forceLoadMetadata(): Promise<void> {
return this.loadIonResource();
}
get mapItems() {
if (this.isLoadingMapItems || this._dataSource === undefined) {
return [];
}
this._dataSource.show = this.show;
return [this._dataSource];
}
get currentTimeAsJulianDate() {
return toJulianDate(this.currentTime);
}
get startTimeAsJulianDate(): JulianDate | undefined {
return toJulianDate(this.startTime);
}
get stopTimeAsJulianDate(): JulianDate | undefined {
return toJulianDate(this.stopTime);
}
/**
* Reloads CzmlDataSource if the source is a URL
* Required for AutoRefreshingMixin
*/
refreshData() {
if (this.url === undefined) return;
const url = proxyCatalogItemUrl(this, this.url, this.cacheDuration);
this._dataSource?.process(url);
}
}
function toJulianDate(time: string | undefined | null): JulianDate | undefined {
return time === undefined || time === null
? undefined
: JulianDate.fromIso8601(time);
}