cesium面積計算_cesium-長度測量和面積測量

(更新)多謝網友的提醒,面積測量的小問題已經修改,經測試可正常使用

網上找的大神的實現方法有點問題,實現有一些bug,作為cesium新手一個,棄之不忍,只好硬著頭皮修改了,不過還好問題不大,再次mark一下,下次就可以直接用了

image.png

import Cesium from "cesium/Cesium";

import widgets from "cesium/Widgets/widgets.css";

export default {

//測量空間直線距離

/******************************************* */

measureLineSpace(viewer, handler) {

// 取消雙擊事件-追蹤該位置

viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);

var positions = [];

var poly = null;

// var tooltip = document.getElementById("toolTip");

var distance = 0;

var cartesian = null;

var floatingPoint;

// tooltip.style.display = "block";

handler.setInputAction(function (movement) {

// tooltip.style.left = movement.endPosition.x + 3 + "px";

// tooltip.style.top = movement.endPosition.y - 25 + "px";

// tooltip.innerHTML = '

單擊開始,右擊結束

';

// cartesian = viewer.scene.pickPosition(movement.endPosition);

let ray = viewer.camera.getPickRay(movement.endPosition);

cartesian = viewer.scene.globe.pick(ray, viewer.scene);

//cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);

if (positions.length >= 2) {

if (!Cesium.defined(poly)) {

poly = new PolyLinePrimitive(positions);

} else {

positions.pop();

// cartesian.y += (1 + Math.random());

positions.push(cartesian);

}

distance = getSpaceDistance(positions);

// console.log("distance: " + distance);

// tooltip.innerHTML='

'+distance+'米

';

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

handler.setInputAction(function (movement) {

// tooltip.style.display = "none";

// cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);

// cartesian = viewer.scene.pickPosition(movement.position);

let ray = viewer.camera.getPickRay(movement.position);

cartesian = viewer.scene.globe.pick(ray, viewer.scene);

if (positions.length == 0) {

positions.push(cartesian.clone());

}

positions.push(cartesian);

//在三維場景中添加Label

// var cartographic = Cesium.Cartographic.fromCartesian(cartesian);

var textDisance = distance + "米";

// console.log(textDisance + ",lng:" + cartographic.longitude/Math.PI*180.0);

floatingPoint = viewer.entities.add({

name: '空間直線距離',

// position: Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180,cartographic.height),

position: positions[positions.length - 1],

point: {

pixelSize: 5,

color: Cesium.Color.RED,

outlineColor: Cesium.Color.WHITE,

outlineWidth: 2,

},

label: {

text: textDisance,

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, -20),

}

});

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

handler.setInputAction(function (movement) {

handler.destroy(); //關閉事件句柄

positions.pop(); //最后一個點無效

// viewer.entities.remove(floatingPoint);

// tooltip.style.display = "none";

}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

var PolyLinePrimitive = (function () {

function _(positions) {

this.options = {

name: '直線',

polyline: {

show: true,

positions: [],

material: Cesium.Color.CHARTREUSE,

width: 10,

clampToGround: true

}

};

this.positions = positions;

this._init();

}

_.prototype._init = function () {

var _self = this;

var _update = function () {

return _self.positions;

};

//實時更新polyline.positions

this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);

viewer.entities.add(this.options);

};

return _;

})();

//空間兩點距離計算函數

function getSpaceDistance(positions) {

var distance = 0;

for (var i = 0; i < positions.length - 1; i++) {

var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);

var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);

/**根據經緯度計算出距離**/

var geodesic = new Cesium.EllipsoidGeodesic();

geodesic.setEndPoints(point1cartographic, point2cartographic);

var s = geodesic.surfaceDistance;

//console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));

//返回兩點之間的距離

s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));

distance = distance + s;

}

return distance.toFixed(2);

}

},

//****************************測量空間面積************************************************//

measureAreaSpace(viewer, handler){

// 取消雙擊事件-追蹤該位置

viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

// 鼠標事件

handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);

var positions = [];

var tempPoints = [];

var polygon = null;

// var tooltip = document.getElementById("toolTip");

var cartesian = null;

var floatingPoint;//浮動點

// tooltip.style.display = "block";

