private static Location LocateInPolygonRing(Coordinate p, LinearRing ring) { // bounding-box check if (!ring.EnvelopeInternal.Intersects(p)) { return(Location.Exterior); } return(PointLocation.LocateInRing(p, ring.CoordinateSequence)); }
/// <summary> /// Uses a heuristic to reduce the number of points scanned to compute the hull. /// The heuristic is to find a polygon guaranteed to /// be in (or on) the hull, and eliminate all points inside it. /// A quadrilateral defined by the extremal points /// in the four orthogonal directions /// can be used, but even more inclusive is /// to use an octilateral defined by the points in the 8 cardinal directions. /// Note that even if the method used to determine the polygon vertices /// is not 100% robust, this does not affect the robustness of the convex hull. /// <para> /// To satisfy the requirements of the Graham Scan algorithm, /// the returned array has at least 3 entries. /// </para> /// </summary> /// <param name="pts">The coordinates to reduce</param> /// <returns>The reduced array of coordinates</returns> private static Coordinate[] Reduce(Coordinate[] pts) { var polyPts = ComputeOctRing(pts /*_inputPts*/); // unable to compute interior polygon for some reason if (polyPts == null) { return(pts); } // add points defining polygon var reducedSet = new HashSet <Coordinate>(); for (int i = 0; i < polyPts.Length; i++) { reducedSet.Add(polyPts[i]); } /* * Add all unique points not in the interior poly. * PointLocation.IsInRing is not defined for points actually on the ring, * but this doesn't matter since the points of the interior polygon * are forced to be in the reduced set. */ for (int i = 0; i < pts.Length; i++) { if (!PointLocation.IsInRing(pts[i], polyPts)) { reducedSet.Add(pts[i]); } } var reducedPts = CoordinateArrays.ToCoordinateArray(reducedSet);// new Coordinate[reducedSet.Count]; Array.Sort(reducedPts); // ensure that computed array has at least 3 points (not necessarily unique) if (reducedPts.Length < 3) { return(PadArray3(reducedPts)); } return(reducedPts); }
private static Location LocateOnLineString(Coordinate p, LineString l) { // bounding-box check if (!l.EnvelopeInternal.Intersects(p)) { return(Location.Exterior); } var pt = l.Coordinates; if (!l.IsClosed) { if (p.Equals(pt[0]) || p.Equals(pt[pt.Length - 1])) { return(Location.Boundary); } } if (PointLocation.IsOnLine(p, pt)) { return(Location.Interior); } return(Location.Exterior); }