Przekształcanie obiektów Shapely Polygon i MultiPolygon

26

Czy istnieje prosty sposób na przekształcanie obiektów foremnych (a mianowicie wielokątów i wielokątów) z jednego rzutu na drugi bez konieczności ręcznego kopania i wyodrębniania współrzędnych?

W rzeczywistości nie dbam nawet o to, czy w tym momencie są one obiektami foremnymi, chcę tylko przekazać funkcje i projekcję i odzyskać ponownie zestaw funkcji.

Czy taka funkcjonalność istnieje, czy musi być ręcznie kodowana?

Chris Fonnesbeck
źródło
2
Wierzę, że to nie wchodzi w zakres Shapely, możesz zajrzeć do Fiony. fiona.transformwygląda na to, czego potrzebujesz.
Jason Scheirer,

Odpowiedzi:

50

Chociaż foremnie nie rozumie natywnie układów współrzędnych, shapely.ops.transform()może to zrobić wraz z pyproj. Jeśli pyproj.Projjest w stanie zrozumieć oba układy współrzędnych, można go przekształcić w funkcję, którą można kształtnie przekształcać.

Od zgrabnych dokumentów :

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
źródło
4
Jeśli nie chcesz korzystać z itertoolsmodułu można zrobić project = lambda x, y: pyproj.transform(pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='epsg:26913'), x, y)i potem g2 = transform(project, g1).
Elmex80s
1
Ta sugerowana odpowiedź dotyczy pyproj1, podczas gdy obecnie preferowana jest transformacja dla pyproj2 Transformer. Zobacz tutaj: pyproj4.github.io/pyproj/stable/gotchas.html
Pragnienie wiedzy
11

Chociaż nie jest to zgrabne rozwiązanie, użycie GeoPandas pozwala na stosunkowo prostą projekcję. Na przykład, jeśli chcemy przekonwertować plik shapefile na 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
źródło
6
Geopanda używa Shapely (patrz na przykład geodataframe.py)
gen
0

Jeśli używasz pyproj2, znacznie łatwiej jest użyć transformatora. Oto przykład:

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

Jest to również znacznie szybsze, ponieważ pyproj nie musi odtwarzać projekcji dla każdego punktu.

Nick ODell
źródło