Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
OGRRingAdapter.hpp
Go to the documentation of this file.
1#pragma once
3#include <fishnet/Segment.hpp>
9
10namespace fishnet::geometry{
11
31private:
32 static OGRUniquePtr<OGRPolygon> asPolygon(OGRUniquePtr<OGRLinearRing> && ringPtr) {
33 ringPtr->closeRings();
34 auto polygon = emptyPolygon();
35 polygon->addRingDirectly(ringPtr.release());
36 return polygon;
37 }
38
39 OGRRingAdapter(OGRUniquePtr<OGRPolygon> && polygonPtr, Canonical canonical)
40 :OGRPolygonalAdapter(std::move(polygonPtr), canonical) {}
41
51 static OGRRingAdapter fromCanonicalRing(const OGRLinearRing & ring) {
52 auto polygon = emptyPolygon();
53 polygon->addRingDirectly(ring.clone());
54 return OGRRingAdapter(std::move(polygon), Canonical{});
55 }
56
64 static OGRRingAdapter fromCanonicalHole(const OGRLinearRing & hole) {
65 auto ring = OGRUniquePtr<OGRLinearRing>(hole.clone());
66 ring->reversePoints();
67 auto polygon = emptyPolygon();
68 polygon->addRingDirectly(ring.release());
69 return OGRRingAdapter(std::move(polygon), Canonical{});
70 }
71
72
83 static OGRRingAdapter borrowed(OGRLinearRing * ring) {
84 return OGRRingAdapter(__impl::borrowRingAsPolygon(ring), Canonical{});
85 }
86
87 friend class OGRPolygonAdapter;
88 friend class OGRGeometryAdapter;
89
94 int openPointCount() const {
95 return std::max(0, exteriorRing()->getNumPoints() - 1);
96 }
97
105 OGRUniquePtr<OGRGeometry> releaseGeometry() && noexcept {
106 auto * ring = geomPtr->getExteriorRing();
107 geomPtr->removeRing(0, false); // detach without deleting; the emptied shell is discarded with this adapter
108 return OGRUniquePtr<OGRGeometry>(ring);
109 }
110
111public:
113
114 using numeric_type = double;
115 static constexpr GeometryType type = GeometryType::RING;
116
117 OGRRingAdapter(OGRUniquePtr<OGRLinearRing> && ringPtr):OGRPolygonalAdapter(asPolygon(std::move(ringPtr))) {}
118
120
122
129 auto getSegments() const & -> fishnet::util::forward_range_of<fishnet::geometry::Segment<double>> auto {
130 return std::ranges::views::iota(0, openPointCount())
131 | std::ranges::views::transform([this](int i) {
132 const auto * ring = exteriorRing();
133 Vec2DReal p1 {ring->getX(i), ring->getY(i)};
134 Vec2DReal p2 {ring->getX(i + 1), ring->getY(i + 1)};
135 return Segment<double>(p1, p2);
136 });
137 }
138
149 std::vector<fishnet::geometry::Segment<double>> getSegments() const && {
150 return fishnet::util::toVector(this->getSegments());
151 }
152
154 auto getPoints() const & -> fishnet::util::forward_range_of<fishnet::geometry::Vec2DReal> auto {
155 return std::ranges::views::iota(0, openPointCount())
156 | std::ranges::views::transform([this](int i) {
157 const auto * ring = exteriorRing();
158 return Vec2DReal(ring->getX(i), ring->getY(i));
159 });
160 }
161
163 std::vector<fishnet::geometry::Vec2DReal> getPoints() const && {
164 return fishnet::util::toVector(this->getPoints());
165 }
166
168 return *this;
169 }
170
179 return Ring<double>(getPoints(), true);
180 }
181
182 std::vector<OGRRingAdapter> getHoles() const{
183 return {};
184 }
185
192 Vec2DReal sum {0,0};
193 size_t count = 0;
194 for(const auto & point : getPoints()){
195 sum = sum + point;
196 ++count;
197 }
198 return sum / static_cast<double>(count);
199 }
200
201 bool intersects(const LinearGeometry auto & linearFeature) const{
202 return ringIntersects(*this, linearFeature);
203 }
204
205 std::unordered_set<Vec2DReal> intersections(const LinearGeometry auto & linearFeature) const{
206 auto intersectionRange = this->getSegments()
207 | std::views::transform([&linearFeature](const auto & segment){return segment.intersection(linearFeature);})
208 | std::views::filter([](const auto & optIntersection){return optIntersection.has_value();})
209 | std::views::transform([](const auto & optIntersection){return optIntersection.value();});
210 return std::unordered_set<Vec2D<double>> {std::ranges::begin(intersectionRange), std::ranges::end(intersectionRange)};
211 }
212
213 bool crosses(const IRing auto & other) const{
214 if(not this->aaBB().overlap(other.aaBB()))
215 return false;
216 return std::ranges::any_of(this->getSegments(),[&other](const auto & s){return other.intersects(s);})
217 || std::ranges::any_of(other.getSegments(),[this](const auto & s){return this->intersects(s);});
218 }
219
220 bool touches(const IRing auto & other) const{
221 if(not this->aaBB().overlap(other.aaBB()))
222 return false;
223 if(this->crosses(other))
224 return false;
225 if(this->contains(other) || other.contains(*this)) return false;
226 for(const auto & p : other.getPoints()){
227 if(this->isOnBoundary(p)) return true;
228 }
229 return false;
230 }
231
232 double distance(const IRing auto & other) const{
233 if(this->contains(other) or other.contains(*this) or this->crosses(other))
234 return 0;
235 return shapeDistance(*this,other);
236 }
237
238 double distance(const OGRRingAdapter & other) const{
239 return geomPtr->Distance(other.geomPtr.get());
240 }
241};
242static_assert(IRing<OGRRingAdapter>);
243}
OGRUniquePtr< OGRPolygon > geomPtr
Definition OGRAdapterBase.hpp:85
Adapter for an OGRGeometry of statically unknown type, as handed out by a data source.
Definition OGRGeometryAdapter.hpp:83
IPolygon implementation backed by an OGRPolygon.
Definition OGRPolygonAdapter.hpp:22
Common base of the OGR backed adapters which enclose an area.
Definition OGRPolygonalAdapter.hpp:24
const OGRLinearRing * exteriorRing() const noexcept
Definition OGRPolygonalAdapter.hpp:116
bool contains(const IPoint auto &point) const
Definition OGRPolygonalAdapter.hpp:178
static OGRUniquePtr< OGRPolygon > toOGRPolygon(const IRing auto &ring)
Copy an arbitrary IRing into an OGRPolygon, ready to be used with GEOS.
Definition OGRPolygonalAdapter.hpp:44
bool isOnBoundary(const IPoint auto &point) const
Definition OGRPolygonalAdapter.hpp:165
Rectangle< double > aaBB() const
Definition OGRPolygonalAdapter.hpp:151
static OGRUniquePtr< OGRPolygon > emptyPolygon()
Definition OGRPolygonalAdapter.hpp:28
IRing implementation backed by an OGRPolygon holding nothing but an exterior ring.
Definition OGRRingAdapter.hpp:30
static constexpr GeometryType type
Definition OGRRingAdapter.hpp:115
OGRRingAdapter(OGRUniquePtr< OGRLinearRing > &&ringPtr)
Definition OGRRingAdapter.hpp:117
double distance(const OGRRingAdapter &other) const
Definition OGRRingAdapter.hpp:238
bool contains(const IPoint auto &point) const
Definition OGRPolygonalAdapter.hpp:178
Vec2DReal centroid() const
Centroid of the ring, i.e. the mean of its points.
Definition OGRRingAdapter.hpp:191
std::vector< fishnet::geometry::Segment< double > > getSegments() const &&
The segments of the ring, eagerly copied out into an owning vector.
Definition OGRRingAdapter.hpp:149
std::vector< fishnet::geometry::Vec2DReal > getPoints() const &&
&&
Definition OGRRingAdapter.hpp:163
auto getPoints() const &-> fishnet::util::forward_range_of< fishnet::geometry::Vec2DReal > auto
The segments of the ring, lazily read through this adapter on every access.
Definition OGRRingAdapter.hpp:154
double distance(const IRing auto &other) const
Definition OGRRingAdapter.hpp:232
bool crosses(const IRing auto &other) const
Definition OGRRingAdapter.hpp:213
std::vector< OGRRingAdapter > getHoles() const
Definition OGRRingAdapter.hpp:182
bool touches(const IRing auto &other) const
Definition OGRRingAdapter.hpp:220
std::unordered_set< Vec2DReal > intersections(const LinearGeometry auto &linearFeature) const
Definition OGRRingAdapter.hpp:205
OGRRingAdapter(IRing auto const &ring)
Definition OGRRingAdapter.hpp:121
bool intersects(const LinearGeometry auto &linearFeature) const
Definition OGRRingAdapter.hpp:201
OGRRingAdapter(OGRUniquePtr< OGRPolygon > &&polygonPtr)
Definition OGRRingAdapter.hpp:119
Ring< double > toNative() const
Copy the ring out into a fishnet Ring, which precomputes its segments.
Definition OGRRingAdapter.hpp:178
auto getSegments() const &-> fishnet::util::forward_range_of< fishnet::geometry::Segment< double > > auto
The segments of the ring, lazily read through this adapter on every access.
Definition OGRRingAdapter.hpp:129
double numeric_type
Definition OGRRingAdapter.hpp:114
const OGRRingAdapter & getBoundary() const
Definition OGRRingAdapter.hpp:167
Implementation of a ring.
Definition Ring.hpp:31
Implementation of a segment.
Definition Segment.hpp:14
Implementation of a two-dimensional vector.
Definition Vec2D.hpp:16
constexpr T getX() const noexcept
Definition Vec2D.hpp:85
Interface for a ring A ring is a closed loop of segments, forming a boundary of a shape.
Definition IRing.hpp:143
Definition IGeometry.hpp:13
Definition BoundingBoxWrapper.hpp:5
std::unique_ptr< T, __impl::OGRGeometryDeleter > OGRUniquePtr
Definition OGRAdapterBase.hpp:48
GeometryType
Definition GeometryBase.hpp:6
Vec2D< fishnet::math::DEFAULT_FLOATING_POINT > Vec2DReal
Definition Vec2D.hpp:220
static fishnet::math::DEFAULT_FLOATING_POINT shapeDistance(Shape auto const &lhs, Shape auto const &rhs, util::BiFunction< Vec2DReal, Vec2DReal, fishnet::math::DEFAULT_FLOATING_POINT > auto const &distanceFunction) noexcept
Compute the distance between two shapes, with custom distance function.
Definition PolygonDistance.hpp:465
static constexpr bool ringIntersects(const R &ring, const L &linearFeature) noexcept
test whether a linear feature intersects a ring Check every intersection of the linear feature with t...
Definition RingIntersection.hpp:28
constexpr auto toVector(R &&range)
Definition CollectionConcepts.hpp:64
Definition BFSClustering.hpp:5
STL namespace.
Tag for a polygon which is known to be in canonical form already.
Definition OGRPolygonalAdapter.hpp:125