private IEnumerable <IFeature> GetFeaturesUsingQuadTree(IEnvelope envelope) { var maximumFeatureSize = SkipRenderingOfVerySmallFeatures ? map.PixelSize * 0.9 : 0; // use quad tree to query features. if (tree == null) { BuildQuadTree(); } var rect = new RectangleF((float)envelope.MinX, (float)envelope.MinY, (float)envelope.Width, (float)envelope.Height); var indices = tree.GetIndices(ref rect, (float)maximumFeatureSize); #region debugging bool wholeMap = envelope.Equals(map.Envelope); if (RenderQuadTreeEnvelopes && !wholeMap) { foreach (IFeature feature in quadTreeEnvelopesLayer.DataSource.Features) { feature.Attributes["IsSelected"] = indices.Contains((int)feature.Attributes["ID"]) ? "true" : "false"; } quadTreeEnvelopesLayer.RenderRequired = true; } #endregion return(indices.Select(i => DataSource.GetFeature(i))); }
/// <summary> /// Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any. /// The innermost enclosing ring is the <i>smallest</i> enclosing ring. /// The algorithm used depends on the fact that: /// ring A contains ring B iff envelope(ring A) contains envelope(ring B). /// This routine is only safe to use if the chosen point of the hole /// is known to be properly contained in a shell /// (which is guaranteed to be the case if the hole does not touch its shell). /// </summary> /// <param name="shellList"></param> /// <param name="testEr"></param> /// <returns>Containing EdgeRing, if there is one, OR /// null if no containing EdgeRing is found.</returns> public static EdgeRing FindEdgeRingContaining(EdgeRing testEr, IList shellList) { ILinearRing teString = testEr.Ring; IEnvelope testEnv = teString.EnvelopeInternal; ICoordinate testPt = teString.GetCoordinateN(0); EdgeRing minShell = null; IEnvelope minEnv = null; for (IEnumerator it = shellList.GetEnumerator(); it.MoveNext();) { EdgeRing tryShell = (EdgeRing)it.Current; ILinearRing tryRing = tryShell.Ring; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) { minEnv = minShell.Ring.EnvelopeInternal; } bool isContained = false; // the hole envelope cannot equal the shell envelope if (tryEnv.Equals(testEnv)) { continue; } testPt = PointNotInList(teString.Coordinates, tryRing.Coordinates); //testPt = CoordinateArrays.PointNotInList(teString.Coordinates,tryRing.Coordinates); if (tryEnv.Contains(testEnv) && CGAlgorithms.IsPointInRing(testPt, tryRing.Coordinates)) { isContained = true; } // check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryShell; } } } return(minShell); }