Come convertire un GEOS MultiLineString al poligono utilizzando Python?
-
23-10-2019 - |
Domanda
Sto sviluppando un'applicazione GeoDjango in cui gli utenti possono caricare file di mappa e fare alcune operazioni di mappatura di base, come l'interrogazione di funzioni all'interno poligoni.
I riconosciuto che gli utenti capita di caricare "MultiLineString" s invece di "Poligono" s volte. Questo fa sì che le query in attesa geometrie chiuse a fallire.
Qual è il modo migliore per convertire un oggetto MultiLineString a un poligono in Python?
Grazie.
- OMAT
Soluzione
Hehe, in un primo momento ho scritto questo:
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
ma poi ho scoperto che c'è un metodo poco nifty chiamato convex_hull che fa la conversione del poligono in modo automatico.
>>> 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)),)
Altri suggerimenti
Questo piccolo codice può risparmiare un sacco di tempo, forse più tardi una forma più breve in geopandas saranno inseriti.
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])