27 Stimmen

wie man NASA .hgt Binärdateien liest

Ich bin mir sicher, dass dies wirklich einfach ist, wenn man sich mit Binärdateien auskennt, aber ich bin ein Neuling auf diesem Gebiet.

Wie kann ich die Daten aus den .hgt-Dateien der NASA extrahieren? Hier ist eine Beschreibung aus www2.jpl.nasa.gov/srtm/faq.html:

Die SRTM-Datendateien tragen Namen wie "N34W119.hgt". Was bedeuten die Buchstaben und Zahlen, und was ist das ".hgt"-Format?

Jede Datendatei deckt einen Bereich von einem Breitengrad mal einem Längengrad ab Block der Erdoberfläche ab. Die ersten sieben Zeichen bezeichnen die südwestliche Ecke des Blocks an, wobei sich N, S, E und W auf Norden, Süden, Osten und Westen beziehen, und Westen. So deckt die Datei "N34W119.hgt" die Breitengrade 34 bis 35 Nord und Längengrade 118-119 West (diese Datei umfasst das Stadtzentrum von Los Angeles, Kalifornien). Die Dateinamenerweiterung ".hgt" steht einfach für das Wort "Höhe", d. h. Elevation. Es handelt sich NICHT um einen Formattyp. Diese Dateien sind im "Rohformat" (ohne Header und nicht komprimiert), 16-Bit-Ganzzahlen mit Vorzeichen, Höhe gemessen in Metern über dem Meeresspiegel, in einem "geografischen" (Breitengrad Längen- und Breitengrad) projiziert, wobei Datenlücken durch -32768 gekennzeichnet sind. Internationale 3-Bogen-Sekunden-Dateien haben 1201 Spalten und 1201 Zeilen mit Daten, mit einer Gesamtdateigröße von 2.884.802 Bytes ( = 1201 x 1201 x 2). Vereinigte USA 1-Bogen-Sekunden-Dateien haben 3601 Spalten und 3601 Zeilen mit einer Gesamtdateigröße von 25.934.402 Bytes ( = 3601 x 3601 x 2). Für weitere Informationen finden Sie in der Textdatei "SRTM_Topo.txt" unter http://edcftp.cr.usgs.gov/pub/data/srtm/Readme.html

Danke für jede Hilfe! Ich werde diese Daten in einem Python-Skript verwenden, wenn Sie also keine sprachspezifischen Tricks für andere Sprachen verwenden könnten, wäre das großartig.

13voto

hruske Punkte 2135

Ein getestetes Numpy-Beispiel:

import os
import math
import numpy

fn = 'DMV/N51E000.hgt'

siz = os.path.getsize(fn)
dim = int(math.sqrt(siz/2))

assert dim*dim*2 == siz, 'Invalid file size'

data = numpy.fromfile(fn, numpy.dtype('>i2'), dim*dim).reshape((dim, dim))

8voto

codelogic Punkte 68703

Da die Datensätze eine feste Länge haben (16-Bit-Ganzzahlen mit Vorzeichen) und die Rastergröße bekannt ist (1201 x 1201 oder 3601 x 3601), kann Pythons Struktur Modul scheint ideal geeignet (ungetesteter Code):

from struct import unpack,calcsize

# 'row_length' being 1201 or 3601 and 'row' being the raw data for one row
def read_row( row, row_length ):
    format = 'h'  # h stands for signed short

    for i in range(0, row_length):
        offset = i * calcsize(format)
        (height,) = unpack(format, row[offset : offset+calcsize(format))
        # do something with the height

Allgemeiner ausgedrückt: Sie wollen die Datei in 2 Bytes auf einmal einlesen, die gelesenen Bytes als 16-Bit-Ganzzahl mit Vorzeichen parsen und sie verarbeiten. Da Sie die Größe des Rasters bereits kennen, können Sie es zeilenweise oder auf jede andere für Ihre Anwendung geeignete Weise lesen. Das bedeutet auch, dass Sie nach dem Zufallsprinzip bestimmte Koordinaten in der Datendatei ansteuern können.

5voto

user532954 Punkte 446

Wenn Sie ein wenig mehr Geschwindigkeit wollen, als Sie von Millionen von Aufrufen von struct.unpack erhalten, schauen Sie sich array.array an. Während die "struct-and-for-loop"-Implementierung auf meinem zugegebenermaßen langsamen Laptop mehrere Sekunden dauert, ist die folgende nahezu augenblicklich:

from array import array

f = open(filename, 'rb')
format = 'h'
row_length = 1201
data = array(format)
data.fromfile(f, row_length*row_length)
data.byteswap()
f.close()

1voto

https://gdal.org/drivers/raster/srtmhgt.html

    Input_HGT = 'N30E120.hgt'
    import gdal
    Raster = gdal.Open(Input_HGT) 

Alle Funktionen, die mit GDAL auf Rasterdateien verfügbar sind, können auf dieses 'Raster' angewendet werden, wie Funktionen, die mit der Variablen 'Raster' verfügbar sind

0voto

Die SRTM-Daten der NASA liegen im Big-Endian-Format vor. Je nachdem, auf welcher Plattform Sie die Daten lesen, müssen Sie möglicherweise eine Konvertierung von Big-Endian in Little-Endian vornehmen.

Es gibt zahlreiche Quellen dazu, ich habe keine Erfahrung mit Python und kann Ihnen daher nicht weiterhelfen.

Aber wenn Sie das vergessen, werden Ihre Werte durcheinander geraten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X