2008-12-10 7 views
22

Я уверен, что это действительно просто, если вы знаете что-нибудь о бинарных файлах, но я новичок на этом счету.Как читать NASA .hgt двоичные файлы

Как извлечь данные из файлов NASA .hgt? Вот описание от www2.jpl.nasa.gov/srtm/faq.html:

файлы данных

SRTM имеют имена, как «N34W119.hgt». На что ссылаются буквы и цифры , а что такое формат «.hgt»?

Каждый файл данных покрывает одну градус широты на один градус долготы Блок земной поверхности. Первые семь символов обозначают юго-западный угол блока, а N, S, E и W относятся к северу, югу, востоку, и к западу. Таким образом, файл «N34W119.hgt» охватывает широты от 34 до 35 северных и долготы 118-119 запад (этот файл включает в себя город Лос-Анджелес, Калифорния). Расширение имени файла .hgt просто означает слово «высота», что означает возвышение. Это НЕ формат. Эти файлы: в «сыром» формате (без заголовков и не сжимаются), 16-разрядные знаковые целые числа, высота, измеренная в метрах над уровнем моря, в проекции «географическая» (широта и долгота) с указанными пустотами данных от -32768. Международные 3-дуговые файлы имеют 1201 столбцов и 1201 строку данных, с общим размером файла 2,884,802 байта (= 1201 x 1201 x 2). United Головные файлы с 1-дуговой секцией имеют 3601 столбцов и 3601 строку данных, с общим размером файла - 25 934 402 байта (= 3601 x 3601 x 2). Для получения дополнительной информации прочитать текстовый файл «SRTM_Topo.txt» в http://edcftp.cr.usgs.gov/pub/data/srtm/Readme.html

Спасибо за любую помощь! Я собираюсь использовать эти данные в сценарии python, поэтому, если вы не можете использовать какие-либо языковые трюки для каких-либо других языков, это было бы потрясающе.

+2

Ссылка на вопрос , но я думаю, что это тот же файл: http://dds.cr.usgs.gov/srtm/version1/Documentation/SRTM_Topo.txt – Hubro 2012-05-14 11:06:10

ответ

6

Поскольку записи фиксированной длины (16-разрядное знаковое целые числа), и вы знаете размер сетки (1201 х 1201 или 3601x3601), struct модуль Python, кажется идеально подходит (непроверенный код):

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 

Описывая он в более общих терминах, в основном вы хотите прочитать файл по 2 байта за раз, проанализируйте байты, считанные как 16-разрядное целое число со знаком, и обработайте его. Поскольку вы уже знаете размер сетки, вы можете читать ее в строке за строкой или любым другим способом, удобным для вашего приложения. Это также означает, что вы можете произвольно искать конкретные координаты внутри файла данных.

+3

Вам действительно нужно использовать формат «! h». big-endian, как описано в спецификациях SRTM – skrat 2010-02-06 13:45:34

0

Файлы данных NASA SRTM находятся в формате Big-Endian, поэтому в зависимости от того, на какой платформе вы читаете данные, вам может потребоваться преобразование из Big-Endian в Little-Endian.

Существует множество источников о том, как это сделать, у меня нет опыта работы с Python, поэтому я не могу вам помочь.

Но если вы забудете об этом, ваши ценности будут испорчены.

0

Если у вас есть фотошоп, вы можете играть с сырым импортом, чтобы получить его, чтобы прочитать эти файлы и сохранить их в чем-то более полезном. У меня был определенный успех в прошлом.

4

Если вам требуется немного больше скорости, чем вы получаете от миллионов вызовов struct.unpack, посмотрите на array.array. В то время как реализация «структура-и-для цикла» занимает несколько секунд на моем правда медленный ноутбук, следующий практически мгновенно:

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

Испытуемый Numpy пример:

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)) 
Смежные вопросы