铯如何在放大/缩小时缩放多边形以匹配Lat-Lon位置

我正在寻找一个Cesium Guru寻找我需要的帮助。 我是新来的铯,但我一直在与教程和一些现有的代码,我已经inheritance。

在我的铯应用程序中,我input我的地址,视图放大到我的街道。 好极了! 然后我放大一点,这样我就可以在我的房子周围绘制一个多边形。 现有的代码做得非常好。 但是, 当我缩小,然后再次放大时,我的多边形不会忠于我家的Lat-Lon位置

铯是否包含一个将像素缩放到lat-lon坐标的实用程序,还是需要使用诸如distanceToBoundingSphere(boundingSphere)之类的东西并自行计算? 我只想要x,y坐标; 我根本不在乎身高。

我一直在看演示和教程,到目前为止还没有find我想要的东西。 也许我已经find了一些东西,但我还不知道我是否find了。 帮帮我!

============================ CODE ===================== =============

收集多边形的位置:

singleClick只捕获该点的坐标,并在用户将鼠标拖动到新点时绘制多段线。 因此,一束多义线和每个点的坐标集合。

positionHandler.setInputAction(function (click) { cartesian = scene.camera.pickEllipsoid(click.position, ellipsoid); if (cartesian) { var setCartographic = ellipsoid.cartesianToCartographic(cartesian); asset.latlonalt.push( Cesium.Math.toDegrees(setCartographic.latitude).toFixed(15), Cesium.Math.toDegrees(setCartographic.longitude).toFixed(15), Cesium.Math.toDegrees(setCartographic.height).toFixed(15) ); lla.push(Cesium.Math.toDegrees(setCartographic.longitude), Cesium.Math.toDegrees(setCartographic.latitude)); if (lla.length >= 4) { self.loggingMessage((lla.length / 2) + ' Points Added'); } Cesium.sampleTerrain(terrainProvider, 11, [cartographic]) .then(function (updatedPositions) { asset.latlonalt[2] = updatedPositions[0].height; stage = 1; }); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); 

然后doubleClick接受singleClick函数中捕获的坐标并调用self.createAsset('add',asset)来创build多边形。

  positionHandler.setInputAction(function (doubleClick){ if (asset.shape == 'Polygon') { var len = asset.latlonalt.length; if(len > 9) { asset.rad = (len / 3); console.log("Creating Asset"); self.loggingMessage("Creating Asset"); socket.emit('newElement', asset.cType, asset); self.createAsset('add', asset); viewer.entities.remove(entity); viewer.entities.remove(newCircle); viewer.entities.remove(newPolygon); viewer.entities.remove(newOutline); positionHandler = positionHandler && positionHandler.destroy(); }else{ console.log('3+ Positions Required'); loggingMessage('3+ Positions Required.'); } } }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) 

创build多边形:

  var newPolygon = viewer.entities.add({ name : asset.id, polygon : { hierarchy : Cesium.Cartesian3.fromDegreesArray(vertices), material : rgba[0], outline : true, outlineColor : rgba[1] } }); var newLabel = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(asset.latlonalt[1], asset.latlonalt[0], 1000), name: asset.id, label: { text: asset.name, font : '16px Helvetica' } }); var newPoint = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(asset.latlonalt[1], asset.latlonalt[0], 0), name: asset.id, point : { pixelSize : 5, color : Cesium.Color.RED, outlineColor : Cesium.Color.RED, outlineWidth : 2 } }); self.currentGeometry[asset.id] = {shape: newPolygon, label: newLabel, point: newPoint}; 

看起来我们正在使用地形(我认为)。

地形图像

我应该关注哪些数字:

在这里输入图像说明

当收集坐标时,只有第一个z不为零:

在这里输入图像说明

我拿这个值,并填充其他z值:

在这里输入图像说明

现在我已经添加了z值,在createAsset方法中出错了。 我需要跟踪这个问题,看看结果。 现在看起来像这样:

在这里输入图像说明

真的很大,轮廓没有被删除。

有一个问题有很多,但我会尽力解决这个问题的关键部分。

首先是Cartesian3类本身。 在内部,在构造之后,这个类包含x, y, z成员,包含像314923.1这样的值。 你可能应该把这些看作是黑盒子,不透明的值。 事实上,它们代表了笛卡尔的位置,以米为单位,来自地球中心,这是渲染引擎所需要的,但对于制图人员来说通常不是很有用。 要理解的关键是z总是会有一个真实的值,而这并不意味着在创build值的时候高度被考虑到了。

有一个单独的类Cartographic ,包含熟悉的经度(Radians),纬度(Radians)和海拔高度(以米为单位)。 一般来说,这些必须转换为Cartesian3然后再交给渲染引擎。 这种转换需要知道Ellipsoid (默认为WGS84椭圆体),因此零高度值指示坐在该椭球体上的点(通常意味着地形打开时该点在地下)。

辅助函数的分类采用常见的值(例如lon / lat度),并转换为这两种格式之一。 这些辅助function中的一些function离开了海拔高度参数,其他的包括它。 这两个类的文档枚举这些助手。

当地形被closures时,从鼠标点击获得确切的长/纬度是简单的,但是由于使用透视3D相机,在打开时更复杂。 没有地形,你可以像在上面的第一个代码示例中所做的那样调用scene.camera.pickEllipsoid ,并获得确切的位置。 但是当地形开始的时候,即使在平原上点击也会计算错误的坐标,在你看到的地形的下面和后面find一个地下点。

一个随便的search没有为此提供正确的代码,但是黄金标准似乎被烘焙到现有的相机控制器中 。 它看起来像这样:

  var depthIntersection; if (scene.pickPositionSupported) { depthIntersection = scene.pickPosition(mousePosition, scratchDepthIntersection); } var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay); var rayIntersection = globe.pick(ray, scene, scratchRayIntersection); var pickDistance = defined(depthIntersection) ? Cartesian3.distance(depthIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; var rayDistance = defined(rayIntersection) ? Cartesian3.distance(rayIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; if (pickDistance < rayDistance) { return Cartesian3.clone(depthIntersection, result); } return Cartesian3.clone(rayIntersection, result); 

这个代码尝试了一个双pipe齐下的方法:它像以前一样尝试select椭球体,并且也尝试从“深度缓冲区”中选取,这是3Dgraphics系统的一部分,允许Cesium检查多边形的多远从相机呈现时。 两个结果进行比较,取其中较接近相机的是声明胜利者。 这可以避免需要sampleTerrain调用,因为鼠标位置已经被用来直接在多边形渲染的空间(这可能是地形,但甚至可能是build筑物的顶部等)的空间中select笛卡尔点。

在你的下一个代码块中,你使用asset.latlonalt来填充lonlat ,但是你有硬编码为01000而不是来自相同的数据结构。 这可能是海拔高度信息丢失的地方,如果它是在那里开始的(不是,如果你只是select椭球本身,虽然它可能被sampleTerrain稍后添加。注意sampleTerrain是asynchronous的到从服务器加载的地形图块)。 如果你决定尝试深度采摘技术,这将直接产生Cartesian3 ,所以你不必担心转换或保存高度等。

最后一个评论,最近版本的铯确实支持允许多边形悬垂在地形上的GroundPrimitive 。 这样做并不能使您不必从“挑选”正确的lon / lat开始(将透视地形考虑在内),而是允许将多边形放置在一个粗糙的表面上,而不是穿过。