32

How to create a polygon from coordinates in GeoPandas with Python?

1
  • If this is a working code, it seems more suited for Code Review stack ( codereview.stackexchange.com), but the GIS libraries are quite specific, so I'm not sure whether it could stay here.
    – ImanolUr
    Commented Aug 28, 2018 at 11:38

3 Answers 3

16

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')

enter image description here

1
  • 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
    Commented Feb 25, 2022 at 16:50
5

I would substitute the for loop for:

polygon_geom = zip(lon_list, lat_list)
4
  • 1
    With zip() simply use polygon_geom = zip(lon_point_list,lat_point_list) (there is no need for list comprehension here)
    – gene
    Commented Aug 28, 2018 at 12:10
  • Indeed, I'll edit the answer.
    – ImanolUr
    Commented Aug 28, 2018 at 13:09
  • 1
    The format of shapely geometries is (x,y), so (longitude, latitude) and not (latitude, longitude)
    – gene
    Commented 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.
    – Davma
    Commented Aug 28, 2018 at 15:26
4

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
"""

polygon created with geopandas

Not the answer you're looking for? Browse other questions tagged or ask your own question.