Cesium实现掩膜效果

先把效果放上来

首先要声明一下,这个也是参考了大佬的代码:

cesium实现地图反选遮罩效果_ceiums地图 洞反选-CSDN博客

主要优化点:

1、优化了一下边界线的生成,从entity改为了primitive,应该对性能会有所优化。也不用担心点击边界线弹出infoBox,感觉获取边界线的情况应该还是比较少的。

2、考虑到多面体的情况,比如上图中的西安,就会出现飞地。

话不多说,直接放代码吧:

<head>
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script>
  <script src="../Build/CesiumUnminified/Cesium.js"></script>
  <style>
    @import url(../Build/CesiumUnminified/Widgets/widgets.css);

    html,
    body,
    #cesiumContainer {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
  </style>
</head>

<body>
  <div id="cesiumContainer"></div>
  <script>
    Cesium.Ion.defaultAccessToken =
      "Cesium的Token";

    // 创建Cesium Viewer对象
    var viewer = new Cesium.Viewer("cesiumContainer", {
      // 是否显示信息窗口
      infoBox: false,
      // 设置地形
      terrainProvider: Cesium.createWorldTerrain({
        requestVertexNormals: true,
        requestWaterMask: true,
      })
    })


    // 使用jQuery加载Geojson数据
    $.get('https://geo.datav.aliyun.com/areas_v3/bound/610100_full.json').then((data) => {
      let holeArr = [];
      let features = data.features;
      let positionArray = [];
      let LineInstanceArr = [];

      // 遍历边界
      features.forEach(feature => {
        feature.geometry.coordinates.forEach((coorList) => {
          holeArr.push({ positions: Cesium.Cartesian3.fromDegreesArray(coorList.flat(Infinity)) });

          // 使用的贴地线,开启地形不会产生影响
          let polyline = new Cesium.GroundPolylineGeometry({
            positions: Cesium.Cartesian3.fromDegreesArray(coorList.flat(Infinity)),
            width: 3,
          });
          let lineInstance = new Cesium.GeometryInstance({
            geometry: polyline
          })
          LineInstanceArr.push(lineInstance);
        })
      })

      let line = new Cesium.GroundPolylinePrimitive({
        geometryInstances: LineInstanceArr,
        //折线外观
        appearance: new Cesium.PolylineMaterialAppearance({
          material: Cesium.Material.fromType('Color', {
            color: Cesium.Color.YELLOW
          })
        })
      });
      viewer.scene.primitives.add(line);

      // 遮罩
      let polygonEntity = new Cesium.Entity({
        polygon: {
          hierarchy: {
            // 添加外部区域为1/4半圆,设置为180会报错
            positions: Cesium.Cartesian3.fromDegreesArray([0, 0, 0, 90, 179, 90, 179, 0]),
            // 中心挖空的“洞”
            holes: holeArr
          },
          material: new Cesium.Color(15 / 255.0, 38 / 255.0, 84 / 255.0, 0.7)
        },
      })

      viewer.entities.add(polygonEntity);

      let layers = viewer.scene.imageryLayers;
      // 天地图影像图层
      var blackMarble1 = layers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
          url: "http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=天地图Token",
        })
      );
      // 添加天地图的国境线图层
      var blackMarble = layers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
          url: "http://t0.tianditu.gov.cn/DataServer?T=ibo_w&x={x}&y={y}&l={z}&tk=天地图Token",
        })
      );
      
      // 具体定位到哪里看自己情况
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(108.941579, 34.157097, 150000.0)
      });

    })
  </script>
</body>

代码中我改了一些,有的没有用到的变量可以自行删除。

然后把GeoJson数据的获取地址放这了:

DataV.GeoAtlas地理小工具系列

想更改具体的使用地点的话就复制对应的url就行。

我目前只测试了全中国和陕西省这一块,如果运行不了或者还有什么其它的问题的话可以评论区留一下言。如果有更好的优化性能的方式也欢迎留言告诉我一下。

猜你喜欢

转载自blog.csdn.net/XFIRR/article/details/134536239
今日推荐