/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 | | |