【问题标题】:how to read NASA .hgt binary files如何读取 NASA .hgt 二进制文件
【发布时间】:2010-09-26 07:47:04
【问题描述】:

如果您对二进制文件有所了解,我相信这真的很简单,但我是这方面的新手。

如何从 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)。团结的 状态 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 脚本中使用这些数据,所以如果你不能对任何其他语言使用任何特定于语言的技巧,那就太棒了。

【问题讨论】:

标签: file binary


【解决方案1】:

一个经过测试的 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))

【讨论】:

  • 请注意,这首先将文件读入一个平面的一维 Numpy 数组,然后再整形为一个二维数组。首先读取字节然后直接加载到二维数组中可能会更快:numpy.ndarray((dim, dim), numpy.dtype('>i2'), buffer) 其中buffer 是文件中的原始字节。
【解决方案2】:

由于记录是固定长度(16 位有符号整数)并且您知道网格大小(1201 x 1201 或 3601x3601),Python 的 struct 模块似乎非常适合(未经测试的代码):

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 位有符号整数并处理它。由于您已经知道网格大小,您可以逐行或以任何其他对您的应用程序方便的方式读取它。这也意味着您可以随机寻找数据文件中的特定坐标。

【讨论】:

  • 您实际上需要使用 '!h' 格式。 SRTM 规范中描述的大端序
  • '!h''>h' 应该可以定义大端:docs.python.org/3/library/…
【解决方案3】:

如果您想要比从数百万次调用 struct.unpack 获得的速度快一点,请查看 array.array。虽然“struct-and-for-loop”实现在我公认的慢速笔记本电脑上需要几秒钟,但以下内容几乎是瞬间完成的:

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

【讨论】:

    【解决方案4】:

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

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

    GDAL 在栅格文件上可用的所有功能都可以应用于此“栅格”,例如 Functions available with the variable, 'Raster'

    【讨论】:

      【解决方案5】:

      NASA SRTM 数据文件采用 Big-Endian 格式,因此根据您读取数据的平台,您可能需要将 Big-Endian 转换为 Little-Endian。

      有很多关于如何做到这一点的资料,我没有使用 Python 的经验,所以我无法帮助你。

      但如果你忘记了这一点,你的价值观就会一团糟。

      【讨论】:

        【解决方案6】:

        如果您有 Photoshop,则可以尝试使用原始导入来读取这些文件并将它们保存到更有用的位置。过去我在做这类事情方面取得了一些成功。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-04
          • 2015-11-22
          • 2013-04-24
          • 2018-01-21
          • 1970-01-01
          • 2019-04-10
          • 1970-01-01
          相关资源
          最近更新 更多