2008-12-10 12 views
22

Estoy seguro de que esto es realmente simple si sabes algo sobre archivos binarios, pero soy un novato en ese aspecto.cómo leer los archivos binarios de NASA .hgt

¿Cómo extraería los datos de los archivos .hgt de la NASA? He aquí una descripción de www2.jpl.nasa.gov/srtm/faq.html:

archivos de datos

El SRTM tienen nombres como "N34W119.hgt". ¿A qué se refieren las letras y números , y qué es el formato ".hgt"?

Cada archivo de datos abarca un bloque de un grado de latitud por un grado de longitud de la superficie de la Tierra. Los primeros siete caracteres indican la esquina suroeste del bloque , con N, S, E y W que hacen referencia al norte, sur, este, y al oeste. Por lo tanto, el archivo "N34W119.hgt" abarca las latitudes 34 a 35 North y longitudes 118-119 West (este archivo incluye el centro de Los Angeles, California). La extensión de nombre de archivo ".hgt" simplemente significa la palabra "altura", que significa elevación. NO es un tipo de formato. Estos archivos son en formato "crudo" (sin encabezados y no comprimidos), enteros de 16 bits, elevación medida en metros sobre el nivel del mar, en proyección "geográfica" (latitud y longitud), con vacíos de datos indicados por -32768. Los archivos internacionales de 3 segundos de arco tienen 1201 columnas y 1201 filas de datos, con un tamaño de archivo total de 2,884,802 bytes (= 1201 x 1201 x 2). United Estados Los archivos de 1 arco de segundo tienen 3601 columnas y 3601 filas de datos, con un tamaño total de archivo de 0 de 25.934.402 bytes (= 3601 x 3601 x 2). Para obtener más información leer el archivo de texto "SRTM_Topo.txt" en http://edcftp.cr.usgs.gov/pub/data/srtm/Readme.html

Gracias por cualquier ayuda! Voy a utilizar estos datos en una secuencia de comandos python, por lo que si no puede utilizar ningún truco específico del idioma para otros idiomas, sería increíble.

+2

El eslabón de la cuestión está roto, pero creo que este es el mismo archivo: http://dds.cr.usgs.gov/srtm/version1/Documentation/SRTM_Topo.txt – Hubro

Respuesta

6

Dado que los registros son de longitud fija (16 bits enteros con signo) y que conoce el tamaño de la cuadrícula (1201 x 1201 o 3601x3601), el módulo de Python struct parece idealmente adecuado (código no probado):

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 

Describiendo en términos más genéricos, básicamente quiere leer el archivo en 2 bytes a la vez, analizar los bytes leídos como un entero con signo de 16 bits y procesarlo. Como ya conoce el tamaño de la cuadrícula, puede leerlo fila por fila o de cualquier otra manera que sea conveniente para su aplicación. También significa que puede buscar aleatoriamente coordenadas específicas dentro del archivo de datos.

+3

Realmente necesita usar el formato '! h'. big-endian como se describe en las especificaciones de SRTM – skrat

0

Los archivos de datos NASA SRTM están en formato Big-Endian, por lo que dependiendo de la plataforma en la que esté leyendo los datos, es posible que tenga que hacer una conversión de Big-Endian a Little-Endian.

Existen numerosas fuentes sobre cómo hacer esto, no tengo experiencia con Python, así que no puedo ayudarte.

Pero si olvida esto, sus valores van a estar completamente desordenados.

0

Si tiene photoshop, es posible que pueda jugar con la importación sin procesar para que lea estos archivos y los guarde en algo más útil. He tenido cierto éxito haciendo este tipo de cosas en el pasado.

4

Si desea un poco más de velocidad que la que obtiene de millones de llamadas a struct.unpack, eche un vistazo a array.array. Si bien la aplicación "estructura-y-para-loop" tarda varios segundos en mi portátil ciertamente lento, lo que sigue es casi instantánea:

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() 
6

Un ejemplo numpy probado:

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)) 
Cuestiones relacionadas