首先,这里讲一下数据源,数据源是拷贝的DataV.GroAtlas里的数据,这里整合了一下之前发的区域高亮的代码来实现的,单击左键使得区域高亮,每次点击都移除上一次点击的模块,双击左键,实现区域下钻并请求对应的数据源,单击右键来实现恢复上一层级。具体代码如下:

- <div>
- <CesiumViewer ref="cesiumViewerRef" />
- div>
-
- <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>
注:如有问题或者有更好的解决方式可以联系笔者,进行解答及优化。