Skip to content

Commit 6142945

Browse files
author
peng.li24
committed
Add shapely geometry and ops
1 parent 6bd3397 commit 6142945

4 files changed

Lines changed: 43 additions & 2 deletions

File tree

geometry/linestring.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class LineString {
5151

5252
Point<double> interpolate(double distance) const;
5353

54+
Polygon<double> buffer(double distance) const;
55+
5456
double length() const;
5557

5658
py::array_t<T> coords_;

geometry/linestring_impl.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,45 @@ Point<double> LineString<T>::interpolate(double distance) const
9292
return Point<double>(coord.x, coord.y);
9393
}
9494

95+
template <typename T>
96+
Polygon<double> LineString<T>::buffer(double distance) const
97+
{
98+
if (!geos_linestring_ || geos_linestring_->isEmpty()) {
99+
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
100+
}
101+
auto buf_geom = geos_linestring_->buffer(distance, 16);
102+
if (buf_geom == nullptr || buf_geom->isEmpty())
103+
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
104+
105+
const geos::geom::Geometry *poly = buf_geom.get();
106+
if (poly->getGeometryTypeId() != geos::geom::GEOS_POLYGON)
107+
{
108+
if (poly->getNumGeometries() > 0)
109+
poly = poly->getGeometryN(0);
110+
}
111+
112+
if (poly->getGeometryTypeId() != geos::geom::GEOS_POLYGON || poly->isEmpty())
113+
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
114+
115+
const geos::geom::Polygon *geos_poly = dynamic_cast<const geos::geom::Polygon *>(poly);
116+
if (!geos_poly)
117+
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
118+
119+
const geos::geom::CoordinateSequence *cs = geos_poly->getExteriorRing()->getCoordinatesRO();
120+
if (!cs || cs->isEmpty())
121+
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
122+
123+
size_t n = cs->getSize();
124+
py::array_t<double> coords(std::vector<py::ssize_t>{static_cast<py::ssize_t>(n - 1), static_cast<py::ssize_t>(2)});
125+
double *p = static_cast<double *>(coords.request().ptr);
126+
for (size_t i = 0; i < n - 1; ++i) {
127+
p[i * 2] = cs->getAt(i).x;
128+
p[i * 2 + 1] = cs->getAt(i).y;
129+
}
130+
131+
return std::move(Polygon<double>(coords));
132+
}
133+
95134
template <typename T>
96135
double LineString<T>::length() const
97136
{

geometry/point_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ double Point<T>::distance(const Polygon<U>& other) const
5555
template <typename T>
5656
Polygon<double> Point<T>::buffer(double distance) const
5757
{
58-
auto buf_geom = geos_point_->buffer(distance);
58+
auto buf_geom = geos_point_->buffer(distance, 16);
5959
if (buf_geom == nullptr || buf_geom->isEmpty())
6060
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
6161

geometry/polygon_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ Polygon<double> Polygon<T>::buffer(double distance) const
174174
if (!geos_polygon_->isValid() || !geos_polygon_->isSimple()) {
175175
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
176176
}
177-
buf_geom = geos_polygon_->buffer(distance);
177+
buf_geom = geos_polygon_->buffer(distance, 16);
178178
if (buf_geom == nullptr || buf_geom->isEmpty())
179179
return std::move(Polygon<double>(py::array_t<double>(std::vector<py::ssize_t>{0, 2})));
180180

0 commit comments

Comments
 (0)