terriajs
Version:
Geospatial data visualization platform.
117 lines (103 loc) • 3.84 kB
text/typescript
import i18next from "i18next";
import prettifyCoordinates from "../Map/Vector/prettifyCoordinates";
import CommonStrata from "./Definition/CommonStrata";
import CzmlCatalogItem from "./Catalog/CatalogItems/CzmlCatalogItem";
import Terria from "./Terria";
import LatLonHeight from "../Core/LatLonHeight";
import { toJS } from "mobx";
import markerIcon from "../../wwwroot/images/map-pin.png";
export const LOCATION_MARKER_DATA_SOURCE_NAME =
"TerriaJS Location Marker Points";
export const MARKER_UNIQUE_ID = "__TERRRIAJS-LOCATIONMARKER__";
export interface MarkerDetails {
name: string;
location: { longitude: number; latitude: number; height?: number };
heightReference?: "NONE" | "CLAMP_TO_GROUND" | "RELATIVE_TO_GROUND";
customMarkerIcon?: string;
}
/**
* Adds a location marker to the map with the position supplied in the result, adding a data source to terria if one hasn't
* already been added, and removing all previously added markers in that data source. This data source is stored in
* terria.locationMarker.
*/
export function addMarker(
terria: Terria,
details: MarkerDetails
): CzmlCatalogItem {
const location = details.location;
const displayCoords = prettifyCoordinates(
details.location.longitude,
details.location.latitude,
{ digits: 5 }
);
const billboard: any = {
image: details.customMarkerIcon || markerIcon,
scale: details.customMarkerIcon ? 1 : 0.5,
verticalOrigin: "BOTTOM",
heightReference:
details.heightReference ||
(details.location.height === undefined ? "CLAMP_TO_GROUND" : "NONE")
};
const document = {
id: "document",
name: LOCATION_MARKER_DATA_SOURCE_NAME,
version: "1.0"
};
const marker = {
name: details.name,
position: {
cartographicDegrees: [
location.longitude,
location.latitude,
location.height || 0.0
]
},
description: `<table><tr><td>${i18next.t("featureInfo.latLon")}</td><td>${
displayCoords.latitude
}, ${displayCoords.longitude}</td></tr></table>`,
billboard: billboard
};
let catalogItem = terria.getModelById(CzmlCatalogItem, MARKER_UNIQUE_ID);
if (catalogItem === undefined) {
catalogItem = new CzmlCatalogItem(MARKER_UNIQUE_ID, terria);
catalogItem.setTrait(
CommonStrata.definition,
"name",
LOCATION_MARKER_DATA_SOURCE_NAME
);
terria.addModel(catalogItem);
}
catalogItem.setTrait(CommonStrata.user, "czmlData", [document, marker]);
terria.overlays.add(catalogItem);
return catalogItem;
}
/** Removes a marker previously added in {@link #addMarker}. */
export function removeMarker(terria: Terria) {
const catalogItem = terria.getModelById(CzmlCatalogItem, MARKER_UNIQUE_ID);
if (catalogItem !== undefined) {
terria.overlays.remove(catalogItem);
}
}
/** Determines whether the location marker is visible previously added in {@link #addMarker}. */
export function isMarkerVisible(terria: Terria): boolean {
const catalogItem = terria.getModelById(CzmlCatalogItem, MARKER_UNIQUE_ID);
return catalogItem !== undefined && terria.overlays.contains(catalogItem);
}
export function getMarkerLocation(terria: Terria): LatLonHeight | undefined {
const catalogItem = terria.getModelById(CzmlCatalogItem, MARKER_UNIQUE_ID);
if (catalogItem === undefined || !terria.overlays.contains(catalogItem)) {
return;
}
const marker: any = catalogItem.czmlData[1];
const position = marker?.position?.cartographicDegrees;
if (Array.isArray(toJS(position))) {
const [longitude, latitude, height] = position;
if (longitude !== undefined && latitude !== undefined) {
return { longitude, latitude, height };
}
}
return undefined;
}
export function getMarkerCatalogItem(terria: Terria) {
return terria.getModelById(CzmlCatalogItem, MARKER_UNIQUE_ID);
}