Hallo, hier ist Alex von DEV STORIES DOT EU. Rasterio:
Numpy für Geodaten, Folge 5 von 5. Manchmal hast du wunderschöne, hochauflösende Satellitenbilder, aber dein Klimamodell akzeptiert nur grobe, niedrig aufgelöste Eingaben. Du kannst das Array nicht einfach zerschneiden, da die resultierenden Pixel immer noch genau dasselbe physische Gebiet darstellen müssen, nur in einem Raster mit geringerer Dichte. Um das korrekt zu machen, brauchst du Resampling und Writing.
Hier geht es nicht um Reprojektion. Das Koordinatenreferenzsystem bleibt exakt gleich. Wir ändern lediglich die Auflösung. Nehmen wir an, du musst ein Raster um die Hälfte verkleinern. In Rasterio führst du das Resampling genau in dem Moment durch, in dem du die Daten in den Speicher lädst. Wenn du die read Methode für dein Dataset aufrufst, übergibst du einen Parameter namens out shape. Anstatt das gesamte Array einzulesen, liest Rasterio es ein und skaliert es sofort auf die gewünschte Form. Bei einem Einzelband-Raster wäre dein out shape ein Tuple, das ein Band, die halbe ursprüngliche Höhe und die halbe ursprüngliche Breite angibt.
Du musst Rasterio außerdem mitteilen, wie die Werte dieser neuen, größeren Pixel berechnet werden sollen. Das machst du, indem du einen resampling Parameter übergibst. Rasterio stellt hierfür ein Resampling Enum bereit. Wenn du mit kontinuierlichen Daten wie Temperaturdaten arbeitest, übergibst du vielleicht Resampling dot bilinear, was einen gewichteten Durchschnitt der umliegenden Pixel berechnet. Wenn du mit kategorialen Daten wie Landbedeckung arbeitest, würdest du Resampling dot nearest verwenden, um die exakten ursprünglichen Klassenwerte beizubehalten.
Hier ist die entscheidende Erkenntnis. Du hast nun ein neues, kleineres Numpy Array, aber es repräsentiert weiterhin exakt denselben geografischen Bereich auf der Erde. Da das Array weniger Pixel enthält, deckt jedes einzelne Pixel einen größeren physischen Raum ab. Das bedeutet, dass dein ursprünglicher Affine Transform nun völlig falsch ist. Wenn du das neue Array mit dem alten Transform auf die Festplatte schreibst, schrumpft dein Bild auf der Karte und deckt nur noch ein Viertel seiner ursprünglichen Fläche ab.
Du musst den Transform skalieren. Das machst du, indem du den ursprünglichen Dataset Transform nimmst und ihn mit einer Affine Scaling Matrix multiplizierst. Die Skalierungsfaktoren findest du, indem du die ursprüngliche Breite durch deine neue Breite und die ursprüngliche Höhe durch deine neue Höhe teilst. Da wir die Dimensionen halbiert haben, sind beide Faktoren genau zwei. Wenn du den ursprünglichen Transform mit diesen Skalierungsfaktoren multiplizierst, bekommst du einen neuen Transform, bei dem die Pixeldimensionen verdoppelt sind, der Ursprungspunkt oben links jedoch perfekt verankert bleibt.
Jetzt hast du dein resampeltes Array und deinen skalierten Transform. Der letzte Schritt ist das Schreiben eines gültigen GeoTIFFs auf die Festplatte. Dafür brauchst du Metadaten. Der sicherste Ansatz ist, die profile Property aus deinem Source Dataset zu kopieren. Dadurch bekommst du ein Dictionary, das den File Driver, das Koordinatenreferenzsystem, den Datentyp und den nodata Value enthält. Anschließend aktualisierst du dieses profile Dictionary mit deiner neuen Höhe, deiner neuen Breite und deinem neu berechneten Transform.
Wenn das aktualisierte profile bereit ist, rufst du rasterio dot open auf. Du gibst den neuen Dateinamen an, setzt den mode auf write und entpackst dein profile Dictionary als Keyword Arguments. Dadurch wird ein leeres Dataset auf der Festplatte erstellt, das exakt deinen Vorgaben entspricht. Zum Schluss rufst du die write Methode auf diesem neuen Dataset Object auf und übergibst dein herunterskaliertes Numpy Array. Das Array wird in die Datei geschrieben, und dein neues GeoTIFF mit niedrigerer Auflösung ist bereit für das Klimamodell.
Denk daran, das Ändern von Rasterdaten ist immer ein zweiteiliger Vertrag: Wenn du die Form des Numpy Arrays änderst, musst du den Affine Transform explizit anpassen, sonst ist dein räumlicher Fußabdruck kaputt. Damit sind wir am Ende unserer Serie angelangt. Ich ermutige dich, die offizielle Rasterio Dokumentation zu lesen, um andere Resampling Algorithmen zu erkunden und zu versuchen, diese Pipelines hands-on zu bauen. Wenn du Themen für eine zukünftige Serie vorschlagen möchtest, besuche devstories dot eu. Ich möchte mir kurz einen Moment Zeit nehmen, um dir fürs Zuhören zu danken – das hilft uns sehr. Mach's gut!