Estrarre elevazione dal file .HGT?


20

Voglio assegnare una posizione long / lat specifica su una mappa all'elevazione dai file di dati SRTM3, ma non ho idea di come trovare il valore specifico. Quindi voglio un esempio di come posso trovare in elevazione N50E14.hgt a 50 ° 24'58.888 "N, 14 ° 55'11.377" E.


1
Quale software stai usando? Ci sono alcune note sul .hgtformato del file nella documentazione SRTM , ma una risposta passo-passo specifica dipende dal software che hai a disposizione.
amato l'

1
Non ho software, sono programmatore c # e sto scrivendo la mia applicazione. Sono in grado di assegnare long / lat a ogni pixel e ora voglio cercare l'elevazione in ogni punto. Il miglior formato di dati dovrebbe essere qualcosa di simile al file CSV. Quindi in una riga posso trovare longitudine; latitudine; altitudine. Ho cercato la documentazione SRTM, ma non riesco ancora a immaginare come posso fornire il data mining sul file.
MartinS

Risposte:


30

Formato dei dati

Lo prenderò come un piccolo esercizio su come programmare un lettore di dati. Dai un'occhiata alla documentazione :

I dati SRTM sono distribuiti su due livelli: SRTM1 (per gli Stati Uniti e i suoi territori e possedimenti) con dati campionati a intervalli di un secondo d'arco in latitudine e longitudine e SRTM3 (per il mondo) campionato a tre secondi d'arco.

I dati sono divisi in caselle di latitudine e longitudine di uno per grado in proiezione "geografica", vale a dire una presentazione raster con uguali intervalli di latitudine e longitudine in nessuna proiezione ma facile da manipolare e mosaico.

I nomi dei file si riferiscono alla latitudine e longitudine dell'angolo in basso a sinistra della piastrella - ad es. N37W105 ha il suo angolo in basso a sinistra a 37 gradi di latitudine nord e 105 gradi di longitudine ovest. Per essere più precisi, queste coordinate si riferiscono al centro geometrico del pixel in basso a sinistra, che nel caso dei dati SRTM3 avrà una estensione di circa 90 metri.

I file di altezza hanno estensione .HGT e sono numeri interi a due byte. I byte sono nell'ordine "big-endian" di Motorola con il byte più significativo per primo, leggibile direttamente da sistemi come Sun SPARC, Silicon Graphics e computer Macintosh che utilizzano processori Power PC. DEC Alpha, la maggior parte dei PC e dei computer Macintosh costruiti dopo il 2006 utilizzano l'ordine Intel ("little-endian"), pertanto potrebbe essere necessario lo scambio di byte. Le altezze sono in metri riferite al geoide WGS84 / EGM96. Ai vuoti di dati viene assegnato il valore -32768.

Come procedere

Per la tua posizione, 50 ° 24'58.888 "N 14 ° 55'11.377" E, hai già trovato la piastrella corretta, N50E14.hgt. Scopriamo a quale pixel sei interessato. Prima latitudine, 50 ° 24'58.888 "N:

24'58.888" = (24 * 60)" + 58.888" = 1498.888"

secondi d'arco. Diviso per tre e arrotondato all'intero più vicino fornisce una riga della griglia di 500. Lo stesso calcolo per la longitudine risulta nella colonna della griglia 1104.

La documentazione di avvio rapido è priva di informazioni su come le file e le colonne sono organizzate nel file, ma nella documentazione completa si afferma che

I dati sono memorizzati nell'ordine principale della riga (tutti i dati per la riga 1, seguiti da tutti i dati per la riga 2, ecc.)

La prima riga del file è molto probabilmente la più settentrionale, vale a dire se siamo interessati alla riga 500 dal bordo inferiore , dobbiamo effettivamente guardare la riga

1201 - 500 = 701

dall'inizio se il file . La nostra cella della griglia è il numero

(1201 * 700) + 1104 = 841804

dall'inizio del file (ovvero saltare 700 righe e nel 701 prendere il campione 1104). Due byte per campione significa che dobbiamo saltare i primi 1683606 byte nel file e quindi leggere due byte per ottenere la nostra cella della griglia. I dati sono big-endian, il che significa che è necessario scambiare i due byte su ad esempio piattaforme Intel.

Programma di esempio