handler.setInputAction(function(movement){

// tooltip.style.left = movement.endPosition.x + 3 + "px";

// tooltip.style.top = movement.endPosition.y - 25 + "px";

// tooltip.innerHTML ='

單擊開始,右擊結束

';

// cartesian = viewer.scene.pickPosition(movement.endPosition);

let ray = viewer.camera.getPickRay(movement.endPosition);

cartesian = viewer.scene.globe.pick(ray, viewer.scene);

//cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);

if(positions.length >= 2){

if (!Cesium.defined(polygon)) {

polygon = new PolygonPrimitive(positions);

}else{

positions.pop();

// cartesian.y += (1 + Math.random());

positions.push(cartesian);

}

// tooltip.innerHTML='

'+distance+'米

';

}

},Cesium.ScreenSpaceEventType.MOUSE_MOVE);

handler.setInputAction(function(movement){

// tooltip.style.display = "none";

// cartesian = viewer.scene.pickPosition(movement.position);

let ray = viewer.camera.getPickRay(movement.position);

cartesian = viewer.scene.globe.pick(ray, viewer.scene);

// cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);

if(positions.length == 0) {

positions.push(cartesian.clone());

}

//positions.pop();

positions.push(cartesian);

//在三維場景中添加點

var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);

var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);

var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);

var heightString = cartographic.height;

tempPoints.push({ lon: longitudeString, lat: latitudeString ,hei:heightString});

floatingPoint = viewer.entities.add({

name : '多邊形面積',

position : positions[positions.length - 1],

point : {

pixelSize : 5,

color : Cesium.Color.RED,

outlineColor : Cesium.Color.WHITE,

outlineWidth : 2,

heightReference:Cesium.HeightReference.CLAMP_TO_GROUND

}

});

},Cesium.ScreenSpaceEventType.LEFT_CLICK);

handler.setInputAction(function(movement){

handler.destroy();

positions.pop();

//tempPoints.pop();

// viewer.entities.remove(floatingPoint);

// tooltip.style.display = "none";

//在三維場景中添加點

// var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);

// var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);

// var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);

// var heightString = cartographic.height;

// tempPoints.push({ lon: longitudeString, lat: latitudeString ,hei:heightString});

var textArea = getArea(tempPoints) + "平方公里";

viewer.entities.add({

name : '多邊形面積',

position : positions[positions.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),

heightReference:Cesium.HeightReference.CLAMP_TO_GROUND

}

});

}, Cesium.ScreenSpaceEventType.RIGHT_CLICK );

var radiansPerDegree = Math.PI / 180.0;//角度轉化為弧度(rad)

var degreesPerRadian = 180.0 / Math.PI;//弧度轉化為角度

//計算多邊形面積

function getArea(points) {

var res = 0;

//拆分三角曲面

for (var i = 0; i < points.length - 2; i++) {

var j = (i + 1) % points.length;

var k = (i + 2) % points.length;

var totalAngle = Angle(points[i], points[j], points[k]);

var dis_temp1 = distance(positions[i], positions[j]);

var dis_temp2 = distance(positions[j], positions[k]);

res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle)) ;

console.log(res);

}

return (res/1000000.0).toFixed(4);

}

/*角度*/

function Angle(p1, p2, p3) {

var bearing21 = Bearing(p2, p1);

var bearing23 = Bearing(p2, p3);

var angle = bearing21 - bearing23;

if (angle < 0) {

angle += 360;

}

return angle;

}

/*方向*/

function Bearing(from, to) {

var lat1 = from.lat * radiansPerDegree;

var lon1 = from.lon * radiansPerDegree;

var lat2 = to.lat * radiansPerDegree;

var lon2 = to.lon * radiansPerDegree;

var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));

if (angle < 0) {

angle += Math.PI * 2.0;

}

angle = angle * degreesPerRadian;//角度

return angle;

}

var PolygonPrimitive = (function(){

function _(positions){

this.options = {

name:'多邊形',

polygon : {

hierarchy : [],

// perPositionHeight : true,

material : Cesium.Color.GREEN.withAlpha(0.5),

// heightReference:20000

}

};

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);

viewer.entities.add(this.options);

};

return _;

})();

function distance(point1,point2){

var point1cartographic = Cesium.Cartographic.fromCartesian(point1);

var point2cartographic = Cesium.Cartographic.fromCartesian(point2);

/**根據經緯度計算出距離**/

var geodesic = new Cesium.EllipsoidGeodesic();

geodesic.setEndPoints(point1cartographic, point2cartographic);

var s = geodesic.surfaceDistance;

//console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));

//返回兩點之間的距離

s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));

