Openlayers getFeaturesAtPixel()以包括分离(隐藏)的功能

Openlayers getFeaturesAtPixel()以包括分离(隐藏)的功能,openlayers,openlayers-3,Openlayers,Openlayers 3,有没有办法在一个特定的像素上获得一层中的所有特征,包括由于分离而隐藏的特征?当前,当调用Map.getFeaturesAtPixel()(或Map.forEachFeatureAtPixel())时,这些功能将被忽略。getFeaturesAtPixel旨在准确报告在地图上呈现的内容。如果您想获取特定位置的所有特征,可以使用ol/source/Vector的getFeaturesInExtent方法在您感兴趣的坐标周围使用一个小缓冲区(例如2个像素): import {boundingExten

有没有办法在一个特定的像素上获得一层中的所有特征,包括由于分离而隐藏的特征?当前,当调用
Map.getFeaturesAtPixel()
(或
Map.forEachFeatureAtPixel()
)时,这些功能将被忽略。

getFeaturesAtPixel
旨在准确报告在地图上呈现的内容。如果您想获取特定位置的所有特征,可以使用
ol/source/Vector
getFeaturesInExtent
方法在您感兴趣的坐标周围使用一个小缓冲区(例如2个像素):

import {boundingExtent, buffer} from 'ol/extent';

map.on('click', function(e) {
  const extent = boundingExtent([e.coordinate]);
  buffer(extent, 2 / view.getResolution());
  matches = source.getFeaturesInExtent(extent);
});
使用矢量平铺时,可以通过首先获取平铺来实现相同的效果

const tileGrid = vectorTileSource.getTileGrid();
const tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate, view.getResolution());
const tile = vectorTileSource.getTile(tileCoord);
然后仅获取缓冲区范围中的功能:

import {intersects} from 'ol/extent';

const features = tile.getFeatures();
const matches = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
  const feature = features[i];
  if (intersects(extent, feature.getGeometry().getExtent()) {
    matches.push(feature);
  }
}
从'ol/extent'导入{intersects};
const features=tile.getFeatures();
常量匹配=[];
for(设i=0,ii=features.length;i
getFeaturesAtPixel
旨在准确报告地图上呈现的内容。如果您想获取特定位置的所有要素,可以使用
ol/source/Vector
GetFeaturesExtent
方法在您感兴趣的坐标周围使用一个小缓冲区(例如2个像素):

import {boundingExtent, buffer} from 'ol/extent';

map.on('click', function(e) {
  const extent = boundingExtent([e.coordinate]);
  buffer(extent, 2 / view.getResolution());
  matches = source.getFeaturesInExtent(extent);
});
使用矢量平铺时,可以通过首先获取平铺来实现相同的效果

const tileGrid = vectorTileSource.getTileGrid();
const tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate, view.getResolution());
const tile = vectorTileSource.getTile(tileCoord);
然后仅获取缓冲区范围中的功能:

import {intersects} from 'ol/extent';

const features = tile.getFeatures();
const matches = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
  const feature = features[i];
  if (intersects(extent, feature.getGeometry().getExtent()) {
    matches.push(feature);
  }
}
从'ol/extent'导入{intersects};
const features=tile.getFeatures();
常量匹配=[];
for(设i=0,ii=features.length;i
对于后代。我认为在大多数情况下,由于分离,您不需要结果来包含隐藏的功能,因为这可能会导致光标位于空白区域的非空结果

最后做的是创建一个附加层,而不启用“分离”(Declutting)。首先,我在那里添加了所有没有标签的功能,并隐藏它们,只是不设置填充样式(将层不透明度设置为零也可以).当一个原始的分离特征与其他特征重叠时,这给了我很好的结果,但在空白区域仍然会出现误报


所以最后我决定在分离层后面展示这个新的层,有不同的样式,没有标签。这样,你可以在视觉上看到所有的功能和分离标签都显示在顶部,从用户体验的角度来看,这也非常好。

对于后代来说。我认为在大多数情况下,你不需要结果o包括由于分离而隐藏的特征,因为如果光标位于空白区域,则可能导致非空结果

最后做的是创建一个附加层,而不启用“分离”(Declutting)。首先,我在那里添加了所有没有标签的功能,并隐藏它们,只是不设置填充样式(将层不透明度设置为零也可以).当一个原始的分离特征与其他特征重叠时,这给了我很好的结果,但在空白区域仍然会出现误报


因此,最后我决定在分离层后面显示这个新层,具有不同的样式,并且没有标签。这样,您可以在视觉上看到所有的功能,并且分离标签显示在顶部,从用户体验的角度来看,这也非常好用。

您可以用最小的不透明度来显示功能,而不是隐藏例如rgba设置中的0.01(肯定有效)。或者您可以使用第二个样式函数来实现这一点,并执行类似于
layer.setStyle(tempsyle);var features=map.getFeaturesAtPixel();layer.setStyle(mainStyle)的操作
但我还没有测试过。谢谢@Mike,我有了一个主意。你可以不隐藏功能,而是在rgba设置中以最小的不透明度(例如0.01)显示功能(肯定有效)。或者你可以使用第二个样式函数来实现这一点,并执行类似于
layer.setStyle(tempsyle);var features=map.getFeaturesAtPixel()的操作;layer.setStyle(mainStyle);
但我还没有测试过。谢谢@Mike,我有了一个主意。这段代码似乎是根据边界框计算交点的。我想知道的是,光标(或光标周围的小缓冲区)是否真的在触摸该功能,方式与getFeaturesAtPixel()相同有效。如果功能未渲染,则光标将永远不会触及它。因此,您必须在图形方式(getFeaturesAtPixel)和近似分析方式(我的答案中的代码)之间进行选择。您可以改进后者,但它始终是一个近似值,因为您无法考虑样式和图标内容。谢谢@ahocevar。事实上,答案比我想象的更复杂,因为通常您不希望所有功能在所有情况下都接触光标(例如,这可能导致空区域中出现非空结果)。此代码似乎基于边界框计算交点。我想知道的是,光标(或光标周围的小缓冲区)是否实际接触到该功能,方式与getFeaturesAtPixel()相同有效。如果功能未渲染,则光标将永远不会触及它。因此,您必须在图形方式(getFeaturesAtPixel)和近似分析方式(我的答案中的代码)之间进行选择。您可以改进后者,但它始终是一个近似值,因为您无法考虑样式和图标内容。谢谢@ahocevar。事实上,答案比我想象的更复杂,因为通常您不希望所有功能在所有情况下都接触光标(例如,这可能导致空区域中出现非空结果)。