@@ -165,6 +165,133 @@ PYBIND11_MODULE(shapelycpp, m) {
165165 .def (" is_ccw" , &LinearRing<double >::is_ccw)
166166 BIND_ACCESSORS (LinearRing<double >);
167167
168+ // -- Multi* factories (multipoint overloads by array dtype; multilinestring/multipolygon by vector<array_t<T>>) --
169+ m.def (" multipoint" , py::overload_cast<const py::array_t <double >&>(&multipoint), py::arg (" coords" ));
170+ m.def (" multipoint" , py::overload_cast<const py::array_t <float >&>(&multipoint), py::arg (" coords" ));
171+ m.def (" multilinestring" , py::overload_cast<const std::vector<py::array_t <double >>&>(&multilinestring), py::arg (" lines" ));
172+ m.def (" multilinestring" , py::overload_cast<const std::vector<py::array_t <float >>&>(&multilinestring), py::arg (" lines" ));
173+ m.def (" multipolygon" , py::overload_cast<const std::vector<py::array_t <double >>&>(&multipolygon), py::arg (" polygons" ));
174+ m.def (" multipolygon" , py::overload_cast<const std::vector<py::array_t <float >>&>(&multipolygon), py::arg (" polygons" ));
175+
176+ // ======================================================================
177+ // MultiPoint<double> — full API
178+ // ======================================================================
179+ py::class_<MultiPoint<double >>(m, " MultiPoint" )
180+ .def (py::init ([](const py::array_t <double >& arr) {
181+ auto buf = arr.request ();
182+ return new MultiPoint<double >(static_cast <const double *>(buf.ptr ), buf.shape [0 ], buf.shape [1 ]);
183+ }), py::arg (" coords" ))
184+ .def (" num_geometries" , &MultiPoint<double >::num_geometries)
185+ .def (" geometry_n" , &MultiPoint<double >::geometry_n)
186+ .def (" distance" , [](const MultiPoint<double >& self, const Point<double >& o) {
187+ return self.distance (o);
188+ })
189+ .def (" distance" , [](const MultiPoint<double >& self, const MultiPoint<double >& o) {
190+ return self.distance (o);
191+ })
192+ .def (" intersects" , [](const MultiPoint<double >& self, const Point<double >& o) {
193+ return self.intersects (o);
194+ })
195+ .def (" intersects" , [](const MultiPoint<double >& self, const MultiPoint<double >& o) {
196+ return self.intersects (o);
197+ })
198+ BIND_ACCESSORS (MultiPoint<double >);
199+
200+ // ======================================================================
201+ // MultiLineString<double> — full API
202+ // ======================================================================
203+ py::class_<MultiLineString<double >>(m, " MultiLineString" )
204+ .def (py::init ([](const std::vector<py::array_t <double >>& arrays) {
205+ auto * mls = new MultiLineString<double >();
206+ for (auto & arr : arrays) {
207+ auto buf = arr.request ();
208+ mls->add_line (static_cast <const double *>(buf.ptr ), buf.shape [0 ], buf.shape [1 ]);
209+ }
210+ return mls;
211+ }), py::arg (" lines" ))
212+ .def (" num_geometries" , &MultiLineString<double >::num_geometries)
213+ .def (" geometry_n" , &MultiLineString<double >::geometry_n)
214+ .def (" add_line" , [](MultiLineString<double >& self, const py::array_t <double >& arr) {
215+ auto buf = arr.request ();
216+ self.add_line (static_cast <const double *>(buf.ptr ), buf.shape [0 ], buf.shape [1 ]);
217+ })
218+ .def (" distance" , [](const MultiLineString<double >& self, const Point<double >& o) {
219+ return self.distance (o);
220+ })
221+ .def (" distance" , [](const MultiLineString<double >& self, const LineString<double >& o) {
222+ return self.distance (o);
223+ })
224+ .def (" distance" , [](const MultiLineString<double >& self, const MultiLineString<double >& o) {
225+ return self.distance (o);
226+ })
227+ .def (" intersects" , [](const MultiLineString<double >& self, const Point<double >& o) {
228+ return self.intersects (o);
229+ })
230+ .def (" intersects" , [](const MultiLineString<double >& self, const LineString<double >& o) {
231+ return self.intersects (o);
232+ })
233+ .def (" intersects" , [](const MultiLineString<double >& self, const MultiLineString<double >& o) {
234+ return self.intersects (o);
235+ })
236+ BIND_ACCESSORS (MultiLineString<double >);
237+
238+ // ======================================================================
239+ // MultiPolygon<double> — full API
240+ // ======================================================================
241+ py::class_<MultiPolygon<double >>(m, " MultiPolygon" )
242+ .def (py::init ([](const std::vector<py::array_t <double >>& arrays) {
243+ auto * mp = new MultiPolygon<double >();
244+ for (auto & arr : arrays) {
245+ auto buf = arr.request ();
246+ mp->add_polygon (static_cast <const double *>(buf.ptr ), buf.shape [0 ], buf.shape [1 ]);
247+ }
248+ return mp;
249+ }), py::arg (" polygons" ))
250+ .def (" num_geometries" , &MultiPolygon<double >::num_geometries)
251+ .def (" geometry_n" , &MultiPolygon<double >::geometry_n)
252+ .def (" add_polygon" , [](MultiPolygon<double >& self, const py::array_t <double >& arr) {
253+ auto buf = arr.request ();
254+ self.add_polygon (static_cast <const double *>(buf.ptr ), buf.shape [0 ], buf.shape [1 ]);
255+ })
256+ .def (" distance" , [](const MultiPolygon<double >& self, const Point<double >& o) {
257+ return self.distance (o);
258+ })
259+ .def (" distance" , [](const MultiPolygon<double >& self, const LineString<double >& o) {
260+ return self.distance (o);
261+ })
262+ .def (" distance" , [](const MultiPolygon<double >& self, const Polygon<double >& o) {
263+ return self.distance (o);
264+ })
265+ .def (" distance" , [](const MultiPolygon<double >& self, const MultiPolygon<double >& o) {
266+ return self.distance (o);
267+ })
268+ .def (" intersects" , [](const MultiPolygon<double >& self, const Point<double >& o) {
269+ return self.intersects (o);
270+ })
271+ .def (" intersects" , [](const MultiPolygon<double >& self, const LineString<double >& o) {
272+ return self.intersects (o);
273+ })
274+ .def (" intersects" , [](const MultiPolygon<double >& self, const Polygon<double >& o) {
275+ return self.intersects (o);
276+ })
277+ .def (" intersects" , [](const MultiPolygon<double >& self, const MultiPolygon<double >& o) {
278+ return self.intersects (o);
279+ })
280+ BIND_ACCESSORS (MultiPolygon<double >);
281+
282+ // ======================================================================
283+ // GeometryCollection — basic API
284+ // ======================================================================
285+ py::class_<GeometryCollection>(m, " GeometryCollection" )
286+ .def (py::init<>())
287+ .def (" num_geometries" , &GeometryCollection::num_geometries)
288+ .def (" is_empty" , &GeometryCollection::is_empty)
289+ .def (" area" , &GeometryCollection::area)
290+ .def (" length" , &GeometryCollection::length)
291+ .def (" wkt" , &GeometryCollection::wkt)
292+ .def (" buffer" , &GeometryCollection::buffer)
293+ .def (" normalize" , &GeometryCollection::normalize);
294+
168295 // ======================================================================
169296 // Cross-type predicates (via pycpp macros)
170297 // ======================================================================
0 commit comments