return s;

}

}

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537095.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537095.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537095.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot自動配置原理流程

前言 新公司太忙了&#xff0c;都沒啥空更新博客&#xff0c;就隨便記錄一下以前的學習筆記吧。SpringBoot是基于Spring上的衍生框架&#xff0c;只要看懂了Spring的話&#xff0c;學這個就比較簡單了&#xff1b;SpringBoot也是在當前微服務時代下流行的框架&#xff0c;并且…

算法:對象方式數組去重

var arr [3, 1, 1, 4 , 2 , 4 , 2 , 4 , 2, 1, 1, 3, 3, 3];var ary[];var obj{};for(var i0;i<arr.length;i){var curarr[i];if(!obj[cur]){obj[cur]cur;ary.push(cur);}}console.log(ary); 復制代碼

python實現路由功能_python 實現重啟路由器

有一些服務&#xff0c;需要動態IP&#xff0c;所以我們用重啟路由器的方法實現。人工重啟不可選&#xff0c;用定時腳本執行即可。貼代碼&#xff0c;每種路由器&#xff0c;提示不一樣。需要路由器有telnet功能才行。#!/usr/bin/env python# -*- coding: utf-8 -*-import tel…

SpringBoot自定義Starter(自動配置類)

前言 SpringBoot其實從誕生以來圍繞的核心就是快速構建項目&#xff0c;快速構建的前提是有人幫你做好輪子&#xff0c;開發者只要拿來即用就好了&#xff0c;而造好輪子的人就是SpringBoot的開發者&#xff0c;引入自動配置的形式幫助開發者快速創建項目&#xff0c;而自動配…

Java并發編程之synchronized關鍵字解析

前言 公司加班太狠了&#xff0c;都沒啥時間充電&#xff0c;這周終于結束了。這次整理了Java并發編程里面的synchronized關鍵字&#xff0c;又稱為隱式鎖&#xff0c;與JUC包中的Lock顯示鎖相對應&#xff1b;這個關鍵字從Java誕生開始就有&#xff0c;稱之為重量級鎖&#xf…

raidrive安裝失敗_記一次RaiDrive映射OneDrive遇到的問題

大概在1周以前&#xff0c;出于需要存放直播錄像的原因&#xff0c;根據別人的視頻教程去自己動手搞了個5T網盤的帳號。(體驗一下&#xff0c;其實我還同時存一份在百度云&#xff0c;怕不穩定)用RaiDrive創建OneDrive的映射&#xff0c;在這步驟點確定后&#xff0c;會彈出微軟…

通過代理模式 + 責任鏈模式實現對目標執行方法攔截和增強功能

前言 最近需要實現一個插件功能&#xff0c;但是如果做成兩個接口的話&#xff08;即執行前和執行后&#xff09;&#xff0c;那么會降低插件的可玩性&#xff0c;所以需做成類似AOP的環繞通知形式&#xff0c;所以就使用到了責任鏈模式和代理模式進行實現。 介紹 代理模式(P…

Javascript基礎之-原型(prototype)

首先呢&#xff0c;prototype是對象里的一個內置屬性&#xff0c;并且呢&#xff0c;這個屬性是對于其他對象的一個引用。所以呢&#xff0c;思考下面的例子&#xff1a; var obj {a: 2 } var myObj Object.create(obj); console.log(myObj.a); // 2 console.log(myObj obj)…

Oracle查詢今天、昨天、本周、上周、本月、上月數據

查詢今天數據&#xff1a; SELECT COUNT(1) FROM T_CALL_RECORDS WHERE TO_CHAR(T_RKSJ,YYYY-MM-DD)TO_CHAR(SYSDATE,YYYY-MM-DD)&#xff1b; 查詢昨天數據&#xff1a; SELECT COUNT(1) FROM T_CALL_RECORDS WHERE TO_CHAR(T_RKSJ,YYYY-MM-DD)TO_CHAR(SYSDATE-1,YYYY-MM-DD)&…

usb一轉多 樹莓派zero_樹莓派 Zero USB/以太網方式連接配置教程

