cesium如何实现区域下钻

news2024/12/25 9:57:00

        首先,这里讲一下数据源,数据源是拷贝的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>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1199671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

社会公益服务小程序的作用是什么

公益包含的项目比较广&#xff0c;包括助学、环保、关爱特殊群体等&#xff0c;市场中无论相关机构还是团队&#xff0c;都有不少&#xff0c;而在实际运作中&#xff0c;也有些一些难题&#xff1a; 首先就是信息展示方面&#xff0c;自身服务及案例难以展示&#xff0c;线上…

每天一点python——day66

#每天一点Python——66 #字符串的分隔 #如图&#xff1a; #方法①split()从左开始分隔&#xff0c;默认空格为分割字符&#xff0c;返回值是一个列表 shello world jisuanji#首先创建一个字符串 list1s.split() print(list1)#输出结果是&#xff1a;[hello, world, jisuanji]注…

AI 绘画 | Stable Diffusion精确控制ControlNet扩展插件

ControlNet ControlNet是一个用于控制AI图像生成的插件&#xff0c;通过使用Conditional Generative Adversarial Networks&#xff08;条件生成对抗网络&#xff09;的技术来生成图像。它允许用户对生成的图像进行更精细的控制&#xff0c;从而在许多应用场景中非常有用&#…

Reeds-Shepp曲线

汽车都有一个最小转向半径&#xff0c;Reeds-Shepp曲线由几段半径固定的圆弧和一段直线段拼接组成&#xff0c;而且圆弧的半径就是汽车的最小转向半径。从起始点到目标点的路径长度是指汽车中心运动轨迹的长度&#xff0c;也就是所有圆弧的弧长和直线段的长度之和。 当环境中…

STM32F4X定时器之通用定时器

一、STM32通用定时器概述 通用定时器包括一个16位或32位自动重载计数器&#xff0c;可通过可编程预分频器进行驱动。定时器可以实现多种功能&#xff0c;包括测量输入信号的脉冲宽度和生成输出波形&#xff0c;通过使用定时器预分频器和RCC时钟控制器预分频器&#xff0c;可以…

深度学习之基于Pytorch框架的MNIST手写数字识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 MNIST是一个手写数字识别的数据集&#xff0c;是深度学习中最常用的数据集之一。基于Pytorch框架的MNIST手写数字识…

牛客网刷题笔记231112 最小k位数+二叉树层序遍历+SQL异常邮件概率

算法题牛客网NC119 最小的k个数 题目&#xff1a; 用了一下python列表的便利&#xff0c;不知道在面试时允许用不。当然最简单的方法其实是直接sort()一下取前k位数即可。本次写的思路如下&#xff1a; 用一个最大容量为k的列表存储结果&#xff0c;遍历n个元素&#xff0c;当…

Python基础入门例程52-NP52 累加数与平均值(循环语句)

最近的博文&#xff1a; Python基础入门例程51-NP51 列表的最大与最小(循环语句)-CSDN博客 Python基础入门例程50-NP50 程序员节&#xff08;循环语句&#xff09;-CSDN博客 Python基础入门例程49-NP49 字符列表的长度-CSDN博客 目录 最近的博文&#xff1a; 描述 输入描…

【C++】stack,queue和deque

stack的介绍 stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并提供一组特定 的成…

华为ensp:ospf动态路由

ip已配置好了 &#xff0c;现在进入路由器去宣告网段 R1 进入系统视图 ospf 1 area 1 network 192.168.1.0 0.0.0.255 network 1.1.1.0 0.0.0.255 R2 进入系统视图 ospf 1area 1 network 1.1.1.0 0.0.0.255 quit area 0 network 192.168.2.0 0.0.0.255 network 2.2…

Java13新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 今天我们来一起看一下Java13这个版本的一些重要信息 版本介绍 Java 13 是在 2019 年 9 月 17 日…

不同性别人群的股骨颈骨密度随年龄的变化趋势

增龄是发生骨质疏松的危险因素。因此&#xff0c;中老年人需要积极防范骨质疏松&#xff0c;以免发生骨折等不良事件。 为了探究不同性别人群的股骨颈骨密度随年龄的变化趋势&#xff0c;首先创建一个df&#xff0c;变量有id&#xff08;编号&#xff09;、age&#xff08;年龄…

Linux:安装MySQL5.7

1. 下载 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/5.7.html#downloads 2. 解压 tar -xvf mysql-5.7.26-linux-glibc2.12-x86_64.tar 再移动并重命名一下 mv mysql-5.7.26-linux-glibc2.12-x86_64 /usr/local/mysql3. 创建mysql用户组和用户并修改权限 g…

山西电力市场日前价格预测【2023-11-13】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-13&#xff09;山西电力市场全天平均日前电价为428.16元/MWh。其中&#xff0c;最高日前电价为751.89元/MWh&#xff0c;预计出现在18: 30。最低日前电价为289.03元/MWh&#xff0c;预计…

【原型详解】JavaScript原型链:深入了解Prototype,超级详细!!!

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;JavaScript进阶指南 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继…

不使用 pip 安装 Python 包

在本文中&#xff0c;我们将学习如何在 Python 中安装没有 pip 的库。 我们还将学习如何使用 conda 命令在 Python 中安装包。 不使用 pip 命令安装 Python 库 在 Python 中&#xff0c;pip 命令是我们系统中安装开源库最常用的方法。 但是&#xff0c;除了 pip 命令之外&…

是谁为所欲为,将我的电脑控作己用?

在刚刚发完短篇小杂文《要找事做&#xff0c;我真怕被闲死》的投稿之后&#xff0c;笔者继续浏览社交网站的网页搜索...... 正看到《温州殡仪馆 》《温州动车723事故死亡高 》《 动车脱轨温州事件真正原因》《 浙江平阳县灭门惨案处理结果公布》《 温州厉秀珍死亡 》这一串又一…

C++ 中的内存分配 -- new 与 delete

c 常用的内存分配 分配释放类别是否可以重载mallocfreeC否newdeleteC 表达式(expressions)否operator new()operator delete()c 函数是operator new[]operator delete[]c 函数&#xff08;用于数组&#xff09;是allocator<T>::allocateallocator<T>::deallocatec …

java使用geotools导出shp文件

SHP格式是一种矢量数据格式&#xff0c;用于存储地理信息系统&#xff08;GIS&#xff09;数据。 SHP文件由一系列有序的文件组成&#xff0c;我们导出的shp文件包括.shp、.shx、.dbf、.prj以及.fix文件。 .shp&#xff08;shape&#xff09;文件&#xff1a;存储矢量地图数据&…

Ubuntu 22.04源码安装cmake 3.27.7

安装参考博客是《ubuntu安装cmake》和《Ubuntu 安装CMake》。 https://cmake.org/download是cmake官网下载的网址。 sudo wget -c https://github.com/Kitware/CMake/releases/download/v3.27.7/cmake-3.27.7.tar.gz可以下载源码&#xff0c;最后显示‘cmake-3.27.7.tar.gz’…