在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 entities let 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 entities let 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运行