首先,这里讲一下数据源,数据源是拷贝的DataV.GroAtlas里的数据,这里整合了一下之前发的区域高亮的代码来实现的,单击左键使得区域高亮,每次点击都移除上一次点击的模块,双击左键,实现区域下钻并请求对应的数据源,单击右键来实现恢复上一层级。具体代码如下:
<template>
<div>
<CesiumViewer ref="cesiumViewerRef" />
</div>
</template>
<script setup>
import * as Cesium from "cesium";
import { ref, onMounted } from "vue";
import {
province,
xizang,
ali,
naqu,
changdu,
linzhi,
shannan,
lasan,
rika,
} from "./json/data";
// import CesiumViewer from "../../cesiumComponents/cesiumViewer.vue";
import CesiumViewer from "@/components/cesiumViewer.vue";
let viewer, dataSource, highlightEntity;
const cesiumViewerRef = ref();
const regionValue = ref();
const regionData = ref([]);
onMounted(() => {
viewer = window.cesiumViewer;
dataSource = new Cesium.GeoJsonDataSource();
viewer.dataSources.add(dataSource);
provinceDataSource();
});
// 移除高亮显示
const removeHighlight = () => {
if (Cesium.defined(highlightEntity)) {
highlightEntity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
highlightEntity = null;
}
};
// 加载西藏
const provinceDataSource = () => {
// 移除事件监听和高亮显示
destroyAllEvents();
dataSource
.load(province, {
fill: Cesium.Color.TRANSPARENT,
stroke: Cesium.Color.TRANSPARENT, //设置多边形轮廓的默认颜色
strokeWidth: 20, //轮廓的宽度
clamToGround: true, //让地图贴地
})
.then(() => {
// 设置行政区域的样式
const entities = dataSource.entities.values;
entities?.forEach((item, index) => {
const entity = entities[index];
if (entity.name == "西藏自治区") {
entity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
entity.polygon.outline = true;
entity.polygon.outlineColor = Cesium.Color.RED;
var polyPositions = entity.polygon.hierarchy.getValue(
Cesium.JulianDate.now()
).positions;
var polyCenter =
Cesium.BoundingSphere.fromPoints(polyPositions).center;
polyCenter =
Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
viewer.entities.add({
position: polyCenter,
label: {
//标签
scale: 0.6,
font: "24px sans-serif",
text: entity.properties.name,
// showBackground: true,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
});
}
});
});
// 双击
viewer.screenSpaceEventHandler.setInputAction((event) => {
const pickedObject = viewer.scene.pick(event.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity &&
pickedObject.id.name === "西藏自治区"
) {
removeHighlight();
console.log(pickedObject.id.properties.adcode);
if (pickedObject.id.properties.adcode) {
cityDataSource();
// 移除父级区域
viewer.entities.removeAll();
}
// 高亮显示行政区域
} else {
removeHighlight();
}
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
// 单击
viewer.screenSpaceEventHandler.setInputAction((event) => {
const pickedObject = viewer.scene.pick(event.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity &&
pickedObject.id.name === "西藏自治区"
) {
removeHighlight();
// 高亮显示行政区域
highlightEntity = pickedObject.id;
regionValue.value = highlightEntity.properties.adcode.getValue()
highlightEntity.polygon.material = Cesium.Color.POWDERBLUE;
} else {
removeHighlight();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
const cityDataSource = () => {
// 移除事件监听和高亮显示
destroyAllEvents();
dataSource
.load(xizang, {
stroke: Cesium.Color.TRANSPARENT, //设置多边形轮廓的默认颜色
strokeWidth: 20, //轮廓的宽度
clamToGround: true, //让地图贴地
})
.then(() => {
// 设置行政区域的样式
const entities = dataSource.entities.values;
entities?.forEach((item, index) => {
const entity = entities[index];
entity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
entity.polygon.outline = true;
entity.polygon.outlineColor = Cesium.Color.RED;
var polyPositions = entity.polygon.hierarchy.getValue(
Cesium.JulianDate.now()
).positions;
var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
viewer.entities.add({
position: polyCenter,
label: {
//标签
scale: 0.6,
font: "24px sans-serif",
text: entity.properties.name,
// showBackground: true,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
});
});
});
let pickedId = "";
// 单击
viewer.screenSpaceEventHandler.setInputAction((event) => {
const pickedObject = viewer.scene.pick(event.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity
) {
pickedId = pickedObject.id.id;
removeHighlight();
// 高亮显示行政区域
highlightEntity = pickedObject.id;
regionValue.value = highlightEntity.properties.adcode.getValue()
highlightEntity.polygon.material = Cesium.Color.POWDERBLUE;
} else {
removeHighlight();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 双击
viewer.screenSpaceEventHandler.setInputAction((event) => {
const pickedObject = viewer.scene.pick(event.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity
) {
if (pickedObject.id.name == "阿里地区") {
countyDataSource(ali);
} else if (pickedObject.id.name == "那曲市") {
countyDataSource(naqu);
} else if (pickedObject.id.name == "昌都市") {
countyDataSource(changdu);
} else if (pickedObject.id.name == "林芝市") {
countyDataSource(linzhi);
} else if (pickedObject.id.name == "山南市") {
countyDataSource(shannan);
} else if (pickedObject.id.name == "拉萨市") {
countyDataSource(lasan);
} else if (pickedObject.id.name == "日喀则市") {
countyDataSource(rika);
}
removeHighlight();
// 移除父级区域
viewer.entities.removeAll();
// viewer.dataSources.removeAll();
} else {
removeHighlight();
}
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
viewer.screenSpaceEventHandler.setInputAction((event) => {
const pickedObject = viewer.scene.pick(event.position);
if (
typeof pickedObject == "undefined" ||
(Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity &&
pickedObject.id.id !== pickedId)
) {
removeHighlight();
// 移除父级区域
viewer.entities.removeAll();
provinceDataSource();
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};
const countyDataSource = (data) => {
// 移除事件监听和高亮显示
destroyAllEvents();
dataSource
.load(data, {
stroke: Cesium.Color.TRANSPARENT, //设置多边形轮廓的默认颜色
strokeWidth: 20, //轮廓的宽度
clamToGround: true, //让地图贴地
})
.then(() => {
// 设置行政区域的样式
const entities = dataSource.entities.values;
entities?.forEach((item, index) => {
const entity = entities[index];
entity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
entity.polygon.outline = true;
entity.polygon.outlineColor = Cesium.Color.RED;
var polyPositions = entity.polygon.hierarchy.getValue(
Cesium.JulianDate.now()
).positions;
var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
viewer.entities.add({
position: polyCenter,
label: {
//标签
scale: 0.6,
font: "24px sans-serif",
text: entity.properties.name,
// showBackground: true,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
});
});
});
// 单击
let pickedId = "";
viewer.screenSpaceEventHandler.setInputAction((event) => {
const pickedObject = viewer.scene.pick(event.position);
if (
Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity
) {
pickedId = pickedObject.id.id;
removeHighlight();
// 高亮显示行政区域
highlightEntity = pickedObject.id;
highlightEntity.polygon.material = Cesium.Color.POWDERBLUE;
} else {
removeHighlight();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
viewer.screenSpaceEventHandler.setInputAction((event) => {
const pickedObject = viewer.scene.pick(event.position);
if (
typeof pickedObject == "undefined" ||
(Cesium.defined(pickedObject) &&
pickedObject.id instanceof Cesium.Entity &&
pickedObject.id.id !== pickedId)
) {
removeHighlight();
// 移除父级区域
viewer.entities.removeAll();
cityDataSource();
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};
// 移除事件
const destroyAllEvents = () => {
// 单击左键
viewer.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_CLICK
);
// 双击左键
viewer.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
// 单击右键
viewer.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.RIGHT_CLICK
);
};
const handleNodeClick = (e) => {
console.log(e, "========1234");
};
</script>
<style lang="scss" scoped>
.zkr-el-tree {
width: 240px;
height: 500px;
overflow: auto;
position: absolute;
top: 20px;
}
</style>
注:如有问题或者有更好的解决方式可以联系笔者,进行解答及优化。