先把效果放上来
首先要声明一下,这个也是参考了大佬的代码:
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数据的获取地址放这了:
想更改具体的使用地点的话就复制对应的url就行。
我目前只测试了全中国和陕西省这一块,如果运行不了或者还有什么其它的问题的话可以评论区留一下言。如果有更好的优化性能的方式也欢迎留言告诉我一下。