Un programma Python semplicistico per recuperare i dati giusti sarebbe simile a questo (consultare i documenti per l'uso del modulo struct):

import struct

def get_sample(filename, n, e):
    i = 1201 - int(round(n / 3, 0))
    j = int(round(e / 3, 0))
    with open(filename, "rb") as f:
        f.seek(((i - 1) * 1201 + (j - 1)) * 2)  # go to the right spot,
        buf = f.read(2)  # read two bytes and convert them:
        val = struct.unpack('>h', buf)  # ">h" is a signed two byte integer
        if not val == -32768:  # the not-a-valid-sample value
            return val
        else:
            return None

if __name__ == "__main__":
    n = 24 * 60 + 58.888
    e = 55 * 60 + 11.377
    tile = "N50E14.hgt"  # Or some magic to figure it out from position
    print get_sample(tile, n, e)

Si noti che il recupero efficiente dei dati dovrebbe apparire un po 'più sofisticato (ad es. Non aprire il file per ogni singolo campione).

alternative

È inoltre possibile utilizzare un programma in grado di leggere i file .hgt immediatamente. Ma è noioso.


Battimi, e con più dettagli per l'avvio!
amato l'

Bello spiegare, ti amo. Grazie per l'aiuto. Tutti voi ragazzi.
MartinS

1
+1 Sì, le file sono ordinate da nord a sud. Questo è chiaro non appena si mappa uno dei file. Inoltre, considera di ottenere altezze tramite interpolazione bilineare tra i quattro centri cellulari che circondano la posizione.
whuber

Grazie per queste informazioni complete! Ho una domanda: quando stiamo cercando dati di elevazione per 50 ° 24'58.888, perché sottrai il numero di riga 500 dal bordo inferiore quando le righe sono ordinate da nord a sud? Grazie!
Georg,

Se non sbaglio, credo che (j-1) sarà solo j. Il valore j va da 0 a 1200, quindi non è necessario sottrarre 1.
Malipivo

6

GDAL può leggere / scrivere questi formati raster con il driver SRTMHGT . Ciò significa che puoi visualizzare il raster con QGIS, ArcGIS o utilizzare le utility GDAL come gdallocationinfo per ottenere valori da un punto, ad esempio:

Converti DMS in DD:

  • Lat: 50 ° 24'58.888 "N = 50 + (24/60) + (58.888 / 3600) = 50.4163577778
  • Lungo: 14 ° 55'11.377 "E = 14 + (55/60) + (11.377 / 3600) = 14.9198269444

Quindi da una shell, utilizzare gdallocationinfo file.hgt -wgs84 long lat:

$ gdallocationinfo N50E14.hgt -wgs84 14.9198269444 50.4163577778
Report:
  Location: (1104P,700L)
  Band 1:
    Value: 216

L'altitudine è di 216 m.


1
Che ne dici di posizioni nei lati sud o ovest?
Muhammet Ali Asan,

2

Se si utilizza QGIS, verificare che sia installato il plug-in Python "Point Sampling Tool". Lo troverai su -> Miglioramenti (Python) -> Analizza.

Seleziona il tuo layer di punti delle posizioni richieste, quindi avvia il PST, scegli hgt (o qualunque file raster / poligono) e scegli una nuova forma di punto per l'output.

È tutto :-)

  Chris

0

La risposta di Chris indica che è semplice campionare punti da un livello in QGIS.

Tuttavia, poiché la tua risposta al mio commento chiarisce che stai scrivendo il tuo programma per leggere i valori di elevazione dai .hgtfile, dai un'occhiata al PDF Quickstart nei documenti SRTM. Spiega come vengono memorizzati i dati di elevazione. Riassumere:

  • I file SRTM3 contengono una sequenza di valori interi big-endian.
  • Ogni valore intero rappresenta un'elevazione "in metri riferita al geoide WGS84 / EGM96", ad eccezione dei valori di -32768, che indicano pixel senza dati.
  • Ci sono 1201 righe di 1201 campioni, quindi dovrebbero esserci complessivamente 1442401 valori interi.

Dici che puoi convertire tra coordinate lon / lat e pixel, quindi ottenere l'elevazione è una questione di lettura del valore intero dall'offset appropriato nel file. Date le coordinate pixel xe yrelative all'angolo in alto a sinistra della scena, questo è fondamentalmente offset = (y * 1201) + x. Pixel 0,0è il primo numero intero nel file e pixel 1200,1200è l'ultimo numero intero nel file.


1
Questo è corretto, ma mancano alcuni dettagli cruciali forniti dalla risposta di Bhell, incluso che le coordinate sono associate ai centri cellulari . Pertanto, ad esempio, l'angolo superiore sinistro di N50E014.hgt si trova effettivamente alla longitudine 13.99958 E, latitudine 51.00042 N.
whuber
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.