Cesium面積測量之思路解析加原始碼
阿新 • • 發佈:2018-12-17
如果你看過我的距離量測文章,那麼我相信,面積也是你需要測量的吧,那就看看吧。
一、實現思路
首先我們需要用到的滑鼠移動事件、單擊事件和雙擊事件,具體功能如下:
1,滑鼠移動事件:判斷是否開始進行測量操作(單擊為開始標誌),如果沒有,則什麼也不做,如何開始則需要把單擊的座標作為起點,滑鼠當前位置作為終點畫面,隨著滑鼠的移動需要不停的重新整理面。
2,單擊事件:將測面狀態更新為真,當點選次數大於倆次,開始繪製面,這裡有面積計算和更新面倆個函式比較重要,後續你會看到
3,雙擊事件:將之前註冊的事件取消,並清空臨時物件。是不是很簡單呢?
二、原始碼實現
<!--測量空間面積--> <script type="text/javascript"> //測量面積 var measureArea = function (viewer) { var tooltip = document.getElementById("ToolTip"); var isDraw = false; var polygonPath = []; var polygon = null; var handler = viewer.screenSpaceEventHandler; handler.setInputAction(function (movement) { //新增部分 var position1; var cartographic; var ray = viewer.scene.camera.getPickRay(movement.endPosition); if (ray) position1 = viewer.scene.globe.pick(ray, viewer.scene); if (position1) cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position1); if (cartographic) { //海拔 var height = viewer.scene.globe.getHeight(cartographic); var point = Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180, height); if (isDraw) { tooltip.style.left = movement.endPosition.x + 10 + "px"; tooltip.style.top = movement.endPosition.y + 20 + "px"; tooltip.style.display = "block"; if (polygonPath.length < 2) { return; } if (!Cesium.defined(polygon)) { polygonPath.push(point); polygon = new CreatePolygon(polygonPath, Cesium); AllEnities.push(polygon); } else { polygon.path.pop(); polygon.path.push(point); AllEnities.push(polygon); } if (polygonPath.length >= 2) { tooltip.innerHTML = '<p>雙擊確定終點</p>'; } } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); handler.setInputAction(function (movement) { isDraw = true; //新增部分 var position1; var cartographic; var ray = viewer.scene.camera.getPickRay(movement.position); if (ray) position1 = viewer.scene.globe.pick(ray, viewer.scene); if (position1) cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position1); if (cartographic) { //海拔 var height = viewer.scene.globe.getHeight(cartographic); var point = Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180, height); if (isDraw) { polygonPath.push(point); var tmep = viewer.entities.add({ position: point, point: { show: true, color: Cesium.Color.SKYBLUE, pixelSize: 3, outlineColor: Cesium.Color.YELLOW, outlineWidth: 1 }, }); AllEnities.push(tmep); } } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); handler.setInputAction(function () { handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); if (polygonPath.length >= 2) { var label = String(countAreaInCartesian3(polygon.path)); label = label.substr(0, label.indexOf(".", 0)); var text; if (label.length < 6) text = label + "平方米"; else { label = String(label / 1000000); label = label.substr(0, label.indexOf(".", 0) + 3); text = label + "平方公里" } var textArea = text; var lastpoint = viewer.entities.add({ name: '多邊形面積', position: polygon.path[polygon.path.length - 1], point: { pixelSize: 5, color: Cesium.Color.RED, outlineColor: Cesium.Color.WHITE, outlineWidth: 2, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND }, label: { text: textArea, font: '18px sans-serif', fillColor: Cesium.Color.GOLD, style: Cesium.LabelStyle.FILL_AND_OUTLINE, outlineWidth: 2, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(20, -40) } }); AllEnities.push(lastpoint); } viewer.trackedEntity = undefined; isDraw = false; tooltip.style.display = 'none'; }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); var CreatePolygon = (function () { function _(positions, cesium) { if (!Cesium.defined(positions)) { throw new Cesium.DeveloperError('positions is required!'); } if (positions.length < 3) { throw new Cesium.DeveloperError('positions 的長度必須大於等於3'); } this.options = { polygon: { show: true, hierarchy: undefined, outline: true, outlineColor: Cesium.Color.WHITE, outlineWidth: 2, material: Cesium.Color.YELLOW.withAlpha(0.4) } }; this.path = positions; this.hierarchy = positions; this._init(); } _.prototype._init = function () { var _self = this; var _update = function () { return _self.hierarchy; }; //實時更新polygon.hierarchy this.options.polygon.hierarchy = new Cesium.CallbackProperty(_update, false); var oo = viewer.entities.add(this.options); AllEnities.push(oo); }; return _; })(); //微元法求面積 var countAreaInCartesian3 = function (ps) { var s = 0; for (var i = 0; i < ps.length; i++) { var p1 = ps[i]; var p2; if (i < ps.length - 1) p2 = ps[i + 1]; else p2 = ps[0]; s += p1.x * p2.y - p2.x * p1.y; } return Math.abs(s / 2); } } </script> <!--測量空間面積-->
三、效果圖
四、更多
如果程式碼任何問題可以加群談論,我們基地的地址是:450342630
讓我們下一篇飛行效果實現再見。