如何在铯地形上添加标记

时间:2017-02-15 13:04:07

标签: javascript maps cesium

为了在铯的地形上添加标记,我使用sampleTerrain函数来获得高度。

我可以在山顶添加标记,但标记远离鼠标点击。如何在Cesium地形上添加标记,以便标记将完全添加到单击的位置?

作为参考,我会把我的代码放在这里:

async leftClickInputAction(event:{position: {x:number, y:number}}):Promise<any> {

let positionCartesian3 = this.cesium.viewer.camera.pickEllipsoid(event.position);
let positionCartographic = Cesium.Cartographic.fromCartesian(positionCartesian3);
await Cesium.sampleTerrain(this.cesium.viewer.terrainProvider, 9, [positionCartographic]);

let height = positionCartographic.height;
let cart3_with_height = Cesium.Cartesian3.fromRadians(positionCartographic.longitude, positionCartographic.latitude, positionCartographic.height );
let window_coordinates = this.cesium.calcService.toFixes7Obj(Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.cesium.viewer.scene,cart3_with_height));
positionCartesian3 = this.cesium.viewer.camera.pickEllipsoid(event.position);
positionCartographic = Cesium.Cartographic.fromCartesian(positionCartesian3);
positionCartographic.height = height;*/

let lngDeg:number = Cesium.Math.toDegrees(positionCartographic.longitude);
let latDeg:number = Cesium.Math.toDegrees(positionCartographic.latitude);
let position: [number, number, number] = [lngDeg, latDeg, positionCartographic.height];
let color:string = this.cesium.positionFormService.getSelectedColor();
let marker_picker = {position};
if(color != "blue") marker_picker['color'] = color;
this.cesium.queryParamsHelperService.addMarker(marker_picker);

2 个答案:

答案 0 :(得分:3)

这一行是你的问题:

    let positionCartesian3 = this.cesium.viewer.camera.pickEllipsoid(event.position);

pickEllipsoid函数从WGS84椭圆体中选择值(想想&#34;类似于海平面&#34;但不要将它与实际的MSL混淆)。此功能永远不会从山顶返回一个点。

当然,您通过调用sampleTerrain来增强此功能,这很好,但不能解决问题。 &#34;选择&#34;错过了山顶,并最终在山下方和后方的椭圆体上拾取了一个点,而不是靠近用户认为他们点击的位置。

您可以使用另一个函数viewer.scene.pickPosition,它将通过从WebGL的深度缓冲区中读取它们来返回位置。这意味着该功能仅在近距离可靠时才可靠,此时相机足够接近单个山脉,例如未缩小到整个地球。但它确实可以让你选择山顶等。

这是一个演示,使用从Picking Demo解除的代码并修改为在珠穆朗玛峰工作。点击&#34;运行代码段&#34;在这个底部。您可能还想点击&#34;完整页面&#34;之后的弹出链接。

&#13;
&#13;
var terrain = Cesium.createDefaultTerrainProviderViewModels();
var viewer = new Cesium.Viewer('cesiumContainer', {
    navigationInstructionsInitiallyVisible: false,
    animation: false,
    timeline: false,
    geocoder : false,
    selectionIndicator : false,
    infoBox : false,
    terrainProviderViewModels: terrain,
    selectedTerrainProviderViewModel: terrain[1]
});

function lookAtMtEverest() {
    var target = new Cesium.Cartesian3(300770.50872389384, 5634912.131394585, 2978152.2865545116);
    var offset = new Cesium.Cartesian3(6344.974098678562, -793.3419798081741, 2499.9508860763162);
    viewer.camera.lookAt(target, offset);
    viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
}

lookAtMtEverest();

var labelEntity = viewer.entities.add({
    label : {
        show : false,
        showBackground : true,
        font : '14px monospace',
        horizontalOrigin : Cesium.HorizontalOrigin.LEFT,
        verticalOrigin : Cesium.VerticalOrigin.TOP,
        pixelOffset : new Cesium.Cartesian2(15, 0)
    }
});

var sceneModeWarningPosted = false;

// Mouse over the globe to see the cartographic position
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(movement) {
    var foundPosition = false;
    var scene = viewer.scene;
    var pickedObject = scene.pick(movement.endPosition);
    if (scene.pickPositionSupported) {
        if (scene.mode === Cesium.SceneMode.SCENE3D) {
            var cartesian = viewer.scene.pickPosition(movement.endPosition);

            if (Cesium.defined(cartesian)) {
                var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
                var longitudeString = Cesium.Math.toDegrees(cartographic.longitude).toFixed(3);
                var latitudeString = Cesium.Math.toDegrees(cartographic.latitude).toFixed(3);
                var heightString = cartographic.height.toFixed(2);

                labelEntity.position = cartesian;
                labelEntity.label.show = true;
                labelEntity.label.text =
                    'Lon: ' + ('   ' + longitudeString).slice(-8) + '\u00B0' +
                    '\nLat: ' + ('   ' + latitudeString).slice(-8) + '\u00B0' +
                    '\nAlt: ' + ('   ' + heightString).slice(-7) + 'm';

                var camera = scene.camera;
                labelEntity.label.eyeOffset = new Cesium.Cartesian3(0.0, 0.0, camera.frustum.near * 1.5 - Cesium.Cartesian3.distance(cartesian, camera.position));

                foundPosition = true;
            }
        } else if (!sceneModeWarningPosted) {
            sceneModeWarningPosted = true;
            console.log("pickPosition is currently only supported in 3D mode.");
        }
    }

    if (!foundPosition) {
        labelEntity.label.show = false;
    }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
&#13;
html, body, #cesiumContainer {
  width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
  font-family: sans-serif;
}
&#13;
<link href="http://cesiumjs.org/releases/1.30/Build/Cesium/Widgets/widgets.css" 
      rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.30/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我用过:

     let ray = this.cesium.viewer.camera.getPickRay(event.position);
      let positionCartesian3 = this.cesium.viewer.scene.globe.pick(ray, this.cesium.viewer.scene);
      let positionCartographic = Cesium.Cartographic.fromCartesian(positionCartesian3);
      let lngDeg: number = Cesium.Math.toDegrees(positionCartographic.longitude);
      let latDeg: number = Cesium.Math.toDegrees(positionCartographic.latitude);
       position = [lngDeg, latDeg, positionCartographic.height];