Add an optional feature filter to getClosestFeatureToCoordinate

This commit is contained in:
Frederic Junod
2016-04-12 11:43:46 +02:00
parent 50b956b108
commit 05ceaab620
2 changed files with 56 additions and 18 deletions

View File

@@ -612,10 +612,13 @@ ol.source.Vector.prototype.getFeaturesInExtent = function(extent) {
* This method is not available when the source is configured with
* `useSpatialIndex` set to `false`.
* @param {ol.Coordinate} coordinate Coordinate.
* @param {function(ol.Feature):boolean=} opt_filter Feature filter function.
* The filter function will receive one argument, the {@link ol.Feature feature}
* and it should return a boolean value. By default, no filtering is made.
* @return {ol.Feature} Closest feature.
* @api stable
*/
ol.source.Vector.prototype.getClosestFeatureToCoordinate = function(coordinate) {
ol.source.Vector.prototype.getClosestFeatureToCoordinate = function(coordinate, opt_filter) {
// Find the closest feature using branch and bound. We start searching an
// infinite extent, and find the distance from the first feature found. This
// becomes the closest feature. We then compute a smaller extent which any
@@ -632,28 +635,31 @@ ol.source.Vector.prototype.getClosestFeatureToCoordinate = function(coordinate)
goog.asserts.assert(this.featuresRtree_,
'getClosestFeatureToCoordinate does not work with useSpatialIndex set ' +
'to false');
var filter = opt_filter ? opt_filter : ol.functions.TRUE;
this.featuresRtree_.forEachInExtent(extent,
/**
* @param {ol.Feature} feature Feature.
*/
function(feature) {
var geometry = feature.getGeometry();
goog.asserts.assert(geometry,
'feature geometry is defined and not null');
var previousMinSquaredDistance = minSquaredDistance;
minSquaredDistance = geometry.closestPointXY(
x, y, closestPoint, minSquaredDistance);
if (minSquaredDistance < previousMinSquaredDistance) {
closestFeature = feature;
// This is sneaky. Reduce the extent that it is currently being
// searched while the R-Tree traversal using this same extent object
// is still in progress. This is safe because the new extent is
// strictly contained by the old extent.
var minDistance = Math.sqrt(minSquaredDistance);
extent[0] = x - minDistance;
extent[1] = y - minDistance;
extent[2] = x + minDistance;
extent[3] = y + minDistance;
if (filter(feature)) {
var geometry = feature.getGeometry();
goog.asserts.assert(geometry,
'feature geometry is defined and not null');
var previousMinSquaredDistance = minSquaredDistance;
minSquaredDistance = geometry.closestPointXY(
x, y, closestPoint, minSquaredDistance);
if (minSquaredDistance < previousMinSquaredDistance) {
closestFeature = feature;
// This is sneaky. Reduce the extent that it is currently being
// searched while the R-Tree traversal using this same extent object
// is still in progress. This is safe because the new extent is
// strictly contained by the old extent.
var minDistance = Math.sqrt(minSquaredDistance);
extent[0] = x - minDistance;
extent[1] = y - minDistance;
extent[2] = x + minDistance;
extent[3] = y + minDistance;
}
}
});
return closestFeature;