Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
flatten geometry series (3D to 2D) in geopandas dataframe
# Often when reading in a ShapeFile from Basemap, you'll get: "ValueError: readshapefile can only handle 2D shape types"
# A trick can be to convert your geometry in your GeoPandas Dataframe and restoring the new flattened 2D geometry
# series back into a shapefile and try again.
# edit from http://stackoverflow.com/questions/33417764/basemap-readshapefile-valueerror
from shapely.geometry import Polygon, MultiPolygon, shape, Point
import geopandas as gp
def convert_3D_2D(geometry):
'''
Takes a GeoSeries of 3D Multi/Polygons (has_z) and returns a list of 2D Multi/Polygons
'''
new_geo = []
for p in geometry:
if p.has_z:
if p.geom_type == 'Polygon':
lines = [xy[:2] for xy in list(p.exterior.coords)]
new_p = Polygon(lines)
new_geo.append(new_p)
elif p.geom_type == 'MultiPolygon':
new_multi_p = []
for ap in p:
lines = [xy[:2] for xy in list(ap.exterior.coords)]
new_p = Polygon(lines)
new_multi_p.append(new_p)
new_geo.append(MultiPolygon(new_multi_p))
return new_geo
geodf_2d = gp.GeoDataFrame.from_file(shp_file) # plug_in your shapefile
geodf_2d.geometry = convert_3D_2D(geodf_2d.geometry) # new geodf with 2D geometry series
# geodf_2d.to_file(path + shapefile.shp, driver = 'ESRI Shapefile') will sore a shapefile with 2D shape types
@lemartinet

This comment has been minimized.

Copy link

@lemartinet lemartinet commented Feb 11, 2019

Thanks for this snippet, it helped me a lot!

@koshy1123

This comment has been minimized.

Copy link

@koshy1123 koshy1123 commented Apr 18, 2019

If you're using shapely, here's another helpful hack to convert a geometry object from 3D to 2D:

geom = shapely.wkb.loads(
        shapely.wkb.dumps(geom, output_dimension=2))
@rajexp

This comment has been minimized.

Copy link

@rajexp rajexp commented Jun 22, 2020

@koshy1123 Thanks for the hack. It looks much cleaner

@porn

This comment has been minimized.

Copy link

@porn porn commented Apr 9, 2021

@koshy1123 Thanks too! Is also quite fast 😀

@andhuang-CLGX

This comment has been minimized.

Copy link

@andhuang-CLGX andhuang-CLGX commented Aug 18, 2021

shapely.wkb.loads(shapely.wkb.dumps(geom, output_dimension=2)) is cleaner, but I think convert_3D_2D(geometry) is much faster if I am not mistaken

@andhuang-CLGX

This comment has been minimized.

@santiago-vas

This comment has been minimized.

Copy link

@santiago-vas santiago-vas commented Nov 17, 2021

amazing function thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment