Vue+Ts+Cesium:加载JSON数据

目录

前言

一、加载地球

二、加载JSON数据

1.获取JSON数据

2.加载数据

三.异步操作注意事项

完整代码

最终效果

总结


前言

本文涉及Cesium加载JSON数据、异步操作、Promise对象的知识完成边界数据的加载,后续会以此为基础进行简单的拓展。诸如地图层次下钻以及信息弹窗

一、加载地球

<template>
  <div id="viewerDiv"></div>
</template>

<script setup lang="ts">
import { onMounted } from "vue";
import * as Cesium from "cesium";
import { createBaseViewer } from "../utils/createBaseViewer";

let viewer: Cesium.Viewer;

function createViewer() {
  viewer = createBaseViewer(viewer, "viewerDiv", ["vec", "w"]);
}

onMounted(() => {
  createViewer();
});
</script>

<style scoped>
#viewerDiv {
  position: absolute;
  width: 100%;
  height: 100%;
}
</style>

对加载地球有疑惑的可以看我之前的文章

二、加载JSON数据

1.获取JSON数据

地理空间数据网站

从上面的链接可以获取到行政区边界的JSON数据

我们先选个不包含子区域的中国边界数据:https://geo.datav.aliyun.com/areas_v3/bound/100000.json

可以直接下载本地加载,这里我们就直接通过url加载

2.加载数据

Cesium提供GeoJsonDataSource.load()这个函数能够读取JSON数据

其中data可以是一个url、或者一个JSON以及Topo数据对象,当然本地文件路径也是可以的。注意的是它返回的是Promise对象,有三种状态:pending(进行中)fulfilled(已成功)rejected(已失败)。其他Promise对象的知识本文不过多阐述建议参考其他文章。

需要注意的是这是一个异步操作,这意味着执行这个操作不会立即完成。它会先返回一个Promise对象,然后继续执行后面的操作,如果后面紧接着调用数据而Promise对象还处于pending(进行中)或者rejected(已失败)会调用数据失败导致报错。后面我会谈到如何处理这个问题。

完成JSON数据的读取,接下来就是加载到viewer中,通过dataSources.add(),它能加载DataSource或者Promise对象封装的DataSource

function loadGeoJson() {
  viewer.dataSources.add(
    Cesium.GeoJsonDataSource.load(
      "https://geo.datav.aliyun.com/areas_v3/bound/100000.json"
    )
  );
}

这样我们就完成了最简单的JSON数据加载,但这样看太单调,我们可以利用GeoJsonDataSource.load()中的option参数(可选)进行简单的调整

function loadGeoJson() {
  viewer.dataSources.add(
    Cesium.GeoJsonDataSource.load(
      "https://geo.datav.aliyun.com/areas_v3/bound/100000.json", {
        stroke: Cesium.Color.RED,  //边界线颜色
        fill: Cesium.Color.BLUE.withAlpha(0.5),  //填充色
        strokeWidth: 10  //边界线宽度
      }
    )
  );
}

这只是一个中国边界数据,我们还可以同时加载多个边界数据

https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json

这样我们就能看到中国各个省份的边界数据,但这样太难辨识。我们可以遍历数据中的每一个边界数据进行调整。

async function loadGeoJson(adcode: number) {
  // 从指定的URL加载GeoJson数据,参数为adcode
  await Cesium.GeoJsonDataSource.load(
    `https://geo.datav.aliyun.com/areas_v3/bound/${adcode}_full.json`,
    {

    }
  ).then((dataSource: Cesium.GeoJsonDataSource) => {
    // 将加载的GeoJson数据添加到viewer中
    viewer.dataSources.add(dataSource);
    // 获取dataSource中的entities
    let entities = dataSource.entities.values;
    // 遍历entities中的每一个entity
    entities.forEach((entity) => {
      // 获取entity的颜色(随机生成颜色,并设置entity的material)
      let color: Cesium.Color = Cesium.Color.fromRandom({ alpha: 0.2 }); //透明度调整为0.2
      // 设置entity的material
      if (entity.polygon) {
        entity.polygon.material = new Cesium.ColorMaterialProperty(color);
        (entity.polygon.outline as unknown) = false;
        (entity.polygon.extrudedHeight as unknown) = 20000; //高度扩大20000倍,便于观察!
      }
    });
  });

  //移动视角
  viewer.flyTo(viewer.dataSources.get(viewer.dataSources.length - 1));
  console.log(viewer.dataSources.get(viewer.dataSources.length - 1));
}

我们一步步来解读这段代码。

1.首先第一步读取JSON数据,当Promise对象状态为fulfilled(已成功)也就是读取成功时,执行then中的箭头函数,箭头函数传入的参数就是完成读取后的JSON数据。(rejected(已失败)也可以执行then,但我没有编写失败执行的代码)

2.第二步加载GeoJson数据到viewer

