• cesium如何实现区域下钻


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

    1. <script setup>
    2. import * as Cesium from "cesium";
    3. import { ref, onMounted } from "vue";
    4. import {
    5. province,
    6. xizang,
    7. ali,
    8. naqu,
    9. changdu,
    10. linzhi,
    11. shannan,
    12. lasan,
    13. rika,
    14. } from "./json/data";
    15. // import CesiumViewer from "../../cesiumComponents/cesiumViewer.vue";
    16. import CesiumViewer from "@/components/cesiumViewer.vue";
    17. let viewer, dataSource, highlightEntity;
    18. const cesiumViewerRef = ref();
    19. const regionValue = ref();
    20. const regionData = ref([]);
    21. onMounted(() => {
    22. viewer = window.cesiumViewer;
    23. dataSource = new Cesium.GeoJsonDataSource();
    24. viewer.dataSources.add(dataSource);
    25. provinceDataSource();
    26. });
    27. // 移除高亮显示
    28. const removeHighlight = () => {
    29. if (Cesium.defined(highlightEntity)) {
    30. highlightEntity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
    31. highlightEntity = null;
    32. }
    33. };
    34. // 加载西藏
    35. const provinceDataSource = () => {
    36. // 移除事件监听和高亮显示
    37. destroyAllEvents();
    38. dataSource
    39. .load(province, {
    40. fill: Cesium.Color.TRANSPARENT,
    41. stroke: Cesium.Color.TRANSPARENT, //设置多边形轮廓的默认颜色
    42. strokeWidth: 20, //轮廓的宽度
    43. clamToGround: true, //让地图贴地
    44. })
    45. .then(() => {
    46. // 设置行政区域的样式
    47. const entities = dataSource.entities.values;
    48. entities?.forEach((item, index) => {
    49. const entity = entities[index];
    50. if (entity.name == "西藏自治区") {
    51. entity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
    52. entity.polygon.outline = true;
    53. entity.polygon.outlineColor = Cesium.Color.RED;
    54. var polyPositions = entity.polygon.hierarchy.getValue(
    55. Cesium.JulianDate.now()
    56. ).positions;
    57. var polyCenter =
    58. Cesium.BoundingSphere.fromPoints(polyPositions).center;
    59. polyCenter =
    60. Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
    61. viewer.entities.add({
    62. position: polyCenter,
    63. label: {
    64. //标签
    65. scale: 0.6,
    66. font: "24px sans-serif",
    67. text: entity.properties.name,
    68. // showBackground: true,
    69. horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
    70. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
    71. },
    72. });
    73. }
    74. });
    75. });
    76. // 双击
    77. viewer.screenSpaceEventHandler.setInputAction((event) => {
    78. const pickedObject = viewer.scene.pick(event.position);
    79. if (
    80. Cesium.defined(pickedObject) &&
    81. pickedObject.id instanceof Cesium.Entity &&
    82. pickedObject.id.name === "西藏自治区"
    83. ) {
    84. removeHighlight();
    85. console.log(pickedObject.id.properties.adcode);
    86. if (pickedObject.id.properties.adcode) {
    87. cityDataSource();
    88. // 移除父级区域
    89. viewer.entities.removeAll();
    90. }
    91. // 高亮显示行政区域
    92. } else {
    93. removeHighlight();
    94. }
    95. }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    96. // 单击
    97. viewer.screenSpaceEventHandler.setInputAction((event) => {
    98. const pickedObject = viewer.scene.pick(event.position);
    99. if (
    100. Cesium.defined(pickedObject) &&
    101. pickedObject.id instanceof Cesium.Entity &&
    102. pickedObject.id.name === "西藏自治区"
    103. ) {
    104. removeHighlight();
    105. // 高亮显示行政区域
    106. highlightEntity = pickedObject.id;
    107. regionValue.value = highlightEntity.properties.adcode.getValue()
    108. highlightEntity.polygon.material = Cesium.Color.POWDERBLUE;
    109. } else {
    110. removeHighlight();
    111. }
    112. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    113. };
    114. const cityDataSource = () => {
    115. // 移除事件监听和高亮显示
    116. destroyAllEvents();
    117. dataSource
    118. .load(xizang, {
    119. stroke: Cesium.Color.TRANSPARENT, //设置多边形轮廓的默认颜色
    120. strokeWidth: 20, //轮廓的宽度
    121. clamToGround: true, //让地图贴地
    122. })
    123. .then(() => {
    124. // 设置行政区域的样式
    125. const entities = dataSource.entities.values;
    126. entities?.forEach((item, index) => {
    127. const entity = entities[index];
    128. entity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
    129. entity.polygon.outline = true;
    130. entity.polygon.outlineColor = Cesium.Color.RED;
    131. var polyPositions = entity.polygon.hierarchy.getValue(
    132. Cesium.JulianDate.now()
    133. ).positions;
    134. var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
    135. polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
    136. viewer.entities.add({
    137. position: polyCenter,
    138. label: {
    139. //标签
    140. scale: 0.6,
    141. font: "24px sans-serif",
    142. text: entity.properties.name,
    143. // showBackground: true,
    144. horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
    145. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
    146. },
    147. });
    148. });
    149. });
    150. let pickedId = "";
    151. // 单击
    152. viewer.screenSpaceEventHandler.setInputAction((event) => {
    153. const pickedObject = viewer.scene.pick(event.position);
    154. if (
    155. Cesium.defined(pickedObject) &&
    156. pickedObject.id instanceof Cesium.Entity
    157. ) {
    158. pickedId = pickedObject.id.id;
    159. removeHighlight();
    160. // 高亮显示行政区域
    161. highlightEntity = pickedObject.id;
    162. regionValue.value = highlightEntity.properties.adcode.getValue()
    163. highlightEntity.polygon.material = Cesium.Color.POWDERBLUE;
    164. } else {
    165. removeHighlight();
    166. }
    167. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    168. // 双击
    169. viewer.screenSpaceEventHandler.setInputAction((event) => {
    170. const pickedObject = viewer.scene.pick(event.position);
    171. if (
    172. Cesium.defined(pickedObject) &&
    173. pickedObject.id instanceof Cesium.Entity
    174. ) {
    175. if (pickedObject.id.name == "阿里地区") {
    176. countyDataSource(ali);
    177. } else if (pickedObject.id.name == "那曲市") {
    178. countyDataSource(naqu);
    179. } else if (pickedObject.id.name == "昌都市") {
    180. countyDataSource(changdu);
    181. } else if (pickedObject.id.name == "林芝市") {
    182. countyDataSource(linzhi);
    183. } else if (pickedObject.id.name == "山南市") {
    184. countyDataSource(shannan);
    185. } else if (pickedObject.id.name == "拉萨市") {
    186. countyDataSource(lasan);
    187. } else if (pickedObject.id.name == "日喀则市") {
    188. countyDataSource(rika);
    189. }
    190. removeHighlight();
    191. // 移除父级区域
    192. viewer.entities.removeAll();
    193. // viewer.dataSources.removeAll();
    194. } else {
    195. removeHighlight();
    196. }
    197. }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    198. viewer.screenSpaceEventHandler.setInputAction((event) => {
    199. const pickedObject = viewer.scene.pick(event.position);
    200. if (
    201. typeof pickedObject == "undefined" ||
    202. (Cesium.defined(pickedObject) &&
    203. pickedObject.id instanceof Cesium.Entity &&
    204. pickedObject.id.id !== pickedId)
    205. ) {
    206. removeHighlight();
    207. // 移除父级区域
    208. viewer.entities.removeAll();
    209. provinceDataSource();
    210. }
    211. }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    212. };
    213. const countyDataSource = (data) => {
    214. // 移除事件监听和高亮显示
    215. destroyAllEvents();
    216. dataSource
    217. .load(data, {
    218. stroke: Cesium.Color.TRANSPARENT, //设置多边形轮廓的默认颜色
    219. strokeWidth: 20, //轮廓的宽度
    220. clamToGround: true, //让地图贴地
    221. })
    222. .then(() => {
    223. // 设置行政区域的样式
    224. const entities = dataSource.entities.values;
    225. entities?.forEach((item, index) => {
    226. const entity = entities[index];
    227. entity.polygon.material = Cesium.Color.POWDERBLUE.withAlpha(0.3);
    228. entity.polygon.outline = true;
    229. entity.polygon.outlineColor = Cesium.Color.RED;
    230. var polyPositions = entity.polygon.hierarchy.getValue(
    231. Cesium.JulianDate.now()
    232. ).positions;
    233. var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
    234. polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
    235. viewer.entities.add({
    236. position: polyCenter,
    237. label: {
    238. //标签
    239. scale: 0.6,
    240. font: "24px sans-serif",
    241. text: entity.properties.name,
    242. // showBackground: true,
    243. horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
    244. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
    245. },
    246. });
    247. });
    248. });
    249. // 单击
    250. let pickedId = "";
    251. viewer.screenSpaceEventHandler.setInputAction((event) => {
    252. const pickedObject = viewer.scene.pick(event.position);
    253. if (
    254. Cesium.defined(pickedObject) &&
    255. pickedObject.id instanceof Cesium.Entity
    256. ) {
    257. pickedId = pickedObject.id.id;
    258. removeHighlight();
    259. // 高亮显示行政区域
    260. highlightEntity = pickedObject.id;
    261. highlightEntity.polygon.material = Cesium.Color.POWDERBLUE;
    262. } else {
    263. removeHighlight();
    264. }
    265. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    266. viewer.screenSpaceEventHandler.setInputAction((event) => {
    267. const pickedObject = viewer.scene.pick(event.position);
    268. if (
    269. typeof pickedObject == "undefined" ||
    270. (Cesium.defined(pickedObject) &&
    271. pickedObject.id instanceof Cesium.Entity &&
    272. pickedObject.id.id !== pickedId)
    273. ) {
    274. removeHighlight();
    275. // 移除父级区域
    276. viewer.entities.removeAll();
    277. cityDataSource();
    278. }
    279. }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    280. };
    281. // 移除事件
    282. const destroyAllEvents = () => {
    283. // 单击左键
    284. viewer.screenSpaceEventHandler.removeInputAction(
    285. Cesium.ScreenSpaceEventType.LEFT_CLICK
    286. );
    287. // 双击左键
    288. viewer.screenSpaceEventHandler.removeInputAction(
    289. Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    290. );
    291. // 单击右键
    292. viewer.screenSpaceEventHandler.removeInputAction(
    293. Cesium.ScreenSpaceEventType.RIGHT_CLICK
    294. );
    295. };
    296. const handleNodeClick = (e) => {
    297. console.log(e, "========1234");
    298. };
    299. script>
    300. <style lang="scss" scoped>
    301. .zkr-el-tree {
    302. width: 240px;
    303. height: 500px;
    304. overflow: auto;
    305. position: absolute;
    306. top: 20px;
    307. }
    308. style>

    注:如有问题或者有更好的解决方式可以联系笔者,进行解答及优化。

  • 相关阅读:
    MySQL数据库 —— 常用语句
    在Spring Boot中实现类似SPI机制的功能(二)
    随机抽奖转盘微信小程序项目源码
    vue大屏可视化项目页面全屏展示(强制缩放实现)
    常用的dos网络命令总结
    如何处理 java.lang.NoClassDefFoundError
    训练营第二十九天贪心(简单题目)
    oracle查询历史SQL记录
    kotlin 之几个常见的内联函数(五)
    网络安全(黑客)—自学
  • 原文地址:https://blog.csdn.net/qq_43474235/article/details/134361956