Raster-Datenarray-Ausgabe mit Python / GDAL auf der x-Achse gespiegelt?


9

Ich versuche, ein Raster mit den Python-GDAL-Bibliotheken zu erstellen, und bin an dem Punkt angelangt, an dem Daten ausgegeben werden, aber die Ausgabedaten werden auf der x-Achse des Ursprungspunkts gespiegelt . Ich weiß, dass ich etwas übersehen muss, aber ich kann nicht herausfinden, wo ich falsch liege. Irgendwelche Ideen?

Beim Erstellen des Rasters habe ich die x / y-Werte oben links festgelegt, und das Array scheint von links oben indiziert zu sein und weiter nach rechts unten zu gehen. Im folgenden Code fülle ich das Array mit dem Wert der Zeile.

Beim Ausdrucken des Arrays sieht es folgendermaßen aus:

[[  1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.
    1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.
    1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.
    1.   1.   1.   1.   1.   1.]
 [  2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.
    2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.
    2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.
    2.   2.   2.   2.   2.   2.]
 [  3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.
    3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.
    3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.
    3.   3.   3.   3.   3.   3.]
 [  4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.
    4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.
    4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.
    4.   4.   4.   4.   4.   4.]
...

Und diese Daten werden erfolgreich in das Rasterband geschrieben. Bei der Anzeige in MapWindow GIS scheinen die Daten jedoch in die entgegengesetzte Richtung zu gehen, wobei der ursprünglich festgelegte Ursprungspunkt oben links als Wert unten links angezeigt wird.

Mit anderen Worten, die Daten werden auf der x-Achse des Ursprungspunkts gespiegelt.

import gdal
import osr
import numpy

OUTPUT_FORMAT = "GTiff"
def create_raster(filename="test.tif"):
    driver = gdal.GetDriverByName(OUTPUT_FORMAT)
    band_type = gdal.GDT_Byte
    number_of_bands = 1

    x_rotation = 0 # not supported
    y_rotation = 0 # not supported
    cell_width_meters = 50
    cell_height_meters = 50

    (min_lon, min_lat, max_lon, max_lat) = _get_point_bounds() # retrieve bounds for point data        
    srs = osr.SpatialReference()
    srs.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon        
    srs.SetUTM( 54, True) # Set projected coordinate system  to handle meters        

    # create transforms for point conversion
    wgs84_coordinate_system = srs.CloneGeogCS() # clone only the geographic coordinate system
    wgs84_to_utm_transform = osr.CoordinateTransformation(wgs84_coordinate_system, srs)

    # convert to UTM
    top_left_x, top_left_y, z = wgs84_to_utm_transform.TransformPoint(min_lon, max_lat, 0)     
    lower_right_x, lower_right_y, z = wgs84_to_utm_transform.TransformPoint(max_lon, min_lat, 0) 

    cols, rows = _get_raster_size(top_left_x, lower_right_y, lower_right_x, top_left_y, cell_width_meters, cell_height_meters)
    dataset = driver.Create(filename, cols, rows, number_of_bands, band_type) #

    # GeoTransform parameters
    # --> need to know the area that will be covered to define the geo tranform
    # top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
    geo_transform = [ top_left_x, cell_width_meters, x_rotation, top_left_y, y_rotation, cell_height_meters ]
    dataset.SetGeoTransform(geo_transform)
    dataset.SetProjection(srs.ExportToWkt())

    dataset_band = dataset.GetRasterBand(1)
    data = dataset_band.ReadAsArray(0, 0, cols, rows).astype(numpy.float32) # returns empty array 

    for row in xrange(rows):
        for col in xrange(cols):
            data[row][ col] = row + 1

    dataset_band.WriteArray(data, 0, 0)
    dataset_band.SetNoDataValue(0.0)
    dataset_band.FlushCache()
    dataset = None # Close file

Ich habe auch bemerkt, dass bei der Berechnung der Pixelposition für ein bestimmtes Lat / Lon der y-Wert zu einem negativen Index führt, der irgendwie korrekt erscheint, wenn man bedenkt, dass das Array von links oben nach rechts unten verläuft .

inverse_geo_transform = gdal.InvGeoTransform(self.geo_transform)[1] # for mapping lat/lon to pixel
pixel_x, pixel_y = gdal.ApplyGeoTransform(self.inverse_geo_transform, utm_x, utm_y)

Antworten:


10

Ich habe das Problem gefunden ....

Das Problem besteht in der Definition der geo_transform. Ich hatte folgendes:

x_rotation = 0 
y_rotation = 0 
cell_width_meters = 50
cell_height_meters = 50

geo_transform = [ top_left_x, cell_width_meters, x_rotation, top_left_y, y_rotation, cell_height_meters ]
dataset.SetGeoTransform(geo_transform)

In der Gdal-Dokumentation ist nicht wirklich klar, um welche Werte es sich handelt. (Siehe SetGeoTransform ) Durchsuchen der Internetseiten Ich habe abgeleitet, dass die übergebenen Werte (in der Reihenfolge) sein sollten:

  • top_left_x
  • cell_width_meters
  • x_rotation
  • top_left_y
  • y_rotation
  • cell_height_meters

Was richtig erscheint, ABER beim erneuten Überprüfen des GDAL-API-Tutorials habe ich festgestellt, dass der letzte Wert cell_height_metersin einem negativen Wert angegeben wurde. Es scheint, dass dies alles war, was benötigt wurde, um die Daten in der erwarteten Ausrichtung richtig auszugeben.

Jetzt habe ich die Definitionszeile geo_transform in Folgendes geändert :

(Beachten Sie das hinzugefügte "-")

geo_transform = [ top_left_x, cell_width_meters, x_rotation, top_left_y, y_rotation, -cell_height_meters ]

Dies ist die traditionelle Art, mit den Bildwelten wie den Ursprüngen oben links und der geografischen Art, links unten umzugehen, umzugehen.
Ian Turton

Sobald Sie es wissen, ist es sinnvoll, aber wenn Sie sich dem Problem anhand der Codebeispiele nähern, ist es schwierig, die Argumentation zu erfassen. Ich habe festgestellt, dass die ArcGIS-Dokumentation einige großartige Dokumentationen zu Rastern
enthält
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.