Як конвертувати афінні координати в lat / lng?


14

Я надзвичайно новачок у ГІС.

Я використовую gdalдля читання на карті землекористування / наземного покриття, і мені потрібно вибрати лат / lng певних типів земельного покриву, щоб індексувати в інший набір даних, який виражається лише в lat / lng. На жаль, я не розумію форму координат x і y, що даються мені з геотрансформи, а саме originXта originYнижче:

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

Друк цих значень дає мені такі координати (447466.693808, 4952570.40529). Як вони ставляться до вихідної широти та довготи?

Редагувати:

Ось простий приклад пітона, який отримав мені те, що я шукав:

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

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

Викрадено з: tolatlong.py


Схоже, ваші дані проектуються (наприклад, UTM), і вам потрібно буде знати, що таке проекція, щоб "непроізорувати" його назад до довгих / кінцевих координат.

@Dan Спасибі, тому я знаю, що можу отримати проекцію через a dataset.GetProjectionRef()і дізнаюся , що я використовую "UTM Zone 10", але що тоді? Я гуглю навколо таких методів, як "непроектувати", але я прийшов до недійсного.
Багатий

вибачте за використання терміна unproject (у лапках), оскільки дані в десяткових градусах не прогнозуються, але якщо ви хочете повернути прогнозовані дані до десяткових градусів від будь-якої заданої проекції, вам доведеться (зазначити лапки) "проект" він повертається до географічної системи координат, також даних про десяткові ступені.

2
Цей (новіший) потік дає явний приклад та інше рішення: gis.stackexchange.com/questions/8430/…
whuber

Відповіді:


10

gdal_translate буде відхиляти ваші дані з будь-якої іншої проекції в будь-яку іншу (у цьому випадку ви хочете EPSG: 4326), використовуючи:

gdal_translate -a_srs epsg:4326 srcfile new_file 

або ви можете використовувати gdaltrasform для перетворення очок (і я впевнений, що ви можете отримати доступ до цього також із Python (?))


(+1) Я не знаю, чому це було спровоковано, Іан, тому що мені це виглядає як така операція, як це буде потрібно після застосування афінної трансформації.
whuber

gdal_translate не працюватиме так, як у вас є (а точніше, це буде просто призначити EPSG: 4326 даним), вам потрібно викривити дані чимось на зразок: gdalwarp -s_srs EPSG: 32610 -t_srs EPSG: 4326 src dest If дані вже мають метадані proj, ви можете скинути параметр -s_srs.
MerseyViking

Можливо, це те, що я після цього. Чи "epsg: 4326" є перетворенням на глобальний lat / lng? Я думаю, що бачу деякі класи, де я можу запропонувати проекцію, я думав "WGS: 84", але я не знаю різниці.
Багатий

1
@Rich Клацніть на тезі "система координат" у вашому запитанні, сортуйте отриману сторінку за голосами та починайте читати. На багато ваших запитань відповідуть протягом декількох хвилин.
whuber

7

Геотрансформація задокументована у https://gdal.org/user/raster_data_model.html . Ідея полягає в тому, що ви берете (x, y) координати прямо з набору даних, застосовуєте лінійне перетворення для отримання (u, v) з

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

(ви можете взяти це за те, що є визначення лінійного перетворення), а потім перенесіть початок, додавши геотрансформацію [0] до u, а геотрансформацію [3] на v. Це дає "афінну трансформацію" (x, y). Він дійсно призначений для обертання, зміни масштабу, можливо, трохи виправлення помилок перекосу та перестановки конкретних даних (x, y), щоб відповідати відомій системі координат. В результаті передбачається отримати прогнозовані координати. Це просто означає, що існує математична процедура, яка приймає (довготу, широту) і перетворює їх у відомі координати: це називається "проекцією". "Непроектування" робить зворотне; тож, якщо ви знаєте, яка проекція потрібна, ви застосовуєте це до афінних перетворених (x, y) координат щоб отримати широту і довготу.

До речі, значення констант a, b, c, d задаються 1, 2, 4 та 5 записами в масиві геотрансформ.


1
Я читав розділ геотрансформації посилання, яке ви надали, але не думаю, що це те, про що я пішов. Вибачте, якщо мені тупо, але це не описує, як проектувати індекси x та y (від 0 до XSize або YSize) на прогнозовані координати? Мені цікаво, як ви перекладаєте прогнозовані координати у широту та довготу. Як простий приклад, геотрансформа визначає походження x / y верхнього лівого кута растру в проектованих координатах (447466.693808, 4952570.40529). Як би я повернув ці координати назад у lat / lng (щось на зразок lat: 44, lng: -122).
Багатий

@Rich Ні, це посилання не описує проекцію. Він лише описує зміну координат між двома картами, а не між світом та картою. Unprojection перетворює Афінний перетворення координат в (широта, довгота). Ви не хочете писати код для цього, якщо можете допомогти! Непроекція майже завжди полягає у визначенні того, яка проекція потрібна, та виклику правильного програмного забезпечення, яке б виконувало роботу за вас (як це запропоновано у відповіді @iant).
whuber

Посилання розірвано. @whuber, я правий, що афінне перетворення (від GetGeoTransform GDAL) - це перетворення між пікселями та координатами CRS? Так, наприклад, якщо дані є проекцією GDA, точки потрібно перетворити з WGS84 / lat / lon в GDAXX, використовуючи, наприклад, CoordianteTransform, а потім у пікселі, використовуючи афінну GeoTransform? Цей двоетапний процес - це щось, що мене викликає досить багато, і я підозрюю, що спричиняє проблеми з ОП. Не допомогло те, що у xarray / rasterio виявляється помилка, яка викручує значення GeoTransform
naught101

@naught Я знайшов нову URL-адресу та оновив свою публікацію.
whuber

0

Ви можете використовувати наступне:

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)

координата поверне довготу (x) та широту (y) усіх пікселів. Майте на увазі, що координати розташовані в лівому куті пікселя


Чи не повинні це бути індекси [1] * padfTransform [1] + індекси [0] * padfTransform [2] і навпаки для yp?
CMCDragonkai
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.