3.第三步为核心,dataSource中包含了多个entity也就是边界面数据entity,篇幅关系我就不一一在控制台输出展示了。

 所以我们利用forEach对dataSource中的每一个entity进行遍历修改。在循环中,随机生成一种透明度为20%的颜色,并修改entity.polygon.material(面要素纹理),这里我们借助Cesium.ColorMaterialProperty构造函数修改成随机生成的颜色。这里不直接设置的原因是ts的类型约束会导致报错

但是程序是能够正确执行的,嫌麻烦可以直接不管或者//@ts-ignore取消报错。当然最好还是查阅一下官方的API解决类型问题,后面两步嫌麻烦我直接as unknown

4.最后一步移动视角到我们加载的最新dataSources

三.异步操作注意事项

loadGeoJson()中我使用了asyncawait关键字(详情建议参考其他文章),前面我提到了异步操作的问题,async用于声明一个函数是一个异步函数,而await就是等待Promise对象处理完成返回fulfilled(已成功)或者rejected(已失败),再执行后边的操作。如果Promise对象处理完成就会执行then

加了async、await关键字的执行顺序

不加的情况

如果不加asyncawait关键字的话,会先执行移动视角,但此时数据还未加载成功,程序就会发生错误

值得一提的是,只有async声明的函数内部会受await的限制等待,外部不会受影响照常执行

完整代码

<template>
  <div id="viewerDiv"></div>
</template>

<script setup lang="ts">
import { onMounted } from "vue";
import * as Cesium from "cesium";
import { createBaseViewer } from "../utils/createBaseViewer";

let viewer: Cesium.Viewer;

function createViewer() {
  viewer = createBaseViewer(viewer, "viewerDiv", ["vec", "w"]);
}

async function loadGeoJson(adcode: number) {
  // 从指定的URL加载GeoJson数据,参数为adcode
  await Cesium.GeoJsonDataSource.load(
    `https://geo.datav.aliyun.com/areas_v3/bound/${adcode}_full.json`,
    {

    }
  ).then((dataSource: Cesium.GeoJsonDataSource) => {
    // 将加载的GeoJson数据添加到viewer中
    viewer.dataSources.add(dataSource);
    // 获取dataSource中的entities
    let entities = dataSource.entities.values;
    // 遍历entities中的每一个entity
    entities.forEach((entity) => {
      // 获取entity的颜色(随机生成颜色,并设置entity的material)
      let color: Cesium.Color = Cesium.Color.fromRandom({ alpha: 0.2 }); //透明度调整为0.2
      // 设置entity的material
      if (entity.polygon) {
        entity.polygon.material = new Cesium.ColorMaterialProperty(color);
        (entity.polygon.outline as unknown) = false;
        (entity.polygon.extrudedHeight as unknown) = 20000; //提高高度赋予立体效果
      }
    });
  });
  //移动视角
  viewer.flyTo(viewer.dataSources.get(viewer.dataSources.length - 1));
  console.log(viewer.dataSources.get(viewer.dataSources.length - 1));
}

onMounted(() => {
  createViewer();
  loadGeoJson(100000);
});
</script>

<style scoped>
#viewerDiv {
  position: absolute;
  width: 100%;
  height: 100%;
}
</style>

最终效果

  • 29
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3和TypeScriptCesium中的使用是相当常见和方便的。以下是一些关于Vue3、TypeScriptCesium结合使用的步骤: 1. 首先,确保你已经创建了一个Vue3项目。你可以使用Vue CLI来快速创建一个Vue3项目。 ``` npm install -g @vue/cli vue create my-project ``` 2. 安装Cesium库。你可以通过npm或者yarn来安装cesium。 ``` npm install cesium ``` 3. 在Vue项目的入口文件中,引入Cesium和样式文件。 ```javascript import 'cesium/Build/Cesium/Widgets/widgets.css' import Cesium from 'cesium' window.Cesium = Cesium ``` 4. 创建一个Vue组件,并在其中使用Cesium。 ```vue <template> <div class="cesium-container"> <div ref="cesiumContainer" class="cesium-viewer"></div> </div> </template> <script lang="ts"> import { defineComponent, onMounted } from 'vue' export default defineComponent({ name: 'CesiumViewer', setup() { onMounted(() => { const viewer = new Cesium.Viewer( ref: 'cesiumContainer', terrainProvider: Cesium.createWorldTerrain() ) }) return {} } }) </script> <style> .cesium-container { width: 100%; height: 100vh; display: flex; align-items: center; justify-content: center; } .cesium-viewer { width: 100%; height: 100%; } </style> ``` 5. 在其他Vue组件中使用CesiumViewer组件。 ```vue <template> <div> <h1>My Cesium App</h1> <CesiumViewer /> </div> </template> <script lang="ts"> import { defineComponent } from 'vue' import CesiumViewer from '@/components/CesiumViewer.vue' export default defineComponent({ name: 'App', components: { CesiumViewer } }) </script> ``` 通过上述步骤,你就可以在Vue3和TypeScript项目中使用Cesium了。当然,这只是一个简单的示例,你可以根据自己的需求进行更多的定制化操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值