/// <summary>
        /// Marks an edge which forms part of the boundary of the result area.
        /// This is determined by the overlay operation being executed,
        /// and the location of the edge.
        /// The relevant location is either the right side of a boundary edge,
        /// or the line location of a non-boundary edge.
        /// </summary>
        /// <param name="e">The edge to mark</param>
        /// <param name="overlayOpCode">The overlay operation</param>
        public void MarkInResultArea(OverlayEdge e, SpatialFunction overlayOpCode)
        {
            var label = e.Label;

            if (label.IsBoundaryEither &&
                OverlayNG.IsResultOfOp(
                    overlayOpCode,
                    label.GetLocationBoundaryOrLine(0, Position.Right, e.IsForward),
                    label.GetLocationBoundaryOrLine(1, Position.Right, e.IsForward)))
            {
                e.MarkInResultArea();
            }
            //Debug.println("markInResultArea: " + e);
        }
Ejemplo n.º 2
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);
        }