背景:企业项目在管理界面可以上传shp数据文件集合,需要在用户界面可视化展示
注意: Cesium是不能直接加载shp数文件的
所以需要后端将上传的shp数据转成WMS服务,这样Cesium就可以加载WMS服务来可视化shp数据了
注意后端接口必须返回以下关于WMS服务的参数
前提: Vue使用Cesium处理npm,还需要在Webpack文件配置,详情可看上期文章
基于Vue的Cesium配置
// 初始化
<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>
// 加载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('该地图服务没有坐标可以定位')
}
对与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
});
},