/// <summary> /// Sony NS @ 2013-08-06 /// </summary> /// <param name="worldPos"></param> /// <param name="limit"></param> /// <param name="outLayer"></param> /// <param name="condition"></param> /// <returns></returns> public IFeature FindNearestFeature(ICoordinate worldPos, float limit, out ILayer outLayer, Func <ILayer, bool> condition) { IFeature nearestFeature = null; outLayer = null; // Since we are only interested in one geometry object start with the topmost trackersLayer and stop // searching the lower layers when an object is found. // Sony NS @ 2013-08-06, order list ILayer Desc, karena untuk layer-layer symbol diload paling terakhir foreach (ILayer mapLayer in Map.GetAllVisibleLayers(true).Reverse()) { if (mapLayer is DiscreteGridPointCoverageLayer) { try { var curvilinearGridLayer = (DiscreteGridPointCoverageLayer)mapLayer; var coverage = (IDiscreteGridPointCoverage)curvilinearGridLayer.Coverage; var nearestFeatures = coverage.GetFeatures(worldPos.X, worldPos.Y, limit); if (nearestFeatures != null) { if (!curvilinearGridLayer.ShowFaces) { nearestFeatures = nearestFeatures.Where(f => !(f is IGridFace)); } if (!curvilinearGridLayer.ShowVertices) { nearestFeatures = nearestFeatures.Where(f => !(f is IGridVertex)); } } nearestFeature = nearestFeatures.FirstOrDefault(); outLayer = curvilinearGridLayer; } catch (Exception) { // GetCoordinateAtPosition will throw exception if x, y is not within the coverage } } if (mapLayer is VectorLayer) { var vectorLayer = mapLayer as VectorLayer; IEnvelope envelope; float localLimit = limit; if ((!vectorLayer.IsSelectable) || ((null != condition) && (!condition(vectorLayer)))) { continue; } // Adjust the marge limit for Layers with a symbol style and if the size of the symbol exceeds // the minimum limit. Ignore layers with custom renderers if ((vectorLayer.Style.Symbol != null) && (0 == vectorLayer.CustomRenderers.Count)) { ICoordinate size = MapHelper.ImageToWorld(MapControl.Map, vectorLayer.Style.Symbol.Width, vectorLayer.Style.Symbol.Height); if ((size.X > localLimit) || (size.Y > localLimit)) { envelope = MapHelper.GetEnvelope(worldPos, size.X, size.Y); localLimit = (float)Math.Max(envelope.Width, envelope.Height); } else { envelope = GetEnvelope(worldPos, localLimit); } } else { envelope = GetEnvelope(worldPos, localLimit); } IFeatureProvider featureProvider = vectorLayer.DataSource; if (null != featureProvider) { // Get features in the envelope IList objectsAt; if (vectorLayer.CustomRenderers.Count > 0) { objectsAt = vectorLayer.CustomRenderers[0].GetFeatures(envelope, vectorLayer); } else { objectsAt = featureProvider.GetFeatures(envelope); } // Mousedown at new position if (null != objectsAt) { IFeature feature = null; if (objectsAt.Count == 1) { feature = objectsAt.OfType <IFeature>().First(); } else if (objectsAt.Count > 1) { double localDistance; feature = FindNearestFeature(vectorLayer, objectsAt, worldPos, localLimit, out localDistance); } if (null != feature) { nearestFeature = feature; outLayer = vectorLayer; break; } } } } else if (mapLayer is IRegularGridCoverageLayer) { try { IRegularGridCoverageLayer regularGridCoverageLayer = (IRegularGridCoverageLayer)mapLayer; IRegularGridCoverage regularGridCoverage = (IRegularGridCoverage)regularGridCoverageLayer.Coverage; nearestFeature = regularGridCoverage.GetRegularGridCoverageCellAtPosition(worldPos.X, worldPos.Y); outLayer = regularGridCoverageLayer; } catch (Exception) { // GetCoordinateAtPosition will throw exception if x, y is not within the coverage } } } return(nearestFeature); }
public IFeature FindNearestFeature(ICoordinate worldPos, float limit, out ILayer outLayer, Func <ILayer, bool> condition) { IFeature nearestFeature = null; outLayer = null; // Since we are only interested in one geometry object start with the topmost trackersLayer and stop // searching the lower layers when an object is found. foreach (ILayer mapLayer in MapHelper.GetAllMapLayers(Map.Layers, false)) { if (mapLayer is VectorLayer) { var vectorLayer = mapLayer as VectorLayer; IEnvelope envelope; float localLimit = limit; if ((!vectorLayer.IsSelectable) || ((null != condition) && (!condition(vectorLayer)))) { continue; } // Adjust the marge limit for Layers with a symbol style and if the size of the symbol exceeds // the minimum limit. Ignore layers with custom renderers if ((vectorLayer.Style.Symbol != null) && (0 == vectorLayer.CustomRenderers.Count)) { ICoordinate size = MapControlHelper.ImageToWorld(MapControl.Map, vectorLayer.Style.Symbol.Width, vectorLayer.Style.Symbol.Height); if ((size.X > localLimit) || (size.Y > localLimit)) { envelope = MapControlHelper.GetEnvelope(worldPos, size.X, size.Y); localLimit = (float)Math.Max(envelope.Width, envelope.Height); } else { envelope = GetEnvelope(worldPos, localLimit); } } else { envelope = GetEnvelope(worldPos, localLimit); } IFeatureProvider featureProvider = vectorLayer.DataSource; if (null != featureProvider) { // Get features in the envelope IList objectsAt; if (vectorLayer.CustomRenderers.Count > 0) { objectsAt = vectorLayer.CustomRenderers[0].GetFeatures(envelope, vectorLayer); } else { objectsAt = featureProvider.GetFeatures(envelope); } // Mousedown at new position if ((null != objectsAt) && (objectsAt.Count > 0)) { double localDistance; IFeature feature = FindNearestFeature(vectorLayer, objectsAt, worldPos, localLimit, out localDistance); if (null != feature) { nearestFeature = feature; outLayer = vectorLayer; break; } } } } else if (mapLayer is IRegularGridCoverageLayer) { try { IRegularGridCoverageLayer regularGridCoverageLayer = (IRegularGridCoverageLayer)mapLayer; IRegularGridCoverage regularGridCoverage = (IRegularGridCoverage)regularGridCoverageLayer.Coverage; nearestFeature = regularGridCoverage.GetRegularGridCoverageCellAtPosition(worldPos.X, worldPos.Y); outLayer = regularGridCoverageLayer; } catch (Exception) { // GetCoordinateAtPosition will throw exception if x, y is not within the coverage } } } return(nearestFeature); }