Cell.cpp
Go to the documentation of this file.
1 //=============================================================================
2 // Copyright (C) 2021-2024 Wageningen University - All Rights Reserved
3 // Author: Gonzalo Mier
4 // BSD-3 License
5 //=============================================================================
6 
9 
10 namespace f2c::types {
11 
13  this->data_ = std::shared_ptr<OGRPolygon>(
14  downCast<OGRPolygon*>(OGRGeometryFactory::createGeometry(wkbPolygon)),
15  [](OGRPolygon* f) {OGRGeometryFactory::destroyGeometry(f);});
16 }
17 
18 Cell::Cell(const OGRGeometry* geom) {
19  if (wkbFlatten(geom->getGeometryType()) == OGRwkbGeometryType::wkbPolygon) {
20  this->data_ =
21  std::shared_ptr<OGRPolygon>(downCast<OGRPolygon*>(geom->clone()),
22  [](OGRPolygon* f) {OGRGeometryFactory::destroyGeometry(f);});
23  } else {
24  throw std::invalid_argument(
25  sstr("Cell(const OGRGeometry*): Type of OGRGeometry* is ",
26  wkbFlatten(geom->getGeometryType()) , " instead of wkbPolygon(" ,
27  OGRwkbGeometryType::wkbPolygon , ")"));
28  }
29 }
30 
32  this->addRing(ring);
33 }
34 
35 void Cell::getGeometry(size_t i, LinearRing& ring) {
36  if (i >= this->size()) {
37  throw std::out_of_range(
38  "Geometry does not contain point " + std::to_string(i));
39  }
40  ring = LinearRing(((i == 0) ?
41  this->data_->getExteriorRing() :
42  this->data_->getInteriorRing(i-1)), EmptyDestructor());
43 }
44 
45 void Cell::getGeometry(size_t i, LinearRing& ring) const {
46  if (i >= this->size()) {
47  throw std::out_of_range(
48  "Geometry does not contain point " + std::to_string(i));
49  }
50 
51  ring = LinearRing(((i == 0) ?
52  this->data_->getExteriorRing() :
53  this->data_->getInteriorRing(i-1)), EmptyDestructor());
54 }
55 
57  if (i >= this->size()) {
58  throw std::out_of_range(
59  "Geometry does not contain point " + std::to_string(i));
60  }
61  return (i == 0) ? this->getExteriorRing() : this->getInteriorRing(i-1);
62 }
63 
64 const LinearRing Cell::getGeometry(size_t i) const {
65  if (i >= this->size()) {
66  throw std::out_of_range(
67  "Geometry does not contain point " + std::to_string(i));
68  }
69  return (i == 0) ? this->getExteriorRing() : this->getInteriorRing(i-1);
70 }
71 
72 void Cell::setGeometry(size_t i, const LinearRing& line) {
73  auto n = this->size();
74  if (i < n) {
75  Cell cell;
76  for (size_t j = 0; j < n; ++j) {
77  cell.addGeometry((i == j) ? line : this->getGeometry(j));
78  }
79  *this = cell;
80  return;
81  } else if (i != n) {
82  for (size_t j = n; j < i; ++j) {
83  this->addGeometry(LinearRing());
84  }
85  }
86  this->addGeometry(line);
87 }
88 
89 size_t Cell::size() const {
90  return this->isEmpty() ? 0 : (1 + this->data_->getNumInteriorRings());
91 }
92 
93 void Cell::operator*=(double b) {
94  for (auto&& ring : *this) {
95  ring *= b;
96  }
97 }
98 
99 Cell Cell::buffer(const Cell& geom, double width) {
100  return destroyResGeom<Cell>(geom.OGRBuffer(width));
101 }
102 
103 Cell Cell::buffer(const LineString& geom, double width) {
104  return destroyResGeom<Cell>(geom.OGRBuffer(width));
105 }
106 
107 Cell Cell::buffer(const LinearRing& geom, double width) {
108  Cell cell(geom);
109  Cells b_cell_out {buffer(cell, fabs(width))};
110  Cell b_cell_in = buffer(cell, -fabs(width));
111  auto diff = b_cell_out.difference(b_cell_in);
112  return (diff.size() > 0 ? diff.getGeometry(0) : Cell());
113 }
114 
115 Cell Cell::buffer(const Point& geom, double width) {
116  return destroyResGeom<Cell>(geom->Buffer(width));
117 }
118 
120  return destroyResGeom<Cell>(this->data_->ConvexHull());
121 }
122 
123 void Cell::addRing(const LinearRing& t) {
124  auto r = t.clone();
125  this->data_->addRing(r.closeRing().get());
126 }
127 
129  this->addRing(ring);
130 }
131 
133  return LinearRing(this->data_->getExteriorRing());
134 }
135 
136 const LinearRing Cell::getInteriorRing(size_t i) const {
137  return LinearRing(this->data_->getInteriorRing(i));
138 }
139 
140 
141 bool Cell::isConvex() const {
142  if (this->data_->getNumInteriorRings() > 0 || this->data_->get_Area() <= 0) {
143  return false;
144  }
145  auto border = this->getExteriorRing();
146  if (border.size() < 2) {
147  return false;
148  }
149  auto getAng = [&border] (size_t i) {
151  border.getGeometry(i),
152  border.getGeometry(i + 1),
153  border.getGeometry(i + 2));
154  };
155  bool inv = M_PI > getAng(0);
156  for (size_t i = 1; i < border.size() - 2; ++i) {
157  if (inv != (getAng(i) < M_PI)) {
158  return false;
159  }
160  }
161  return true;
162 }
163 
164 LineString Cell::createSemiLongLine(const Point& point, double angle) const {
165  return LineString({point,
166  point.getPointFromAngle(angle, this->getMinSafeLength())});
167 }
168 
170  const Point& point, double angle) const {
171  return LineString({
172  point.getPointFromAngle(M_PI + angle, this->getMinSafeLength()),
173  point.getPointFromAngle(angle, this->getMinSafeLength())});
174 }
175 
177  return MultiLineString::intersection(line, *this);
178 }
179 
181  return lines.intersection(*this);
182 }
183 
184 bool Cell::isPointInBorder(const Point& p) const {
185  return p.touches(*this);
186 }
187 
188 bool Cell::isPointIn(const Point& p) const {
189  return p.within(*this);
190 }
191 
193  const f2c::types::Point& p, double ang) const {
194  const MultiLineString ray(this->createSemiLongLine(p, ang));
195  const auto intersections(ray.intersection(*this));
196  Point best_point{p};
197  double min_dist {std::numeric_limits<double>::max()};
198  for (auto&& line : intersections) {
199  for (auto&& p_l : line) {
200  double dist = p_l.distance(p);
201  if (dist > 1e-5 && min_dist > dist) {
202  best_point = p_l;
203  min_dist = dist;
204  }
205  }
206  }
207  return (best_point == p) ? LineString() : LineString({p, best_point});
208 }
209 
211  std::vector<double> dist;
212  std::vector<Point> ps;
213  for (auto&& ring : *this) {
214  ps.emplace_back(ring.closestPointTo(p));
215  dist.emplace_back(ps.back().distance(p));
216  }
217  return ps[std::min_element(dist.begin(), dist.end()) - dist.begin()];
218 }
219 
220 
221 } // namespace f2c::types
222 
f2c::types::Cell::buffer
static Cell buffer(const Cell &geom, double width)
Definition: Cell.cpp:99
f2c::types::Geometry::within
bool within(const Geometry< T2, R2 > &geom) const
Check if this geometry is inside another geometry.
Definition: Geometry_impl.hpp:163
f2c::types::Cell::convexHull
Cell convexHull() const
Definition: Cell.cpp:119
f2c::types::Geometry::touches
bool touches(const Geometry< T2, R2 > &geom) const
Check if this and another geometry touch each other.
Definition: Geometry_impl.hpp:157
Cell.h
f2c::types::Cell::isConvex
bool isConvex() const
Check if the Cell is convex.
Definition: Cell.cpp:141
f2c::types
Types used by fields2cover library.
Definition: Cell.h:20
f2c::types::MultiLineString::intersection
MultiLineString intersection(const Geometry< T, R > &g) const
Definition: MultiLineString.h:63
f2c::types::Cell::addRing
void addRing(const LinearRing &ring)
Definition: Cell.cpp:123
f2c::types::Cell::createSemiLongLine
LineString createSemiLongLine(const Point &point, double angle) const
Definition: Cell.cpp:164
f2c::types::Geometries::clone
SAMETYPE clone() const
Definition: Geometries_impl.hpp:19
f2c::types::Cell::Cell
Cell()
Definition: Cell.cpp:12
1_basic_types.cell
cell
Definition: 1_basic_types.py:88
f2c::types::sstr
std::string sstr(Args &&... args)
Definition: Cell.h:24
f2c::types::Cell::isPointInBorder
bool isPointInBorder(const Point &p) const
Check if a point is in the border of this cell.
Definition: Cell.cpp:184
f2c::types::Cell::getLinesInside
MultiLineString getLinesInside(const LineString &line) const
Compute the sections of a LineString that is inside this cell.
Definition: Cell.cpp:176
f2c::types::MultiLineString
Definition: MultiLineString.h:18
f2c::types::LinearRing
Definition: LinearRing.h:18
f2c::types::Geometry< OGRPolygon, R >::getMinSafeLength
double getMinSafeLength() const
Definition: Geometry_impl.hpp:130
f2c::types::Cell::isPointIn
bool isPointIn(const Point &p) const
Check if a point is inside this cell.
Definition: Cell.cpp:188
f2c::types::Geometry::OGRBuffer
OGRGeometry * OGRBuffer(double dfDist, int side=0) const
Definition: Geometry_impl.hpp:291
f2c::types::Cell
Definition: Cell.h:32
f2c::types::Geometry< OGRPolygon, R >::isEmpty
bool isEmpty() const
Definition: Geometry_impl.hpp:222
f2c::types::Cell::getInteriorRing
const LinearRing getInteriorRing(size_t i_ring) const
Definition: Cell.cpp:136
1_basic_types.ring
ring
Definition: 1_basic_types.py:68
2_objective_functions.width
float width
Definition: 2_objective_functions.py:29
f2c::types::LineString
Definition: LineString.h:19
8_complete_flow.ps
list ps
Definition: 8_complete_flow.py:43
f2c::types::Cells
Definition: Cells.h:21
f2c::types::Point::getAngleFromPoints
double getAngleFromPoints(const Point &end) const
Definition: Point.cpp:132
f2c::types::Point
Definition: Point.h:21
f2c::types::Cell::createStraightLongLine
LineString createStraightLongLine(const Point &point, double angle) const
Definition: Cell.cpp:169
f2c::types::Cell::size
size_t size() const
Definition: Cell.cpp:89
f2c::types::Geometry::distance
double distance(const Geometry< T2, R2 > &p) const
Compute shortest distance between this and another geometry.
Definition: Geometry_impl.hpp:139
f2c::types::Cell::setGeometry
void setGeometry(size_t i, const LinearRing &ring)
Definition: Cell.cpp:72
f2c::types::Cell::createLineUntilBorder
LineString createLineUntilBorder(const Point &p, double ang) const
Generate a line from a point to the border of this cell.
Definition: Cell.cpp:192
Cells.h
f2c::types::Geometry< OGRPolygon, R >::data_
std::shared_ptr< OGRPolygon > data_
Definition: Geometry.h:129
f2c::types::Cell::getGeometry
void getGeometry(size_t i, LinearRing &ring)
Definition: Cell.cpp:35
f2c::types::Cell::addGeometry
void addGeometry(const LinearRing &ring)
Definition: Cell.cpp:128
f2c::types::EmptyDestructor
Definition: Geometry.h:23
f2c::types::Cell::operator*=
void operator*=(double b)
Scale this Cell by a scale factor.
Definition: Cell.cpp:93
f2c::types::Cell::getExteriorRing
const LinearRing getExteriorRing() const
Definition: Cell.cpp:132
1_basic_types.lines
lines
Definition: 1_basic_types.py:73
f2c::types::Cell::closestPointOnBorderTo
Point closestPointOnBorderTo(const Point &p) const
Find the closest point from a point to the border of the field.
Definition: Cell.cpp:210
f2c::types::to_string
std::string to_string(double d, const int precision=6)
Definition: Path.cpp:274
f2c::types::Point::getPointFromAngle
Point getPointFromAngle(double angle, double dist) const
Definition: Point.cpp:145


fields2cover
Author(s):
autogenerated on Fri Apr 25 2025 02:18:31