Cesium使用turf.js创建一块区域的网格mesh

实现一块区域的网格mesh,坡度计算,点位密集的情况下,会接近高程地形效果

  var pos = [{
      longitude: 120.817976,
      latitude: 23.9530403,
      height: 0
    }, {
      longitude: 120.9817976,
      latitude: 23.6530403,
      height: 0
    }, {
      longitude: 121.6517976,
      latitude: 23.630403,
      height: 0
    }, {
      longitude: 121.6917976,
      latitude: 23.30403,
      height: 0
    }, {
      longitude: 122.6917976,
      latitude: 24.30403,
      height: 0
    }]
    CreateMesh();
    //创建mesh网格
    function CreateMesh() {
      // 1. 创建一个矩形区域
      //  var rectangle = Cesium.Rectangle.fromDegrees(117.09649937089316, 36.20673458245797, 117.11797117691083, 36.230040948473906)
      var rectangle = Cesium.Rectangle.fromDegrees(pos[0].longitude, pos[0].latitude, pos[3].longitude, pos[3].latitude)
      // 2. 在这个矩形区域内生成点集
      var width = 100;  // 横向点数
      var height = 100; // 纵向点数
      var terrainProvider = viewer.terrainProvider
      var positions = [];
      for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
          var longitude = Cesium.Math.lerp(rectangle.west, rectangle.east, x / (width - 1));
          var latitude = Cesium.Math.lerp(rectangle.south, rectangle.north, y / (height - 1));

          positions.push(Cesium.Cartographic.fromRadians(longitude, latitude));
        }
      }

      Cesium.sampleTerrainMostDetailed(terrainProvider, positions).then(function (samples) {
        console.log(samples, "0000000000000000000000");
        var points = samples.map(function (sample) {
          return turf.point([Cesium.Math.toDegrees(sample.longitude), Cesium.Math.toDegrees(sample.latitude), sample.height],
            { z: sample.height })  // 将高度值保存到名为 'z' 的属性中);
        });
        console.log(points, "11111111111111");
        //显示点集  
        var cartesianPoints = points.map(function (point) {
          var coord = point.geometry.coordinates;
          var cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1], coord[2]);
          return Cesium.Cartographic.toCartesian(cartographic);
        });
        var pointCollection = new Cesium.PointPrimitiveCollection();

        cartesianPoints.forEach(function (position) {
          pointCollection.add({
            position: position,
            color: Cesium.Color.RED,
            pixelSize: 5
          });
        });
        viewer.scene.primitives.add(pointCollection);

      })

      Cesium.sampleTerrainMostDetailed(terrainProvider, positions).then(function (samples) {
        var points = samples.map(function (sample) {
          return turf.point([Cesium.Math.toDegrees(sample.longitude), Cesium.Math.toDegrees(sample.latitude), sample.height],
            { z: sample.height })  // 将高度值保存到名为 'z' 的属性中);
        });
        // 创建一个FeatureCollection
        var featureCollection = turf.featureCollection(points);
        var tin = turf.tin(featureCollection, 'z');
        var geometryInstances = [];  // 用于存放所有的三角形GeometryInstance
        var instances = [];
        // 遍历每个TIN三角形
        tin.features.forEach(function (feature, i) {
          var coordinates = feature.geometry.coordinates[0];
          var heights = [feature.properties.a, feature.properties.b, feature.properties.c];
          var positions = coordinates.map(function (coord, index) {
            return Cesium.Cartesian3.fromDegrees(coord[0], coord[1], heights[index]);
          });
          const point1 = positions[0];
          const point2 = positions[1];
          const point3 = positions[2];
          //使用我们新定义的函数计算每个三角形的坡度
          var analysisResult = calculateSlopeAndAspect(point1, point2, point3);

          var slope = analysisResult.slope;
          var hue = slope / 90.0; // 将坡度从0到90度映射到色调从0到1
          var saturation = 1.0;   // 全饱和度
          var lightness = 0.5;    // 正常亮度
          var alpha = 1.0;        // 完全不透明
          //将HSL颜色转换为RGBA,当坡度为0度时,hue变为0,颜色是红色;当坡度为90度时,hue变为1,颜色是绿色;在0到90度之间的坡度将映射到从红色到绿色之间的颜色。
          var color = Cesium.Color.fromHsl(hue, saturation, lightness).withAlpha(alpha);
          console.log("三角形坡度:", analysisResult);

          viewer.entities.add({
            name: "三角面",
            id: "triangle" + i,
            polygon: {
              hierarchy: [positions[0], positions[1], positions[2]],
              heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
              perPositionHeight: true,
              material: color,// Cesium.Color.fromCssColorString("#23B8BA").withAlpha(
              // 1.0
              //),
              //  extrudedHeight: 0,
              outline: true,
              outlineColor: Cesium.Color.GREEN,
            }
          });


        });

        var cartesianPoints = points.map(function (point) {
          var coord = point.geometry.coordinates;
          var cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1], coord[2]);
          return Cesium.Cartographic.toCartesian(cartographic);
        });
        var pointCollection = new Cesium.PointPrimitiveCollection();

        cartesianPoints.forEach(function (position) {
          pointCollection.add({
            position: position,
            color: Cesium.Color.RED,
            pixelSize: 5
          });
        });
        viewer.scene.primitives.add(pointCollection);
      })

    }

    /**
       * 计算三角形的坡度
       * @param {*} point1 
       * @param {*} point2 
       * @param {*} point3 
       * @returns 
       */
    function calculateSlopeAndAspect(point1, point2, point3) {
      console.log("point1", point1, "point2", point2, "point3", point3);
      // 计算两个向量,它们位于三角形的两边
      var v1 = Cesium.Cartesian3.subtract(
        point1,
        point2,
        new Cesium.Cartesian3()
      );
      var v2 = Cesium.Cartesian3.subtract(
        point2,
        point3,
        new Cesium.Cartesian3()
      );

      // 计算这两个向量的叉积,得到三角形的法向量
      var normal = new Cesium.Cartesian3();
      Cesium.Cartesian3.cross(v1, v2, normal);
      Cesium.Cartesian3.normalize(normal, normal);
      console.log("v1", v1, "v2", v2, "normal", normal);
      // 计算三角形的中心点
      var centroid = new Cesium.Cartesian3(
        (point1.x + point2.x + point3.x) / 3,
        (point1.y + point2.y + point3.y) / 3,
        (point1.z + point2.z + point3.z) / 3
      );

      // 得到从地球中心到三角形中心的单位向量(这里不应该使用垂直向量(0,0,1),如果使用(0,0,1)会导致面南的坡度大,面北的坡度小)
      var centerToCentroid = Cesium.Cartesian3.normalize(centroid, new Cesium.Cartesian3());

      // 确保法线向量指向地球外部
      if (Cesium.Cartesian3.dot(normal, centerToCentroid) < 0) {
        Cesium.Cartesian3.negate(normal, normal);
      }

      // 计算坡度:法向量和从地球中心到三角形中心的径向向量之间的夹角
      var slopeRadians = Math.acos(Cesium.Cartesian3.dot(normal, centerToCentroid));

      var slopeDegrees = Cesium.Math.toDegrees(slopeRadians);
      console.log("坡度:", slopeRadians, "角度:", slopeDegrees, "中心点:", centroid);
      // 如果坡度大于90度,则将其减少到90度以下
      if (slopeDegrees > 90) {
        slopeDegrees = 180 - slopeDegrees;
      }
      // 返回坡度值
      return { slope: slopeDegrees };
    }

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值