Cesium反选遮罩实现局部地图凸显,原来Entity这么好用

大家好,我是日拱一卒的攻城师不浪,专注可视化、数字孪生、前端提效、nodejs、AI学习、GIS等学习沉淀,这是2024年输出的第22/100篇文章。

交流合作:brown_7778

前言

先来解释一下什么是遮罩反选。

在实际的项目工作中,产品经理或者项目经理经常会要求开发将地图要展示的某个区域做突出重点显示,然后不属于这个区域的周边做暗化处理,但又不能简单的用纯色覆盖。

这样做呢,从产品设计角度有几个目的:

  • 数据筛选 :突出显示特定区域的数据或信息,而将其他区域进行忽略,防止信息混乱干扰

  • 视觉突出:通过反选遮罩,可以突出显示用户选择的区域,使这些区域在视觉上更加醒目,便于用户识别和分析。

  • 产品美化:如果只是单独展示某个区块或者说让周边区域都是纯色覆盖,用户在视觉美观体验上会有很大的不足。

OK,今天我们就在Cesium中实现地图的遮罩反选效果。

区域边界数据

要想重点突出某个区域的显示,我们需要先将这个区域的边界线勾勒出来,所以首先需要获取这个区域的边界数据。

这里我从政府数据官网对青岛市莱西市的边界数据进行了下载,一个geojson文件格式。

数据处理

js 复制代码
const { res } = await getGeojson("/json/laixi.geojson");
const { features } = res;
const maskpointArray = [];
// 这里的数据筛选要大家根据自己的json数据结构进行获取
const arr = features[0].geometry.coordinates[0][0];
// 处理莱西市的边界数据,整理成我们想要的格式
for (let i = 0, l = arr.length; i < l; i++) {
  maskpointArray.push(arr[i][0]);
  maskpointArray.push(arr[i][1]);
}
// 将其转换成下边渲染entity所需的3D笛卡尔坐标系。
var maskspoint = Cesium.Cartesian3.fromDegreesArray(maskpointArray);

我一开始拿到的json数据坐标是经纬度,这里我们利用Cartesian3将其转换成3D笛卡尔坐标系,为后边渲染边界区域做准备。

原数据:

转换后:

实现原理

先来说下实现原理:

  1. 首先需要把整个区域都用一个黑色带有透明度的遮罩层覆盖;
  2. 勾勒出需要突出显示的区域;
  3. 在黑色带有透明度的遮罩层中挖开一个洞,这个洞其实就是要突出显示的区域;

polygon区域面绘制

使用Entity实现的绘制,代码下方有代码详细解析。

js 复制代码
const area = new Cesium.Entity({
    id: 1,
    polygon: {
      hierarchy: {
        // 定义多边形或孔外边界的线性环。
        positions: Cesium.Cartesian3.fromDegreesArray([
          100, 0, 100, 89, 160, 89, 160, 0,
        ]), 
        // 一组多边形层次结构,定义多边形中的孔。
        holes: [
          {
            positions: maskspoint, //挖空区域
          },
        ],
      },
      // 填充多边形的材质
      material: Cesium.Color.BLACK.withAlpha(0.9),
    },
  });

代码实现解析

  1. 使用Entity渲染区域几何体,接收参数具体参考【API文档】:cesium.xin/cesium/cn/D...

  2. polygon:构建一个多边形几何体作为遮罩层整体;

  3. material:给多边形上色,我们这里用的黑色带有透明度的配置;

  4. hierarchy :定义多边形及其孔的线性环的层次结构。孔本身也可能具有嵌套内部多边形的孔,【API文档】:cesium.xin/cesium/cn/D...

边界线勾勒

突出区域绘制好之后,为了视觉上更加能够区分边界区域以及美观性,我们需要勾勒一个好看的边界线。

同样使用Entity大类实现线的绘制。

js 复制代码
const line = new Cesium.Entity({
    id: 2,
    polyline: {
      positions: maskspoint,
      width: 4, //边界线宽
      material: Cesium.Color.fromCssColorString("#6dcdeb"), //边界线颜色
      clampToGround: true, // 贴地
    },
  });

【API文档】:cesium.xin/cesium/cn/D...

几何体都绘制完成之后,别忘记最后将其添加进viewer场景中。

js 复制代码
viewer.entities.add(area);
viewer.entities.add(line);

OK,以上就完成了遮罩反选的效果,非常easy😊。

完整代码和源数据 可从下方链接获取,如果开源对你又帮助,也希望点一个star,支持我开源更多代码。

【开源地址】:github.com/tingyuxuan2...

有需要进技术产品开发交流群(可视化&GIS)可以加我:brown_7778,也欢迎数字孪生可视化领域的交流合作。

最后,如果觉得文章对你有帮助,也希望可以一键三连👏👏👏,支持我持续开源和分享~

相关推荐
a栋栋栋2 小时前
apifox
java·前端·javascript
请叫我飞哥@2 小时前
HTML 标签页(Tabs)详细讲解
前端·html
Anlici3 小时前
React18与Vue3组件通信对比学习(详细!建议收藏!!🚀🚀)
前端·vue.js·react.js
m0_748251523 小时前
PDF在线预览实现:如何使用vue-pdf-embed实现前端PDF在线阅读
前端·vue.js·pdf
中生代技术3 小时前
3.从制定标准到持续监控:7个关键阶段提升App用户体验
大数据·运维·服务器·前端·ux
m0_748239333 小时前
从零开始:如何在.NET Core Web API中完美配置Swagger文档
前端·.netcore
m0_748232924 小时前
【前端】Node.js使用教程
前端·node.js·vim
hawleyHuo4 小时前
umi 能适配 taro组件?
前端·前端框架
web130933203984 小时前
[JAVA Web] 02_第二章 HTML&CSS
java·前端·html
黑客呀4 小时前
Go Web开发之Revel - 网页请求处理流程
开发语言·前端·web安全·golang·系统安全