近期工作中需要使用Cesium加载各类服务,并进行点击查询。故针对不同的服务对加载方法和点击查询方法进行了整理。
一、加载方法
1.1加载WMS
export function wmsService(url,layer){
let wms=new Cesium.WebMapServiceImageryProvider({
url : url,//如'http://106.12.xxx/geoserver/xxx/wms'
layers : layer,//'数据源:图层名'
parameters: {
service : 'WMS',
format: 'image/png',//返回格式为png格式
transparent: true,
}
})
return wms;
}
//调用
let wmsservice = _this.viewer.imageryLayers.addImageryProvider(wmsService(url, layer))
1.2加载WMTS
export function wmtsService(url,layer){
let wmts=new Cesium.WebMapTileServiceImageryProvider({
url : url,//如'http://106.12.253.xxx/geoserver/xxx/service/wmts'
layer : layer,//'数据源:图层名'
style : '',
format : 'image/png',
tileMatrixSetID :'EPSG:4326',//坐标系
tileMatrixLabels :['EPSG:4326:0','EPSG:4326:1','EPSG:4326:2',
'EPSG:4326:3','EPSG:4326:4','EPSG:4326:5',
'EPSG:4326:6','EPSG:4326:7','EPSG:4326:8','EPSG:4326:9',
'EPSG:4326:10','EPSG:4326:11','EPSG:4326:12','EPSG:4326:13',
'EPSG:4326:14','EPSG:4326:15','EPSG:4326:16','EPSG:4326:17',
'EPSG:4326:18','EPSG:4326:19','EPSG:4326:20','EPSG:4326:21',],//查看geoserver,看切了几层
maximumLevel: 19,//设置最高显示层级
tilingScheme:new Cesium.GeographicTilingScheme(),//必要
});
return wmts;
}
//调用
let wmtsservice= _this.viewer.imageryLayers.addImageryProvider(wmtsService(url, layer))
1.3加载WFS
export function wfsService(url,layer){
return axios({
methods: "GET",
url: url,//如'http://106.12.253.xxx/geoserver/xxx/service/ows'
params: {
service: "WFS",
version: "1.0.0",
request: "GetFeature",
typeName: layer, //'数据源:图层名'
outputFormat: "application/json",
},
})
}
//调用
let wfsservice = wfsService(url, layer)
wfsservice.then((res) => {
let datasource=Cesium.GeoJsonDataSource.load(res.data,{
stroke: Cesium.Color.RED, // 边框颜色
strokeWidth: 3, // 边框宽度
markerColor:Cesium.Color.RED,
});
_this.viewer.dataSources.add(datasource)
二、点击查询
2.1 WMS点击查询
//点击WMS查询
clickWMSLayers () {
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas)
let _this = this
this.handler.setInputAction(async function (click) {
_this.viewer.selectedEntity = undefined
var pickRay = _this.viewer.camera.getPickRay(click.position)
var featuresPromise = await _this.viewer.imageryLayers.pickImageryLayerFeatures(pickRay, _this.viewer.scene)
if (featuresPromise[0] != null) {
_this.tableData = []
//高亮
if (featuresPromise[0].data.geometry.type == 'MultiPolygon' || featuresPromise[0].data.geometry.type == 'Polygon'
|| featuresPromise[0].data.geometry.type == 'MultiLineString') {
_this.viewer.entities.removeAll()
_this.viewer.entities.add({
id: 'polygon' + id,
name: 'glTc',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights(_this.getDegreesArrayHeights(featuresPromise[0].data, 0)),
width: 15,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1,
color: Cesium.Color.fromCssColorString('#FF4500'),
}),
clampToGround: true, //是否贴着地表
},
polygon: {
hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(_this.getDegreesArrayHeights(featuresPromise[0].data, 0))),
material: Cesium.Color.AQUA.withAlpha(0.5),
// perPositionHeight: true,
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
}
})
} else if (featuresPromise[0].data.geometry.type == 'Point') {
_this.viewer.entities.removeAll()
_this.viewer.entities.add({
id: 'point' + id,
name: 'glTc',
position: Cesium.Cartesian3.fromDegrees(_this.getDegreesArrayHeights(featuresPromise[0].data, 0)[0],
_this.getDegreesArrayHeights(featuresPromise[0].data, 0)[1], 0),
point: {
color: Cesium.Color.FUCHSIA,//修改颜色
pixelSize: 15,
disableDepthTestDistance: 5000000
},
})
}
let data = featuresPromise[0].data
let name = featuresPromise[0].name
let id = data.id
let stationSerieType = data.properties.STATIONSERIETYPE
//获取的信息加载在前端
_this.tableData.push({
id: id,
name: name,
stationSerieType: stationSerieType
})
_this.infoBoxShow = true
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
2.2 WMTS点击查询
//点击WMTS查询
clickWMTSLayers () {
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
let _this = this
this.handler.setInputAction(async function (click) {
_this.viewer.selectedEntity = undefined
var featuresPromise = await _this.viewer.imageryLayers._layers[1]._imageryProvider
let layer = featuresPromise._layer
let url = featuresPromise._resource._url
// 屏幕坐标转世界坐标
let ellipsoid = _this.viewer.scene.globe.ellipsoid
let cartesian3 = _this.viewer.camera.pickEllipsoid(click.position, ellipsoid)
//笛卡尔坐标转web墨卡托
let webMercator = cartesianToWebMercator(cartesian3)
//获取相机高度
let height = _this.viewer.camera.positionCartographic.height
//计算近似层级
let zoom = heightToZoom(height)
//查看geoserver网格集
let resolutions = [0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625,
0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 6.866455078125E-4,
3.4332275390625E-4, 1.71661376953125E-4, 8.58306884765625E-5, 4.291534423828125E-5,
2.1457672119140625E-5, 1.0728836059570312E-5, 5.364418029785156E-6, 2.682209014892578E-6,
1.341104507446289E-6, 6.705522537231445E-7, 3.3527612686157227E-7]
//查看geoserver看中点位置和分辨率
let origin = [-180, 90]
let tileSize = [256, 256]
let fx = (webMercator[0] - origin[0]) / (resolutions[zoom] * tileSize[0])
let fy = (origin[1] - webMercator[1]) / (resolutions[zoom] * tileSize[1])
let tileCol = Math.floor(fx)
let tileRow = Math.floor(fy)
let tileI = Math.floor((fx - tileCol) * tileSize[0])
let tileJ = Math.floor((fy - tileRow) * tileSize[1])
let matrixIds = ['EPSG:4326:0', 'EPSG:4326:1', 'EPSG:4326:2',
'EPSG:4326:3', 'EPSG:4326:4', 'EPSG:4326:5',
'EPSG:4326:6', 'EPSG:4326:7', 'EPSG:4326:8', 'EPSG:4326:9',
'EPSG:4326:10', 'EPSG:4326:11', 'EPSG:4326:12', 'EPSG:4326:13',
'EPSG:4326:14', 'EPSG:4326:15', 'EPSG:4326:16', 'EPSG:4326:17',
'EPSG:4326:18', 'EPSG:4326:19', 'EPSG:4326:20', 'EPSG:4326:21']
let matrixId = matrixIds[zoom]
let tile = {
col: tileCol,
row: tileRow,
I: tileI,
J: tileJ,
TILEMATRIX: matrixId
}
function heightToZoom (height) {
//固定参数,地球各个指标参
let A = 40487.57
let B = 0.00007096758
let C = 91610.74
let D = -40467.74
return Math.round(D + (A - D) / (1 + Math.pow(height / C, B)))
}
function cartesianToWebMercator (cartesian) {
// 将笛卡尔坐标转换为地理坐标(弧度)
let cartographic = Cesium.Cartographic.fromCartesian(cartesian)
//弧度转经纬度
cartographic.latitude = Cesium.Math.toDegrees(cartographic.latitude)
cartographic.longitude = Cesium.Math.toDegrees(cartographic.longitude)
/* //度转墨卡托
let earthRad = 6378137.0;
let x = ((cartographic.longitude * Math.PI) / 180) * earthRad;
let a = (cartographic.latitude * Math.PI) / 180;
let y = (earthRad / 2) * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));*/
return [cartographic.longitude, cartographic.latitude]
}
//访问
let featuresPromises = wmtsFeatureService(url, layer, tile)
featuresPromises.then((res) => {
const data = res.data
let featuresPromise = data.features
if (featuresPromise[0] != null) {
_this.tableData = []
//高亮
if (featuresPromise[0].geometry.type == 'MultiPolygon' || featuresPromise[0].geometry.type == 'Polygon'
|| featuresPromise[0].geometry.type == 'MultiLineString') {
_this.viewer.entities.removeAll()
_this.viewer.entities.add({
id: 'polygon' + id,
name: 'glTc',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights(_this.getDegreesArrayHeights(featuresPromise[0], 0)),
width: 15,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1,
color: Cesium.Color.fromCssColorString('#FF4500'),
}),
clampToGround: true, //是否贴着地表
},
polygon: {
hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(_this.getDegreesArrayHeights(featuresPromise[0], 0))),
material: Cesium.Color.AQUA.withAlpha(0.5),
// perPositionHeight: true,
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
}
})
} else if (featuresPromise[0].geometry.type == 'Point') {
_this.viewer.entities.removeAll()
_this.viewer.entities.add({
id: 'point' + id,
name: 'glTc',
position: Cesium.Cartesian3.fromDegrees(_this.getDegreesArrayHeights(featuresPromise[0], 0)[0],
_this.getDegreesArrayHeights(featuresPromise[0], 0)[1], 0),
point: {
color: Cesium.Color.FUCHSIA,//修改颜色
pixelSize: 15,
disableDepthTestDistance: 5000000
},
})
}
let name = featuresPromise[0].properties.SERIESNAME
let id = featuresPromise[0].id
let stationSerieType = featuresPromise[0].properties.STATIONSERIETYPE
_this.tableData.push({
id: id,
name: name,
stationSerieType: stationSerieType
})
_this.infoBoxShow = true
}
})
.catch((error) => {
console.log('请求失败,失败信息:' + error)
})
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
2.3 WFS点击查询
//点击WFS查询
clickWFSLayers(url,layer){
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas)
let _this = this
this.handler.setInputAction(async function (click) {
_this.tableData = []
let pick=_this.viewer.scene.pick(click.position);
if (Cesium.defined(pick)){
let featuresPromise=pick.id.properties
let name = featuresPromise._SERIESNAME._value
let id = featuresPromise._definitionChanged._scopes[0]._id
let stationSerieType = featuresPromise._STATIONSERIETYPE._value
// console.log(featuresPromise._definitionChanged._scopes[0]._polyline._positions._value) //获取要素坐标
_this.tableData.push({
id: id,
name: name,
stationSerieType: stationSerieType
})
_this.infoBoxShow = true
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
*********设置要素点击高亮效果的函数
//高亮函数
getDegreesArrayHeights (feature, height) {
let newHeight = height
let degreesArrayHeights = []
let coordinates
if (feature.geometry.type == 'MultiPolygon') {
coordinates = feature.geometry.coordinates[0][0]
//坐标串转为需要的格式[x,y,z,x,y,z....]
for (let i = 0; i < coordinates.length; i++) {
const element = coordinates[i]
degreesArrayHeights.push(element[0])
degreesArrayHeights.push(element[1])
degreesArrayHeights.push(newHeight)
}
} else if (feature.geometry.type == 'Polygon') {
coordinates = feature.geometry.coordinates[0]
//坐标串转为需要的格式[x,y,z,x,y,z....]
for (let i = 0; i < coordinates.length; i++) {
const element = coordinates[i]
degreesArrayHeights.push(element[0])
degreesArrayHeights.push(element[1])
degreesArrayHeights.push(newHeight)
}
} else if (feature.geometry.type == 'MultiLineString') {
coordinates = feature.geometry.coordinates[0]
//坐标串转为需要的格式[x,y,z,x,y,z....]
for (let i = 0; i < coordinates.length; i++) {
const element = coordinates[i]
degreesArrayHeights.push(element[0])
degreesArrayHeights.push(element[1])
degreesArrayHeights.push(newHeight)
}
} else if (feature.geometry.type == 'Point') {
degreesArrayHeights.push(feature.geometry.coordinates[0])
degreesArrayHeights.push(feature.geometry.coordinates[1])
degreesArrayHeights.push(newHeight)
}
return degreesArrayHeights
},