예제 #1
0
 public OverlayEdge(Coordinate orig, Coordinate dirPt, bool direction, OverlayLabel label, Coordinate[] pts) : base(orig)
 {
     DirectionPt = dirPt;
     IsForward   = direction;
     Coordinates = pts;
     Label       = label;
 }
예제 #2
0
        /// <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));
        }
예제 #3
0
        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);
        }
예제 #4
0
 /// <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));
 }
예제 #5
0
        /// <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;
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
        /// <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);
        }