前言
❝
要素(Feature)查询是GIS开发要解决的一个重要问题,通过数据查询是否高效、准确,可以判断一个GIS系统是否具备易用性。要素查询作为GIS开发的核心功,常用于地图交互、空间分析与过滤等场景。
本文将介绍两个Map对象方法forEachFeatureAtPixel(pixel)
、getFeaturesAtPixel(pixel)
和一个矢量图层方法getFeatures(pixel)
三种要素查询的方法,读者可以根据自己的应用场景进行选择。
1. forEachFeatureAtPixel(pixel)
forEachFeatureAtPixel:
该方法为Map对象属性,接收三个参数:第一个参数为事件像素坐标;第二个参数为回调函数;第三个参数为可选对象。
检测视口上与像素相交的特征,并对每个相交的特征执行回调。对于没有填充的多边形,只有笔划将用于命中检测。多边形必须应用填充样式,以确保检测到多边形内的像素。填充物可以是透明的。
const feature = map.forEachFeatureAtPixel(pixel, feature => feature, {})
第一个参数很简单,就不多做解释了,重点说一下后两个参数。第二个参数callback
是一个回调函数,该回调函数具有两个参数,具体可见下方说明(来源于百度翻译)
回调函数将使用两个参数调用。 第一个参数是像素处的一个特征或渲染特征,第二个参数是该特征的图层,对于非托管图层将为空。 为了停止检测,回调函数可以返回一个真值。
具体使用就是可以使用回调函数返回查询要素,并且在查询到数据之后,返回一个真值以停止检测。
const feature = map.forEachFeatureAtPixel(pixel, feature => {
if (feature) {
return feature
}
})
第三个参数为可选对象,主要是规定了数据过滤的附加条件。该对象又具有三个参数,第一个参数layerFilter
为图层过滤器;第二个参数hitTolerance
为过滤容差值;第三个参数检查是否是有效的几何对象,反正使用默认值,设置为true就OK了。
图层过滤器参数可以用一个函数表示,这个函数具有一个图层(Layer)参数,可以根据图层属性如名称、可见性、缩放大小等进行过滤。
const feature = map.forEachFeatureAtPixel(pixel, feature => {
if (feature) {
return feature
}
}, {
// 图层过滤器
layerFilter: (layer) => {
const properties = layer.getProperties()
if (properties.title === "云南行政区") {
return false
}
}
})
如下图所示,当将过滤条件设置为【图层名称为云南行政区】则不进行检测,此时将鼠标移入行政区图层没有反应,若想查询指定图层,将返回值改为true
即可。
hitTolerance
参数为过滤容差,默认值为0,单位为CSS像素。通过该值可以检测给定位置以容差值为半径圆形区域内的要素。
const feature = map.forEachFeatureAtPixel(pixel, feature => {
if (feature) {
return feature
}
}, {
// 图层过滤器
layerFilter: (layer) => {
const properties = layer.getProperties()
if (properties.title === "云南行政区") {
return false
}
},
// 过滤容差
hitTolerance: 100
})
如上我将过滤容差设置为100个像素单位,则鼠标还处于查询图层外部就可以查询到要素信息。
2. getFeaturesAtPixel(pixel)
getFeaturesAtPixel:
该方法与forEachFeatureAtPixel
一样,都属于Map对象属性。但是getFeaturesAtPixel方法只接收两个参数。第一个参数为事件像素坐标;第二个参数为可选对象。
两者的区别在于参数个数和返回值不一样。使用getFeaturesAtPixel方法如果查询到数据的将会返回一个要素数组,否则返回一个空数组。其实现效果与forEachFeatureAtPixel
一致。
const features = map.getFeaturesAtPixel(pixel, {
// 图层过滤器
layerFilter: (layer) => {
const properties = layer.getProperties()
if (properties.title === "云南行政区") {
return true
}
},
// 过滤容差
hitTolerance: 100
})
3. getFeatures(pixel)
getFeatures(pixel):
getFeatures(pixel)
方法与前两个不同,它是矢量图层属性,接收一个事件像素坐标参数,并返回一个Promise
对象。
以下来源于百度翻译:
使用此方法可以获取视口上与给定像素【相交】的最顶部特征。用于此方法的命中检测算法针对性能进行了优化,但不如【map.getFeaturesAtPixel()】中使用的算法准确。不考虑文本,图标仅由其边界框表示,而不是精确的图像。
regionLayer.getFeatures(pixel).then(features => {
// 若未查询到要素,则退出
if (!features.length) {
if (highlightFeat) {
highlightLayer.getSource().removeFeature(highlightFeat)
highlightFeat = undefined
}
return
}
// 获取要素属性
const properties = features[0].getProperties()
// 将事件坐标转换为地图坐标
const coords = map.getCoordinateFromPixel(pixel)
if (features[0] != highlightFeat) {
// 移除高亮要素
if (highlightFeat) {
highlightLayer.getSource().removeFeature(highlightFeat)
highlightFeat = undefined
}
highlightLayer.getSource().addFeature(features[0])
highlightFeat = features[0]
}
openPopupTable(properties, popupColums, coords)
})
4. 三个方法对比
方法名 | 所属对象 | 参数 | 返回值 |
forEachFeatureAtPixel | Map | {pixel,callback,options} | 最后一个回调执行值或者第一个为真的回调值 |
getFeaturesAtPixel | Map | {pixel,options} | 一个要素数组或者空数组 |
getFeatures | VectorLayer | {pixel} | 一个解析了要素数组的Promise对象 |