/// <summary> /// Computes all interior intersections in the collection of <see cref="ISegmentString" />s, /// and returns their <see cref="Coordinate" />s. /// Does NOT node the segStrings. /// </summary> /// <param name="segStrings"></param> /// <param name="li"></param> /// <returns>A list of <see cref="Coordinate" />s for the intersections.</returns> private static IList<Coordinate> FindInteriorIntersections(IList<ISegmentString> segStrings, LineIntersector li) { InteriorIntersectionFinderAdder intFinderAdder = new InteriorIntersectionFinderAdder(li); SinglePassNoder noder = new MCIndexNoder(intFinderAdder); noder.ComputeNodes(segStrings); return intFinderAdder.InteriorIntersections; }
private static bool HasInteriorIntersection(LineIntersector li, Coordinate p0, Coordinate p1) { for (var i = 0; i < li.IntersectionNum; i++) { var intPt = li.GetIntersection(i); if (!(intPt.Equals(p0) || intPt.Equals(p1))) return true; } return false; }
/// <summary> /// Initializes a new instance of the <see cref="HotPixel"/> class. /// </summary> /// <param name="pt">The coordinate at the center of the hot pixel</param> /// <param name="scaleFactor">The scale factor determining the pixel size</param> /// <param name="li">THe intersector to use for testing intersection with line segments</param> public HotPixel(Coordinate pt, double scaleFactor, LineIntersector li) { _originalPt = pt; _pt = pt; _scaleFactor = scaleFactor; _li = li; if (scaleFactor <= 0d) throw new ArgumentException("Scale factor must be non-zero"); if (scaleFactor != 1.0) { _pt = new Coordinate(Scale(pt.X), Scale(pt.Y)); _p0Scaled = new Coordinate(); _p1Scaled = new Coordinate(); } InitCorners(_pt); }
/// <summary> /// Add an <see cref="SegmentNode" /> for intersection intIndex. /// An intersection that falls exactly on a vertex /// of the <see cref="NodedSegmentString" /> is normalized /// to use the higher of the two possible segmentIndexes. /// </summary> /// <param name="li"></param> /// <param name="segmentIndex"></param> /// <param name="geomIndex"></param> /// <param name="intIndex"></param> public void AddIntersection(LineIntersector li, int segmentIndex, int geomIndex, int intIndex) { Coordinate intPt = new Coordinate(li.GetIntersection(intIndex)); AddIntersection(intPt, segmentIndex); }
/// <summary> /// /// </summary> /// <param name="g"></param> /// <param name="li"></param> /// <param name="includeProper"></param> /// <returns></returns> public SegmentIntersector ComputeEdgeIntersections(GeometryGraph g, LineIntersector li, bool includeProper) { SegmentIntersector si = new SegmentIntersector(li, includeProper, true); si.SetBoundaryNodes(BoundaryNodes, g.BoundaryNodes); EdgeSetIntersector esi = CreateEdgeSetIntersector(); esi.ComputeIntersections(Edges, g.Edges, si); return si; }
public OffsetSegmentGenerator(IPrecisionModel precisionModel, IBufferParameters bufParams, double distance) { _precisionModel = precisionModel; _bufParams = bufParams; // compute intersections in full precision, to provide accuracy // the points are rounded as they are inserted into the curve line _li = new RobustLineIntersector(); _filletAngleQuantum = Math.PI / 2.0 / bufParams.QuadrantSegments; /** * Non-round joins cause issues with short closing segments, so don't use * them. In any case, non-round joins only really make sense for relatively * small buffer distances. */ if (bufParams.QuadrantSegments >= 8 && bufParams.JoinStyle == JoinStyle.Round) _closingSegLengthFactor = MaxClosingSegLenFactor; Init(distance); }
///<summary> /// Creates an intersection finder which counts all interior intersections. /// The intersections are note recorded to reduce memory usage. ///</summary> /// <param name="li">A line intersector.</param> /// <returns>a intersection finder which counts all interior intersections.</returns> public static InteriorIntersectionFinder CreateIntersectionCounter(LineIntersector li) { InteriorIntersectionFinder finder = new InteriorIntersectionFinder(li); finder.FindAllIntersections = true; finder.KeepIntersections = false; return finder; }
/// <summary> /// Computes all interior intersections in the collection of <see cref="ISegmentString" />s, /// and returns their <see cref="Coordinate" />s. /// /// Does NOT node the segStrings. /// </summary> /// <param name="segStrings"></param> /// <param name="li"></param> /// <returns>A list of Coordinates for the intersections.</returns> private IList<Coordinate> FindInteriorIntersections(IList<ISegmentString> segStrings, LineIntersector li) { InteriorIntersectionFinderAdder intFinderAdder = new InteriorIntersectionFinderAdder(li); _noder.SegmentIntersector = intFinderAdder; _noder.ComputeNodes(segStrings); return intFinderAdder.InteriorIntersections; }
/// <summary> /// Initializes a new instance of the <see cref="MCIndexSnapRounder"/> class. /// </summary> /// <param name="pm">The <see cref="PrecisionModel" /> to use.</param> public MCIndexSnapRounder(IPrecisionModel pm) { _li = new RobustLineIntersector { PrecisionModel = pm }; _scaleFactor = pm.Scale; }
/// <summary> /// Add an EdgeIntersection for intersection intIndex. /// An intersection that falls exactly on a vertex of the edge is normalized /// to use the higher of the two possible segmentIndexes. /// </summary> /// <param name="li"></param> /// <param name="segmentIndex"></param> /// <param name="geomIndex"></param> /// <param name="intIndex"></param> public void AddIntersection(LineIntersector li, int segmentIndex, int geomIndex, int intIndex) { Coordinate intPt = new Coordinate(li.GetIntersection(intIndex)); var normalizedSegmentIndex = segmentIndex; var dist = li.GetEdgeDistance(geomIndex, intIndex); // normalize the intersection point location var nextSegIndex = normalizedSegmentIndex + 1; if (nextSegIndex < Points.Length) { var nextPt = Points[nextSegIndex]; // Normalize segment index if intPt falls on vertex // The check for point equality is 2D only - Z values are ignored if (intPt.Equals2D(nextPt)) { normalizedSegmentIndex = nextSegIndex; dist = 0.0; } // Add the intersection point to edge intersection list. EdgeIntersectionList.Add(intPt, normalizedSegmentIndex, dist); } }
///<summary> /// Creates an intersection finder using a given <see cref="LineIntersector"/> ///</summary> /// <param name="li">The LineIntersector to use</param> public SegmentIntersectionDetector(LineIntersector li) { _li = li; }
/// <summary> /// Initializes a new instance of the <see cref="IntersectionAdder"/> class. /// </summary> /// <param name="li"></param> public IntersectionAdder(LineIntersector li) { _li = li; }
public OldOffsetCurveBuilder( IPrecisionModel precisionModel, IBufferParameters bufParams ) { _precisionModel = precisionModel; _bufParams = bufParams; // compute intersections in full precision, to provide accuracy // the points are rounded as they are inserted into the curve line _li = new RobustLineIntersector(); _filletAngleQuantum = Math.PI / 2.0 / bufParams.QuadrantSegments; /** * Non-round joins cause issues with short closing segments, * so don't use them. In any case, non-round joins * only really make sense for relatively small buffer distances. */ if (bufParams.QuadrantSegments >= 8 && bufParams.JoinStyle == JoinStyle.Round) closingSegFactor = MAX_CLOSING_SEG_FRACTION; }
/// <summary> /// Compute self-nodes, taking advantage of the Geometry type to /// minimize the number of intersection tests. (E.g. rings are /// not tested for self-intersection, since they are assumed to be valid). /// </summary> /// <param name="li">The <c>LineIntersector</c> to use.</param> /// <param name="computeRingSelfNodes">If <c>false</c>, intersection checks are optimized to not test rings for self-intersection.</param> /// <returns>The SegmentIntersector used, containing information about the intersections found.</returns> public SegmentIntersector ComputeSelfNodes(LineIntersector li, bool computeRingSelfNodes) { SegmentIntersector si = new SegmentIntersector(li, true, false); EdgeSetIntersector esi = CreateEdgeSetIntersector(); // optimized test for Polygons and Rings if (!computeRingSelfNodes && (_parentGeom is ILinearRing || _parentGeom is IPolygon || _parentGeom is IMultiPolygon)) esi.ComputeIntersections(Edges, si, false); else esi.ComputeIntersections(Edges, si, true); AddSelfIntersectionNodes(_argIndex); return si; }
/// <summary> /// Adds EdgeIntersections for one or both /// intersections found for a segment of an edge to the edge intersection list. /// </summary> /// <param name="li"></param> /// <param name="segmentIndex"></param> /// <param name="geomIndex"></param> public void AddIntersections(LineIntersector li, int segmentIndex, int geomIndex) { for (var i = 0; i < li.IntersectionNum; i++) AddIntersection(li, segmentIndex, geomIndex, i); }
/// <summary> /// Initializes a new instance of the <see cref="IteratedNoder"/> class. /// </summary> /// <param name="pm"></param> public IteratedNoder(IPrecisionModel pm) { _li = new RobustLineIntersector {PrecisionModel = pm}; }
public LineIntersectionAdder(LineIntersector li) { this.li = li; }
/// <summary> /// /// </summary> /// <param name="segStrings"></param> /// <param name="li"></param> private void SnapRound(IList<ISegmentString> segStrings, LineIntersector li) { IList<Coordinate> intersections = FindInteriorIntersections(segStrings, li); ComputeIntersectionSnaps(intersections); ComputeVertexSnaps(segStrings); }
/// <summary> /// /// </summary> /// <param name="li"></param> /// <param name="bdyNodes"></param> /// <returns></returns> private static bool IsBoundaryPoint(LineIntersector li, IList<Node>[] bdyNodes) { if (bdyNodes == null) return false; if (IsBoundaryPoint(li, bdyNodes[0])) return true; if (IsBoundaryPoint(li, bdyNodes[1])) return true; return false; }
///<summary> /// Creates an intersection finder which tests if there is at least one interior intersection. /// Uses short-circuiting for efficient performance. /// The intersection found is recorded. ///</summary> /// <param name="li">A line intersector.</param> /// <returns>A intersection finder which tests if there is at least one interior intersection.</returns> public static InteriorIntersectionFinder CreateAnyIntersectionFinder(LineIntersector li) { return new InteriorIntersectionFinder(li); }
/// <summary> /// /// </summary> /// <param name="li"></param> /// <param name="bdyNodes"></param> /// <returns></returns> private static bool IsBoundaryPoint(LineIntersector li, IEnumerable<Node> bdyNodes) { foreach (Node node in bdyNodes) { Coordinate pt = node.Coordinate; if (li.IsIntersection(pt)) return true; } return false; }
///<summary> /// Creates an intersection finder which finds an interior intersection if one exists ///</summary> ///<param name="li">the LineIntersector to use</param> public InteriorIntersectionFinder(LineIntersector li) { _li = li; _interiorIntersection = null; }
/// <summary> /// /// </summary> /// <param name="li"></param> /// <param name="includeProper"></param> /// <param name="recordIsolated"></param> public SegmentIntersector(LineIntersector li, bool includeProper, bool recordIsolated) { _li = li; _includeProper = includeProper; _recordIsolated = recordIsolated; }
/// <summary> /// /// </summary> /// <param name="li"></param> public EdgeSetNoder(LineIntersector li) { _li = li; }
/// <summary> /// Creates an intersection finder which finds all proper intersections. /// </summary> /// <param name="li">The <see cref="LineIntersector" /> to use.</param> public IntersectionFinderAdder(LineIntersector li) { _li = li; _interiorIntersections = new List<Coordinate>(); }