bill_lai 5 سال پیش
والد
کامیت
2075af8378
4فایلهای تغییر یافته به همراه234 افزوده شده و 31 حذف شده
  1. 22 6
      src/App.vue
  2. 6 1
      src/core/listen.js
  3. 203 21
      src/core/measure.js
  4. 3 3
      src/core/viewer.js

+ 22 - 6
src/App.vue

@@ -11,7 +11,10 @@
                 </li>
             </ul>
         </div>
-        <span class="measure" @click="measure = true">{{measure ? '测量中' : '测量'}}</span>
+        <div class="function">
+            <span class="measure" @click="measure = true">{{measure ? '测量中' : '测量'}}</span>
+            <span class="measure" @click="getll = !getll">{{getll ? '关闭获取经纬度' : '获取经纬度'}}</span>
+        </div>
         <div id="toolTip" v-show="measure"></div>
     </div>
 </template>
@@ -22,12 +25,13 @@ export default {
     data() {
         return {
             layers: null,
-            measure: false
+            measure: false,
+            getll: false
         };
     },
     created() {
         this.$bus.$on("config", config => {
-            this.layers = config.layers.filter(item=>item.show);
+            this.layers = config.layers.filter(item=> item.style ? item.style.show && item.show : item.show );
         });
     },
     computed:{
@@ -40,6 +44,13 @@ export default {
     watch: {
         measure() {
             this.measure && this.$bus.$emit('measure')
+        },
+        getll() {
+            if (this.getll) {
+                this.$bus.$emit('getLongLat')
+            } else {
+                this.$bus.$emit('closeGetLongLat')
+            }
         }
     },
     mounted() {
@@ -71,23 +82,28 @@ img {
     border: 0;
     outline: 0;
 }
-.measure {
+.function {
     position: absolute;
     left: 50%;
     top: 5px;
+    transform: translateX(-50%);
+
+}
+.function span {
+    display: inline-block;
     height: 22px;
     line-height: 22px;
     padding: 3px 10px;
     background: #2c363b;
     border: solid 1px #b9baba;
-    transform: translateX(-50%);
     line-height: 22px;
     font-size: 14px;
     color: #fff;
-    border: solid 1px #b9baba;
     border-radius: 6px;
     cursor: pointer;
+    margin: 0 10px;
 }
+
 #toolTip {
     position: absolute;
     z-index: 2;

+ 6 - 1
src/core/listen.js

@@ -1,6 +1,6 @@
 import bus from '../utils/bus'
 import { addMakers } from './maker'
-import measure from './measure'
+import measure, { getLongLat } from './measure'
 
 bus.$on('addMaker', async () => {
   let pois = await addMakers([
@@ -28,4 +28,9 @@ bus.$on('measure', () => {
   measure(() => {
     bus.$emit('measureComplete')
   })
+})
+
+bus.$on('getLongLat', () => {
+  let close = getLongLat();
+  bus.$once('closeGetLongLat', () => close())
 })

+ 203 - 21
src/core/measure.js

@@ -1,4 +1,5 @@
 import {
+  Math as CMath,
   Entity,
   Ellipsoid,
   Cartesian3,
@@ -20,6 +21,85 @@ import {
 /******************************************* */
 //测量空间直线距离 
 /******************************************* */
+var radiansPerDegree = Math.PI / 180.0;//角度转化为弧度(rad) 
+var degreesPerRadian = 180.0 / Math.PI;//弧度转化为角度
+
+/*角度*/
+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 distance(point1, point2) {
+  var point1cartographic = Cartographic.fromCartesian(point1);
+  var point2cartographic = Cartographic.fromCartesian(point2);
+  /**根据经纬度计算出距离**/
+  var geodesic = new 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;
+}
+
+
+//计算多边形面积
+function getArea(positions, 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 transfromItem(pos) {
+  var cartographic = Cartographic.fromCartesian(pos);
+  var longitudeString = CMath.toDegrees(cartographic.longitude);
+  var latitudeString = CMath.toDegrees(cartographic.latitude);
+  var heightString = cartographic.height;
+  return { lon: longitudeString, lat: latitudeString, hei: heightString }
+}
+
+function transfroms(positions) {
+  return positions.map(transfromItem)
+}
+
+
+
 
 var measureLineSpace = function (cb) {
   var handler = new ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
@@ -29,6 +109,11 @@ var measureLineSpace = function (cb) {
   var distance = 0;
   var cartesian = null;
   var floatingPoint;
+  var floatingLabel;
+  var ddis = 0
+  var zdis = 0
+  var tempPoints = []
+
 
   handler.setInputAction(function (movement) {
     tooltip.style.left = movement.endPosition.x + 3 + "px";
@@ -49,26 +134,40 @@ var measureLineSpace = function (cb) {
         // cartesian.y += (1 + Math.random());
         positions.push(cartesian);
       }
-      distance = getSpaceDistance(positions);
+      zdis = getSpaceDistance(positions)
+
+
       // console.log("distance: " + distance);
       // tooltip.innerHTML='<p>'+distance+'米</p>';
     }
   }, ScreenSpaceEventType.MOUSE_MOVE);
 
-  handler.setInputAction(function (movement) {
-    // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
-    cartesian = viewer.scene.pickPosition(movement.position);
-    if (positions.length == 0) {
-      positions.push(cartesian.clone());
-    }
-    positions.push(cartesian);
+  function showLocal(auto = false) {
+
     //在三维场景中添加Label
     // var cartographic = Cartographic.fromCartesian(cartesian);
-    var textDisance = distance + "米";
+    let ps = [...positions]
+    auto || ps.pop()
+
+    var pixelOffset
+    var center
+    if (ps.length > 1) {
+      center = {
+        x: (ps[ps.length - 2].x + ps[ps.length - 1].x) / 2,
+        y: (ps[ps.length - 2].y + ps[ps.length - 1].y) / 2,
+        z: (ps[ps.length - 2].z + ps[ps.length - 1].z) / 2
+      }
+    } else {
+      pixelOffset = new Cartesian2(20, -20)
+    }
+
+    ddis = (zdis - distance).toFixed()
+    distance = zdis
+    var textDisance = ddis + "米";
     // console.log(textDisance + ",lng:" + cartographic.longitude/Math.PI*180.0);
+
     floatingPoint = viewer.entities.add({
       name: '空间直线距离',
-      // position: Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180,cartographic.height),
       position: positions[positions.length - 1],
       point: {
         pixelSize: 5,
@@ -77,24 +176,65 @@ var measureLineSpace = function (cb) {
         outlineWidth: 2,
         heightReference: HeightReference.NONE
       },
+    })
+
+    if (center) {
+      floatingLabel = viewer.entities.add({
+        name: '空间直线距离2',
+        position: center,
+        label: {
+          text: textDisance,
+          font: '18px sans-serif',
+          fillColor: Color.GOLD,
+          style: LabelStyle.FILL_AND_OUTLINE,
+          outlineWidth: 2,
+          verticalOrigin: VerticalOrigin.BOTTOM,
+          pixelOffset: pixelOffset,
+          heightReference: HeightReference.NONE
+        }
+      })
+    }
+  }
+
+  handler.setInputAction(function (movement) {
+    // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
+    // cartesian = viewer.scene.pickPosition(movement.position);
+    if (positions.length == 0) {
+      positions.push(cartesian.clone());
+    }
+    positions.push(cartesian);
+
+    showLocal()
+  }, ScreenSpaceEventType.LEFT_CLICK);
+
+  handler.setInputAction(function (movement) {
+    
+    handler.destroy();//关闭事件句柄
+    positions.pop();//最后一个点无效
+    viewer.entities.remove(floatingPoint);
+    viewer.entities.remove(floatingLabel);
+    if (positions.length > 2) {
+      positions.push({...positions[0]});
+      zdis = getSpaceDistance(positions);
+      showLocal(true)
+    }
+    viewer.entities.add({
+      name: '多边形面积',
+      position: positions[positions.length - 1],
       label: {
-        text: textDisance,
+        text: getArea(positions, transfroms(positions)) + '平方公里',
         font: '18px sans-serif',
         fillColor: Color.GOLD,
         style: LabelStyle.FILL_AND_OUTLINE,
         outlineWidth: 2,
         verticalOrigin: VerticalOrigin.BOTTOM,
-        pixelOffset: new Cartesian2(20, -20),
-        heightReference: HeightReference.NONE
+        pixelOffset: new Cartesian2(20, -40),
+        heightReference: HeightReference.CLAMP_TO_GROUND
       }
-    });
-  }, ScreenSpaceEventType.LEFT_CLICK);
+    }); 
 
-  handler.setInputAction(function (movement) {
-    handler.destroy();//关闭事件句柄
-    positions.pop();//最后一个点无效
-    viewer.entities.remove(floatingPoint);
-    cb()
+
+    cb(positions)
   }, ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
 
   var PolyLinePrimitive = (function () {
@@ -147,4 +287,46 @@ function getSpaceDistance(positions) {
   }
   return distance.toFixed(2);
 }
-export default measureLineSpace
+export default measureLineSpace
+
+var getHandler
+
+export const getLongLat = () => {
+  var points = []
+  getHandler = new ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
+
+  getHandler.setInputAction(function (movement) {
+    var position = viewer.scene.pickPosition(movement.position);
+    var pixelOffset = new Cartesian2(20, -20)
+
+    points.push(
+      viewer.entities.add({
+        name: '经纬度',
+        position: position,
+        point: {
+          pixelSize: 5,
+          color: Color.RED,
+          outlineColor: Color.WHITE,
+          outlineWidth: 2,
+          heightReference: HeightReference.NONE
+        },
+        label: {
+          text: JSON.stringify(transfromItem(position)),
+          font: '16px sans-serif',
+          fillColor: Color.GOLD,
+          style: LabelStyle.FILL_AND_OUTLINE,
+          outlineWidth: 2,
+          verticalOrigin: VerticalOrigin.BOTTOM,
+          pixelOffset: pixelOffset,
+          heightReference: HeightReference.NONE
+        }
+      })
+    )
+
+  }, ScreenSpaceEventType.LEFT_CLICK);
+
+  return () => {
+    points.forEach(point => viewer.entities.remove(point))
+    getHandler.destroy()
+  }
+}

+ 3 - 3
src/core/viewer.js

@@ -126,7 +126,7 @@ async function main() {
             }
         })
 
-        var resource = Resource.createIfNeeded('/config.json?_'+Date.now());
+        var resource = Resource.createIfNeeded('/3dmap/config.json?_'+Date.now());
         var config = await resource.fetchJson()
 
         bus.$emit('config', config)
@@ -193,8 +193,8 @@ async function main() {
                 } else {
                     var addLayer;
                     if(layer.type === 'geodata' && layer.url){
-                        let style = layer.fillColor ? grentStyle(layer) : createMapboxStreetsV6Style
-                        
+                        let style = layer.style ? grentStyle(layer.style) : createMapboxStreetsV6Style
+                        console.log(layer)
                         addLayer = renderStyle(ol, style, {
                             url: layer.url+'/{z}/{x}/{y}.pbf',
                             key: "pk.eyJ1IjoibXV5YW8xOTg3IiwiYSI6ImNpcm9ueHd6cjAwNzZoa20xazY1aWlubjIifQ.5tLtC5j1rh8Eqjlyrq3OaA"