ArcGIS for JS 、Supermap for WebGL+ iServer和OpenLayer+Geoserver的查询方式;
ArcGIS for JS 查询API官方介绍得已经十分清楚,并且有很多相关的Sample Code,所以在此只介绍介绍一下多个FeatureLayer图层的属性和空间查询。
主要使用FeatureLayer.queryFeatures(query, options),Query类,以及dojo/promise/all
Query类定义了查询细节,包括空间查询条件和属性查询条件。
执行FeatureLayer.queryFeatures(query, options)会返回一个异步对象promise,将多个promise放入数组,使用promise/all等待每个图层的查询执行完毕后返回查询结果。
代码:
import Query = require('esri/tasks/support/Query');
import All = require('dojo/promise/all');
const layers = this.sceneView.map.allLayers;
const query = new Query();
query.geometry = geometry;//空间查询条件
//query.where = "STATE_NAME = 'Washington'";//属性查询条件
query.returnGeometry = true;
query.spatialRelationship = 'intersects';
query.outFields = ["*"];//返回字段
let tableresulte = [];
let allpromise = [];//查询异步对象数组
layers.forEach((layer: __esri.FeatureLayer) => {
const promise = layer.queryFeatures(query);//图层查询异步对象
allpromise.push(promise);
})
All(allpromise).then((result) => {
result.forEach(item => {
if (item.features.length > 0) {
tableresulte.push({ "layer": item.features[0].layer, "features": item.features });
}
})
})
超图 supermap for webgl ,基于Cesium开源框架。进行多图层的属性和空间查询。iServer版本为10i。
超图的关于三维数据服务的查询就不介绍了。官方例子很清楚了。
http://support.supermap.com.cn:8090/webgl/examples/examples.html#search-attribute-search
但是三维数据服务返回的查询结果没有根据图层分离。因此,使用三维数据对应的二维数据的地图服务进行多图层的属性和空间查询。iServer服务接口API地址:https://iclient.supermap.io/libs/iclient8c/apidoc/files/SuperMap/REST-js.html
代码:
//针对地图服务的查询
function queryMapByGeometryAndAttributes(options: {
url: string,
mapNames: string[],//图层名称
geometry: SuperMap.Geometry.Polygon,//查询空间范围
sql?: string,//属性查询条件
groupBy?: string,
orderBy?: string,
queryOption?: SuperMap.REST.QueryOption,
spatialMode?:SuperMap.REST.SpatialQueryMode//空间关系
fields?: string[],
completed: Function,//成功回调函数
failed: Function//失败回调函数
}) {
let filterParams = [];
filterParams = options.mapNames.map(item => {
return new SuperMap.REST.FilterParameter({//查询过滤条件参数类,多个图层对应多个
name: item,
attributeFilter: options.sql,
groupBy: options.groupBy,
orderBy: options.orderBy,
fields: options.fields
});
});
//Geometry 查询参数类
const geoParams = new SuperMap.REST.QueryByGeometryParameters({
geometry: options.geometry,
queryParams: filterParams,
returnContent: true,
spatialQueryMode: !options.spatialMode?SuperMap.REST.SpatialQueryMode.INTERSECT:options.spatialMode,
queryOption: !options.queryOption ? SuperMap.REST.QueryOption.ATTRIBUTEANDGEOMETRY : options.queryOption
});
//Geometry 查询服务类
const queryService = new SuperMap.REST.QueryByGeometryService(options.url, {
eventListeners: {
processCompleted: options.completed,
processFailed: options.failed
}
});
queryService.processAsync(geoParams);
}
//cesium笛卡尔坐标转超图查询服务类所需类型(geometry)
function convert(points:array){
const spPoints=[];
for(let i = 0,j = points.length;i < j;i++){
const lonlatPoint = Cesium.Cartographic.fromCartesian(point);
//注意geometry地理坐标系需要与地图服务的地理坐标系保持一直,这里为WGS84
const x = Cesium.Math.toDegrees(lonlatPoint.longitude);
const y = Cesium.Math.toDegrees(lonlatPoint.latitude);
const point=new SuperMap.Geometry.Point(x,y);
spPoints.push(point);
}
const linearRing = new SuperMap.Geometry.LinearRing(spPoints);
return new SuperMap.Geometry.Polygon(linearRing);
}
若只需要进行属性查询,可使用QueryBySQLService查询类。
目前使用的是supermap for leaflet。官方案例:https://iclient.supermap.io/examples/leaflet/editor.html#04_bufferAnalystService_geometry
也可直接使用iServer中的空间分析服务中的buffer方法。
http://www.supermapol.com/realspace/services/spatialanalyst-changchun/restjsr/spatialanalyst/geometry/buffer
版本:OpenLayers:6.2.1;Geoserver:2.12.3
1、针对WFS服务的多图层空间查询:使用Geoserver的Filter Encoding Language
geoserver支持的过滤语言:https://docs.geoserver.org/stable/en/user/filter/syntax.html
使用了openlayers的ol/format/WFS,ol/format/filter/Intersects
//注意:geometryName必须与postGIS中数据的geometry类型字段的名称一致
const filter = new ol.format.filter.Intersects(geometryName, geometry);//这里geometryName='geom'
const requestUrl = new ol.format.WFS().writeGetFeature({
featureTypes: featureTypes,//geoserver图层名数组
featureNs: featureNs,//geoserver 工作空间名称
outputFormat: 'application/json',
srsName: 'EPSG:4326',
filter: filter
});
//wfsUri=http://[IP]:[PORT]/geoserver/wfs
fetch(wfsUri, {
method: 'post',
body: new XMLSerializer().serializeToString(requestUrl)
}).then(function (res) {
return res.json();
}).then(function (data) {
console.log(data);
}).catch(err=>{
console.error(err);
})
2、针对WFS服务的多图层属性和空间查询:使用Geoserver的CQL/ECQL
ECQL参考:https://docs.geoserver.org/latest/en/user/filter/ecql_reference.html
主要用到了geoserver中的WFS服务的cql_filter参数。
const sqlFilter='count>50';
const wkt=new ol.format.WKT().writeGeometry(geo);//geo为openlayer几何多边形
//ECQL的空间过滤函数中的geometry需要使用wkt格式
const geoFilter='INTERSECTS(geom,'+wkt+')';//geom为查询对象个geometryName;
//get方式
const params = {
service: 'wfs',
version: '1.0.0',
request: 'GetFeature',
outputFormat: 'application/json',
cql_filter: sqlFilter+geoFilter,//where后的语句,包含属性过滤和空间过滤
typeName: featureTypes.join(',')//图层名称使用逗号拼接
};
const url = wfsUri;//‘http://[IP]:[PORT]/geoserver/wfs'
//拼接成URL地址,如:http://[IP]:[PORT]/geoserver/wfs?service=WFS&version=1.0.0&request=GetFeature&typeName=[typeNames]&outputFormat=application/json&cql_filter=sql
const queryLayerUrl = appendParams(url, params);
//https://github.com/openlayers/openlayers/blob/v6.2.1/src/ol/uri.js
fetch(queryLayerUrl).then((res) => {
return res.json();
}).then((data) => {
console.log(data);
}).catch(error => {
console.log('查询出错');
})
重点是将参数拼接成一个完整的URL地址,如:
http://[IP]:[PORT]/geoserver/wfs?service=WFS&version=1.0.0&request=GetFeature&typeName=[typeNames]&outputFormat=application/json&cql_filter=sqlFilter+geoFilter
当进行更复杂的查询时,就需要使用cql_filter的内置函数去拼接sql语句。
https://docs.geoserver.org/latest/en/user/filter/function_reference.html
如使用正则表达式:"cql_filter=parseDouble(strReplace('200X500','(.*)[^0-9]','',true))=500;"
使用了JSTS几何空间库。官方案例:https://openlayers.org/en/latest/examples/jsts.html