小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
三维地图可视化,就是将地理数据转换成
三维立体的可视化形态,通过将具有地域特征的数据,或者数据分析结果,形象地表现在三维地图上,使得用户可以更加容易理解数据规律和趋势。
通俗地讲,三维地图可视化可以将地理数据更清晰直白地展现出来。
开发前准备
城市建筑矢量数据(.shp 文件)- 搭建一个
vue + cesium的开发环境 .shp矢量数据转GeoJson或者3dtiles( 建议使用 3dtiles 来加载 )cesium基础使用 ( 加载底图以及控件等 )vue基础 ( 本人做的所有实例都是基于 vue 来开发的 )
具体环境配置以及数据转换操作和代码实现
环境搭建 ( vue + cesium )
npm install cesium --save
webpack 配置
// resolve
resolve: {
alias: {
cesium: path.resolve(__dirname, '../node_modules/cesium/Source')
}
},
// plugins
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
// Copy Cesium Assets, Widgets, and Workers to a static directory
new CopyWebpackPlugin([ { from: path.join('node_modules/cesium/Source', '../Build/Cesium/Workers'), to: 'Workers' } ]),
new CopyWebpackPlugin([ { from: path.join('node_modules/cesium/Source', 'Assets'), to: 'Assets' } ]),
new CopyWebpackPlugin([ { from: path.join('node_modules/cesium/Source', 'Widgets'), to: 'Widgets' } ]),
new webpack.DefinePlugin({
// Define relative base path in cesium for loading assets
CESIUM_BASE_URL: JSON.stringify('')
})
],
组件内引入
import Cesium from 'cesium/Cesium'
import 'cesium/Widgets/widgets.css'
至此,基本环境已经搭建完成, 下一步 把准备好的 shp 数据转换成 3dtiles
数据转换
ceisum 加载 shp 格式的建筑。有两种思路,目前推荐第二种。
-
方法一:将 shp 格式转换为 geojson 格式,然后采用 cesium 提供的接口加载到 ceisum 中。 -
严重缺陷:在面对大场景问题,即数据量较大时,非常容易卡死、崩溃
-
方法二:将 shp 转换为 3dtiles,然后加载到 ceiusm 中。
3dtiles 是 ceisum 解决大场景问题专门提供的一种数据格式。
打开下载好的 shp 数据 和转换工具
按照图上所示,根据自己的需求来选择即可,这里除了做一些基础设置外还可以设置贴图和地形高程,在这里不做过多阐述,可自行研究
最终选择输出目录,点击确认,即可获得自己想要的 3dtiles 数据
数据和开发环境都有了,那就直接上代码吧:
-
首先到官方获取 token
https://cesium.com/ion/signin/tokens -
组件中设置
token
Cesium.Ion.defaultAccessToken = "你自己的 token"
- 初始化地图,加载高德影像地图 ( 这里可以加载多种地图,比如 mapbox Google 地图 天地图 等,本实列加载的是高德 )
var viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: Cesium.createWorldTerrain({
// required for water effects
requestWaterMask: true,
// required for terrain lighting
requestVertexNormals: true,
}),
animation: true, //是否显示动画控件
animation: false, //是否显示动画控件
scene3DOnly: true,
baseLayerPicker: false, //是否显示图层选择控件
geocoder: true, //是否显示地名查找控件
timeline: true, //是否显示时间线控件
sceneModePicker: true, //是否显示投影方式控件
navigationHelpButton: false, //是否显示帮助信息控件
infoBox: true, //是否显示点击要素之后显示的信息
// 加载高德影像地图
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url:
"https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
}),
});
- 加载转换好的 3dtiles 数据
3dtiles 数据最好是本地启个服务去加载,最简单的方式就是 vscode live server
var palaceTileset = new Cesium.Cesium3DTileset({
url: "http://127.0.0.1:5501/tileset.json",
});
viewer.scene.primitives.add(palaceTileset);
palaceTileset.readyPromise
.then(function (tileset) {
viewer.scene.primitives.add(tileset);
viewer.zoomTo(
tileset,
new Cesium.HeadingPitchRange(
0.5,
-0.2,
tileset.boundingSphere.radius * 1.0
)
);
})
.otherwise(function (error) {
console.log(error);
});
- 这个时候建筑加载出来的还是白色, 为了效果可以加点色 (根据建筑物高度设置不同的颜色,也可以根据经纬度来设置)
palaceTileset.style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [
["${Floor} >= 300", "rgba(45, 0, 75, 0.5)"],
["${Floor} >= 200", "rgba(102, 71, 151,0.5)"],
["${Floor} >= 100", "rgba(45, 0, 75, 0.5)"],
["${Floor} >= 50", "rgba(102, 71, 151,0.5)"],
["${Floor} >= 25", "rgba(252, 230, 200,0.5)"],
["${Floor} >= 10", "rgba(248, 176, 87,0.5)"],
["${Floor} >= 5", "rgba(198, 106, 11,0.5)"],
["true", "rgb(127, 59, 8)"],
],
},
});
- 最后来给地图加个点吧
let entity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(118.78, 32.07, 20.61),
point: {
color: Cesium.Color.RED, //点位颜色
pixelSize: 10, //像素点大小
},
label: {
// text : '测试名称',
font: "14pt Source Han Sans CN", //字体样式
fillColor: Cesium.Color.BLACK, //字体颜色
backgroundColor: Cesium.Color.AQUA, //背景颜色
showBackground: true, //是否显示背景颜色
style: Cesium.LabelStyle.FILL, //label 样式
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.CENTER, //垂直位置
horizontalOrigin: Cesium.HorizontalOrigin.LEFT, //水平位置
pixelOffset: new Cesium.Cartesian2(10, 0), //偏移
},
});
写在最后
公众号:前端开发爱好者专注分享web前端相关技术文章、视频教程资源、热点资讯等,如果喜欢我的分享,给 🐟🐟 点一个赞👍 或者关注➕ 都是对我最大的支持。