Cesium測量距離和麵積、位置座標
阿新 • • 發佈:2020-12-06
Cesium測量距離和麵積
直接上程式碼,下面兩個函式已經封裝好,可以直接呼叫;有疑問請加群討論:1047907561
//線長度測量 function measureLine(viewer) { var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection); var positions = []; var poly = null; var distance = 0; var cartesian = null; var floatingPoint; var labelPt; handler.setInputAction(function (movement) { let ray = viewer.camera.getPickRay(movement.endPosition); cartesian = viewer.scene.globe.pick(ray, viewer.scene); if (!Cesium.defined(cartesian)) //跳出地球時異常 return; if (positions.length >= 2) { if (!Cesium.defined(poly)) { poly = new PolyLinePrimitive(positions); } else { positions.pop(); positions.push(cartesian); } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); handler.setInputAction(function (movement) { let ray = viewer.camera.getPickRay(movement.position); cartesian = viewer.scene.globe.pick(ray, viewer.scene); if (!Cesium.defined(cartesian)) //跳出地球時異常 return; if (positions.length == 0) { positions.push(cartesian.clone()); } positions.push(cartesian); //記錄滑鼠單擊時的節點位置,非同步計算貼地距離 labelPt = positions[positions.length - 1]; if (positions.length > 2) { getSpaceDistance(positions); } else if (positions.length == 2) { //在三維場景中新增Label floatingPoint = viewer.entities.add({ name: '空間距離', position: labelPt, point: { pixelSize: 5, color: Cesium.Color.RED, outlineColor: Cesium.Color.WHITE, outlineWidth: 2, } }); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); handler.setInputAction(function (movement) { handler.destroy(); //關閉事件控制代碼 handler = undefined; positions.pop(); //最後一個點無效 if (positions.length == 1) viewer.entities.remove(floatingPoint); }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); var PolyLinePrimitive = (function () { function _(positions) { this.options = { name: '直線', polyline: { show: true, positions: [], material: Cesium.Color.CHARTREUSE, width: 5, 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); var addedEntity = viewer.entities.add(this.options); }; return _; })(); //空間兩點距離計算函式 function getSpaceDistance(positions) { console.log(22) //只計算最後一截,與前面累加 //因move和滑鼠左擊事件,最後兩個點座標重複 var i = positions.length - 3; var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]); var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]); getTerrainDistance(point1cartographic, point2cartographic); } function getTerrainDistance(point1cartographic, point2cartographic) { var geodesic = new Cesium.EllipsoidGeodesic(); geodesic.setEndPoints(point1cartographic, point2cartographic); var s = geodesic.surfaceDistance; var cartoPts = [point1cartographic]; for (var jj = 1000; jj < s; jj += 1000) { //分段取樣計算距離 var cartoPt = geodesic.interpolateUsingSurfaceDistance(jj); cartoPts.push(cartoPt); } cartoPts.push(point2cartographic); //返回兩點之間的距離 var promise = Cesium.sampleTerrain(viewer.terrainProvider, 8, cartoPts); Cesium.when(promise, function (updatedPositions) { for (var jj = 0; jj < updatedPositions.length - 1; jj++) { var geoD = new Cesium.EllipsoidGeodesic(); geoD.setEndPoints(updatedPositions[jj], updatedPositions[jj + 1]); var innerS = geoD.surfaceDistance; innerS = Math.sqrt(Math.pow(innerS, 2) + Math.pow(updatedPositions[jj + 1].height - updatedPositions[jj].height, 2)); distance += innerS; } //在三維場景中新增Label var lon1 = viewer.scene.globe.ellipsoid.cartesianToCartographic(labelPt).longitude; var lat1 = viewer.scene.globe.ellipsoid.cartesianToCartographic(labelPt).latitude; var lonLat = "(" + Cesium.Math.toDegrees(lon1).toFixed(2) + "," + Cesium.Math.toDegrees(lat1).toFixed(2) + ")"; var textDisance = distance.toFixed(2) + "米"; if (distance > 10000) textDisance = (distance / 1000.0).toFixed(2) + "千米"; floatingPoint = viewer.entities.add({ name: '貼地距離', position: labelPt, point: { pixelSize: 5, color: Cesium.Color.RED, outlineColor: Cesium.Color.WHITE, outlineWidth: 2, }, label: { text: lonLat + 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), } }); }); } } //面積測量 function measurePolygn(viewer) { // 滑鼠事件 var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection); var positions = []; var tempPoints = []; var polygon = null; var cartesian = null; var floatingPoint;//浮動點 handler.setInputAction(function (movement) { let ray = viewer.camera.getPickRay(movement.endPosition); cartesian = viewer.scene.globe.pick(ray, viewer.scene); positions.pop();//移除最後一個 positions.push(cartesian); if (positions.length >= 2) { var dynamicPositions = new Cesium.CallbackProperty(function () { return new Cesium.PolygonHierarchy(positions); return positions; }, false); polygon = PolygonPrimitive(dynamicPositions); } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); handler.setInputAction(function (movement) { 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); //在三維場景中新增點 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; var labelText = "(" + longitudeString.toFixed(2) + "," + latitudeString.toFixed(2) + ")"; 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 }, label: { text: labelText, 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(); var textArea = getArea(tempPoints) + "平方公里"; viewer.entities.add({ name: '多邊形面積', position: positions[positions.length - 1], 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)); } 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; } function PolygonPrimitive(positions) { polygon = viewer.entities.add({ polygon: { hierarchy: positions, material: Cesium.Color.GREEN.withAlpha(0.1), } }); } 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; //返回兩點之間的距離 s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2)); return s; } } measureLine(viewer) measurePolygn(viewer)//獲取座標點 //handler.setInputAction(function(event){ //viewer.scene.globe.depthTestAgainstTerrain=true; //varearthPosition=viewer.scene.pickPosition(event.position); //console.log(earthPosition) ////3.地標座標:獲取點選處地球表面的世界座標,不包括模型、傾斜攝影表面 //varray=viewer.camera.getPickRay(event.position); //varearthPosition=viewer.scene.globe.pick(ray,viewer.scene);
/* vue中整理好 */
////距離計算 //measureLine(viewer){ //varhandler=newCesium.ScreenSpaceEventHandler( //this.viewer.scene._imageryLayerCollection //); //varpositions=[]; //varpoly=null; //vardistance=0; //varcartesian=null;