Bagaimana cara saya mengkonversi koordinat affine ke lat / lng?

14

Saya sangat baru dalam GIS.

Saya menggunakan gdaluntuk membaca dalam peta penggunaan lahan / tutupan lahan dan saya perlu memilih lat / lng dari tipe tutupan lahan tertentu untuk diindeks ke dalam dataset yang berbeda yang hanya dinyatakan dalam lat / lng. Unfortuantely, saya tidak mengerti bentuk x dan y koordinat yang diberikan kepada saya dari transformasi geografi, khususnya yang originXdan originYbawah:

geotransform = dataset.GetGeoTransform()
originX = geotransform[0]
originY = geotransform[3]

Mencetak nilai-nilai ini memberi saya koordinat seperti (447466.693808, 4952570.40529). Bagaimana hubungan ini dengan garis lintang dan bujur asli?

Edit:

Berikut adalah contoh python sederhana yang memberi saya apa yang saya cari:

srs = osr.SpatialReference()
srs.ImportFromWkt(dataset.GetProjection())

srsLatLong = srs.CloneGeogCS()
ct = osr.CoordinateTransformation(srs,srsLatLong)
print ct.TransformPoint(originX,originY)

Dicuri dari: tolatlong.py

Kaya
sumber
Sepertinya data Anda diproyeksikan (mis. UTM) dan Anda perlu mengetahui proyeksi apa yang harus dilakukan untuk "tidak memproyeksikan" kembali ke koordinat panjang / lat.
@Dan Terima kasih, jadi saya tahu saya bisa mendapatkan proyeksi melalui a dataset.GetProjectionRef()dan mencari tahu saya menggunakan "UTM Zone 10", tapi lalu apa? Saya mencari-cari metode seperti "tidak memproyeksikan" tetapi saya akan muncul nol.
Kaya
maaf untuk penggunaan istilah unproject (dalam tanda kutip) karena data dalam derajat desimal tidak diproyeksikan, tetapi jika Anda ingin mendapatkan data yang diproyeksikan kembali ke derajat desimal dari proyeksi yang diberikan, maka Anda harus (perhatikan tanda kutip) "proyek" kembali ke sistem koordinat geografis, alias data derajat desimal.
2
Utas (yang lebih baru) ini memberikan contoh eksplisit dan solusi lain: gis.stackexchange.com/questions/8430/…
whuber

Jawaban:

10

gdal_translate akan memproyeksi ulang data Anda dari proyeksi apa pun ke proyeksi lain (dalam hal ini Anda ingin EPSG: 4326) menggunakan:

gdal_translate -a_srs epsg:4326 srcfile new_file 

atau Anda dapat menggunakan gdaltrasform untuk mengonversi titik (dan saya yakin Anda dapat mengaksesnya dari Python (?) juga)

Ian Turton
sumber
(+1) Saya tidak tahu mengapa ini diturunkan, Ian, karena bagi saya sepertinya semacam operasi yang akan diperlukan setelah transformasi affine diterapkan.
whuber
gdal_translate tidak akan berfungsi seperti yang Anda miliki (atau lebih tepatnya itu hanya akan menetapkan EPSG: 4326 ke data), Anda perlu warp data dengan sesuatu seperti: gdalwarp -s_srs EPSG: 32610 -t_srs EPSG: 4326 src dest Jika data sudah memiliki metadata proj, Anda dapat membuang parameter -s_srs.
MerseyViking
Mungkin ini yang saya cari. Apakah "epsg: 4326" adalah transformasi ke global lat / lng? Saya pikir saya melihat beberapa kelas di mana saya dapat memberikan proyeksi, saya berpikir "WGS: 84", tetapi saya tidak tahu bedanya.
Kaya
1
@ Kaya Klik pada tag "sistem koordinat" dalam pertanyaan Anda, urutkan halaman yang dihasilkan berdasarkan suara, dan mulai membaca. Banyak pertanyaan Anda akan dijawab dalam beberapa menit.
whuber
7

Geotransform ini didokumentasikan di https://gdal.org/user/raster_data_model.html . Idenya adalah bahwa Anda mengambil (x, y) koordinat langsung dari dataset, menerapkan transformasi linear untuk mendapatkan (u, v) dengan

