Coverage Report

Created: 2026-02-14 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/include/geos/operation/overlayng/OverlayNGRobust.h
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2020 Paul Ramsey <pramsey@cleverelephant.ca>
7
 *
8
 * This is free software; you can redistribute and/or modify it under
9
 * the terms of the GNU Lesser General Public Licence as published
10
 * by the Free Software Foundation.
11
 * See the COPYING file for more information.
12
 *
13
 **********************************************************************
14
 *
15
 * Last port: operation/overlayng/OverlayNGRobust.java 6ef89b09
16
 *
17
 **********************************************************************/
18
19
#pragma once
20
21
#include <geos/export.h>
22
#include <geos/geom/PrecisionModel.h>
23
#include <geos/operation/union/UnionStrategy.h>
24
#include <geos/operation/overlayng/OverlayNG.h>
25
26
27
// Forward declarations
28
namespace geos {
29
namespace geom {
30
class Geometry;
31
}
32
}
33
34
namespace geos {      // geos.
35
namespace operation { // geos.operation
36
namespace overlayng { // geos.operation.overlayng
37
38
39
/**
40
 * Performs an overlay operation, increasing robustness by using a series of
41
 * increasingly aggressive (and slower) noding strategies.
42
 *
43
 * The noding strategies used are:
44
 *
45
 *  - A simple, fast noder using FLOATING precision.
46
 *  - A {@link noding::snap::SnappingNoder} using an automatically-determined snap tolerance
47
 *  - First snapping each geometry to itself,
48
 *    and then overlaying them using a SnappingNoder.
49
 *  - The above two strategies are repeated with increasing snap tolerance, up to a limit.
50
 *
51
 * If the above heuristics still fail to compute a valid overlay,
52
 * the original {@link util::TopologyException} is thrown.
53
 *
54
 * This algorithm relies on each overlay operation execution
55
 * throwing a {@link util::TopologyException} if it is unable
56
 * to compute the overlay correctly.
57
 * Generally this occurs because the noding phase does
58
 * not produce a valid noding.
59
 * This requires the use of a {@link noding::ValidatingNoder}
60
 * in order to check the results of using a floating noder.
61
 *
62
 * @author Martin Davis
63
 */
64
class GEOS_DLL OverlayNGRobust {
65
    using Geometry = geos::geom::Geometry;
66
67
private:
68
69
70
    // Constants
71
    static constexpr int NUM_SNAP_TRIES = 5;
72
    /**
73
    * A factor for a snapping tolerance distance which
74
    * should allow noding to be computed robustly.
75
    */
76
    static constexpr double SNAP_TOL_FACTOR = 1e12;
77
78
    static std::unique_ptr<Geometry> overlaySnapping(
79
        const Geometry* geom0, const Geometry* geom1, int opCode, double snapTol);
80
81
    static std::unique_ptr<Geometry> overlaySnapBoth(
82
        const Geometry* geom0, const Geometry* geom1, int opCode, double snapTol);
83
84
    static std::unique_ptr<Geometry> overlaySnapTol(
85
        const Geometry* geom0, const Geometry* geom1, int opCode, double snapTol);
86
87
    static double snapTolerance(const Geometry* geom);
88
89
    /**
90
    * Computes the largest magnitude of the ordinates of a geometry,
91
    * based on the geometry envelope.
92
    *
93
    * @param geom a geometry
94
    * @return the magnitude of the largest ordinate
95
    */
96
    static double ordinateMagnitude(const Geometry* geom);
97
98
    /**
99
    * Overlay using Snap-Rounding with an automatically-determined
100
    * scale factor.
101
    *
102
    * NOTE: currently this strategy is not used, since all known
103
    * test cases work using one of the Snapping strategies.
104
    */
105
    static std::unique_ptr<Geometry>
106
    overlaySR(const Geometry* geom0, const Geometry* geom1, int opCode);
107
108
  /**
109
     * Self-snaps a geometry by running a union operation with it as the only input.
110
     * This helps to remove narrow spike/gore artifacts to simplify the geometry,
111
     * which improves robustness.
112
     * Collapsed artifacts are removed from the result to allow using
113
     * it in further overlay operations.
114
     *
115
     * @param geom geometry to self-snap
116
     * @param snapTol snap tolerance
117
     * @return the snapped geometry (homogeneous)
118
     */
119
  static std::unique_ptr<Geometry>
120
  snapSelf(const Geometry* geom, double snapTol);
121
122
123
public:
124
125
    class SRUnionStrategy : public operation::geounion::UnionStrategy {
126
127
        std::unique_ptr<geom::Geometry> Union(const geom::Geometry* g0, const geom::Geometry* g1) override
128
136k
        {
129
136k
            return OverlayNGRobust::Overlay(g0, g1, OverlayNG::UNION);
130
136k
        };
131
132
        bool isFloatingPrecision() const override
133
0
        {
134
0
            return true;
135
0
        };
136
137
    };
138
139
    static std::unique_ptr<Geometry> Intersection(
140
        const Geometry* g0, const Geometry* g1);
141
142
    static std::unique_ptr<Geometry> Union(
143
        const Geometry* g0, const Geometry* g1);
144
145
    static std::unique_ptr<Geometry> Difference(
146
        const Geometry* g0, const Geometry* g1);
147
148
    static std::unique_ptr<Geometry> SymDifference(
149
        const Geometry* g0, const Geometry* g1);
150
151
    static std::unique_ptr<Geometry> Union(
152
        const Geometry* a);
153
154
    static std::unique_ptr<Geometry> Overlay(
155
        const Geometry* geom0, const Geometry* geom1, int opCode);
156
157
    static std::unique_ptr<Geometry> overlaySnapTries(
158
        const Geometry* geom0, const Geometry* geom1, int opCode);
159
160
    /**
161
    * Computes a heuristic snap tolerance distance
162
    * for overlaying a pair of geometries using a {@link noding::snap::SnappingNoder}.
163
    */
164
    static double snapTolerance(const Geometry* geom0, const Geometry* geom1);
165
166
167
168
169
};
170
171
172
} // namespace geos.operation.overlayng
173
} // namespace geos.operation
174
} // namespace geos
175