网络地图服务 (WMS) 、网络地图切片服务 (WMTS) ,根据用户的请求返回相应的地图(包括PNG,GIF,JPEG等栅格形式或者是SVG和WEB CGM等矢量形式)。
下面是常见的geoserver发布的图层格式,有矢量图层(点、线、面),或栅格图层(具体概念不再赘述)
不论是WMS或者是WMTS,大部分请求回的是图片格式,所以我们没有办法直接获取到当前点击点的信息,但实际工作中,我们经常要查看某一点的具体信息,比如下图,我们想要查看影像图的像元信息
核心一:借助WFS、点与面的相交,获取信息
点/线图层----核心是围绕当前点构造缓冲区与判断是否与图层点相交
围绕点击点构造缓冲区 geom
let polygonGeom = null
let pixel = this.map.getPixelFromCoordinate(mapEvt.coordinate);//获取点击点的x,y坐标
let bufPixel = 10; //缓冲距离
let p1 = [pixel[0] - bufPixel, pixel[1] - bufPixel];
let p2 = [pixel[0] + bufPixel, pixel[1] - bufPixel];
let p3 = [pixel[0] + bufPixel, pixel[1] + bufPixel];
let p4 = [pixel[0] - bufPixel, pixel[1] + bufPixel];
polygonGeom = new Polygon([([
[
this.map.getCoordinateFromPixel(p1),
this.map.getCoordinateFromPixel(p2),
this.map.getCoordinateFromPixel(p3),
this.map.getCoordinateFromPixel(p4),
this.map.getCoordinateFromPixel(p1),
],
])]); //构造缓冲区
面图层-----核心就是判断点击点与图层面是否相交
点击点的geom
let pointGeom = new Point(mapEvt.coordinate);
核心二、借助ECQL中的相交函数INTERSECTS
1、先将geom转为wkt格式
//如果是点/线 图层就是
let wkt = new WKT().writeGeometry(polygonGeom) //构造的缓冲区
// 如果是面图层就是
let wkt = new WKT().writeGeometry(pointGeom)
2、利用INTERSECTS 构造cql_filter
//INTERSECTS用法,第一个字段是数据库表中的空间字段,第二个就是一个wkt字符串
INTERSECTS(the_geom'', wkt)
核心三、发送wfs请求
下面是封装好的wfs请求函数
/**
接收一个对象,对象里面的参数支持
url(必传)
layername (必传) bincheng:gis_xjqy
cql(非必传)
propertyname:需要返回的字段,参数是以逗号分割的字符串(默认返回全部)
**/
export function wfsQuery(obj = {}) {
const { url, layername, cql, propertyname,srsName='EPSG:4326' } = obj
return new Promise((resolve, reject) => {
let featureRequest = {
service: "WFS",
version: "1.0.0",
request: "GetFeature",
srsName,
typename: layername,
outputFormat: "application/json",
};
if (cql) featureRequest.CQL_FILTER = cql
if (propertyname) featureRequest.PROPERTYNAME = propertyname
let fetchUrl = ''
fetchUrl = `${url}${url.indexOf("?") > -1 ? '&' : '?'}${formateObjToParamStr(featureRequest)}`
fetch(fetchUrl, {
method: 'GET',
headers: new Headers({
'Accept': 'application/json;charset=utf-8',
'Content-Type': 'application/x-www-form-urlencoded'
}),
mode: "cors"
})
.then(function(response) {
return response.json();
}).then(json => {
resolve(json)
}).catch((err) => {
reject(err)
})
})
}
export function formateObjToParamStr(paramObj) {
const params = new URLSearchParams();
for (let attr in paramObj) {
params.append(attr, paramObj[attr]);
}
return params.toString();
}
使用
wfsQuery({
layername:'test:cjqy',
url:`http://localhost:8010/geoserver/wfs`,
cql:`INTERSECTS(the_geom'',${wkt})`
}).then(res => {
console.log(res) //查询结果
})
栅格图层查像元信息,主要借助的是getFeatureInfoUrl
调用代码
var viewResolution = this.map.getView().getResolution();
let url = this.layer.getSource().getFeatureInfoUrl(e.coordinate, viewResolution, this.projection || "EPSG:4326", {
INFO_FORMAT: "application/json",
})
if(url){
fetch(url).then(function (res) {
return res.text(); //返回Promise
}).then((data) => {
let objData = JSON.parse(data);
// let info = objData.features[0].properties.GRAY_INDEX;
console.log(objData)
});
}
//wfsQuery函数,上面已经有了,这里不再重复写了
/*
coordinate:坐标点
wfsUrl:wfs地址
srs: 投影坐标系
type类型,接收(Point/PolyLine/Polygon/tiff)
shape(string|null): 空间字段,如果是矢量图层,则需要传,默认the_geom, 栅格图层传null即可
layername: 图层
*/
queryclickinfo({ coordinate, type, wfsUrl, shape, layername, srs }) {
return new Promise((resolve, reject) => {
{
if (type == "tiff") {
var viewResolution = this.map.getView().getResolution();
let url = this.layer
.getSource()
.getFeatureInfoUrl(
e.coordinate,
viewResolution,
srs || "EPSG:4326",
{
INFO_FORMAT: "application/json",
}
);
if (url) {
fetch(url)
.then(function (res) {
return res.text(); //返回Promise
})
.then((data) => {
let objData = JSON.parse(data);
// let info = objData.features[0].properties.GRAY_INDEX;
resolve(objData);
})
.catch((err) => reject(err));
}
}
let geom, wkt;
if (type == "Point" || type == "PolyLine") {
let pixel = this.map.getPixelFromCoordinate(coordinate); //获取点击点的x,y坐标
let bufPixel = 10; //缓冲距离
let p1 = [pixel[0] - bufPixel, pixel[1] - bufPixel];
let p2 = [pixel[0] + bufPixel, pixel[1] - bufPixel];
let p3 = [pixel[0] + bufPixel, pixel[1] + bufPixel];
let p4 = [pixel[0] - bufPixel, pixel[1] + bufPixel];
geom = new Polygon([
[
[
this.map.getCoordinateFromPixel(p1),
this.map.getCoordinateFromPixel(p2),
this.map.getCoordinateFromPixel(p3),
this.map.getCoordinateFromPixel(p4),
this.map.getCoordinateFromPixel(p1),
],
],
]); //构造缓冲区
}
if (type == "Polygon") {
geom = new Point(coordinate);
}
if (geom) wkt = new WKT().writeGeometry(geom);
if (wkt) {
this.wfsQuery({
layername,
url: wfsUrl,
cql: `INTERSECTS(${shape},${wkt})`,
})
.then((res) => {
resolve(res);
})
.catch((err) => reject(err));
}
}
});
}
返回结果如下