@@ -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+
95134template <typename T>
96135double LineString<T>::length() const
97136{
0 commit comments