Transformar objetos Shapely Polygon y MultiPolygon

26

¿Hay una manera fácil de transformar objetos Shapely (a saber, polígonos y polígonos múltiples) de una proyección a otra sin tener que cavar y extraer coordenadas a mano?

De hecho, ni siquiera me importa si son objetos Shapely en este punto, solo quiero pasar características y una proyección, y recuperar un conjunto de características reproyectadas.

¿Existe este tipo de funcionalidad o debe codificarse a mano?

Chris Fonnesbeck
fuente
2
Creo que está fuera del alcance de Shapely, es posible que desee ver a Fiona. fiona.transformparece tener lo que necesitas.
Jason Scheirer

Respuestas:

50

Si bien Shapely no entiende de forma nativa los sistemas de coordenadas, shapely.ops.transform()puede hacerlo junto con pyproj. Si pyproj.Projpuede comprender sus dos sistemas de coordenadas, entonces se puede convertir en una función con la que se puede transformar bien.

De los documentos bien formados :

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
Alex Kerney
fuente
44
Si no desea utilizar el itertoolsmódulo, puede hacerlo project = lambda x, y: pyproj.transform(pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='epsg:26913'), x, y)y luego g2 = transform(project, g1).
Elmex80s
1
Esta respuesta sugerida es para pyproj1, mientras que ahora hay una transformación preferida para usar pyproj2 Transformer. Ver aquí: pyproj4.github.io/pyproj/stable/gotchas.html
Sed de conocimiento
11

Si bien no es una solución bien proporcionada, el uso de GeoPandas permite una proyección relativamente sencilla. Por ejemplo, si queremos convertir un shapefile a 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'})
Chris Fonnesbeck
fuente
66
Geopandas usa Shapely (mira geodataframe.py por ejemplo)
gene
0

Si está usando pyproj2, es mucho más fácil usar un Transformer. Aquí hay un ejemplo:

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

Esto también es mucho más rápido, porque pyproj no necesita recrear la proyección para cada punto.

Nick ODell
fuente