/// <summary> /// Returns the next feature at worldPos. /// </summary> /// <param name="worldPos"></param> /// <param name="limit"></param> /// <param name="outLayer"></param> /// the layer containing the next feature; null if no next feature is found. /// <param name="feature"></param> /// <param name="condition"></param> /// <returns>the next feature at worldPos, null if there is no next feature.</returns> public IFeature GetNextFeatureAtPosition(ICoordinate worldPos, float limit, out Layer outLayer, IFeature feature, Func <ILayer, bool> condition) { IEnvelope envelope = GetEnvelope(worldPos, limit); IFeature nextFeature = null; bool featureFound = false; outLayer = null; foreach (ILayer mapLayer in Map.GetAllVisibleLayers(false)) { var vectorLayer = mapLayer as VectorLayer; IPoint point = GeometryFactory.CreatePoint(worldPos); if (vectorLayer == null || !vectorLayer.IsSelectable) { continue; } if ((null != condition) && (!condition(vectorLayer))) { continue; } FeatureCollection provider = vectorLayer.DataSource as FeatureCollection; // this will skip shapefile layers if (null != provider) { IList objectsAt = provider.GetFeatures(envelope); foreach (IFeature featureAt in objectsAt) { // GetFeatures(envelope) uses the geometry bounds; this results in more // geometries than we actually are interested in (especially linestrings and polygons). double distance = featureAt.Geometry.Distance(point); if (distance >= limit) { continue; } if (featureFound) { nextFeature = featureAt; outLayer = vectorLayer; return(nextFeature); } if (featureAt == feature) { featureFound = true; continue; } if (null != nextFeature) { continue; } // If feature is last in collections objectsAt nextfeature is first nextFeature = featureAt; outLayer = vectorLayer; } } } return(nextFeature); }