公司项目中需要加载图层获取要素信息,折腾了好久,做个备份吧,如有不对,请批评指正!
在探索过程中,一共找到了四种方法,下面一一叙述。(个人觉得第四种最好)
一、加载WMS图层,并获取要素信息(很容易但是效率低)
这主要是使用Cesium加载wms服务,并使用Cesium的pickImageryLayerFeature函数获取要素信息,代码十分简单,但是加载wms的效率比wmts效率低
var wmsImageryProvider = new Cesium.WebMapServiceImageryProvider({
url:"",//服务地址,到wmsserver
layers: "000",//图层名
rectangle:Cesium.Rectangle.fromDegrees(118.08795779022113,39.55685670605424,118.22210080995278,39.63972903104975),//服务的经纬度区间
parameters:{
transparent: false,
format: "image/jpeg",
srs: "EPSG:4326",
//style: "",
},
getFeatureInfoParameters:{
request: "GetFeatureInfo"
}
})
let layer = viewer.imageryLayers.addImageryProvider(wmsImageryProvider);
var hander = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
hander.setInputAction(async function (event) {
viewer.selectedEntity = undefined;
var pickRay = viewer.camera.getPickRay(event.position);
var featurePromise = await viewer.imageryLayers.pickImageryLayerFeatures(pickRay,viewer.scene);
},Cesium.ScreenSpaceEventType.LEFT_CLICK);
二、加载wms和wmts两个图层(比较鸡肋比较智障的想法)
既然wms效率低,wmts效率高,那就想着干脆加两个,wms给应隐藏了(当时wmts获取不了属性,我又不知道怎么用js从wms获取要素信息)。
那么直接将透明度设为0,测试发现将图层layer的show改变是不起作用的
layer.alpha = 0;
三、加载wmts图层,采用wfs获取要素信息
需要查看服务内经纬度对应哪一个字段
test2(){
var wfsurl = '.../MapServer/WFSServer'//服务地址
var param = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName:'',//图层名
}
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
var ellipsoid = viewer.scene.globe.ellipsoid;
var th = this
handler.setInputAction(function (movement) {
var cartesian = viewer.camera.pickEllipsoid(movement.position,ellipsoid);
if(cartesian){
var cartographic = ellipsoid.cartesianToCartographic(cartesian);
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
var point = longitudeString+','+latitudeString;
th.queryWFSByPoint(wfsurl,point,param.typeName);
}
},Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
queryWFSByPoint(wfsurl,point,typeName){
var filter = '<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">';
filter += '<Intersects>';
filter += '<PropertyName>the_geom</PropertyName>';
filter += '<gml:Point>';
filter += '<gml:coordinates>' + point + '</gml:coordinates>';
filter += '</gml:Point>';
filter += '</Intersects>';
filter += '</Filter>';
var param = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: typeName,
filter: filter,
}
axios({
url: wfsurl+this.getParamString(param,wfsurl),
async: true,
type: 'GET',
})
},
getParamString(obj,existingUrl,uppercase){
var params = [];
for(var i in obj){
params.push(encodeURIComponent(uppercase?i.toUpperCase():i)+'='+encodeURIComponent(obj[i]));
}
return ((!existingUrl||existingUrl.indexOf('?')===-1)?'?':'&')+params.join('&');
},
四、加载wmts采用wms获取要素信息
加载wmts的方法就不在这说了,可以看我之前的博客,这里只说要素 信息,比较坑的是,这是在你点击的位置的经纬度附近,设置一个偏移量,在这里我设置的0.0003,这个值可以根据自己项目,进行调试,选择一个合适的值,那么经度-0.0003,经度+0.0003,纬度也是,这样构成了一个矩形,width、height、x、y分别是假如这个矩形的像素是width宽,height高,那么点击位置距离矩形左上角的像素距离x、y。这样做的目的是为了适应不同的坐标系。(但属实在这折腾了一两天),在这里因为我上下左右偏移的量是一样的,经过几次求取,发现我的xy都是128,所有就直接写了
test3(){
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
var ellipsoid = viewer.scene.globe.ellipsoid;
var th = this
handler.setInputAction(function (movement) {
var cartesian = viewer.camera.pickEllipsoid(movement.position,ellipsoid);
if(cartesian){
var cartographic = ellipsoid.cartesianToCartographic(cartesian);
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
//通过经纬度画一个矩形,x,y为以矩形左上角为原点,点击位置的屏幕坐标,通过计算发现,采用wgs84坐标系,width256,height256,点击点往往在中心128,128
/* var change = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, new Cesium.Cartesian3((longitudeString-0.0003),(latitudeString+0.0003),0));
var changex = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, new Cesium.Cartesian3(longitudeString,latitudeString,0));
var changep = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, new Cesium.Cartesian3((longitudeString+0.0003),(latitudeString-0.0003),0));
var X = (change.x-changex.x)*256/(change.x-changep.x)
var Y = (change.y-changex.y)*256/(change.y-changep.y)
console.log(change,movement.position,changex,changep,X,Y)*/
var wfsurl = '.../MapServer/WMSServer?request=GetFeatureInfo&service=WMS&version=1.1.1'
var bbox = "&bbox=" + (longitudeString-0.0003) +"%2C"+(latitudeString-0.0003)+"%2C"+(longitudeString+0.0003)+"%2C"+(latitudeString+0.0003);
var end = "&x=128&y=128&width=256&height=256&srs=EPSG%3A4326&query_layers=000&info_format=application%2Fjson";
th.test4(wfsurl+bbox+end)
}
},Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
async test4(url){
var result = await axios({
url: url,
method: 'get',
})
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json(result.data);
console.log(jsonObj)
},