How to create a polygon from coordinates in GeoPandas with Python?
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!– DavmaCommented Feb 25, 2022 at 16:50
I would substitute the for loop for:
polygon_geom = zip(lon_list, lat_list)
-
1With
zip()
simply usepolygon_geom = zip(lon_point_list,lat_point_list)
(there is no need for list comprehension here)– geneCommented Aug 28, 2018 at 12:10 -
-
1The format of shapely geometries is
(x,y)
, so(longitude, latitude)
and not(latitude, longitude)
– geneCommented Aug 28, 2018 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.– DavmaCommented Aug 28, 2018 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
"""