コード例 #1
0
        /// <summary>
        /// Unions a collection of geometries
        /// using a given precision model.
        /// <para/>
        /// This class is most useful for performing UnaryUnion using
        /// a fixed-precision model.
        /// For unary union using floating precision,
        /// <see cref="OverlayNGRobust.Union(Geometry)"/> should be used.
        /// </summary>
        /// <param name="geom">The geometry to union</param>
        /// <param name="pm">The precision model to use</param>
        /// <returns>The union of the geometries</returns>
        /// <seealso cref="OverlayNGRobust"/>
        public static Geometry Union(Geometry geom, PrecisionModel pm)
        {
            if (geom == null)
            {
                throw new ArgumentNullException(nameof(geom));
            }

            var unionSRFun = new UnionStrategy((g0, g1) =>
                                               OverlayNG.Overlay(g0, g1, SpatialFunction.Union, pm), OverlayUtility.IsFloating(pm));

            var op = new UnaryUnionOp(geom)
            {
                UnionStrategy = unionSRFun
            };

            return(op.Union());
        }
コード例 #2
0
        //===============================================

        /// <summary>
        /// Attempt Overlay using Snap-Rounding with an automatically-determined
        /// scale factor.
        /// </summary>
        /// <param name="geom0"></param>
        /// <param name="geom1"></param>
        /// <param name="opCode"></param>
        /// <returns>the computed overlay result, or null if the overlay fails</returns>
        public static Geometry OverlaySR(Geometry geom0, Geometry geom1, SpatialFunction opCode)
        {
            Geometry result;

            try
            {
                //System.out.println("OverlaySnapIfNeeded: trying snap-rounding");
                double scaleSafe = PrecisionUtility.SafeScale(geom0, geom1);
                var    pmSafe    = new PrecisionModel(scaleSafe);
                result = OverlayNG.Overlay(geom0, geom1, opCode, pmSafe);
                return(result);
            }
            catch (TopologyException ex)
            {
                //---- ignore exception, return null result to indicate failure
            }
            return(null);
        }
コード例 #3
0
        /// <summary>
        /// Overlay two geometries, using heuristics to ensure
        /// computation completes correctly.
        /// In practice the heuristics are observed to be fully correct.
        /// </summary>
        /// <param name="geom0">A geometry</param>
        /// <param name="geom1">A geometry</param>
        /// <param name="opCode">The overlay operation code</param>
        /// <returns>The overlay result geometry</returns>
        public static Geometry Overlay(Geometry geom0, Geometry geom1, SpatialFunction opCode)
        {
            if (geom0 == null)
            {
                throw new ArgumentNullException(nameof(geom0));
            }

            switch (opCode)
            {
            case SpatialFunction.Intersection:
            case SpatialFunction.Union:
            case SpatialFunction.Difference:
            case SpatialFunction.SymDifference:
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(opCode), opCode, "Only Intersection, Union, Difference, and SymDifference are recognized at this time.");
            }

            /*
             * First try overlay with a PrecisionModels.Floating noder, which is
             * fast and causes least change to geometry coordinates
             * By default the noder is validated, which is required in order
             * to detect certain invalid noding situations which otherwise
             * cause incorrect overlay output.
             */
            try
            {
                return(OverlayNG.Overlay(geom0, geom1, opCode));
            }
            catch (Exception ex)
            {
                /*
                 * On failure retry using snapping noding with a "safe" tolerance.
                 * if this throws an exception just let it go,
                 * since it is something that is not a TopologyException
                 */
                try
                {
                    if (OverlaySnapTries(geom0, geom1, opCode) is Geometry result)
                    {
                        return(result);
                    }
                }
                catch (Exception ex2)
                {
                    throw new AggregateException(ex, ex2);
                }

                /*
                 * On failure retry using snap-rounding with a heuristic scale factor (grid size).
                 */
                try
                {
                    if (OverlaySR(geom0, geom1, opCode) is Geometry result)
                    {
                        return(result);
                    }
                }
                catch (Exception ex2)
                {
                    throw new AggregateException(ex, ex2);
                }

                /*
                 * Just can't get overlay to work, so throw original error.
                 */
                throw;
            }
        }
コード例 #4
0
        private static Geometry OverlaySnapTol(Geometry geom0, Geometry geom1, SpatialFunction opCode, double snapTol)
        {
            var snapNoder = new SnappingNoder(snapTol);

            return(OverlayNG.Overlay(geom0, geom1, opCode, snapNoder));
        }