3分钟,教你搭建一个三维城市建筑可视化系统 ( Cesium 加载 shp 数据 )

简单点说,三维地图可视化,就是将地理数据转换成三维立体的可视化形态,通过将具有地域特征的数据,或者数据分析结果,形象地表现在三维地图上,使得用户可以更加容易理解数据规律和趋势。

通俗地讲,三维地图可视化可以将地理数据更清晰直白地展现出来。

开发前准备 

1. 城市建筑矢量数据 (.shp文件)2. 搭建一个vue + cesium 的开发环境
3. .shp 矢量数据转 GeoJson  或者 3dtiles ( 建议使用 3dtiles 来加载 ) 4. cesium 基础使用 ( 加载底图以及控件等 )
5. vue 基础 ( 本人做的所有实例都是基于vue来开发的 )

想要获取全国62个城市矢量数据以及shp转3dtiles转换工具,可以关注【 前端开发爱好者 】,后台回复 【 三维城市建筑可视化 】即可获取下载链接

先看看最终要实现的效果吧 ,是不是感觉很酷呢,赶快关注 【 前端开发爱好者 】获取资源,自己动手来尝试一下吧 !!!3分钟,教你搭建一个三维城市建筑可视化系统 ( Cesium 加载 shp 数据 )

具体环境配置以及数据转换操作和代码实现

1. 环境搭建 ( vue + cesium )


npm install cesium --save

webpack配置


// resolveresolve: {     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

2. 数据转换

    ceisum加载shp格式的建筑。有两种思路,目前推荐第二种。


   方法一:将shp格式转换为geojson格式,然后采用cesium提供的接口加载到ceisum                       中。

      严重缺陷:在面对大场景问题,即数据量较大时,非常容易卡死、崩溃


  方法二:将shp转换为3dtiles,然后加载到ceiusm中。

      3dtiles是ceisum解决大场景问题专门提供的一种数据格式。

        

        打开下载好的 shp 数据 和转换工具3分钟,教你搭建一个三维城市建筑可视化系统 ( Cesium 加载 shp 数据 )   按照图上所示,根据自己的需求来选择即可,这里除了做一些基础设置外还可以设置贴图和地形高程,在这里不做过多阐述,可自行研究

最终选择输出目录,点击确认,即可获得自己想要的 3dtiles 数据

3分钟,教你搭建一个三维城市建筑可视化系统 ( Cesium 加载 shp 数据 )想要获取全国62个城市矢量数据以及shp转3dtiles转换工具,可以关注【 前端开发爱好者 】,后台回复 【 三维城市建筑可视化 】即可获取下载链接



数据和开发环境都有了,那就直接上代码吧: 

1. 首先到官方获取 token   https://cesium.com/ion/signin/tokens 

2. 组件中设置 token 


Cesium.Ion.defaultAccessToken = "你自己的token"

    3.初始化地图,加载高德影像地图 ( 这里可以加载多种地图,比如 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}",      }),    });

   4. 加载转换好的 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);      });

   5.  这个时候建筑加载出来的还是白色, 为了效果可以加点色 (根据建筑物高度设置不同的颜色,也可以根据经纬度来设置,具体查看官方实列   )

https://sandcastle.cesium.com/index.html?src=3D%20Tiles%20Feature%20Styling.html


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)"],        ],      },    });

    6. 最后来给地图加个点吧


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), //偏移      },    });






本人,某个不知名小公司的前端小菜鸡,由于技术太菜,业余时间总是喜欢捣鼓一些花里胡哨的东西,一边学习一边分享,希望能够和大家一起成长,梦想着成为一位前端大大牛。


上一篇:ES6 reduce 实现异步串行【初中级前端必会】


下一篇:25 道神奇的 javascript 示例,全答对算我输!!!