считывание точки прицеливания с карты
This commit is contained in:
+73
-29
@@ -8,7 +8,9 @@
|
|||||||
viewer: null,
|
viewer: null,
|
||||||
mapDataSource: null,
|
mapDataSource: null,
|
||||||
pickHandler: null,
|
pickHandler: null,
|
||||||
|
resizeObserver: null,
|
||||||
cursorCoordsPanel: null,
|
cursorCoordsPanel: null,
|
||||||
|
targetOverlay: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
function el(id) {
|
function el(id) {
|
||||||
@@ -169,13 +171,15 @@
|
|||||||
...naturalEarthLayerOptions(),
|
...naturalEarthLayerOptions(),
|
||||||
});
|
});
|
||||||
state.viewer.scene.globe.enableLighting = false;
|
state.viewer.scene.globe.enableLighting = false;
|
||||||
state.viewer.scene.requestRenderMode = true;
|
state.viewer.scene.requestRenderMode = false;
|
||||||
state.mapDataSource = new Cesium.CustomDataSource('angular-motion-map-data');
|
state.mapDataSource = new Cesium.CustomDataSource('angular-motion-map-data');
|
||||||
state.viewer.dataSources.add(state.mapDataSource);
|
state.viewer.dataSources.add(state.mapDataSource);
|
||||||
initCursorCoordinates();
|
initCursorCoordinates();
|
||||||
|
initTargetOverlay();
|
||||||
state.pickHandler = new Cesium.ScreenSpaceEventHandler(state.viewer.scene.canvas);
|
state.pickHandler = new Cesium.ScreenSpaceEventHandler(state.viewer.scene.canvas);
|
||||||
state.pickHandler.setInputAction(function (movement) {
|
state.pickHandler.setInputAction(function (movement) {
|
||||||
if (!state.picking) return;
|
if (!state.picking) return;
|
||||||
|
resizeMap();
|
||||||
const cartesian = pickGlobePoint(movement.position);
|
const cartesian = pickGlobePoint(movement.position);
|
||||||
if (!cartesian) return;
|
if (!cartesian) return;
|
||||||
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
||||||
@@ -183,10 +187,37 @@
|
|||||||
el('angular-motion-lon').value = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
|
el('angular-motion-lon').value = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
|
||||||
setPicking(false);
|
setPicking(false);
|
||||||
drawMap();
|
drawMap();
|
||||||
|
updateTargetOverlay(movement.position);
|
||||||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||||
|
initMapResizeSync();
|
||||||
|
state.viewer.scene.postRender.addEventListener(() => updateTargetOverlay());
|
||||||
drawMap();
|
drawMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initMapResizeSync() {
|
||||||
|
window.addEventListener('resize', scheduleMapResize);
|
||||||
|
if (typeof ResizeObserver !== 'undefined') {
|
||||||
|
state.resizeObserver = new ResizeObserver(scheduleMapResize);
|
||||||
|
state.resizeObserver.observe(el('angular-motion-map'));
|
||||||
|
}
|
||||||
|
scheduleMapResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function scheduleMapResize() {
|
||||||
|
resizeMap();
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
resizeMap();
|
||||||
|
requestAnimationFrame(resizeMap);
|
||||||
|
});
|
||||||
|
setTimeout(resizeMap, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeMap() {
|
||||||
|
if (!state.viewer) return;
|
||||||
|
state.viewer.resize();
|
||||||
|
state.viewer.scene.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
function initCursorCoordinates() {
|
function initCursorCoordinates() {
|
||||||
state.cursorCoordsPanel = document.createElement('div');
|
state.cursorCoordsPanel = document.createElement('div');
|
||||||
state.cursorCoordsPanel.className = 'angular-motion-cursor-coords-panel';
|
state.cursorCoordsPanel.className = 'angular-motion-cursor-coords-panel';
|
||||||
@@ -207,6 +238,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initTargetOverlay() {
|
||||||
|
state.targetOverlay = document.createElement('div');
|
||||||
|
state.targetOverlay.className = 'angular-motion-target-marker';
|
||||||
|
state.targetOverlay.innerHTML = '<span class="angular-motion-target-marker__label">ЦЛМ</span><span class="angular-motion-target-marker__dot"></span>';
|
||||||
|
state.viewer.cesiumWidget.container.appendChild(state.targetOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
function naturalEarthLayerOptions() {
|
function naturalEarthLayerOptions() {
|
||||||
const url = '/webjars/cesium/1.107.2/Build/Cesium/Assets/Textures/NaturalEarthII';
|
const url = '/webjars/cesium/1.107.2/Build/Cesium/Assets/Textures/NaturalEarthII';
|
||||||
if (Cesium.ImageryLayer?.fromProviderAsync && Cesium.TileMapServiceImageryProvider?.fromUrl) {
|
if (Cesium.ImageryLayer?.fromProviderAsync && Cesium.TileMapServiceImageryProvider?.fromUrl) {
|
||||||
@@ -225,9 +263,10 @@
|
|||||||
function pickGlobePoint(position) {
|
function pickGlobePoint(position) {
|
||||||
if (!state.viewer || !position) return null;
|
if (!state.viewer || !position) return null;
|
||||||
const scene = state.viewer.scene;
|
const scene = state.viewer.scene;
|
||||||
if (scene.pickPositionSupported) {
|
const ray = state.viewer.camera.getPickRay(position);
|
||||||
const picked = scene.pickPosition(position);
|
if (ray) {
|
||||||
if (Cesium.defined(picked)) return picked;
|
const globePoint = scene.globe.pick(ray, scene);
|
||||||
|
if (Cesium.defined(globePoint)) return globePoint;
|
||||||
}
|
}
|
||||||
return state.viewer.camera.pickEllipsoid(position, scene.globe.ellipsoid);
|
return state.viewer.camera.pickEllipsoid(position, scene.globe.ellipsoid);
|
||||||
}
|
}
|
||||||
@@ -324,32 +363,27 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTarget() {
|
function updateTargetOverlay(screenPosition = null) {
|
||||||
if (!state.mapDataSource) return;
|
if (!state.viewer || !state.targetOverlay) return;
|
||||||
const lat = Number(el('angular-motion-lat').value);
|
const lat = Number(el('angular-motion-lat').value);
|
||||||
const lon = Number(el('angular-motion-lon').value);
|
const lon = Number(el('angular-motion-lon').value);
|
||||||
if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;
|
if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
|
||||||
state.mapDataSource.entities.add({
|
state.targetOverlay.style.display = 'none';
|
||||||
name: 'Точка съемки',
|
return;
|
||||||
position: Cesium.Cartesian3.fromDegrees(lon, lat, 0),
|
}
|
||||||
point: {
|
|
||||||
pixelSize: 10,
|
const position = screenPosition || Cesium.SceneTransforms.wgs84ToWindowCoordinates(
|
||||||
color: Cesium.Color.RED,
|
state.viewer.scene,
|
||||||
outlineColor: Cesium.Color.WHITE,
|
Cesium.Cartesian3.fromDegrees(lon, lat, 0)
|
||||||
outlineWidth: 2,
|
);
|
||||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
if (!Cesium.defined(position)) {
|
||||||
},
|
state.targetOverlay.style.display = 'none';
|
||||||
label: {
|
return;
|
||||||
text: 'ЦЛМ',
|
}
|
||||||
font: '12px sans-serif',
|
|
||||||
fillColor: Cesium.Color.RED,
|
state.targetOverlay.style.display = 'block';
|
||||||
outlineColor: Cesium.Color.WHITE,
|
state.targetOverlay.style.left = `${position.x}px`;
|
||||||
outlineWidth: 2,
|
state.targetOverlay.style.top = `${position.y}px`;
|
||||||
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
||||||
pixelOffset: new Cesium.Cartesian2(0, -18),
|
|
||||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function flightLineBounds() {
|
function flightLineBounds() {
|
||||||
@@ -400,19 +434,29 @@
|
|||||||
|
|
||||||
function drawMap(centerMode = null) {
|
function drawMap(centerMode = null) {
|
||||||
if (!state.mapDataSource || typeof Cesium === 'undefined') return;
|
if (!state.mapDataSource || typeof Cesium === 'undefined') return;
|
||||||
|
resizeMap();
|
||||||
state.mapDataSource.entities.removeAll();
|
state.mapDataSource.entities.removeAll();
|
||||||
const points = Array.isArray(state.flightLine) ? state.flightLine : [];
|
const points = Array.isArray(state.flightLine) ? state.flightLine : [];
|
||||||
addPolyline(points, 'leftLatitudeDeg', 'leftLongitudeDeg', Cesium.Color.CORNFLOWERBLUE.withAlpha(0.85), 2, 'Левая граница полосы');
|
addPolyline(points, 'leftLatitudeDeg', 'leftLongitudeDeg', Cesium.Color.CORNFLOWERBLUE.withAlpha(0.85), 2, 'Левая граница полосы');
|
||||||
addPolyline(points, 'rightLatitudeDeg', 'rightLongitudeDeg', Cesium.Color.CORNFLOWERBLUE.withAlpha(0.85), 2, 'Правая граница полосы');
|
addPolyline(points, 'rightLatitudeDeg', 'rightLongitudeDeg', Cesium.Color.CORNFLOWERBLUE.withAlpha(0.85), 2, 'Правая граница полосы');
|
||||||
addPolyline(points, 'latitudeDeg', 'longitudeDeg', Cesium.Color.YELLOW, 3, 'Трасса полета');
|
addPolyline(points, 'latitudeDeg', 'longitudeDeg', Cesium.Color.YELLOW, 3, 'Трасса полета');
|
||||||
addSurveyContour();
|
addSurveyContour();
|
||||||
addTarget();
|
updateTargetOverlay();
|
||||||
if (centerMode === 'flight-line') {
|
if (centerMode === 'flight-line') {
|
||||||
fitMapToFlightLine();
|
fitMapToFlightLine();
|
||||||
} else if (centerMode === 'target') {
|
} else if (centerMode === 'target') {
|
||||||
centerMapOnTarget();
|
centerMapOnTarget();
|
||||||
}
|
}
|
||||||
|
requestMapRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestMapRender() {
|
||||||
|
if (!state.viewer) return;
|
||||||
state.viewer.scene.requestRender();
|
state.viewer.scene.requestRender();
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
state.viewer?.scene.requestRender();
|
||||||
|
requestAnimationFrame(() => state.viewer?.scene.requestRender());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPicking(value) {
|
function setPicking(value) {
|
||||||
|
|||||||
@@ -65,6 +65,39 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.angular-motion-target-marker {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1001;
|
||||||
|
display: none;
|
||||||
|
pointer-events: none;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-motion-target-marker__dot {
|
||||||
|
display: block;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ff1f2f;
|
||||||
|
box-shadow: 0 0 0 1px rgba(255, 31, 47, 0.65);
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-motion-target-marker__label {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 16px;
|
||||||
|
color: #ff4d5d;
|
||||||
|
font: 700 12px sans-serif;
|
||||||
|
text-shadow:
|
||||||
|
-1px -1px 0 #fff,
|
||||||
|
1px -1px 0 #fff,
|
||||||
|
-1px 1px 0 #fff,
|
||||||
|
1px 1px 0 #fff;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.angular-motion-result-card {
|
.angular-motion-result-card {
|
||||||
min-height: 360px;
|
min-height: 360px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user