How to create polygon from bbox data in python?

Question:

I have created a code in R which extracts bbox from a list of points and then creates a polygon using st_as_sfc. Now I am trying to do the same in python where I was able to get the bbox coordinates from the list of points data and then tried to create polygon using the two points by help of shapely.geometry which is throwing error. Is there any alternative for st_as_sfc in python or how can I create a polygon from the obtained bbox coordinates?

R code:-

print(st_as_sfc(st_bbox(sgrid)))
result:-
Geometry set for 1 feature 
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -9574057 ymin: 3590448 xmax: -9494057 ymax: 3670448
Projected CRS: WGS 84 / Pseudo-Mercator
POLYGON ((-9574057 3590448, -9494057 3590448, -...

Python :-
data frame from bbox coordinates xmin,ymin and xmax,ymax

from shapely import geometry
print(df)
              x             y                               geometry
0  3.418932e+06 -2.088506e+07  POINT (-20885056.99629 3418931.63321)
1  3.478932e+06 -2.082506e+07  POINT (-20825056.99629 3478931.63321)
poly = geometry.Polygon([[p.x, p.y] for p in gdf_p['geometry'].tolist()])
print(poly.wkt)  

error:-

ValueError: A linearring requires at least 4 coordinates.
Asked By: data en

||

Answers:

No need to first produce point geometries from your coordinates. Simply provide all 4 corners like so:

poly = geometry.Polygon(((xmin,ymin), (xmin,ymax), (xmax,ymax), (xmax,ymin)))
Answered By: Roman

If you already have a dataframe, you can achieve this through unary_union & envelope:

import pandas as pd
import geopandas as gpd
from io import StringIO

points = '''geometry
POINT (-20885056.99629 3418931.63321)
POINT (-20825056.99629 3478931.63321)'''
df = pd.read_table(StringIO(points))
gdf = gpd.GeoDataFrame(geometry=gpd.GeoSeries.from_wkt(df['geometry']))

print(gdf)
#                             geometry
# 0  POINT (-20885056.996 3418931.633)
# 1  POINT (-20825056.996 3478931.633)

print(gdf.geometry.unary_union.envelope.wkt)
# POLYGON ((-20885056.99629 3418931.63321, -20825056.99629 3418931.63321, -20825056.99629 3478931.63321, -20885056.99629 3478931.63321, -20885056.99629 3418931.63321))

With (minx, miny, maxx, maxy) tuples you can use shapely.geometry.box():

from shapely import geometry
bbox_tuple = gdf.total_bounds
print(bbox_tuple)
# [-20885056.99629   3418931.63321 -20825056.99629   3478931.63321]

bbox_polygon = geometry.box(*bbox_tuple)
print(bbox_polygon.wkt)
# POLYGON ((-20825056.99629 3418931.63321, -20825056.99629 3478931.63321, -20885056.99629 3478931.63321, -20885056.99629 3418931.63321, -20825056.99629 3418931.63321))
Answered By: margusl
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.