作者:John
MapLibreGL 调用 wfs100 GetFeature 进行空间相交查询
SuperMap iClient for Classic 已提供 WFS 1.0.0 服务的空间查询示例,其他框架也有基础查询的 Demo,但在 MapLibreGL(原MapboxGL) 上,针对 WFS 空间查询(如相交分析) 的完整示例较为欠缺。本文将以 空间相交查询(Intersects) 为例,简单介绍如何通过 SuperMap iClient for MapLibreGL 调用 WFS 1.0.0 的 GetFeature 接口实现空间分析功能。
1、iServer wfs 1.0.0 rest-api 介绍
对于使用而言首先我们需要知道SuperMap iServer 发布的 wfs 1.0.0 服务支持那些参数已经必填参数之类,请求参数详见:GetFeature 操作的主要请求参数。其过滤参数 Filter 支持 DWithin、Beyond、Contains、Crosses、Disjoint、Intersects、Distance 等,请参见 FilterType。目前不支持 FeatureId、Function、Geometry。过滤参数示例详见: WFS 1.0.0 GetFeature FILTER 过滤器示例

2、相关包引入
因为需要调用接口,除了需要 iClient for MapLibreGL ,还需要用到 ajax,文章使用使用的 Vue 框架。
下载包
npm install @supermapgis/iclient-maplibregl -S
npm install axios -S
引入
import maplibregl from 'maplibre-gl';
import axios from 'axios';
3、简单 geometry 转 GML
因为需要进行空间相交查询操作,wfs 1.0.0 的 GetFeature 需要传入 gml 格式的 geometry对象,文中就针对简单的几何点、线、面对象进行转 gml 格式单独剔除做一个方法便于使用。
geoJsonToGml(geojson, srsName = 'EPSG:4326') {
if(!geojson)
return null
const { type, coordinates } = geojson;
switch (type) {
case 'Point':
return `<gml:Point srsName="${srsName}"><gml:coordinates>${coordinates.join(',')}</gml:coordinates></gml:Point>`;
case 'LineString':
return `<gml:LineString srsName="${srsName}"><gml:coordinates>${coordinates.map(c => c.join(',')).join(' ')}</gml:coordinates></gml:LineString>`;
case 'Polygon':
return `<gml:Polygon srsName="${srsName}"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>${coordinates[0].map(c => c.join(',')).join(' ')}</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>`;
default:
throw new Error(`Unsupported geometry type: ${type}`);
}
}
4、封装 wfs 1.0.0 GetFeature (Post)请求
wfs 1.0.0 的 GetFeature 支持 Get 和 Post 请求,但是针对复杂空间查询请求通常以 XML 格式发送空间查询条件,就需要将请求体进行封装成 xml 格式。
WFS100GetFeatureParameter2xml(outputFormat, typeName, PropertyName, srsName, geojson) {
if(!(typeName && typeName && geojson))
return null
let xmlstr = `<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs"
xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"
service="WFS" version="1.0.0" `
if (outputFormat && outputFormat === 'json')
xmlstr = `${xmlstr}outputFormat="json"`
else {
console.log(`Unsupported outputFormat type: ${WFS100GetFeatureParameter.OUTPUTFORMAT},use default type "GML2"`)
}
xmlstr = `${xmlstr}><wfs:Query typeName="${typeName}"><ogc:Filter><ogc:Intersects><ogc:PropertyName>${PropertyName}</ogc:PropertyName>`
let tmp = geoJsonToGml(geojson, srsName)
xmlstr = `${xmlstr}${tmp}</ogc:Intersects></ogc:Filter></wfs:Query></wfs:GetFeature>`
retrun xmlstr
}
5、测试验证
data(){
return {
map: null,
basemapurl: "http://127.0.0.1:8090/iserver/services/map-World/rest/maps/World/zxyTileImage.png?z={z}&x={x}&y={y}",
wfsserverurl:"http://127.0.0.1:8090/iserver/services/data-World/wfs100"
}
},
// wfs 空间相交查询
this.map = new maplibregl.Map({
container: 'map',
style: {
"version": 8,
"sources": {
"raster-tiles": {
"type": "raster",
"tiles": [this.basemapurl],
"tileSize": 256
}
},
"layers": [{
"id": "simple-tiles",
"type": "raster",
"source": "raster-tiles",
"minzoom": 0,
"maxzoom": 22
}]
},
center: [120.143, 30.236],
zoom: 3
});
let Polygon = {
type: "Polygon",
coordinates: [[
[90, 30],
[110, 30],
[110, 40],
[90, 40],
[90, 30]
]]
};
this.map.addLayer({
"id": "queryPolygon",
"source": {
"type": "geojson",
"data": {
"type": "Feature",
"geometry": Polygon
}
},
"type": "fill",
"paint": {
"fill-color": "green",
"fill-opacity": 0.2
},
});
const xmlparams = this.wfs100GetFeatureParameter2xml("json", "World:Countries", "", "EPSG:4326", Polygon);
let _this = this
axios.post(this.wfsserverurl, xmlparams).then( res => {
console.log(res.data)
_this.map.addSource("wfsqueryDatas", {
"type": "geojson",
"data": res.data
});
_this.map.addLayer({
"id": "wfsqueryDatas",
"type": "fill",
"source": "wfsqueryDatas",
"paint": {
"fill-color": "red",
"fill-opacity": 0.8
}
});
})


507

被折叠的 条评论
为什么被折叠?



