上周一直在用ArcGis
的FeatureLayer
做点击查询和空间查询。由于一直坚持走开源路线,所以今天就来折腾下Openlayers
的空间查询,下面主要包括三种查询,分别是点击地图查询,过滤条件查询,多边形查询等。说明的文字不是很多,直接看代码,最后提供一份完整的代码,直接复制到html
中就可以运行。
1.点击查询
点击查询主要是使用map
的forEachFeatureAtPixel
进行查询,首先需要给地图添加一个点击事件,如下所示:
//点击查询
map.on('singleclick',function(evt){
var pixel = map.getEventPixel(evt.originalEvent);
map.forEachFeatureAtPixel(pixel, function (feature, layer) {
if (feature != undefined) {
console.log(feature);
}
})
})
2.条件过滤查询
条件过滤查询使用的是ol.format.filter
,可以添加过滤条件,过滤条件全部都 在ol.format.filter
里面,包括Or
,Not
,Bbox
,Within
,IsNull
,IsLike
,During
,EqualTo
,LessThan
,Contains
,IsBetWeen
,NotEqualTo
,Instresects
,GreaterThan
,LessThanOrEqualTo
,greaterThanOrEqualTo
等。如下所示:
function filterQuery(){
var featureRequest = new ol.format.WFS().writeGetFeature({
srsName: 'EPSG:3857',
featureNS: 'http://openstreemap.org',
featurePrefix: 'osm',
featureTypes: ['water_areas'],
outputFormat: 'application/json',
filter: ol.format.filter.and(
ol.format.filter.like('name', 'Mississippi*'),
ol.format.filter.equalTo('waterway', 'riverbank')
)
});
fetch('https://ahocevar.com/geoserver/wfs', {
method: 'POST',
body: new XMLSerializer().serializeToString(featureRequest)
}).then(function(response) {
return response.json();
}).then(function(json) {
var features = new ol.format.GeoJSON().readFeatures(json);
vectorSource.addFeatures(features);
map.getView().fit(vectorSource.getExtent());
});
}
3.空间查询
空间查询其实就是过滤查询,只是传递的过滤条件是几何体,这里使用intersects
来查询相交的数据,其中第一个参数geometryName
需要跟数据库中的空间字段对应,这里使用的是the_geom
。如下所示:
//多边形查询
function query(){
var featureRequest = new ol.format.WFS().writeGetFeature({
srsName: 'EPSG:3857',
featureNS: 'http://openstreemap.org',
featurePrefix: 'osm',
featureTypes: ['water_areas'],
outputFormat: 'application/json',
filter: ol.format.filter.intersects("the_geom", feature.getGeometry(), 'EPSG:3857')
});
fetch('https://ahocevar.com/geoserver/wfs', {
method: 'POST',
body: new XMLSerializer().serializeToString(featureRequest)
}).then(function(response) {
return response.json();
}).then(function(json) {
var features = new ol.format.GeoJSON().readFeatures(json);
if(features.length == 0){
alert('没有数据')
}else{
spaceSource.addFeatures(features);
map.getView().fit(spaceSource.getExtent());
}
});
}
以下为完整代码,并且包含了多边形绘制,代码可能有点乱,demo嘛,知识怎么用就行了。
<!DOCTYPE html>
<html>
<head>
<title>WFS - GetFeature</title>
<link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://cdn.bootcss.com/openlayers/4.6.5/ol-debug.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<div style="position: absolute;top:30px;left: 100px;">
<button onclick="addInteraction()">多边形</button>
<button onclick="query()">查询</button>
</div>
<script>
var vectorSource = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 255, 1.0)',
width: 2
})
})
});
var spaceSource = new ol.source.Vector();
var spaceVector = new ol.layer.Vector({
source: spaceSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(255, 0, 0, 1.0)',
width: 2
})
})
});
var drawSource = new ol.source.Vector({wrapX: false});
var drawVector = new ol.layer.Vector({
source: drawSource
});
var map = new ol.Map({
layers: [vector,drawVector,spaceVector],
target: document.getElementById('map'),
view: new ol.View({
center: [-8908887.277395891, 5381918.072437216],
maxZoom: 19,
zoom: 12
})
});
var feature;
function addInteraction() {
var draw = new ol.interaction.Draw({
source: drawSource,
type: 'Polygon'
});
map.addInteraction(draw);
draw.on('drawend',function(evt){
feature = evt.feature;
map.removeInteraction(draw);
})
}
//多边形查询
function query(){
var featureRequest = new ol.format.WFS().writeGetFeature({
srsName: 'EPSG:3857',
featureNS: 'http://openstreemap.org',
featurePrefix: 'osm',
featureTypes: ['water_areas'],
outputFormat: 'application/json',
filter: ol.format.filter.intersects("the_geom", feature.getGeometry(), 'EPSG:3857')
});
fetch('https://ahocevar.com/geoserver/wfs', {
method: 'POST',
body: new XMLSerializer().serializeToString(featureRequest)
}).then(function(response) {
return response.json();
}).then(function(json) {
var features = new ol.format.GeoJSON().readFeatures(json);
if(features.length == 0){
alert('没有数据')
}else{
spaceSource.addFeatures(features);
map.getView().fit(spaceSource.getExtent());
}
});
}
// 过滤查询
filterQuery();
function filterQuery(){
var featureRequest = new ol.format.WFS().writeGetFeature({
srsName: 'EPSG:3857',
featureNS: 'http://openstreemap.org',
featurePrefix: 'osm',
featureTypes: ['water_areas'],
outputFormat: 'application/json',
filter: ol.format.filter.and(
ol.format.filter.like('name', 'Mississippi*'),
ol.format.filter.equalTo('waterway', 'riverbank')
)
});
fetch('https://ahocevar.com/geoserver/wfs', {
method: 'POST',
body: new XMLSerializer().serializeToString(featureRequest)
}).then(function(response) {
return response.json();
}).then(function(json) {
var features = new ol.format.GeoJSON().readFeatures(json);
vectorSource.addFeatures(features);
map.getView().fit(vectorSource.getExtent());
});
}
//点击查询
map.on('singleclick',function(evt){
var pixel = map.getEventPixel(evt.originalEvent);
map.forEachFeatureAtPixel(pixel, function (feature, layer) {
if (feature != undefined) {
console.log(feature);
}
})
})
</script>
</body>
</html>