cesium學習記錄08-鼠標繪制多邊形

上一篇學習了實體的一些基礎知識,這一篇來學習鼠標繪制實體多邊形的實現

一、方法一:

1,結果顯示

貼地:

在這里插入圖片描述

不貼地:

在這里插入圖片描述

2,方法全部代碼:

主方法:
 /*** 繪制多邊形* @param {Object}  option* @param {Boolean} option.ground 是否貼地*/ DrawPolygon(option) {var allPoints=[]// 設置返回值return new Promise((resolve, reject) => {// 1. 獲取Cesium Viewerlet viewer = this.viewer;// 2. 創建一個用于存儲多邊形頂點的數組let polygonPoints = [];// 3. 創建一個用于顯示當前繪制中的多邊形的實體let drawingPolygon = viewer.entities.add({id: "drawingPolygon",name: "畫多邊形",polygon: {hierarchy: new Cesium.CallbackProperty(() => {return new Cesium.PolygonHierarchy(polygonPoints);}, false),material: Cesium.Color.BLUE.withAlpha(0.2),perPositionHeight: (option&&option.ground)||false // true:不貼地/false:貼地},});// 4. 創建一個用于顯示當前繪制中的線的實體let drawingLine = viewer.entities.add({id: "drawingLine",name: "畫線",polyline: {positions: new Cesium.CallbackProperty(() => {return polygonPoints;}, false),width: 3,material: Cesium.Color.GREEN}});// 5. 監聽鼠標點擊事件,將點擊的點添加到頂點數組中,并添加點實體let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);handler.setInputAction(event => {var cartesian = this.getCatesian3FromPX(event.position);if (cartesian) {// 將點坐標添加到數組中polygonPoints.push(cartesian.clone());// 在第一次點擊時,添加一個克隆的點到數組中,用于動態更新if (polygonPoints.length === 1) {polygonPoints.push(cartesian.clone());}// 添加點實體viewer.entities.add({position: cartesian,point: {color: Cesium.Color.RED,pixelSize: 10}});//將三維笛卡爾坐標系點轉為經緯度坐標點,并保存到點數組中let cartesian3 = cartesian.clone()// 使用Cesium.Cartographic.fromCartesian將Cartesian3對象轉換為Cartographic對象let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);allPoints.push([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height]);}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);// 6. 監聽鼠標移動事件,動態更新多邊形和線的形狀handler.setInputAction(event => {var cartesian = this.getCatesian3FromPX(event.endPosition);if (polygonPoints.length >= 2) {if (cartesian && cartesian.x) {polygonPoints.pop();polygonPoints.push(cartesian);}}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);// 7. 監聽鼠標右鍵點擊事件,結束繪制handler.setInputAction(() => {var cartesian=polygonPoints[polygonPoints.length-1]// 添加點實體viewer.entities.add({position: cartesian,point: {color: Cesium.Color.RED,pixelSize: 10}});polygonPoints.push(polygonPoints[0]);handler.destroy(); // 關閉鼠標事件監聽,結束繪制resolve(allPoints);}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);})},
調用進行位置拾取和轉換的方法(此處三個方法來自測量插件):
 /*** 拾取位置點* @param {Object} px 屏幕坐標* @return {Object} Cartesian3 三維坐標*/getCatesian3FromPX: function(px) {if (this.viewer && px) {var picks = this.viewer.scene.drillPick(px);var cartesian = null;var isOn3dtiles = false,isOnTerrain = false;// drillPickfor (let i in picks) {let pick = picks[i];if ((pick && pick.primitive instanceof Cesium.Cesium3DTileFeature) ||(pick && pick.primitive instanceof Cesium.Cesium3DTileset) ||(pick && pick.primitive instanceof Cesium.Model)) {//模型上拾取isOn3dtiles = true;}// 3dtilsetif (isOn3dtiles) {this.viewer.scene.pick(px); // pickcartesian = this.viewer.scene.pickPosition(px);if (cartesian) {let cartographic = Cesium.Cartographic.fromCartesian(cartesian);if (cartographic.height < 0) cartographic.height = 0;let lon = Cesium.Math.toDegrees(cartographic.longitude),lat = Cesium.Math.toDegrees(cartographic.latitude),height = cartographic.height;cartesian = this.transformWGS84ToCartesian({lng: lon,lat: lat,alt: height});}}}// 地形let boolTerrain =this.viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider;// Terrainif (!isOn3dtiles && !boolTerrain) {var ray = this.viewer.scene.camera.getPickRay(px);if (!ray) return null;cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);isOnTerrain = true;}// 地球if (!isOn3dtiles && !isOnTerrain && boolTerrain) {cartesian = this.viewer.scene.camera.pickEllipsoid(px,this.viewer.scene.globe.ellipsoid);}if (cartesian) {let position = this.transformCartesianToWGS84(cartesian);if (position.alt < 0) {cartesian = this.transformWGS84ToCartesian(position, 0.1);}return cartesian;}return false;}},/**** 坐標轉換 84轉笛卡爾* @param {Object} {lng,lat,alt} 地理坐標* @return {Object} Cartesian3 三維位置坐標*/transformWGS84ToCartesian: function(position, alt) {if (this.viewer) {return position? Cesium.Cartesian3.fromDegrees(position.lng || position.lon,position.lat,(position.alt = alt || position.alt),Cesium.Ellipsoid.WGS84): Cesium.Cartesian3.ZERO;}},/**** 坐標轉換 笛卡爾轉84* @param {Object} Cartesian3 三維位置坐標* @return {Object} {lng,lat,alt} 地理坐標*/transformCartesianToWGS84: function(cartesian) {if (this.viewer && cartesian) {var ellipsoid = Cesium.Ellipsoid.WGS84;var cartographic = ellipsoid.cartesianToCartographic(cartesian);return {lng: Cesium.Math.toDegrees(cartographic.longitude),lat: Cesium.Math.toDegrees(cartographic.latitude),alt: cartographic.height};}},

3,調用方法:

let option = {ground: true     //true:不貼地/false:貼地           };
DrawPolygon(option).then(allPoints => {// 在這里,allPoints是結束繪制后的點坐標數組var resultPoints=allPoints})

4,DrawPolygon方法說明:

1,定義返回結果的方式:
var allPoints=[]
return new Promise((resolve, reject) => {
......
}

在這個方法開始時,定義了一個allPoints數組,用于存儲繪制的多邊形的所有頂點,并且返回一個Promise,允許在繪制結束后將這些點的坐標返回。

2,獲取Cesium Viewer:
let viewer = this.viewer;

獲取Cesium的Viewer實例

3,創建一個實體以顯示繪制中的多邊形:
let drawingPolygon = viewer.entities.add({ ... });

這段代碼通過Cesium的entities.add方法創建一個新的實體,并將它添加到地圖上。這個實體用于實時顯示用戶繪制的多邊形。

4,創建一個實體以顯示繪制中的線:
let drawingLine = viewer.entities.add({ ... });

創建一個實體來實時顯示用戶繪制的線。

5,設置鼠標點擊事件的監聽:
let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(event => { ... }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

這段代碼創建一個新的ScreenSpaceEventHandler實例來監聽鼠標和觸摸事件。然后設置一個函數來監聽左鍵點擊事件。每當用戶點擊鼠標左鍵時,這個函數就會被調用,并將點擊的位置添加到polygonPoints數組(即多邊形的頂點)和allPoints數組。
需要說明的是這一段代碼:

//將三維笛卡爾坐標系點轉為經緯度坐標點,并保存到點數組中let cartesian3 = cartesian.clone()// 使用Cesium.Cartographic.fromCartesian將Cartesian3對象轉換為Cartographic對象let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);allPoints.push([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height]);

加上這一段只是因為,如果要對獲取的點數組進行進一步使用,我更習慣使用經緯度坐標

6,設置鼠標移動事件的監聽:
handler.setInputAction(event => { ... }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

當用戶移動鼠標時,這個函數會被調用。它用于實時更新正在繪制的多邊形和線的形狀。

7,設置鼠標雙擊事件的監聽:
handler.setInputAction(() => { ... }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

這個函數監聽鼠標左鍵雙擊事件。當用戶雙擊鼠標左鍵時,這個函數會被調用,表示用戶完成了多邊形的繪制。此時,它會添加最后一個點實體,關閉鼠標事件監聽,結束繪制,并通過resolve(allPoints)將繪制的點坐標返回。

8,總說明:

這個方法允許用戶通過點擊和移動鼠標在Cesium地圖上繪制一個多邊形。在用戶完成繪制(通過雙擊鼠標左鍵)后,這個方法通過Promise的resolve函數將繪制的點坐標數組allPoints返回,供其他部分的代碼使用。
(比如進行填挖方的計算,將上面的點數組傳到地形填挖方計算的方法,用來生成三角網)
在這里插入圖片描述

5,getCatesian3FromPX方法說明:

該方法根據給定的屏幕坐標px,計算出對應的三維世界坐標。該三維世界坐標可以代表一個具體的點在地圖上的位置。
使用drillPick方法來獲取屏幕坐標點上所有的對象。如果該點上有一個或多個對象,方法會嘗試從3D模型上拾取坐標。
如果拾取不在3D模型上,并且地形存在,則從地形上拾取坐標。
如果既不在3D模型上也不在地形上,則從地球橢球體上拾取坐標。
最后返回這個點的三維世界坐標,或者在無法確定時返回false。

6,transformWGS84ToCartesian方法說明:

該方法根據給定的地理坐標(WGS84格式)計算出相應的三維世界坐標(笛卡爾坐標)。
使用Cesium的Cartesian3.fromDegrees方法從給定的經緯度和高度計算出三維坐標。

7,transformCartesianToWGS84方法說明:

該方法根據給定的三維世界坐標(笛卡爾坐標)計算出相應的地理坐標(WGS84格式)。
使用Cesium的Ellipsoid.WGS84和cartesianToCartographic方法將三維世界坐標轉換為地理坐標。

8,后續學習記錄文章說明:

將火星科技(Mars3D)的一些例子,自己用Cesium來實現

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

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

相關文章

華為OD機試 - 公共子串計算(Java 2023 B卷 100分)

目錄 專欄導讀一、題目描述二、輸入描述三、輸出描述四、解題思路五、Java算法源碼六、效果展示 華為OD機試 2023B卷題庫瘋狂收錄中&#xff0c;刷題點這里 專欄導讀 本專欄收錄于《華為OD機試&#xff08;JAVA&#xff09;真題&#xff08;A卷B卷&#xff09;》。 刷的越多&…

VictoriaMetrics部署及vmalert集成釘釘告警

1、部署VictoriaMetrics cd /usr/local wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.65.0/victoria-metrics-amd64-v1.65.0.tar.gz mkdir victoria-metrics && tar -xvzf victoria-metrics-amd64-v1.65.0.tar.gz && \ mv …

論AI GPT跨境貿易架構及其應用

摘要 2023年初,我司啟動了智慧化跨境貿易供應鏈一體化平臺的建設工作。我在該項目中擔任系統架構設計師的職務,主要負責設計平臺系統架構和安全體系架構。該平臺以移動信息化發展為契機,采用”平臺+AI”的模式解決現有應用的集中移動化需求。平臺整體的邏輯復雜,對系統的高…

react之Hooks的介紹、useState與useEffect副作用的使用

react之Hooks的介紹、useState與useEffect副作用的使用 一、Hooks的基本介紹二、useState的使用2.1 簡單使用2.2 數組結構簡化2.3 狀態的讀取和修改2.3 組件的更新過程 三、useEffect的使用3.1 副作用介紹3.2 基本使用3.3 依賴3.4 不要對依賴項撒謊3.5 依賴項可以是空數組3.6 清…

ZZULIOJ 1193: 單科成績排序(結構體專題),Java

ZZULIOJ 1193: 單科成績排序&#xff08;結構體專題&#xff09;&#xff0c;Java 題目描述 有一學生成績表&#xff0c;包括學號、姓名、3門課程成績。請按要求排序輸出&#xff1a;若輸入1&#xff0c;則按第1門課成績降序輸出成績表&#xff0c;若輸入為i&#xff08;1<…

清風數學建模——擬合算法

擬合算法 文章目錄 擬合算法概念 確定擬合曲線最小二乘法的幾何解釋求解最小二乘法matlab求解最小二乘法如何評價擬合的好壞計算擬合優度的代碼 概念 在前面的篇幅中提到可以使用插值算法&#xff0c;通過給定的樣本點推算出一定的曲線從而推算出一些想要的值。但存在一些問題…

解決內網GitLab 社區版 15.11.13項目拉取失敗

問題描述 GitLab 社區版 發布不久&#xff0c;搭建在內網拉取項目報錯&#xff0c;可能提示 unable to access https://github.comxxxxxxxxxxx: Failed to connect to xxxxxxxxxxxxxGit clone error - Invalid argument error:14077438:SSL routines:SSL23_GET_S 15.11.13ht…

QT網絡編程之TCP

QT網絡編程之TCP TCP 編程需要用到倆個類: QTcpServer 和 QTcpSocket。 #------------------------------------------------- # # Project created by QtCreator 2023-08-

mysql截取最后一個字符之前的數據

1、mysql截取最后一個字符之前的數據 select --截取斜杠之前的數據REVERSE(SUBSTR(REVERSE(SPNH-dfg-2012) ; --截取斜杠后的數據 INSTR(REVERSE(SPNH-fg-2012),-)1))2、mysql獲取最后一個字符后的數據 select SUBSTRING_INDEX(SPNH-dfg-2012,-,-1) 3、mysql更新某個字段…

SpringBoot 該如何預防 XSS 攻擊

XSS 漏洞到底是什么&#xff0c;說實話我講不太清楚。但是可以通過遇到的現象了解一下。在前端Form表單的輸入框中&#xff0c;用戶沒有正常輸入&#xff0c;而是輸入了一段代碼&#xff1a;</input><img src1 onerroralert1> 這個正常保存沒有問題。問題出在了列表…

驅動 實現三個燈的亮滅

1、編寫LED燈的驅動&#xff0c;可以控制三個燈&#xff0c;應用程序中編寫控制燈的邏輯&#xff0c;要使用自動創建設備節點機制 head.h #ifndef __HEAD_H__ #define __HEAD_H__#define PHY_LED1_MODER 0x50006000 #define PHY_LED1_ODR 0x50006014 #define PHY_LED1_RCC 0x…

設計模式之責任鏈模式【Java實現】

責任鏈&#xff08;Chain of Resposibility&#xff09; 模式 概念 責任鏈&#xff08;chain of Resposibility&#xff09; 模式&#xff1a;為了避免請求發送者與多個請求處理者耦合在一起&#xff0c;于是將所有請求的處理者 通過前一對象記住其下一個對象的引用而連成一條…

什么是ServiceMesh(Istio一)

現在最火的后端架構無疑是微服務了&#xff0c;微服務將之前的單體應用拆分成了許多獨立的服務應用&#xff0c;每個微服務都是獨立的&#xff0c;好處自然很多&#xff0c;但是隨著應用的越來越大&#xff0c;微服務暴露出來的問題也就隨之而來了&#xff0c;微服務越來越多&a…

【Python】使用python解析普通格式的報文為someip格式報文

文章目錄 1.安裝scapy庫2.示例 1.安裝scapy庫 使用 pip 安裝 scapy 第三方庫&#xff0c;打開 cmd&#xff0c;輸入以下命令&#xff1a; pip install scapy出現如圖所示&#xff0c;表示安裝成功&#xff1a; 2.示例 要解析someip格式報文&#xff0c;需要導入someip模塊&a…

【Spring 】了解Spring AOP

目錄 一、什么是Spring AOP 二、AOP的使用場景 三、AOP組成 四、Spring AOP的實現 1、添加Spring AOP依賴 2、定義切面和切點 3、定義相關通知 五、 AOP的實現原理 1、什么是動態代理 2、 JDK代理和CGLIB代理的區別 一、什么是Spring AOP AOP&#xff08;Aspect Ori…

PLY模型格式詳解【3D】

本文介紹PLY 多邊形文件格式&#xff0c;這是一種用于存儲被描述為多邊形集合的圖形對象。 PLY文件格式的目標是提供一種簡單且易于實現但通用的格式足以適用于各種模型。 PLY有兩種子格式&#xff1a;易于入門的 ASCII 表示形式和用于緊湊存儲和快速保存和加載的二進制格式。 …

【FastColoredTextBox】C# 開源文本編輯控件

主界面截圖 使用Demos演示 FastColoredTextBox 是一個用于在 C# 程序中實現高亮語法著色、代碼編輯和文本顯示的自定義控件。它提供了許多功能&#xff0c;包括&#xff1a; 語法高亮&#xff1a;FastColoredTextBox 支持多種語言的語法高亮&#xff0c;可以根據語法規則將不同…

write javaBean error, fastjson version 1.2.76

fastjson JSON.toJSONString 報錯&#xff1a; > [0] JavaBeanSerializer.java->541: com.alibaba.fastjson.serializer.JavaBeanSerializer->write()> [1] JavaBeanSerializer.java->154: com.alibaba.fastjson.serializer.JavaBeanSerializer->write()>…

vite4+vue3+electron23.3+ts桌面應用bs端開發 打包windows、linux、max三個系統的安裝包

vite4vue3electron23.3ts桌面應用bs端開發 打包windows、linux、max三個系統的安裝包 主要包依賴 "electron-store": "^8.1.0", //全局數據狀態管理&#xff0c;可選擇性安裝"electron": "23.3.8","electron-builder": &q…

Android 使用SQLite的案例詳解

1、說明 sqlite是個輕量級的數據庫,可用于嵌入式。有時候做本地的web開發的時候,我會把sqlite作為內置數據庫,這樣便于部署,直接啟動應用即可。 這里主要是將android中的使用過程記錄一下。主要包含,數據如何初始化,在不同的activity中如何使用,以及增刪改查的實現。 …