How to create a polygon from coordinates in GeoPandas with Python?
-
If this is a working code, it seems more suited for Code Review stack ( https://codereview.stackexchange.com/), but the GIS libraries are quite specific, so I'm not sure whether it could stay here. – ImanolUr Aug 28 '18 at 11:38
3 Answers
This simple code is working for Python 3.9 and geopandas 0.9.0, and it works for older versions too.
Separate lists with latitude and longitude coordinates
import geopandas as gpd
from shapely.geometry import Polygon
lat_point_list = [50.854457, 52.518172, 50.072651, 48.853033, 50.854457]
lon_point_list = [4.377184, 13.407759, 14.435935, 2.349553, 4.377184]
polygon_geom = Polygon(zip(lon_point_list, lat_point_list))
polygon = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[polygon_geom])
polygon.to_file(filename='polygon.geojson', driver='GeoJSON')
polygon.to_file(filename='polygon.gpkg', driver="GPKG")
polygon.to_file(filename='polygon.shp', driver="ESRI Shapefile")
One list with longitude and latitude coordinates
import geopandas as gpd
from shapely.geometry import Polygon
lon_lat_list = [[4.373352367, 52.091372156], [4.373360755, 52.091365819], [4.373384852, 52.091347618], [4.373410766, 52.091360632], [4.37337828, 52.09138517], [4.373352367, 52.091372156]]
polygon_geom = Polygon(lon_lat_list)
polygon = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[polygon_geom])
polygon.to_file(filename='polygon.geojson', driver='GeoJSON')
polygon.to_file(filename='polygon.gpkg', driver="GPKG")
polygon.to_file(filename='polygon.shp', driver="ESRI Shapefile")
(Bonus) Visualize polygon with folium 0.12.1
import folium
m = folium.Map([50.854457, 4.377184], zoom_start=5, tiles='cartodbpositron')
folium.GeoJson(polygon).add_to(m)
folium.LatLngPopup().add_to(m)
m
# if using Spyder.5
import webbrowser
m.save('test.html')
webbrowser.open_new_tab('test.html')
-
Updated the page to make question and answer more readable. In this answer improvements were added by ImanolUr, gene and reevesii to the code! – Davma Feb 25 '22 at 16:50
I would substitute the for loop for:
polygon_geom = zip(lon_list, lat_list)
- 1,102
- 1
- 10
- 21
-
1With
zip()simply usepolygon_geom = zip(lon_point_list,lat_point_list)(there is no need for list comprehension here) – gene Aug 28 '18 at 12:10 -
-
1The format of shapely geometries is
(x,y), so(longitude, latitude)and not(latitude, longitude)– gene Aug 28 '18 at 14:48 -
Thanks for suggestions. Stupid mistake to reverse longitude and latitude, but the syntax of shapely felt very similar to WKT strings. Next time I should check on the map. – Davma Aug 28 '18 at 15:26
This solution works for large data via .dissolve and .convex_hull.
import pandas as pd
import geopandas as gpd
df = pd.DataFrame(
{
"x": [0, 1, 0.1, 0.5, 0, 0, -1, 0],
"y": [0, 0, 0.1, 0.5, 1, 0, 0, -1],
"label": ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b'],
}
)
gdf = geopandas.GeoDataFrame(
df,
geometry=gpd.points_from_xy(df["x"], df["y"]),
)
# Outputs
"""
gdf
x y label geometry
0 0.0 0.0 a POINT (0.00000 0.00000)
1 1.0 1.0 a POINT (1.00000 1.00000)
2 0.1 0.1 a POINT (0.10000 0.10000)
3 0.5 0.5 a POINT (0.50000 0.50000)
4 0.0 1.0 a POINT (0.00000 1.00000)
5 0.0 0.0 b POINT (0.00000 0.00000)
6 -1.0 0.0 b POINT (-1.00000 0.00000)
7 0.0 -1.0 b POINT (0.00000 -1.00000)
"""
res = gdf.dissolve("label").convex_hull
res.to_wkt()
Outputs
"""
label
a POLYGON ((0 0, 0 1, 1 0, 0 0))
b POLYGON ((0 -1, -1 0, 0 0, 0 -1))
dtype: object
"""
- 15,695
- 1
- 29
- 64
- 41
- 3

