Как мне преобразовать аффинные координаты в широту / долготу?

14

Я чрезвычайно новичок в ГИС.

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

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

Печать этих значений дает мне координаты как (447466.693808, 4952570.40529). Как они связаны с первоначальной широтой и долготой?

Редактировать:

Вот простой пример Python, который дал мне то, что я искал:

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

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

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

Богатый
источник
Похоже, что ваши данные проецируются (например, UTM), и вам нужно знать, что такое проекция, чтобы «отменить проецирование» обратно на координаты long / lat.
@Dan Спасибо, я знаю, что могу получить проекцию через dataset.GetProjectionRef()и узнать, что я использую «UTM Zone 10», но что тогда? Я нахожу в поисках таких методов, как "unproject", но я собираюсь обнулить.
Рич
извините за использование термина unproject (в кавычках), поскольку данные в десятичных градусах не проецируются, но если вы хотите получить проецируемые данные обратно в десятичные градусы из любой заданной проекции, то вам необходимо (отметить кавычки) «project» это обратно к географической системе координат, то есть данные десятичной степени.
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 Если данные уже имеют метаданные proj, вы можете отказаться от параметра -s_srs.
MerseyViking
Может быть, это то, что я после. Является ли "epsg: 4326" преобразованием в глобальный широту / долготу? Я думаю, что вижу некоторые классы, где я могу предоставить прогноз, я думал "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 в массиве геотрансформации.

Whuber
источник
1
Я прочитал раздел геотрансформации по предоставленной вами ссылке, но не думаю, что это то, что мне нужно. Извините, если я тупой, но разве это не описывает, как проецировать индексы x и y (от 0 до XSize или YSize) на проецируемые координаты? Мне интересно, как вы переводите прогнозируемые координаты в широту и долготу. В качестве простого примера, геотрансформация определяет начало координат x / y левого верхнего угла растра в проецируемых координатах (447466.693808, 4952570.40529). Как бы я превратил эти координаты обратно в широту / долготу (что-то вроде широты: 44, долготы: -122).
Рич
@Rich Нет, эта ссылка не описывает проекцию. Он описывает только изменение координат между двумя картами, а не между миром и картой. Unprojection превращает аффинное преобразование координат в (широта, долгота). Вы не хотите писать код для этого, если вы можете помочь этому! Отказ от проекции - это почти всегда вопрос определения того, какая проекция необходима, и выбор подходящего программного обеспечения, которое выполнит эту работу за вас (как это предлагается в ответе @ iant).
whuber
Ссылка не работает. @whuber Прав ли я, что аффинное преобразование (из GetGeoTransform GDAL) является преобразованием между пикселями и координатами CRS? Так, например, если данные находятся в проекции GDA, точки необходимо преобразовать из WGS84 / lat / lon в GDAXX, используя, например, CoordianteTransform, а затем в пиксели, используя аффинный GeoTransform? Этот двухэтапный процесс меня довольно сильно сбивает с толку, и я подозреваю, что он также вызывает проблемы с ОП. Не помогло то, что xarray / rasterio, похоже, содержит ошибку, приводящую к ошибкам в значениях GeoTransform: github.com/pydata/xarray/issues/3185
naught101
@naught Я нашел новый URL и обновил свой пост.
uber
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)

Координата вернет долготу (х) и широту (у) всех пикселей. Имейте в виду, что координаты левого угла пикселя

Ишан Томар
источник
Разве это не должны быть индексы [1] * padfTransform [1] + indexes [0] * padfTransform [2] и наоборот для yp?
CMCDragonkai