u = a*x + b*y
v = c*x + d*y

(Anda dapat menganggap ini sebagai definisi transformasi linear), kemudian menggeser asal dengan menambahkan geotransform [0] ke u dan geotransform [3] ke v. Itu memberikan "transformasi affine" dari (x, y). Ini benar-benar dimaksudkan untuk memutar, mengubah skala, mungkin mengoreksi sedikit untuk beberapa kesalahan miring, dan menempatkan kembali koordinat spesifik data (x, y) agar cocok dengan sistem koordinat yang dikenal. Hasilnya seharusnya menghasilkan koordinat yang diproyeksikan. Ini berarti ada prosedur matematika yang mengambil (bujur, lintang) dan mengubahnya menjadi koordinat yang dikenal: ini disebut "proyeksi." "Tidak memproyeksikan" berarti sebaliknya; jadi, jika Anda tahu proyeksi mana yang dibutuhkan, Anda menerapkannya pada koordinat transformasi x (y, y) untuk mendapatkan garis lintang dan bujur.

Omong-omong, nilai konstanta a, b, c, d diberikan oleh entri 1, 2, 4, dan 5 dalam array geotransform.

whuber
sumber
1
Saya membaca bagian geotransformasi tautan yang Anda berikan, tetapi saya rasa ini bukan yang saya cari. Maaf jika saya bodoh, tetapi tidakkah ini menggambarkan bagaimana memproyeksikan indeks x dan y (0 ke XSize atau YSize) ke koordinat yang diproyeksikan? Saya ingin tahu bagaimana Anda menerjemahkan koordinat yang diproyeksikan ke dalam lintang dan bujur. Sebagai contoh sederhana, geotransform mendefinisikan asal x / y sudut kiri atas raster dalam koordinat yang diproyeksikan (447466.693808, 4952570.40529). Bagaimana saya mengubah koordinat itu kembali menjadi lat / lng (sesuatu seperti lat: 44, lng: -122).
Kaya
@ Kaya Tidak, tautan itu tidak menjelaskan proyeksi. Ini hanya menjelaskan perubahan koordinat antara dua peta, bukan antara dunia dan peta. The unprojection ternyata affine transformasi dari koordinat ke dalam (lat, lon). Anda tidak ingin menulis kode untuk itu jika Anda dapat membantu! Unprojection hampir selalu merupakan masalah mengidentifikasi proyeksi apa yang dibutuhkan dan memanggil perangkat lunak yang tepat untuk melakukan pekerjaan untuk Anda (seperti yang disarankan dalam balasan @ iant).
whuber
Tautan rusak. @whuber saya benar bahwa transformasi affine (dari GetGeoTransform GDAL) adalah transformasi antara piksel dan koordinat CRS? Jadi, misalnya jika data dalam proyeksi GDA, poin perlu diubah dari WGS84 / lat / lon ke GDAXX menggunakan mis. CoordianteTransform, dan kemudian ke piksel menggunakan affine GeoTransform? Proses dua langkah ini adalah sesuatu yang membuat saya tersandung cukup banyak, dan saya curiga menyebabkan masalah OP juga. Tidak membantu bahwa xarray / rasterio tampaknya memiliki bug yang mengacaukan nilai GeoTransform
naught101
@ seharusnya saya menemukan URL baru dan memperbarui posting saya.
Whuber
0

Anda dapat menggunakan yang berikut ini:

import gdal, numpy as n
def coord(file):
    padfTransform = file.GetGeoTransform()
    indices = n.indices(file.ReadAsArray().shape)
    xp = padfTransform[0] + indices[1]*padfTransform[1] + indices[1]*padfTransform[2]   
    yp = padfTransform[3] + indices[0]*padfTransform[4] + indices[0]*padfTransform[5]  
    return xp,yp
file = gdal.Open('Yourfile.tif') # A GeoTiff file
x,y = coord(file)

coord akan mengembalikan garis bujur (x) dan garis lintang (y) dari semua piksel. Ingatlah bahwa koordinat berada di sudut kiri piksel

Ishan Tomar
sumber
Tidakkah harus berupa indix [1] * padfTransform [1] + indeks [0] * padfTransformasi [2] dan sebaliknya untuk yp?
CMCDragonkai