terriajs
Version:
Geospatial data visualization platform.
83 lines (68 loc) • 3.68 kB
JavaScript
import CustomDataSource from 'terriajs-cesium/Source/DataSources/CustomDataSource';
import defined from 'terriajs-cesium/Source/Core/defined';
import Entity from 'terriajs-cesium/Source/DataSources/Entity.js';
import Ellipsoid from 'terriajs-cesium/Source/Core/Ellipsoid';
import Cartographic from 'terriajs-cesium/Source/Core/Cartographic';
import Cartesian3 from 'terriajs-cesium/Source/Core/Cartesian3';
import VerticalOrigin from 'terriajs-cesium/Source/Scene/VerticalOrigin';
import sampleTerrain from 'terriajs-cesium/Source/Core/sampleTerrain';
import prettifyCoordinates from '../Map/prettifyCoordinates';
import markerIcon from '../../wwwroot/images/map-pin.png';
const LOCATION_MARKER_DATA_SOURCE_NAME = 'TerriaJS Location Marker Points';
/**
* 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, result) {
if (!terria.locationMarker) {
terria.locationMarker = new CustomDataSource(LOCATION_MARKER_DATA_SOURCE_NAME);
}
if (!terria.dataSources.contains(terria.locationMarker)) {
terria.dataSources.add(terria.locationMarker);
}
terria.locationMarker.entities.removeAll();
const cartographicPosition = Cartographic.fromDegrees(result.location.longitude, result.location.latitude);
const displayCoords = prettifyCoordinates(result.location.longitude, result.location.latitude, {digits: 5});
const firstPointEntity = new Entity({
name: result.name,
position: Ellipsoid.WGS84.cartographicToCartesian(cartographicPosition),
description: `<table><tr><td>Lat / Lon</td><td>${displayCoords.latitude}, ${displayCoords.longitude}</td></tr></table>`,
billboard: {
image: markerIcon,
scale: 0.5,
eyeOffset: new Cartesian3(0.0, 0.0, 50.0),
verticalOrigin: VerticalOrigin.BOTTOM
}
});
if (terria.cesium && terria.cesium.scene && terria.cesium.scene.globe && terria.cesium.scene.globe.terrainProvider) {
correctEntityHeight(firstPointEntity, cartographicPosition, terria.cesium.scene.globe.terrainProvider, 15);
}
terria.locationMarker.entities.add(firstPointEntity);
}
/**
* Gets the most detailed height from terrainProvider at currentCartographicPosition and updates entity position.
* It starts querying at levelHint and makes its way down to level zero.
*/
function correctEntityHeight(entity, currentCartographicPosition, terrainProvider, levelHint) {
sampleTerrain(terrainProvider, levelHint, [currentCartographicPosition]).then(function (updatedPositions) {
if (updatedPositions[0].height !== undefined) {
entity.position = Ellipsoid.WGS84.cartographicToCartesian(updatedPositions[0]);
} else if (levelHint > 0) {
correctEntityHeight(entity, currentCartographicPosition, terrainProvider, levelHint - 1);
}
});
}
/** Removes a marker previously added in {@link #addMarker}. */
export function removeMarker(terria) {
terria.dataSources.remove(terria.locationMarker);
terria.locationMarker = undefined;
}
/** Determines whether the location marker is visible previously added in {@link #addMarker}. */
export function markerVisible(terria) {
return defined(terria.locationMarker);
}
/**
* The name given to the data source created by {@link #addMarker}.
*/
export { LOCATION_MARKER_DATA_SOURCE_NAME };