/src/geos/include/geos/geom/util/GeometryFixer.h
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (C) 2021 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 | | #pragma once |
16 | | |
17 | | #include <memory> |
18 | | #include <vector> |
19 | | |
20 | | #include <geos/geom/Geometry.h> |
21 | | #include <geos/export.h> |
22 | | |
23 | | // Forward declarations |
24 | | namespace geos { |
25 | | namespace geom { |
26 | | class GeometryFactory; |
27 | | class Point; |
28 | | class Polygon; |
29 | | class LineString; |
30 | | class LinearRing; |
31 | | class MultiPoint; |
32 | | class MultiPolygon; |
33 | | class MultiLineString; |
34 | | class GeometryCollection; |
35 | | } |
36 | | } |
37 | | |
38 | | namespace geos { |
39 | | namespace geom { // geos.geom |
40 | | namespace util { // geos.geom.util |
41 | | |
42 | | /** |
43 | | * Fixes a geometry to be a valid geometry, while preserving as much as |
44 | | * possible of the shape and location of the input. |
45 | | * Validity is determined according to {@link Geometry#isValid()}. |
46 | | * |
47 | | * Input geometries are always processed, so even valid inputs may |
48 | | * have some minor alterations. The output is always a new geometry object. |
49 | | * |
50 | | * <h2>Semantic Rules</h2> |
51 | | * |
52 | | * * Vertices with non-finite X or Y ordinates are removed (as per Coordinate::isValid() ). |
53 | | * * Repeated points are reduced to a single point |
54 | | * * Empty atomic geometries are valid and are returned unchanged |
55 | | * * Empty elements are removed from collections |
56 | | * * <code>Point</code>: keep valid coordinate, or EMPTY |
57 | | * * <code>LineString</code>: coordinates are fixed |
58 | | * * <code>LinearRing</code>: coordinates are fixed, Keep valid ring or else convert into <code>LineString</code> |
59 | | * * <code>Polygon</code>: transform into a valid polygon, |
60 | | * * preserving as much of the extent and vertices as possible. |
61 | | * * Rings are fixed to ensure they are valid< |
62 | | * * Holes intersecting the shell are subtracted from the shell |
63 | | * * Holes outside the shell are converted into polygons |
64 | | * * <code>MultiPolygon</code>: each polygon is fixed, |
65 | | * then result made non-overlapping (via union) |
66 | | * * <code>GeometryCollection</code>: each element is fixed |
67 | | * * Collapsed lines and polygons are handled as follows, |
68 | | * depending on the <code>keepCollapsed</code> setting: |
69 | | * * <code>false</code>: (default) collapses are converted to empty geometries |
70 | | * * <code>true</code>: collapses are converted to a valid geometry of lower dimension |
71 | | * |
72 | | * @author Martin Davis |
73 | | */ |
74 | | class GEOS_DLL GeometryFixer { |
75 | | |
76 | | private: |
77 | | |
78 | | const geom::Geometry* geom; |
79 | | const geom::GeometryFactory* factory; |
80 | | bool isKeepCollapsed; // false |
81 | | |
82 | | public: |
83 | | |
84 | | GeometryFixer(const geom::Geometry* p_geom) |
85 | 0 | : geom(p_geom) |
86 | 0 | , factory(p_geom->getFactory()) |
87 | 0 | , isKeepCollapsed(false) |
88 | 0 | {}; |
89 | | |
90 | | static std::unique_ptr<geom::Geometry> fix(const geom::Geometry* geom); |
91 | | |
92 | | /** |
93 | | * Sets whether collapsed geometries are converted to empty, |
94 | | * (which will be removed from collections), |
95 | | * or to a valid geom::Geometry of lower dimension. |
96 | | * The default is to convert collapses to empty geometries. |
97 | | * |
98 | | * @param p_isKeepCollapsed whether collapses should be converted to a lower dimension geometry |
99 | | */ |
100 | | void setKeepCollapsed(bool p_isKeepCollapsed); |
101 | | |
102 | | /** |
103 | | * Gets the fixed geometry. |
104 | | * |
105 | | * @return the fixed geometry |
106 | | */ |
107 | | std::unique_ptr<geom::Geometry> getResult() const; |
108 | | |
109 | | private: |
110 | | |
111 | | std::unique_ptr<geom::Point> fixPoint(const geom::Point* geom) const; |
112 | | std::unique_ptr<geom::Point> fixPointElement(const geom::Point* geom) const; |
113 | | bool isValidPoint(const geom::Point* pt) const; |
114 | | std::unique_ptr<geom::Geometry> fixMultiPoint(const geom::MultiPoint* geom) const; |
115 | | std::unique_ptr<geom::Geometry> fixLinearRing(const geom::LinearRing* geom) const; |
116 | | std::unique_ptr<geom::Geometry> fixLinearRingElement(const geom::LinearRing* geom) const; |
117 | | std::unique_ptr<geom::Geometry> fixLineString(const geom::LineString* geom) const; |
118 | | std::unique_ptr<geom::Geometry> fixLineStringElement(const geom::LineString* geom) const; |
119 | | |
120 | | /** |
121 | | * Returns a clean copy of the input coordinate array. |
122 | | * |
123 | | * @param pts coordinates to clean |
124 | | * @return an array of clean coordinates |
125 | | */ |
126 | | std::unique_ptr<geom::Geometry> fixMultiLineString(const MultiLineString* geom) const; |
127 | | std::unique_ptr<geom::Geometry> fixPolygon(const geom::Polygon* geom) const; |
128 | | std::unique_ptr<geom::Geometry> fixPolygonElement(const geom::Polygon* geom) const; |
129 | | std::vector<std::unique_ptr<Geometry>> fixHoles(const geom::Polygon* geom) const; |
130 | | std::unique_ptr<geom::Geometry> removeHoles(const geom::Geometry* shell, const geom::Geometry* holes) const; |
131 | | std::unique_ptr<geom::Geometry> fixRing(const geom::LinearRing* ring) const; |
132 | | std::unique_ptr<geom::Geometry> fixMultiPolygon(const geom::MultiPolygon* geom) const; |
133 | | std::unique_ptr<geom::Geometry> fixCollection(const geom::GeometryCollection* geom) const; |
134 | | |
135 | | void classifyHoles( |
136 | | const Geometry* shell, |
137 | | std::vector<std::unique_ptr<Geometry>>& holesFixed, |
138 | | std::vector<const Geometry*>& holes, |
139 | | std::vector<const Geometry*>& shells) const; |
140 | | |
141 | | /** |
142 | | * Subtracts a list of polygonal geometries from a polygonal geometry. |
143 | | * |
144 | | * @param shell polygonal geometry for shell |
145 | | * @param holes polygonal geometries to subtract |
146 | | * @return the result geometry |
147 | | */ |
148 | | std::unique_ptr<Geometry> difference( |
149 | | const Geometry* shell, |
150 | | std::vector<const Geometry*>& holes) const; |
151 | | |
152 | | /** |
153 | | * Unions a list of polygonal geometries. |
154 | | * Optimizes case of zero or one input geometries. |
155 | | * Requires that the inputs are net new objects. |
156 | | * |
157 | | * @param polys the polygonal geometries to union |
158 | | * @return the union of the inputs |
159 | | */ |
160 | | std::unique_ptr<Geometry> unionGeometry( |
161 | | std::vector<const Geometry*>& polys) const; |
162 | | |
163 | | }; |
164 | | |
165 | | } // namespace geos.geom.util |
166 | | } // namespace geos.geom |
167 | | } // namespace geos |
168 | | |
169 | | |