Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
OGRPolygonalAdapter.hpp
Go to the documentation of this file.
1#pragma once
2#include <algorithm>
4#include <fishnet/Segment.hpp>
6#include "OGRAdapterBase.hpp"
7
8namespace fishnet::geometry{
9
24class OGRPolygonalAdapter: public OGRAdapterBase<OGRPolygon>{
25protected:
27
29 return OGRUniquePtr<OGRPolygon>(static_cast<OGRPolygon*>(OGRGeometryFactory::createGeometry(wkbPolygon)));
30 }
31
32 static OGRLinearRing toLinearRing(const IRing auto & ring) {
33 OGRLinearRing ogrRing;
34 for(const auto & point : ring.getPoints()){
35 ogrRing.addPoint(point.getX(), point.getY());
36 }
37 ogrRing.closeRings();
38 return ogrRing;
39 }
40
44 static OGRUniquePtr<OGRPolygon> toOGRPolygon(const IRing auto & ring) {
45 auto polygon = emptyPolygon();
46 auto boundary = toLinearRing(ring);
47 polygon->addRing(&boundary);
48 return polygon;
49 }
50
54 static OGRUniquePtr<OGRPolygon> toOGRPolygon(const IPolygon auto & polygon) {
55 auto ogrPolygon = emptyPolygon();
56 auto boundary = toLinearRing(polygon.getBoundary());
57 ogrPolygon->addRing(&boundary);
58 for(const auto & hole : polygon.getHoles()){
59 auto ogrHole = toLinearRing(hole);
60 ogrPolygon->addRing(&ogrHole);
61 }
62 return ogrPolygon;
63 }
64
73 static bool covers(const OGRGeometry & covering, const OGRGeometry & covered) {
74 auto difference = OGRUniquePtr<OGRGeometry>(covered.Difference(&covering));
75 return difference && difference->IsEmpty();
76 }
77
87 void canonicalize() noexcept {
88 auto normalized = OGRUniquePtr<OGRGeometry>(geomPtr->Normalize());
89 if(normalized && wkbFlatten(normalized->getGeometryType()) == wkbPolygon){
90 geomPtr.reset(normalized.release()->toPolygon());
91 }
92 }
93
104 bool envelopeOverlaps(const IPoint auto & lhs, const IPoint auto & rhs) const noexcept {
105 OGREnvelope envelope;
106 geomPtr->getEnvelope(&envelope);
107 // NOTE: not std::minmax, which returns references to its arguments and would dangle here
108 const double lhsX = lhs.getX(), rhsX = rhs.getX();
109 const double lhsY = lhs.getY(), rhsY = rhs.getY();
110 const double minX = std::min(lhsX, rhsX), maxX = std::max(lhsX, rhsX);
111 const double minY = std::min(lhsY, rhsY), maxY = std::max(lhsY, rhsY);
112 return maxX >= envelope.MinX && minX <= envelope.MaxX
113 && maxY >= envelope.MinY && minY <= envelope.MaxY;
114 }
115
116 const OGRLinearRing * exteriorRing() const noexcept {
117 return geomPtr->getExteriorRing();
118 }
119
125 struct Canonical{};
126
130 OGRPolygonalAdapter(OGRUniquePtr<OGRPolygon> && polygonPtr, Canonical):Base(std::move(polygonPtr)) {}
131
137 OGRPolygonalAdapter(OGRUniquePtr<OGRPolygon> && polygonPtr):Base(std::move(polygonPtr)) {
138 geomPtr->closeRings();
139 canonicalize();
140 }
141
142public:
143
147 double area() const {
148 return geomPtr->get_Area();
149 }
150
152 OGREnvelope boundingBox;
153 geomPtr->getEnvelope(&boundingBox);
154 return Rectangle<double>(boundingBox.MinX, boundingBox.MaxY, boundingBox.MaxX, boundingBox.MinY);
155 }
156
157 bool isInside(const IPoint auto & point) const {
158 OGRPoint ogrPoint(point.getX(), point.getY());
159 return geomPtr->Contains(&ogrPoint);
160 }
161
165 bool isOnBoundary(const IPoint auto & point) const {
166 OGRPoint ogrPoint(point.getX(), point.getY());
167 return geomPtr->Touches(&ogrPoint);
168 }
169
170 bool isOutside(const IPoint auto & point) const {
171 OGRPoint ogrPoint(point.getX(), point.getY());
172 return geomPtr->Disjoint(&ogrPoint);
173 }
174
178 bool contains(const IPoint auto & point) const {
179 OGRPoint ogrPoint(point.getX(), point.getY());
180 return not geomPtr->Disjoint(&ogrPoint);
181 }
182
190 bool contains(const ISegment auto & segment) const {
191 if(not segment.isValid())
192 return contains(segment.p()); // a degenerate segment is contained if its point is
193 if(not envelopeOverlaps(segment.p(), segment.q()))
194 return false;
195 OGRLineString ogrLine;
196 ogrLine.addPoint(segment.p().getX(), segment.p().getY());
197 ogrLine.addPoint(segment.q().getX(), segment.q().getY());
198 return covers(*geomPtr, ogrLine);
199 }
200
201 bool contains(const IRing auto & ring) const {
202 return geomPtr->Contains(toOGRPolygon(ring).get());
203 }
204
205 bool contains(const IPolygon auto & polygon) const {
206 return geomPtr->Contains(toOGRPolygon(polygon).get());
207 }
208
209 bool contains(const OGRPolygonalAdapter & other) const {
210 return geomPtr->Contains(other.geomPtr.get());
211 }
212};
213}
Base class for OGR geometry adapters, which owns an OGR geometry.
Definition OGRAdapterBase.hpp:83
OGRUniquePtr< OGRPolygon > geomPtr
Definition OGRAdapterBase.hpp:85
Common base of the OGR backed adapters which enclose an area.
Definition OGRPolygonalAdapter.hpp:24
double area() const
Area enclosed by the boundary, reduced by the area of the holes.
Definition OGRPolygonalAdapter.hpp:147
const OGRLinearRing * exteriorRing() const noexcept
Definition OGRPolygonalAdapter.hpp:116
OGRPolygonalAdapter(OGRUniquePtr< OGRPolygon > &&polygonPtr)
Adopt a polygon and bring it into canonical form.
Definition OGRPolygonalAdapter.hpp:137
bool isInside(const IPoint auto &point) const
Definition OGRPolygonalAdapter.hpp:157
bool contains(const IPoint auto &point) const
Definition OGRPolygonalAdapter.hpp:178
bool envelopeOverlaps(const IPoint auto &lhs, const IPoint auto &rhs) const noexcept
Whether the bounding box spanned by two points overlaps the one of this polygon.
Definition OGRPolygonalAdapter.hpp:104
static OGRUniquePtr< OGRPolygon > toOGRPolygon(const IPolygon auto &polygon)
Copy an arbitrary IPolygon into an OGRPolygon, ready to be used with GEOS.
Definition OGRPolygonalAdapter.hpp:54
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 isOutside(const IPoint auto &point) const
Definition OGRPolygonalAdapter.hpp:170
bool contains(const OGRPolygonalAdapter &other) const
Definition OGRPolygonalAdapter.hpp:209
bool isOnBoundary(const IPoint auto &point) const
Definition OGRPolygonalAdapter.hpp:165
void canonicalize() noexcept
Bring the wrapped polygon into the canonical form of GEOS.
Definition OGRPolygonalAdapter.hpp:87
static OGRLinearRing toLinearRing(const IRing auto &ring)
Definition OGRPolygonalAdapter.hpp:32
OGRPolygonalAdapter(OGRUniquePtr< OGRPolygon > &&polygonPtr, Canonical)
Adopt a polygon which is already canonical, skipping the GEOS call.
Definition OGRPolygonalAdapter.hpp:130
static bool covers(const OGRGeometry &covering, const OGRGeometry &covered)
Boundary inclusive containment: is every point of covered also a point of covering?
Definition OGRPolygonalAdapter.hpp:73
bool contains(const IRing auto &ring) const
Definition OGRPolygonalAdapter.hpp:201
bool contains(const IPolygon auto &polygon) const
Definition OGRPolygonalAdapter.hpp:205
Rectangle< double > aaBB() const
Definition OGRPolygonalAdapter.hpp:151
static OGRUniquePtr< OGRPolygon > emptyPolygon()
Definition OGRPolygonalAdapter.hpp:28
bool contains(const ISegment auto &segment) const
Definition OGRPolygonalAdapter.hpp:190
Implementation of a rectangle Stores top,right,bottom and left point of the rectangle.
Definition Rectangle.hpp:15
Interface for a point.
Definition IPoint.hpp:92
Interface for a polygon A polygon is a two-dimensional shape defined by a boundary and zero or more h...
Definition IPolygon.hpp:98
Interface for a ring A ring is a closed loop of segments, forming a boundary of a shape.
Definition IRing.hpp:143
Interface for a segment A segment is formed between two points p and q, containing only the points on...
Definition ISegment.hpp:105
Definition BoundingBoxWrapper.hpp:5
std::unique_ptr< T, __impl::OGRGeometryDeleter > OGRUniquePtr
Definition OGRAdapterBase.hpp:48
STL namespace.
Tag for a polygon which is known to be in canonical form already.
Definition OGRPolygonalAdapter.hpp:125