# Transforming Shapely Polygon and MultiPolygon objects

Is there an easy way of transforming Shapely objects (namely, Polygons and MultiPolygons) from one projection to another without having to dig around and extract coordinates by hand?

In fact, I don't even care if they are Shapely objects at this point, I just want to pass features and a projection, and get a reprojected set of features back.

Does this sort of functionality exist, or must it be hand coded?

While shapely doesn't natively understand coordinate systems, `shapely.ops.transform()` can do that along with `pyproj`. If `pyproj.Proj` can understand your both of your coordinate systems, then it can be made into a function that shapely can transform with.

From the shapely docs:

### pyproj >= 2.1.0

``````import pyproj

from shapely.geometry import Point
from shapely.ops import transform

wgs84_pt = Point(-72.2495, 43.886)

wgs84 = pyproj.CRS('EPSG:4326')
utm = pyproj.CRS('EPSG:32618')

project = pyproj.Transformer.from_crs(wgs84, utm, always_xy=True).transform
utm_point = transform(project, wgs84_pt)
``````

### pyproj < 2.1

``````from functools import partial
import pyproj
from shapely.ops import transform

project = partial(
pyproj.transform,
pyproj.Proj(init='epsg:4326'), # source coordinate system
pyproj.Proj(init='epsg:26913')) # destination coordinate system

g2 = transform(project, g1)  # apply projection
``````
• If you do not want to use the `itertools` module you can do `project = lambda x, y: pyproj.transform(pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='epsg:26913'), x, y)` and then `g2 = transform(project, g1)`. – Elmex80s Jan 24 '18 at 13:15
• This suggested answer is for pyproj1 whereas there is now a preferred transformation for pyproj2 using `Transformer`. See here: pyproj4.github.io/pyproj/stable/gotchas.html – Thirst for Knowledge Jul 9 '19 at 14:59
• I found Nick O'Dell's answer below (gis.stackexchange.com/a/328642) to be much faster. – Kyle Barron Dec 27 '19 at 4:21

If you're using pyproj2, it's much easier to use a Transformer. Here's an example:

``````import pyproj
from shapely.ops import transform

project = pyproj.Transformer.from_proj(
pyproj.Proj(init='epsg:4326'), # source coordinate system
pyproj.Proj(init='epsg:26913')) # destination coordinate system

# g1 is a shapley Polygon

g2 = transform(project.transform, g1)  # apply projection
``````

This is also much faster, becase pyproj does not need to recreate the projection for every point.

• Way faster than the accepted answer! – Kyle Barron Dec 27 '19 at 4:20
• Really much faster! fantastic.Great! – Jane Jan 9 at 13:12

While not a Shapely solution, using GeoPandas allows for relatively straightforward projection. For example, if we want to convert a shapefile to ESPG 4326:

``````import geopandas as gpd

HabModelEnviro = gpd.GeoDataFrame.from_file('data/HabModelEnviro.shp').replace({-999: None})

HabModelEnviroWGS84 = HabModelEnviro.to_crs({'proj':'longlat', 'ellps':'WGS84', 'datum':'WGS84'})
``````
• Geopandas uses Shapely (look at geodataframe.py for example) – gene Dec 23 '14 at 16:34