在vite创建的vue3项目中使用Cesium加载纽约建筑模型、设置样式,划分城市区域并着色
-
使用vite创建vue3项目
npm create vite@latest
cd到创建的项目文件夹中
npm install
安装Cesium
npm i cesium vite-plugin-cesium vite -D
-
配置
-
vite.config.js文件:添加Cesium并设置反向代理实现跨域。
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import cesium from 'vite-plugin-cesium'; export default defineConfig({plugins: [vue(), cesium()],//设置反向代理,跨域server: {proxy: {'/ArcGIS': {target: 'https://services.arcgisonline.com',//代理的地址changeOrigin: true,}}} });
-
style.css(可选):修改#app样式
#app {max-width: 100%;margin: 0 auto;padding: 2rem;text-align: center;}
-
-
代码
-
App.vue
<template><div id="cesiumContainer"></div> </template><script setup> import * as Cesium from 'cesium'; import { onMounted } from 'vue'; onMounted(async () => {// 相当于密钥,申请使用下边链接中的数据时需要用到Cesium.Ion.defaultAccessToken = '你的token';Cesium.ArcGisMapService.defaultAccessToken = '你的token';let viewer = new Cesium.Viewer('cesiumContainer', {// 防止报错infoBox: false,// 去掉右上角的一个小选项卡baseLayerPicker: false,// 加载世界街道地图的底图baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.ArcGisMapServerImageryProvider.fromUrl("/ArcGIS/rest/services/World_Street_Map/MapServer")),// 三维立体效果、水波纹terrainProvider: await Cesium.createWorldTerrainAsync({requestVertexNormals: true,requestWaterMask: true})});viewer.camera.setView({// 初始的相机的定位 定在纽约destination: new Cesium.Cartesian3(1332761, -4662399, 4137888),// 方向 俯仰orientation: {heading: 0.6,pitch: -0.66}});// 添加纽约建筑模型let city = viewer.scene.primitives.add(await Cesium.Cesium3DTileset.fromIonAssetId(75343));// 定义建筑的3D样式 层次分明city.style = new Cesium.Cesium3DTileStyle({color: {// 条件判断建筑具体的颜色conditions: [['${Height} >= 300', 'rgba(45,0,75,0.5)'],['${Height} >= 200', 'rgb(102,71,151)'],['${Height} >= 100', 'rgba(170,162,204,0.5)'],['${Height} >= 50', 'rgba(224,226,238,0.5)'],['${Height} >= 25', 'rgba(252,230,200,0.5)'],['${Height} >= 10', 'rgba(248,176,87,0.5)'],["true", 'rgb(127,59,8)']]}})// 邻域边界的加载let neighborhoodsPromise = Cesium.GeoJsonDataSource.load('./assets/SampleData/sampleNeighborhoods.geojson');// 贴在地图表面neighborhoodsPromise.then((dataSource) => {// 将数据添加到查看器viewer.dataSources.add(dataSource);// 把数据进行着色的调整以及放到地图的表面// 拿到区域的实例 Get the array of entitieslet neighborhoodsEntities = dataSource.entities.values;for (let i = 0; i < neighborhoodsEntities.length; i++) {let entity = neighborhoodsEntities[i];// 判断存不存在相应的图形if (Cesium.defined(entity.polygon)) {entity.name = entity.properties.neighborhood;// 设置多边形颜色entity.polygon.material = Cesium.Color.fromRandom({red: 0.1,maximumGreen: 0.5,minimumBlue: 0.5,alpha: 0.6});// 设置地形着色entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;// 设置位置 贴到多边形最底下let polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;entity.position = Cesium.Ellipsoid.WGS84.scaleToGeocentricSurface(Cesium.BoundingSphere.fromPoints(polyPositions).center);// 生成标签entity.label = {text: entity.name,showBackground: true,scale: 0.6,horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,// 设置显示的距离范围distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10, 8000),// 禁用的距离disableDepthTestDistance: 100}}}}) }) </script><style> html, body, #app, #cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden; } </style>
-
解读
-
加载token
// 相当于密钥,申请使用下边链接中的数据时需要用到 Cesium.Ion.defaultAccessToken = '你的token'; Cesium.ArcGisMapService.defaultAccessToken = '你的token';
-
创建查看器viewer,加载世界街道地图,注意vite.config.js中配合的跨域。
let viewer = new Cesium.Viewer('cesiumContainer', {// 防止报错infoBox: false,// 去掉右上角的一个小选项卡baseLayerPicker: false,// 加载世界街道地图的底图baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.ArcGisMapServerImageryProvider.fromUrl("/ArcGIS/rest/services/World_Street_Map/MapServer")),// 三维立体效果、水波纹terrainProvider: await Cesium.createWorldTerrainAsync({requestVertexNormals: true,requestWaterMask: true})});
-
初始化相机位置
viewer.camera.setView({// 初始的相机的定位 定在纽约destination: new Cesium.Cartesian3(1332761, -4662399, 4137888),// 方向 俯仰orientation: {heading: 0.6,pitch: -0.66}});
-
添加纽约建筑模型并设置建筑颜色样式
// 添加纽约建筑模型let city = viewer.scene.primitives.add(await Cesium.Cesium3DTileset.fromIonAssetId(75343));// 定义建筑的3D样式 层次分明city.style = new Cesium.Cesium3DTileStyle({color: {// 条件判断建筑具体的颜色conditions: [['${Height} >= 300', 'rgba(45,0,75,0.5)'],['${Height} >= 200', 'rgb(102,71,151)'],['${Height} >= 100', 'rgba(170,162,204,0.5)'],['${Height} >= 50', 'rgba(224,226,238,0.5)'],['${Height} >= 25', 'rgba(252,230,200,0.5)'],['${Height} >= 10', 'rgba(248,176,87,0.5)'],["true", 'rgb(127,59,8)']]}})
-
划分城市区域并着色,区域文件 提取码:99jq
// 邻域边界的加载let neighborhoodsPromise = Cesium.GeoJsonDataSource.load('./assets/SampleData/sampleNeighborhoods.geojson');// 贴在地图表面neighborhoodsPromise.then((dataSource) => {// 将数据添加到查看器viewer.dataSources.add(dataSource);// 把数据进行着色的调整以及放到地图的表面// 拿到区域的实例 Get the array of entitieslet neighborhoodsEntities = dataSource.entities.values;for (let i = 0; i < neighborhoodsEntities.length; i++) {let entity = neighborhoodsEntities[i];// 判断存不存在相应的图形if (Cesium.defined(entity.polygon)) {entity.name = entity.properties.neighborhood;// 设置多边形颜色entity.polygon.material = Cesium.Color.fromRandom({red: 0.1,maximumGreen: 0.5,minimumBlue: 0.5,alpha: 0.6});// 设置地形着色entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;// 设置位置 贴到多边形最底下let polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;entity.position = Cesium.Ellipsoid.WGS84.scaleToGeocentricSurface(Cesium.BoundingSphere.fromPoints(polyPositions).center);// 生成标签entity.label = {text: entity.name,showBackground: true,scale: 0.6,horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,// 设置显示的距离范围distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10, 8000),// 禁用的距离disableDepthTestDistance: 100}}}})
-
-
-
效果:npm run dev运行