Coverage Report

Created: 2024-07-27 06:14

/src/geos/include/geos/precision/GeometryPrecisionReducer.h
Line
Count
Source (jump to first uncovered line)
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2012 Sandro Santilli <strk@kbt.io>
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: precision/GeometryPrecisionReducer.cpp rev. 1.10 (JTS-1.7)
16
 *
17
 **********************************************************************/
18
19
#pragma once
20
21
#include <geos/export.h>
22
#include <geos/geom/GeometryFactory.h> // for GeometryFactory::Ptr
23
#include <memory> // for unique_ptr
24
25
// Forward declarations
26
namespace geos {
27
namespace geom {
28
class PrecisionModel;
29
class GeometryFactory;
30
class Geometry;
31
}
32
}
33
34
namespace geos {
35
namespace precision { // geos.precision
36
37
/** \brief
38
 * Reduces the precision of a {@link geom::Geometry}
39
 * according to the supplied {@link geom::PrecisionModel},
40
 * ensuring that the result is valid (unless specified otherwise).
41
 *
42
 * By default the reduced result is topologically valid
43
 * To ensure this a polygonal geometry is reduced in a topologically valid fashion
44
 * (technically, by using snap-rounding).
45
 * It can be forced to be reduced pointwise by using setPointwise(boolean).
46
 * Note that in this case the result geometry may be invalid.
47
 * Linear and point geometry is always reduced pointwise (i.e. without further change to
48
 * its topology or structure), since this does not change validity.
49
 *
50
 * By default the geometry precision model is not changed.
51
 * This can be overridden by usingsetChangePrecisionModel(boolean).
52
 *
53
 * Normally collapsed components (e.g. lines collapsing to a point)
54
 * are not included in the result.
55
 * This behavior can be changed by using setRemoveCollapsedComponents(boolean).
56
 */
57
class GEOS_DLL GeometryPrecisionReducer {
58
59
private:
60
61
    // Externally owned
62
    const geom::GeometryFactory* newFactory;
63
64
    const geom::PrecisionModel& targetPM;
65
66
    bool removeCollapsed;
67
    bool changePrecisionModel;
68
    bool useAreaReducer;
69
    bool isPointwise;
70
71
    std::unique_ptr<geom::Geometry> fixPolygonalTopology(const geom::Geometry& geom);
72
73
    geom::GeometryFactory::Ptr createFactory(
74
        const geom::GeometryFactory& oldGF,
75
        const geom::PrecisionModel& newPM);
76
77
    /**
78
    * Duplicates a geometry to one that uses a different PrecisionModel,
79
    * without changing any coordinate values.
80
    *
81
    * @param geom the geometry to duplicate
82
    * @param newPM the precision model to use
83
    * @return the geometry value with a new precision model
84
    */
85
    std::unique_ptr<geom::Geometry> changePM(
86
        const geom::Geometry* geom,
87
        const geom::PrecisionModel& newPM);
88
89
    GeometryPrecisionReducer(GeometryPrecisionReducer const&); /*= delete*/
90
    GeometryPrecisionReducer& operator=(GeometryPrecisionReducer const&); /*= delete*/
91
92
public:
93
94
    /**
95
     * Convenience method for doing precision reduction
96
     * on a single geometry,
97
     * with collapses removed
98
     * and keeping the geometry precision model the same,
99
     * and preserving polygonal topology.
100
     *
101
     * @param g the geometry to reduce
102
     * @param precModel the precision model to use
103
     * @return the reduced geometry
104
     */
105
    static std::unique_ptr<geom::Geometry>
106
    reduce(const geom::Geometry& g, const geom::PrecisionModel& precModel);
107
108
    static std::unique_ptr<geom::Geometry>
109
    reducePointwise(const geom::Geometry& g, const geom::PrecisionModel& precModel);
110
111
    static std::unique_ptr<geom::Geometry>
112
    reduceKeepCollapsed(const geom::Geometry& g, const geom::PrecisionModel& precModel);
113
114
    GeometryPrecisionReducer(const geom::PrecisionModel& pm)
115
        : newFactory(nullptr)
116
        , targetPM(pm)
117
        , removeCollapsed(true)
118
        , changePrecisionModel(false)
119
        , useAreaReducer(false)
120
        , isPointwise(false)
121
0
    {}
122
123
    /**
124
     * \brief
125
     * Create a reducer that will change the precision model of the
126
     * new reduced Geometry
127
     *
128
     * @param changeFactory the factory for the created Geometry.
129
     *           Its PrecisionModel will be used for the reduction.
130
     *           NOTE: ownership left to caller must be kept alive for
131
     *           the whole lifetime of the returned Geometry.
132
     */
133
    GeometryPrecisionReducer(const geom::GeometryFactory& changeFactory)
134
        : newFactory(&changeFactory)
135
        , targetPM(*(changeFactory.getPrecisionModel()))
136
        , removeCollapsed(true)
137
        , changePrecisionModel(false)
138
        , useAreaReducer(false)
139
        , isPointwise(false)
140
0
    {}
141
142
    /**
143
     * Sets whether the reduction will result in collapsed components
144
     * being removed completely, or simply being collapsed to an (invalid)
145
     * Geometry of the same type.
146
     *
147
     * @param remove if true collapsed components will be removed
148
     */
149
    void
150
    setRemoveCollapsedComponents(bool remove)
151
0
    {
152
0
        removeCollapsed = remove;
153
0
    }
154
155
    /** \brief
156
    * Sets whether the {@link geom::PrecisionModel} of the new reduced Geometry
157
    * will be changed to be the {@link geom::PrecisionModel} supplied to
158
    * specify the precision reduction.
159
    * The default is to not change the precision model
160
    *
161
    * @param change if true the precision
162
    * model of the created Geometry will be the
163
    * the precisionModel supplied in the constructor.
164
    */
165
    void
166
    setChangePrecisionModel(bool change)
167
0
    {
168
0
        changePrecisionModel = change;
169
0
    }
170
171
    void
172
    setUseAreaReducer(bool useAR)
173
0
    {
174
0
        useAreaReducer = useAR;
175
0
    }
176
177
    /** \brief
178
     * Sets whether the precision reduction will be done
179
     * in pointwise fashion only.
180
     *
181
     * Pointwise precision reduction reduces the precision
182
     * of the individual coordinates only, but does
183
     * not attempt to recreate valid topology.
184
     * This is only relevant for geometries containing polygonal components.
185
     *
186
     * @param pointwise if reduction should be done pointwise only
187
     */
188
    void
189
    setPointwise(bool pointwise)
190
0
    {
191
0
        isPointwise = pointwise;
192
0
    }
193
194
    std::unique_ptr<geom::Geometry> reduce(const geom::Geometry& geom);
195
196
197
198
};
199
200
} // namespace geos.precision
201
} // namespace geos
202