大家好,我是日拱一卒的攻城师不浪,专注可视化、数字孪生、前端提效、nodejs、AI学习、GIS等学习沉淀,这是2024年输出的第22/100篇文章。
交流合作:brown_7778
前言
先来解释一下什么是遮罩反选。
在实际的项目工作中,产品经理或者项目经理经常会要求开发将地图要展示的某个区域做
突出重点
显示,然后不属于这个区域的周边做
暗化处理
,但又不能简单的用纯色覆盖。
这样做呢,从产品设计角度有几个目的:
- 数据筛选:突出显示特定区域的数据或信息,而将其他区域进行忽略,防止信息
混乱干扰
; - 视觉突出:通过反选遮罩,可以突出显示用户选择的区域,使这些区域在视觉上更加醒目,便于用户识别和分析。
- 产品美化:如果只是单独展示某个区块或者说让周边区域都是纯色覆盖,用户在视觉美观体验上会有很大的不足。
OK,今天我们就在Cesium中实现地图的遮罩反选效果。
区域边界数据
要想重点突出某个区域的显示,我们需要先将这个区域的边界线勾勒出来,所以首先需要获取这个区域的边界数据。
这里我从政府数据官网对青岛市莱西市的边界数据进行了下载,一个
geojson
文件格式。
数据处理
const{ res }=awaitgetGeojson("/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笛卡尔坐标系,为后边渲染边界区域做准备。
原数据:
转换后:
实现原理
先来说下实现原理:
- 首先需要把整个区域都用一个黑色带有透明度的遮罩层覆盖;
- 勾勒出需要突出显示的区域;
- 在黑色带有透明度的遮罩层中挖开一个洞,这个洞其实就是要突出显示的区域;
polygon区域面绘制
使用
Entity
实现
面
的绘制,代码下方有代码详细解析。
const area =newCesium.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),},});
代码实现解析
- 使用
Entity
渲染区域几何体,接收参数具体参考【API文档】:http://cesium.xin/cesium/cn/Documentation1.95/Entity.html#.ConstructorOptions; - polygon:构建一个多边形几何体作为遮罩层整体;
- material:给多边形上色,我们这里用的黑色带有透明度的配置;
- hierarchy:定义多边形及其孔的线性环的层次结构。孔本身也可能具有嵌套内部多边形的孔,【API文档】:http://cesium.xin/cesium/cn/Documentation1.95/PolygonHierarchy.html。
边界线勾勒
突出区域绘制好之后,为了视觉上更加能够区分边界区域以及美观性,我们需要勾勒一个好看的边界线。
同样使用
Entity
大类实现线的绘制。
const line =newCesium.Entity({id:2,polyline:{positions: maskspoint,width:4,//边界线宽material: Cesium.Color.fromCssColorString("#6dcdeb"),//边界线颜色clampToGround:true,// 贴地},});
【API文档】:http://cesium.xin/cesium/cn/Documentation1.95/PolylineGraphics.html#.ConstructorOptions
几何体都绘制完成之后,别忘记最后将其添加进
viewer
场景中。
viewer.entities.add(area);
viewer.entities.add(line);
OK,以上就完成了遮罩反选的效果,非常easy😊。
完整代码和源数据可从下方链接获取,如果开源对你又帮助,也希望点一个
star
,支持我开源更多代码。
【开源地址】:https://github.com/tingyuxuan2302/cesium-vue3-vite/blob/github/src/views/scene/maskReverseSelect.vue
有需要进技术产品开发交流群(可视化&GIS)可以加我:brown_7778,也欢迎
数字孪生可视化领域
的交流合作。
最后,如果觉得文章对你有帮助,也希望可以一键三连👏👏👏,支持我持续开源和分享~
版权归原作者 攻城师不浪 所有, 如有侵权,请联系我们删除。