public OverlayEdge(Coordinate orig, Coordinate dirPt, bool direction, OverlayLabel label, Coordinate[] pts) : base(orig) { DirectionPt = dirPt; IsForward = direction; Coordinates = pts; Label = label; }
/// <summary> /// Tests whether a point with a given topological <see cref="Label"/> /// relative to two geometries is contained in /// the result of overlaying the geometries using /// a given overlay operation. /// <para/> /// The method handles arguments of <see cref="Location.Null"/> correctly /// </summary> /// <param name="label">The topological label of the point</param> /// <param name="opCode">The code for the overlay operation to test</param> /// <returns><c>true</c> if the label locations correspond to the overlay <paramref name="opCode"/></returns> private static bool IsResultOfOpPoint(OverlayLabel label, SpatialFunction opCode) { var loc0 = label.GetLocation(0); var loc1 = label.GetLocation(1); return(IsResultOfOp(opCode, loc0, loc1)); }
public static OverlayEdge CreateEdgePair(Coordinate[] pts, OverlayLabel lbl) { var e0 = CreateEdge(pts, lbl, true); var e1 = CreateEdge(pts, lbl, false); e0.Link(e1); return(e0); }
/// <summary> /// Determines the effective location for a line, /// for the purpose of overlay operation evaluation. /// Line edges and Collapses are reported as INTERIOR /// so they may be included in the result /// if warranted by the effect of the operation on the two edges. /// (For instance, the intersection of a line edge and a collapsed boundary /// is included in the result). /// </summary> /// <param name="lbl">The label of line</param> /// <param name="geomIndex">The index of parent geometry</param> /// <returns>The effective location of the line</returns> private static Location EffectiveLocation(OverlayLabel lbl, int geomIndex) { if (lbl.IsCollapse(geomIndex)) { return(Location.Interior); } if (lbl.IsLineAt(geomIndex)) { return(Location.Interior); } return(lbl.GetLineLocation(geomIndex)); }
/// <summary> /// Creates a label which is a copy of another label. /// </summary> /// <param name="lbl">The template label</param> public OverlayLabel(OverlayLabel lbl) { _aLocLeft = lbl._aLocLeft; _aLocRight = lbl._aLocRight; _aLocLine = lbl._aLocLine; _aDim = lbl._aDim; _aIsHole = lbl._aIsHole; _bLocLeft = lbl._bLocLeft; _bLocRight = lbl._bLocRight; _bLocLine = lbl._bLocLine; _bDim = lbl._bDim; _bIsHole = lbl._bIsHole; }
/// <summary> /// Creates a single OverlayEdge. /// </summary> /// <param name="pts"></param> /// <param name="lbl"></param> /// <param name="direction"></param> /// <returns>A new edge based on the given coordinates and direction.</returns> public static OverlayEdge CreateEdge(Coordinate[] pts, OverlayLabel lbl, bool direction) { Coordinate origin; Coordinate dirPt; if (direction) { origin = pts[0]; dirPt = pts[1]; } else { int ilast = pts.Length - 1; origin = pts[ilast]; dirPt = pts[ilast - 1]; } return(new OverlayEdge(origin, dirPt, direction, lbl, pts)); }
/// <summary> /// Checks if the topology indicated by an edge label /// determines that this edge should be part of a result line. /// <para/> /// Note that the logic here relies on the semantic /// that for intersection lines are only returned if /// there is no result area components. /// </summary> /// <param name="lbl">The label for an edge</param> /// <returns><c>true</c> if the edge should be included in the result</returns> private bool IsResultLine(OverlayLabel lbl) { /* * Omit edge which is a boundary of a single geometry * (i.e. not a collapse or line edge as well). * These are only included if part of a result area. * This is a short-circuit for the most common area edge case */ if (lbl.IsBoundarySingleton) { return(false); } /* * Omit edge which is a collapse along a boundary. * I.e a result line edge must be from a input line * OR two coincident area boundaries. * * This logic is only used if not including collapse lines in result. */ if (!_isAllowCollapseLines && lbl.IsBoundaryCollapse) { return(false); } /* * Omit edge which is a collapse interior to its parent area. * (E.g. a narrow gore, or spike off a hole) */ if (lbl.IsInteriorCollapse) { return(false); } /* * For ops other than Intersection, omit a line edge * if it is interior to the other area. * * For Intersection, a line edge interior to an area is included. */ if (_opCode != OverlayNG.INTERSECTION) { /* * Omit collapsed edge in other area interior. */ if (lbl.IsCollapseAndNotPartInterior) { return(false); } /* * If there is a result area, omit line edge inside it. * It is sufficient to check against the input area rather * than the result area, * because if line edges are present then there is only one input area, * and the result area must be the same as the input area. */ if (_hasResultArea && lbl.IsLineInArea(_inputAreaIndex)) { return(false); } } /* * Include line edge formed by touching area boundaries, * if enabled. */ if (_isAllowMixedResult && _opCode == OverlayNG.INTERSECTION && lbl.IsBoundaryTouch) { return(true); } /* * Finally, determine included line edge * according to overlay op boolean logic. */ var aLoc = EffectiveLocation(lbl, 0); var bLoc = EffectiveLocation(lbl, 1); bool isInResult = OverlayNG.IsResultOfOp(_opCode, aLoc, bLoc); return(isInResult); }