Mengubah objek Shapely Polygon dan MultiPolygon

26

Apakah ada cara mudah untuk mengubah objek Shapely (yaitu, Polygons dan MultiPolygons) dari satu proyeksi ke yang lain tanpa harus menggali sekitar dan mengekstrak koordinat dengan tangan?

Sebenarnya, saya bahkan tidak peduli apakah mereka objek Shapely pada titik ini, saya hanya ingin melewatkan fitur dan proyeksi, dan mendapatkan serangkaian fitur yang diproyeksikan kembali.

Apakah fungsi semacam ini ada, atau haruskah kode tangan?

Chris Fonnesbeck
sumber
2
Saya percaya itu di luar lingkup Shapely, Anda mungkin ingin melihat ke Fiona. fiona.transformterlihat memiliki apa yang Anda butuhkan.
Jason Scheirer

Jawaban:

50

Sementara rupanya Shapely tidak memahami sistem koordinat, shapely.ops.transform()dapat melakukannya bersama pyproj. Jika Anda pyproj.Projdapat memahami kedua sistem koordinat Anda, maka itu dapat dibuat menjadi fungsi yang dapat ditransformasi secara rupawan.

Dari dokumen indah :

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
sumber
4
Jika Anda tidak ingin menggunakan itertoolsmodul yang dapat Anda lakukan project = lambda x, y: pyproj.transform(pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='epsg:26913'), x, y)lalu g2 = transform(project, g1).
Elmex80s
1
Jawaban yang disarankan ini adalah untuk pyproj1 sedangkan sekarang ada transformasi yang lebih disukai untuk penggunaan pyproj2 Transformer. Lihat di sini: pyproj4.github.io/pyproj/stable/gotchas.html
Haus untuk Pengetahuan
11

Meskipun bukan solusi Shapely, menggunakan GeoPandas memungkinkan proyeksi yang relatif mudah. Misalnya, jika kita ingin mengonversi shapefile ke 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
sumber
6
Geopanda menggunakan Shapely (lihat geodataframe.py misalnya)
gen
0

Jika Anda menggunakan pyproj2, jauh lebih mudah menggunakan Transformer. Ini sebuah contoh:

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

Ini juga jauh lebih cepat, karena pyproj tidak perlu membuat ulang proyeksi untuk setiap titik.

Nick ODell
sumber