Uzyskaj szerokość i długość geograficzną z pliku GeoTIFF

Używając GDAL w Pythonie, jak uzyskać szerokość i długość geograficzną pliku GeoTIFF?

GeoTIFF nie przechowuje żadnych informacji o współrzędnych. Zamiast tego przechowują współrzędne XY. Jednak współrzędne XY nie zapewniają szerokości i długości geograficznej lewego górnego rogu i lewego dolnego rogu.

Wygląda na to, że będę musiał zrobić trochę matematyki, aby rozwiązać ten problem, ale nie mam pojęcia, od czego zacząć.

Jaka procedura jest wymagana, aby mieć to wystąpili

Wiem, że metoda GetGeoTransform() jest do tego ważna, jednak nie wiem, co z nią zrobić.

Author: Phanto, 2010-05-27

2 answers

Aby uzyskać współrzędne narożników geotiffa wykonaj następujące czynności:

from osgeo import gdal
ds = gdal.Open('path/to/file')
width = ds.RasterXSize
height = ds.RasterYSize
gt = ds.GetGeoTransform()
minx = gt[0]
miny = gt[3] + width*gt[4] + height*gt[5] 
maxx = gt[0] + width*gt[1] + height*gt[2]
maxy = gt[3] 

Mogą jednak nie być w formacie szerokości/długości geograficznej. Jak zauważył Justin, Twój geotiff będzie przechowywany w jakimś układzie współrzędnych. Jeśli nie wiesz, jaki to jest układ współrzędnych, możesz dowiedzieć się, uruchamiając gdalinfo:

gdalinfo ~/somedir/somefile.tif 

Które wyjście:

Driver: GTiff/GeoTIFF
Size is 512, 512
Coordinate System is:
PROJCS["NAD27 / UTM zone 11N",
    GEOGCS["NAD27",
        DATUM["North_American_Datum_1927",
            SPHEROID["Clarke 1866",6378206.4,294.978698213901]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-117],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1]]
Origin = (440720.000000,3751320.000000)
Pixel Size = (60.000000,-60.000000)
Corner Coordinates:
Upper Left  (  440720.000, 3751320.000) (117d38'28.21"W, 33d54'8.47"N)
Lower Left  (  440720.000, 3720600.000) (117d38'20.79"W, 33d37'31.04"N)
Upper Right (  471440.000, 3751320.000) (117d18'32.07"W, 33d54'13.08"N)
Lower Right (  471440.000, 3720600.000) (117d18'28.50"W, 33d37'35.61"N)
Center      (  456080.000, 3735960.000) (117d28'27.39"W, 33d45'52.46"N)
Band 1 Block=512x16 Type=Byte, ColorInterp=Gray

To wyjście może być wszystkim, czego potrzebujesz. Jeśli jednak chcesz to zrobić programowo w Pythonie, to w ten sposób uzyskasz to samo info.

Jeśli układ współrzędnych jest PROJCS jak w powyższym przykładzie masz do czynienia z rzutowanym układem współrzędnych. Rzutowany układ coordiante jest reprezentacją sferoidalnej powierzchni ziemi, ale spłaszczoną i zniekształconą na płaszczyźnie. Jeśli chcesz szerokość i długość geograficzną, musisz przekonwertować współrzędne na żądany układ współrzędnych geograficznych.

Niestety, nie wszystkie pary Szerokość / Długość geograficzna są równe, są oparte na różnych sferoidalne modele ziemi. W tym przykładzie konwertuję na WGS84 , układ współrzędnych geograficznych preferowany w GPSs i używany przez wszystkie popularne strony mapujące. Układ współrzędnych jest zdefiniowany przez dobrze zdefiniowany ciąg znaków. Katalog z nich jest dostępny w spatial ref , patrz na przykład WGS84.

from osgeo import osr, gdal

# get the existing coordinate system
ds = gdal.Open('path/to/file')
old_cs= osr.SpatialReference()
old_cs.ImportFromWkt(ds.GetProjectionRef())

# create the new coordinate system
wgs84_wkt = """
GEOGCS["WGS 84",
    DATUM["WGS_1984",
        SPHEROID["WGS 84",6378137,298.257223563,
            AUTHORITY["EPSG","7030"]],
        AUTHORITY["EPSG","6326"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.01745329251994328,
        AUTHORITY["EPSG","9122"]],
    AUTHORITY["EPSG","4326"]]"""
new_cs = osr.SpatialReference()
new_cs .ImportFromWkt(wgs84_wkt)

# create a transform object to convert between coordinate systems
transform = osr.CoordinateTransformation(old_cs,new_cs) 

#get the point to transform, pixel (0,0) in this case
width = ds.RasterXSize
height = ds.RasterYSize
gt = ds.GetGeoTransform()
minx = gt[0]
miny = gt[3] + width*gt[4] + height*gt[5] 

#get the coordinates in lat long
latlong = transform.TransformPoint(x,y) 
Mam nadzieję, że to zrobi, co chcesz.
 62
Author: fmark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-28 01:14:52

Nie wiem czy to pełna odpowiedź, ale ta strona mówi:

Wymiary mapy X/y nazywane są Wschodem i północą. W przypadku zbiorów danych w układzie współrzędnych geograficznych trzymałyby one długość i szerokość geograficzną. W przypadku projektowanych układów współrzędnych są one zwykle Wschodem i północą w projektowanym układzie współrzędnych. W przypadku niezagrożonych obrazów Wschód i północ byłyby tylko przesunięciami pikseli/linii każdego piksela (co sugeruje jedność geotransformacja).

Więc mogą być rzeczywiście długość i szerokość geograficzna.

 11
Author: Justin Peel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-12 10:04:02