terriajs
Version:
Geospatial data visualization platform.
221 lines • 9.39 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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import classNames from "classnames";
import { action, makeObservable, computed as mobxComputed, observable } from "mobx";
import { observer } from "mobx-react";
import { useEffect, useMemo, useRef } from "react";
import { useTranslation } from "react-i18next";
import CesiumMath from "terriajs-cesium/Source/Core/Math";
import filterOutUndefined from "../../Core/filterOutUndefined";
import MappableMixin, { ImageryParts } from "../../ModelMixins/MappableMixin";
import GeoJsonCatalogItem from "../../Models/Catalog/CatalogItems/GeoJsonCatalogItem";
import CommonStrata from "../../Models/Definition/CommonStrata";
import CreateModel from "../../Models/Definition/CreateModel";
import ViewerMode from "../../Models/ViewerMode";
import MappableTraits from "../../Traits/TraitsClasses/MappableTraits";
import TerriaViewer from "../../ViewModels/TerriaViewer";
import Styles from "./data-preview-map.scss";
// AdaptForPreviewMap class remains largely the same
class AdaptForPreviewMap extends MappableMixin(CreateModel(MappableTraits)) {
previewed;
constructor(...args) {
super(...args);
makeObservable(this);
}
async forceLoadMapItems() { }
get mapItems() {
return (this.previewed?.mapItems.map((m) => ImageryParts.is(m)
? {
...m,
alpha: m.alpha !== 0.0 ? 1.0 : 0.0,
show: true
}
: m) ?? []);
}
}
__decorate([
observable
], AdaptForPreviewMap.prototype, "previewed", void 0);
__decorate([
mobxComputed
], AdaptForPreviewMap.prototype, "mapItems", null);
const createBoundingRectangleCatalogItem = (terria, bbox, id = "__preview-data-extent") => {
const rectangleCatalogItem = new GeoJsonCatalogItem(id, terria);
rectangleCatalogItem.setTrait(CommonStrata.user, "geoJsonData", {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {
stroke: "#08ABD5",
"stroke-width": 2,
"stroke-opacity": 1
},
geometry: {
type: "LineString",
coordinates: [
[bbox.west, bbox.south],
[bbox.west, bbox.north],
[bbox.east, bbox.north],
[bbox.east, bbox.south],
[bbox.west, bbox.south]
]
}
}
]
});
rectangleCatalogItem.loadMapItems();
return rectangleCatalogItem;
};
const DataPreviewMap = observer((props) => {
const { t } = useTranslation();
const { terria, previewed, showMap } = props;
const mapContainerRef = useRef(null);
const isZoomedToExtentRef = useRef(false);
const homeCamera = useMemo(() => {
return terria.mainViewer.homeCamera;
}, [terria]);
const boundingRectangleCatalogItem = useMemo(() => {
const rectangle = previewed?.rectangle;
if (!rectangle) {
return undefined;
}
const { west, south, east, north } = rectangle;
if (west === undefined ||
south === undefined ||
east === undefined ||
north === undefined) {
return undefined;
}
return createBoundingRectangleCatalogItem(terria, {
west,
south,
east,
north
}, "__preview-data-extent");
}, [previewed?.rectangle, terria]);
const zoomedOutBoundingRectangleCatalogItem = useMemo(() => {
const rectangle = previewed?.rectangle;
if (!rectangle) {
return undefined;
}
let { west, south, east, north } = rectangle;
if (west === undefined ||
south === undefined ||
east === undefined ||
north === undefined) {
return undefined;
}
// When zoomed out, make sure the dataset rectangle is at least 5% of the width and height
// the home view, so that it is actually visible.
const minimumFraction = 0.05;
const homeView = homeCamera;
const minimumWidth = CesiumMath.toDegrees(homeView.rectangle.width) * minimumFraction;
if (east - west < minimumWidth) {
const center = (east + west) * 0.5;
west = center - minimumWidth * 0.5;
east = center + minimumWidth * 0.5;
}
const minimumHeight = CesiumMath.toDegrees(homeView.rectangle.height) * minimumFraction;
if (north - south < minimumHeight) {
const center = (north + south) * 0.5;
south = center - minimumHeight * 0.5;
north = center + minimumHeight * 0.5;
}
return createBoundingRectangleCatalogItem(terria, {
west,
south,
east,
north
}, "__preview-data-extent-zoomed-out");
}, [homeCamera, previewed?.rectangle, terria]);
const previewViewer = useMemo(() => {
const viewer = new TerriaViewer(terria, mobxComputed(() => {
const previewItem = new AdaptForPreviewMap(undefined, terria);
previewItem.previewed = previewed;
return filterOutUndefined([
previewItem,
boundingRectangleCatalogItem,
zoomedOutBoundingRectangleCatalogItem
]);
}));
viewer.viewerMode = ViewerMode.Leaflet;
viewer.disableInteraction = true;
viewer.homeCamera = homeCamera;
return viewer;
}, [
boundingRectangleCatalogItem,
homeCamera,
previewed,
terria,
zoomedOutBoundingRectangleCatalogItem
]);
useEffect(() => {
const container = mapContainerRef.current;
const baseMapItems = terria.baseMapsModel.baseMapItems;
const initPreviewBaseMap = action(() => baseMapItems.find((bm) => bm.item.uniqueId === terria.baseMapsModel.previewBaseMapId))();
if (initPreviewBaseMap) {
previewViewer.setBaseMap(initPreviewBaseMap.item);
}
else {
previewViewer.setBaseMap(baseMapItems.length > 0 ? baseMapItems[0].item : undefined);
}
previewViewer.attach(container);
return () => {
if (previewViewer.attached) {
previewViewer.detach();
}
};
}, [
previewViewer,
terria.baseMapsModel.baseMapItems,
terria.baseMapsModel.previewBaseMapId
]);
const toggleZoom = action(() => {
isZoomedToExtentRef.current = !isZoomedToExtentRef.current;
if (isZoomedToExtentRef.current) {
boundingRectangleCatalogItem?.setTrait(CommonStrata.override, "show", true);
zoomedOutBoundingRectangleCatalogItem?.setTrait(CommonStrata.override, "show", false);
if (previewed) {
previewViewer?.currentViewer.zoomTo(previewed);
}
}
else {
boundingRectangleCatalogItem?.setTrait(CommonStrata.override, "show", false);
zoomedOutBoundingRectangleCatalogItem?.setTrait(CommonStrata.override, "show", true);
previewViewer.currentViewer.zoomTo(previewViewer?.homeCamera);
}
});
const previewBadgeState = useMemo(() => {
if (previewed?.isLoading)
return "loading";
if (previewed?.loadMetadataResult?.error ||
previewed?.loadMapItemsResult?.error)
return "dataPreviewError";
if ((!previewed?.mapItems || previewed.mapItems.length === 0) &&
!boundingRectangleCatalogItem)
return "noPreviewAvailable";
return "dataPreview";
}, [
boundingRectangleCatalogItem,
previewed?.isLoading,
previewed?.loadMapItemsResult?.error,
previewed?.loadMetadataResult?.error,
previewed?.mapItems
]);
const previewBadgeLabels = {
loading: t("preview.loading"),
noPreviewAvailable: t("preview.noPreviewAvailable"),
dataPreview: t("preview.dataPreview"),
dataPreviewError: t("preview.dataPreviewError")
};
return (_jsxs("div", { className: Styles.map, onClick: toggleZoom, children: [showMap ? (_jsx("div", { className: classNames(Styles.terriaPreview), ref: mapContainerRef }, "terria-preview-map" // Ensures DOM is recreated if map needs clean state on show/hide
)) : (_jsx("div", { className: classNames(Styles.terriaPreview, Styles.placeholder) }, "terria-preview-placeholder")), _jsx("label", { className: Styles.badge, children: previewBadgeLabels[previewBadgeState] || "" })] }));
});
export default DataPreviewMap;
//# sourceMappingURL=DataPreviewMap.js.map