using System.Collections; using GeoAPI.Geometries; using GisSharpBlog.NetTopologySuite.Geometries; namespace GisSharpBlog.NetTopologySuite.Algorithm { /// /// Computes whether a point /// lies in the interior of an area Geometry. /// The algorithm used is only guaranteed to return correct results /// for points which are not on the boundary of the Geometry. /// public class SimplePointInAreaLocator { /// /// /// private SimplePointInAreaLocator() {} /// /// Locate is the main location function. It handles both single-element /// and multi-element Geometries. The algorithm for multi-element Geometries /// is more complex, since it has to take into account the boundaryDetermination rule. /// /// /// public static Locations Locate(ICoordinate p, IGeometry geom) { if (geom.IsEmpty) { return Locations.Exterior; } if (ContainsPoint(p, geom)) { return Locations.Interior; } return Locations.Exterior; } /// /// /// /// /// /// public static bool ContainsPointInPolygon(ICoordinate p, IPolygon poly) { if (poly.IsEmpty) { return false; } ILinearRing shell = (ILinearRing) poly.ExteriorRing; if (!CGAlgorithms.IsPointInRing(p, shell.Coordinates)) { return false; } // now test if the point lies in or on the holes for (int i = 0; i < poly.NumInteriorRings; i++) { ILinearRing hole = (ILinearRing) poly.GetInteriorRingN(i); if (CGAlgorithms.IsPointInRing(p, hole.Coordinates)) { return false; } } return true; } /// /// /// /// /// /// private static bool ContainsPoint(ICoordinate p, IGeometry geom) { if (geom is IPolygon) { return ContainsPointInPolygon(p, (IPolygon) geom); } else if (geom is IGeometryCollection) { IEnumerator geomi = new GeometryCollectionEnumerator((IGeometryCollection) geom); while (geomi.MoveNext()) { IGeometry g2 = (IGeometry) geomi.Current; // if(g2 != geom) --- Diego Guidi say's: Java code tests reference equality: in C# with operator overloads we tests the object.equals()... more slower! if (!ReferenceEquals(g2, geom)) { if (ContainsPoint(p, g2)) { return true; } } } } return false; } } }