/src/geos/src/geom/CurvePolygon.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (C) 2024 ISciences, LLC |
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 | | #include <geos/algorithm/Area.h> |
16 | | #include <geos/geom/Curve.h> |
17 | | #include <geos/geom/CurvePolygon.h> |
18 | | #include <geos/geom/CoordinateSequence.h> |
19 | | #include <geos/geom/GeometryFactory.h> |
20 | | #include <geos/geom/LineString.h> |
21 | | #include <geos/geom/MultiCurve.h> |
22 | | #include <geos/geom/SimpleCurve.h> |
23 | | #include <geos/util/UnsupportedOperationException.h> |
24 | | |
25 | | namespace geos { |
26 | | namespace geom { |
27 | | |
28 | | std::unique_ptr<CoordinateSequence> |
29 | | CurvePolygon::getCoordinates() const |
30 | 0 | { |
31 | 0 | auto coordinates = shell->getCoordinates(); |
32 | 0 | for (const auto& hole : holes) { |
33 | 0 | if (auto simpleHole = dynamic_cast<const SimpleCurve*>(hole.get())) { |
34 | 0 | coordinates->add(*simpleHole->getCoordinatesRO()); |
35 | 0 | } else { |
36 | 0 | coordinates->add(*hole->getCoordinates()); |
37 | 0 | } |
38 | 0 | } |
39 | 0 | return coordinates; |
40 | 0 | } |
41 | | |
42 | 60 | std::string CurvePolygon::getGeometryType() const { |
43 | 60 | return "CurvePolygon"; |
44 | 60 | } |
45 | | |
46 | 2.14k | GeometryTypeId CurvePolygon::getGeometryTypeId() const { |
47 | 2.14k | return GEOS_CURVEPOLYGON; |
48 | 2.14k | } |
49 | | |
50 | | static std::unique_ptr<Geometry> |
51 | | getRingForBoundary(const Geometry* ring) |
52 | 0 | { |
53 | | // Convert LinearRing -> LineString |
54 | 0 | if (ring->getGeometryTypeId() == GEOS_LINEARRING) { |
55 | 0 | return ring->getFactory()->createLineString(*static_cast<const LineString*>(ring)); |
56 | 0 | } |
57 | 0 | return ring->clone(); |
58 | 0 | } |
59 | | |
60 | | std::unique_ptr<Geometry> |
61 | 0 | CurvePolygon::getBoundary() const { |
62 | |
|
63 | 0 | const GeometryFactory* gf = getFactory(); |
64 | |
|
65 | 0 | if(isEmpty()) { |
66 | 0 | return gf->createMultiCurve(); |
67 | 0 | } |
68 | | |
69 | 0 | if(holes.empty()) { |
70 | 0 | return getRingForBoundary(shell.get()); |
71 | 0 | } |
72 | | |
73 | 0 | std::vector<std::unique_ptr<Geometry>> rings(holes.size() + 1); |
74 | |
|
75 | 0 | rings[0] = getRingForBoundary(shell.get()); |
76 | 0 | for(std::size_t i = 0; i < holes.size(); ++i) { |
77 | 0 | rings[i + 1] = getRingForBoundary(holes[i].get()); |
78 | 0 | } |
79 | |
|
80 | 0 | return getFactory()->createMultiCurve(std::move(rings)); |
81 | 0 | } |
82 | | |
83 | | void |
84 | | CurvePolygon::normalize() |
85 | 0 | { |
86 | 0 | shell->normalize(); |
87 | 0 | for(auto& lr : holes) { |
88 | 0 | lr->normalize(); |
89 | 0 | lr = lr->reverse(); |
90 | 0 | } |
91 | 0 | std::sort(holes.begin(), holes.end(), [](const auto& a, const auto& b) { |
92 | 0 | return a->compareTo(b.get()) > 0; |
93 | 0 | }); |
94 | 0 | } |
95 | | |
96 | 306 | double CurvePolygon::getArea() const { |
97 | 306 | double sum = algorithm::Area::ofClosedCurve(*shell); |
98 | 306 | for (const auto& hole : holes) { |
99 | 119 | sum -= algorithm::Area::ofClosedCurve(*hole); |
100 | 119 | } |
101 | 306 | return sum; |
102 | 306 | } |
103 | | |
104 | 383 | bool CurvePolygon::hasCurvedComponents() const { |
105 | 383 | if (shell->hasCurvedComponents()) { |
106 | 1 | return true; |
107 | 1 | } |
108 | 382 | for (const auto& hole : holes) { |
109 | 132 | if (hole->hasCurvedComponents()) { |
110 | 0 | return true; |
111 | 0 | } |
112 | 132 | } |
113 | 382 | return false; |
114 | 382 | } |
115 | | |
116 | | Geometry* |
117 | 24 | CurvePolygon::cloneImpl() const { |
118 | 24 | return new CurvePolygon(*this); |
119 | 24 | } |
120 | | |
121 | | Geometry* |
122 | 0 | CurvePolygon::reverseImpl() const { |
123 | 0 | std::unique_ptr<Curve> revShell(static_cast<Curve*>(shell->reverse().release())); |
124 | 0 | std::vector<std::unique_ptr<Curve>> revHoles(holes.size()); |
125 | 0 | for (std::size_t i = 0; i < revHoles.size(); i++) { |
126 | 0 | revHoles[i].reset(static_cast<Curve*>(holes[i]->reverse().release())); |
127 | 0 | } |
128 | 0 | return new CurvePolygon(std::move(revShell), std::move(revHoles), *getFactory()); |
129 | 0 | } |
130 | | |
131 | | } |
132 | | } |