樹莓派 Zero 之所以成為一款非常棒的單板計算機并不全因為它小巧的尺寸和便宜的價格&#xff0c;還得益于它便捷、易用的特性。在加裝了 Zero Quick Plug 或 microUSB/USB 轉換頭之后&#xff0c;將樹莓派 Zero 和電腦連接起來。樹莓派 Zero 即可配置成 USB/以太網設備&#xf…

vscode Go 1.11.4 編譯錯誤 need Delve built by Go 1.11 or later

更新golang的版本為1.11.4之后vscode編譯錯誤&#xff1a;executables built by Go 1.11 or later need Delve built by Go 1.11 or later 原因是delve的版本太老了&#xff0c;需要更新&#xff0c;且delve的github地址已經更換&#xff0c;很多教程里的地址是不對的 新地址安…

oppo的sd卡在哪里打開_oppo的sd卡在哪里打開

大家好&#xff0c;我是時間財富網智能客服時間君&#xff0c;上述問題將由我為大家進行解答。以oppo A91為例&#xff0c;其sd卡可直接在文件管理頁面的存儲里面即可打開。OPPO A91的屏幕為6.4英寸&#xff0c;主屏分辨率2400乘以1080像素&#xff0c;機身顏色有暗夜星辰&…

Navicat使用教程:使用Navicat Query Analyzer優化查詢性能(第1部分)

下載Navicat Monitor最新版本Navicat Monitor 是一套安全、簡單而且無代理的遠程服務器監控工具。它具有強大的功能使你的監控發揮最大效用。受監控的服務器包括 MySQL、MariaDB 和 Percona Server&#xff0c;并與 Amazon RDS、Amazon Aurora、Oracle Cloud、Microsoft Azure …

dg oracle 切換模式_Oracle數據庫 DGbroker三種保護模式的切換

1.三種保護模式– Maximum protection在Maximum protection下&#xff0c; 可以保證從庫和主庫數據完全一樣&#xff0c;做到zero data loss.事務同時在主從兩邊提交完成&#xff0c;才算事務完成。如果從庫宕機或者網絡出現問題&#xff0c;主從庫不能通訊&#xff0c;主庫也立…

軟件包管理

應用程序&#xff1a;程序&#xff1a;Architecture C語言&#xff1a;源代碼-->&#xff08;編譯&#xff09; 二進制格式腳本&#xff1a;解釋器&#xff08;二進制程序&#xff09; 源代碼-->編譯-->鏈接-->運行程序&#xff1a;指令數據指令&#xff1a;芯片CP…

工業機器人碼垛教學實施_工業機器人應用案例碼垛詳解

工業機器人應用案例碼垛詳解隨著科技的進步以及現代化進程的加快&#xff0c;人們對搬運速度的要求越來越高&#xff0c;傳統的人工碼垛只能應用在物料輕便、尺寸和形狀變化大、吞吐量小的場合&#xff0c;這已經遠遠不能滿足工業的需求&#xff0c;機器人碼垛機應運而生。機器…

第一家云創大數據產業學院在佛山職業技術學院掛牌

2019年1月10日&#xff0c;“云創大數據產業學院揭牌暨戰略合作協議簽署儀式”在佛山職業技術學院電子信息學院會議室舉行。云創大數據總裁劉鵬教授、市場部經理單明月&#xff0c;佛山職業技術學院電子信息學院院長唐建生、副院長田鈞、學院辦公室主任趙雪章、信息工程系主任喬…

String與StringBuffer和StringBuilder的根本區別

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

16進制 ksh_AIX系統中如何統計進程打開的文件數目

作者&#xff1a;李燁楠 中國建設銀行來自微信公眾號&#xff1a;平臺人生環境: AIX 6.1 AIX7.1前言:用戶有時需要統計一個進程打開的文件數目&#xff0c;比如&#xff0c;在當前打開文件句柄使用量是否超過用戶資源限制(/etc/security/limits)中 nofiles的取值時。那么&#…

前端Http協議緩存初解

[TOC] 簡介 用戶獲取網絡資源&#xff0c;需要通過非常長的網絡去服務器上請求資源,另外服務端為了應對大量的用戶請求而不斷的提升硬件性能與帶寬。這對用戶與服務端都非常的不友好。而緩存就是為了解決用戶請求速度與釋放服務器壓力而生的。 為什么我會寫Http緩存&#xff0c…