¿Cómo convertir un geos multilinestring a polígono usando python?
-
23-10-2019 - |
Pregunta
Estoy desarrollando una aplicación Geodjango donde los usuarios pueden cargar archivos de mapas y hacer algunas operaciones de mapeo básicas como las funciones de consulta dentro de los polígonos.
Reconocí que los usuarios cargan a veces "Multilinestring" en lugar de "polígono". Esto hace que las consultas que esperan que las geometrías cerradas fallaran.
¿Cuál es la mejor manera de convertir un objeto de múltiples múltiples a un polígono en Python?
Gracias.
- Omat
Solución
Jeje, al principio escribí esto:
def close_geometry(self, geometry):
if geometry.empty or geometry[0].empty:
return geometry # empty
if(geometry[-1][-1] == geometry[0][0]):
return geometry # already closed
result = None
for linestring in geom:
if result is None:
resultstring = linestring.clone()
else:
resultstring.extend(linestring.coords)
geom = Polygon(resultstring)
return geom
Pero luego descubrí que se llama un pequeño método ingenioso llamado convex_hull Eso hace la conversión de polígono para usted automáticamente.
>>> s1 = LineString((0, 0), (1, 1), (1, 2), (0, 1))
>>> s1.convex_hull
<Polygon object at ...>
>>> s1.convex_hull.coords
(((0.0, 0.0), (0.0, 1.0), (1.0, 2.0), (1.0, 1.0), (0.0, 0.0)),)
>>> m1=MultiLineString(s1)
>>> m1.convex_hull
<Polygon object at...>
>>> m1.convex_hull.coords
(((0.0, 0.0), (0.0, 1.0), (1.0, 2.0), (1.0, 1.0), (0.0, 0.0)),)
Otros consejos
Este pequeño código puede ahorrar mucho tiempo, tal vez más tarde se incorporará una forma más corta en Geopandas.
import geopandas as gpd
from shapely.geometry import Polygon, mapping
def linestring_to_polygon(fili_shps):
gdf = gpd.read_file(fili_shps) #LINESTRING
geom = [x for x in gdf.geometry]
all_coords = mapping(geom[0])['coordinates']
lats = [x[1] for x in all_coords]
lons = [x[0] for x in all_coords]
polyg = Polygon(zip(lons, lats))
return gpd.GeoDataFrame(index=[0], crs=gdf.crs, geometry=[polyg])