/// <summary> /// Creates a builder for linear elements which may be present /// in the overlay result. /// </summary> /// <param name="inputGeom">The input geometries</param> /// <param name="graph">The topology graph</param> /// <param name="hasResultArea"><c>true</c> if an area has been generated for the result</param> /// <param name="opCode">The overlay operation code</param> /// <param name="geomFact">The output geometry factory</param> public LineBuilder(InputGeometry inputGeom, OverlayGraph graph, bool hasResultArea, SpatialFunction opCode, GeometryFactory geomFact) { _graph = graph; _opCode = opCode; _geometryFactory = geomFact; _hasResultArea = hasResultArea; _inputAreaIndex = inputGeom.GetAreaIndex(); }
/// <summary> /// Computes a clipping envelope for overlay input geometries. /// The clipping envelope encloses all geometry line segments which /// might participate in the overlay, with a buffer to /// account for numerical precision /// (in particular, rounding due to a precision model. /// The clipping envelope is used in both the <see cref="RingClipper"/> /// and in the <see cref="LineLimiter"/>. /// <para/> /// Some overlay operations (i.e. <see cref="SpatialFunction.Union"/> and <see cref="SpatialFunction.SymDifference"/>) /// cannot use clipping as an optimization, /// since the result envelope is the full extent of the two input geometries. /// In this case the returned /// envelope is <c>null</c> to indicate this. /// </summary> /// <param name="opCode">The overlay op code</param> /// <param name="inputGeom">The input geometries</param> /// <param name="pm">The precision model being used</param> /// <returns>An envelope for clipping and line limiting, or null if no clipping is performed</returns> internal static Envelope ClippingEnvelope(SpatialFunction opCode, InputGeometry inputGeom, PrecisionModel pm) { var resultEnv = ResultEnvelope(opCode, inputGeom, pm); if (resultEnv == null) { return(null); } var clipEnv = RobustClipEnvelopeComputer.GetEnvelope( inputGeom.GetGeometry(0), inputGeom.GetGeometry(1), resultEnv); var safeEnv = SafeEnv(clipEnv, pm); return(safeEnv); }
/// <summary> /// Computes an envelope which covers the extent of the result of /// a given overlay operation for given inputs. /// The operations which have a result envelope smaller than the extent of the inputs /// are: /// <list type="bullet"> /// <item><term><see cref="SpatialFunction.Intersection"/></term> /// <description>result envelope is the intersection of the input envelopes</description></item> /// <item><term><see cref="SpatialFunction.Difference"/></term> /// <description>result envelope is the envelope of the A input geometry</description></item> /// </list> /// Otherwise, <c>null</c> is returned to indicate full extent. /// </summary> /// <param name="opCode">The overlay op code</param> /// <param name="inputGeom">The input geometries</param> /// <param name="pm">The precision model being used</param> /// <returns>The result envelope, or null if the full extent</returns> private static Envelope ResultEnvelope(SpatialFunction opCode, InputGeometry inputGeom, PrecisionModel pm) { Envelope overlapEnv = null; switch (opCode) { case OverlayNG.INTERSECTION: var envA = SafeEnv(inputGeom.GetEnvelope(0), pm); var envB = SafeEnv(inputGeom.GetEnvelope(1), pm); overlapEnv = envA.Intersection(envB); break; case OverlayNG.DIFFERENCE: overlapEnv = SafeEnv(inputGeom.GetEnvelope(0), pm); break; } // return null for UNION and SYMDIFFERENCE to indicate no clipping return(overlapEnv); }
/// <summary> /// Creates an overlay operation on the given geometries, /// with a defined precision model. /// </summary> /// <param name="geom0">The A operand geometry</param> /// <param name="geom1">The B operand geometry (may be <c>null</c>)</param> /// <param name="pm">The precision model to use</param> /// <param name="opCode">The overlay opcode</param> public OverlayNG(Geometry geom0, Geometry geom1, PrecisionModel pm, 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."); } _pm = pm; _opCode = opCode; _geomFact = geom0.Factory; _inputGeom = new InputGeometry(geom0, geom1); }
public OverlayLabeller(OverlayGraph graph, InputGeometry inputGeometry) { _graph = graph; _inputGeometry = inputGeometry; _edges = graph.Edges; }