vue中使用Cesium加载shp文件、wms服务、WMTS服务问题
作者:愿为浪漫渡此劫
这篇文章主要介绍了vue中使用Cesium加载shp文件、wms服务、WMTS服务问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
如何在vue中使用Cesium加载shp文件或者说是wms服务
背景:企业项目在管理界面可以上传shp数据文件集合,需要在用户界面可视化展示
注意: Cesium是不能直接加载shp数文件的
所以需要后端将上传的shp数据转成WMS服务,这样Cesium就可以加载WMS服务来可视化shp数据了
注意后端接口必须返回以下关于WMS服务的参数
- 工作空间 share:xxxx,用于Cesium加载wms服务的图层
- srs : 用于Cesium加载wms服务的srs属性
- wms服务地址 : 类似 http://localhost:8080/geoServer/wms
- 四个坐标xmin,ymin和xmax,ymax : 用于定位WMS地图的位置
Vue初始化Cesium
前提: Vue使用Cesium处理npm,还需要在Webpack文件配置,详情可看上期文章
// 初始化 <template> // 地图容器 <div class="img-box" id="cesiumContainer"></div> </template> <script> export default { props: ["fileUrl","srs","workspace","zb"], data() { return { viewer: {}, Cesium: {}, highlightColor: null, normalColor: null, wmsLayer : null // wms 地图服务图层 }; }, methods: { // init : 初始化Cesium init() { const Cesium = this.cesium; this.highlightColor = Cesium.Color.GREEN.withAlpha(0.6); this.normalColor = Cesium.Color.YELLOW.withAlpha(0.6); this.viewer = new Cesium.Viewer("cesiumContainer", { //先行禁止infoBox弹出 selectionIndicator: false, infoBox: false, //baseLayerPicker : false, geocoder: false, homeButton: false, sceneModePicker: false, fullscreenButton: false, navigationHelpButton: false, animation: false, timeline: false, fulllscreenButtond: false, vrButton: false, // getImageryProviderArr和getTerrainProviderViewModelsArr 可根据项目需求进行实现 //获取或设置可用于图像选择的ProviderViewModel实例数组。 imageryProviderViewModels: this.getImageryProviderArr(), // //获取或设置可用于地形选择的ProviderViewModel实例数组。 terrainProviderViewModels: this.getTerrainProviderViewModelsArr(), }); this.viewer._cesiumWidget._creditContainer.style.display = "none"; // 隐藏版权 }, getImageryProviderArr() { const Cesium = this.cesium; return [ new Cesium.ProviderViewModel({ //图层的名称。 name: "影像底图", //显示项目被隐藏的工具提示 tooltip: "影像底图", //代表图层的图标 iconUrl: require("@/assets/img/yxdt.png"), //一个函数或命令,用于创建一个或多个提供程序,这些提供程序将在选择此项目时添加到地球仪中。 creationFunction: function () { return new Cesium.ArcGisMapServerImageryProvider({ url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", }); }, }), new Cesium.ProviderViewModel({ //图层的名称 name: "电子地图", //显示项目被隐藏的工具提示 tooltip: "电子地图", //代表图层的图标 iconUrl: require("@/assets/img/sldt.png"), //一个函数或命令,用于创建一个或多个提供程序,这些提供程序将在选择此项目时添加到地球仪中 creationFunction: function () { return new Cesium.ArcGisMapServerImageryProvider({ url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", }); }, }), ]; }, getTerrainProviderViewModelsArr() { const Cesium = this.cesium; return [ new Cesium.ProviderViewModel({ //图层的名称 name: "无地形", //显示项目被隐藏的工具提示 tooltip: "WGS84标准球体", //代表图层的图标 iconUrl: require("@/assets/img/WGS84.png"), //一个函数或命令,用于创建一个或多个提供程序,这些提供程序将在选择此项目时添加到地球仪中 creationFunction: function () { return new Cesium.EllipsoidTerrainProvider({ ellipsoid: Cesium.Ellipsoid.WGS84, }); }, }), new Cesium.ProviderViewModel({ //图层的名称 name: "地形", //显示项目被隐藏的工具提示 tooltip: "STK在线地形", //代表图层的图标 iconUrl: require("@/assets/img/STK在线地形.png"), //一个函数或命令,用于创建一个或多个提供程序,这些提供程序将在选择此项目时添加到地球仪中 creationFunction: function () { return new Cesium.CesiumTerrainProvider({ url: Cesium.IonResource.fromAssetId(1), requestWaterMask: !0, requestVertexNormals: !0, }); }, }), ]; }, }, }; </script>
加载WMS服务
// 加载geoserver wms服务 addWMS(fileUrl) { // 删除之前的wms 图层 // 这块移除图层 需要指出图层变量名 this.viewer.imageryLayers.remove(this.wmsLayer); this.wmsLayer = null; const Cesium = this.cesium; if(this.zb.xmin) { var provider = new Cesium.WebMapServiceImageryProvider({ url : fileUrl, // wms服务地址 // layers 必须参数,不写会报错; // layers写的不对会报如下错误: An error occered in "WebMapServiceImageryProvider": // Failed to obtain image tile X : 425y (有的博客说这是跨域????) // 后端API接口返回 layers: this.workspace, // 必须参数rectangle : 用来定位加载的WMS位置 后端API接口返回 rectangle: Cesium.Rectangle.fromDegrees( +this.zb.xmin, +this.zb.ymin, +this.zb.xmax, +this.zb.ymax), // 必须有 parameters: { service : 'WMS', format: 'image/png', transparent: true, // 后端API接口返回的 srs: this.srs, } }); // 加载WMS服务到viewer this.wmsLayer = this.viewer.imageryLayers.addImageryProvider(provider); // 飞入动画 this.viewer.flyTo(this.wmsLayer, { duration: 2 }); } else { this.$message.warning('该地图服务没有坐标可以定位') }
加载WMTS服务
对与url 属性: 很多博客都说要进行 如下拼接:
后端返回的wmts/rest/{layer}/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format=image/png
其实不用拼接 只需要后端返回的/wtms路径即可
// 加载geoserver wmts服务 addWMTS(fileUrl) { const Cesium = this.cesium; let provider = new Cesium.WebMapTileServiceImageryProvider({ // 对与url 很多博客都说要进行 如下拼接 // 后端返回的wmts/rest/{layer}/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format=image/png // 其实不用拼接 只需要后端返回的/wtms路径即可 url: fileUrl, //服务地址 服务地址只需要后端返回的 /WMTS 不需要给后面拼接任何东西, layer: this.workspace, //图层名称 : "pucheng:satellite" style: '', format: 'image/png', tileMatrixSetID: this.srs, // "EPSG:900913" // 地图飞入 定位的坐标 后端返回的数据 rectangle: Cesium.Rectangle.fromDegrees( +this.zb.xmin, +this.zb.ymin, +this.zb.xmax, +this.zb.ymax), // 必须加 不然地图出不来 //之所以要在这里提出这个tileMatrixLabels参数,是因为GeoServer在缓冲切分瓦片时对每一个缩放级别的存储目录没有使用相应的数字,而使用了网格+级别的方式来命名,如“EPSG:9100913:10”表示的是使用“EPSG:9100913”网格切分的第10级瓦片。 tileMatrixLabels : [`${this.srs}:0`,`${this.srs}:1`, `${this.srs}:2`,`${this.srs}:3`,`${this.srs}:4`,`${this.srs}:5`,`${this.srs}:6`, `${this.srs}:7`,`${this.srs}:8`,`${this.srs}:9`,`${this.srs}:10`,`${this.srs}:11`,`${this.srs}:12`,`${this.srs}:13`,`${this.srs}:14`, `${this.srs}:15`,`${this.srs}:16`,`${this.srs}:17`,`${this.srs}:18`, ], // 必须加 不然地图出不来 tilingScheme: new Cesium.GeographicTilingScheme({//此处很重要,很重要。。。 numberOfLevelZeroTilesX: 2, numberOfLevelZeroTilesY: 1 }), // tilematrixset: this.srs, // maximumLevel: 18, }); let layer = this.viewer.imageryLayers.addImageryProvider(provider); //控制图层显示 this.viewer.flyTo(layer, { duration: 2 }); },
cesium加载shp格式的白模建筑
ceisum加载shp格式的建筑。有两种思路,目前推荐第二种。
方法一
将shp格式转换为geojson格式,然后采用cesium提供的接口加载到ceisum中。
严重缺陷:在面对大场景问题,即数据量较大时,非常容易卡死、崩溃
方法二
将shp转换为3dtiles,然后加载到ceiusm中。
3dtiles是ceisum解决大场景问题专门提供的一种数据格式。
关键:转换工具,我使用的是cesiumLab,比较好用,工具中需要加载dem,目测是用来与地形贴合的。
推荐方法:方法二。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。