.HGTファイルから標高を抽出していますか?


20

SRTM3データファイルからの標高に、マップ上の特定のロング/緯度位置を割り当てたいのですが、特定の値を見つける方法がわかりません。それで、N50E14.hgtの高度が50°24'58.888 "N、14°55'11.377" Eである場合の見つけ方の例を示します。


1
どのソフトウェアを使用していますか?SRTMのドキュメントには.hgtファイル形式に関する注意事項がいくつかありますが、具体的な段階的な回答は、使用可能なソフトウェアによって異なります。
20:50に

1
私はソフトウェアを持っていません、私はc#プログラマーで、自分のアプリケーションを書いています。私はすべてのピクセルに長い/緯度を割り当てることができますが、今では各ポイントの標高を検索したいです。最適なデータ形式はCSVファイルのようなものでなければなりません。したがって、1行で経度、緯度、高度を見つけることができます。SRTMドキュメントを検索しましたが、ファイルにデータマイニングを提供する方法を想像することはできません。
マルティンス

回答:


30

データ形式

これを、データリーダーのプログラミング方法の小さな演習として取り上げます。ドキュメントを見てください:

SRTMデータは、緯度と経度で1アーク秒間隔でサンプリングされたSRTM1(米国およびその領土と所有物)と、3アーク秒でサンプリングされたSRTM3(世界)の2つのレベルで配信されます。

データは「地理的」投影法で緯度と経度のタイルごとに1つに分割されます。つまり、投影法はまったくないが、操作とモザイクが簡単な、緯度と経度の等間隔のラスタープレゼンテーションです。

ファイル名は、タイルの左下隅の緯度と経度を指します。たとえば、N37W105の左下隅は北緯37度、西経105度です。より正確には、これらの座標は、左下のピクセルの幾何学的中心を指します。SRTM3データの場合、その範囲は約90メートルです。

高さファイルの拡張子は.HGTで、符号付きの2バイト整数です。バイトはモトローラの「ビッグエンディアン」順で、最上位バイトが最初で、Power PCプロセッサを使用するSun SPARC、Silicon Graphics、Macintoshコンピュータなどのシステムで直接読み取り可能です。DEC Alpha、2006年以降に構築されたほとんどのPCおよびMacintoshコンピューターはIntel(「リトルエンディアン」)順序を使用するため、バイト交換が必要になる場合があります。高さは、WGS84 / EGM96ジオイドを基準としたメートル単位です。データ無効には値-32768が割り当てられます。

どうやって進める

あなたの位置、50°24'58.888 "N 14°55'11.377" Eについては、すでに正しいタイル、N50E14.hgtが見つかりました。興味のあるピクセルを見つけましょう。第一緯度、50°24'58.888 "N:

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

アーク秒。3で除算し、最も近い整数に丸めると、500のグリッド行が得られます。経度の同じ計算の結果、グリッド列1104が得られます。

クイックスタートドキュメントには、ファイル内の行と列の構成に関する情報がありませんが、完全なドキュメントでは、

データは行優先順に格納されます(行1のすべてのデータに続いて行2のすべてのデータが続きます)。

ファイルの最初の行は最北の行である可能性が非常に高いです。つまり、下端から行500に興味がある場合、実際には行を見る必要があります

1201 - 500 = 701

ファイルの場合は最初から。グリッドセルは数値です

(1201 * 700) + 1104 = 841804

ファイルの先頭から(つまり、700行をスキップし、701行目でサンプル1104を取得します)。サンプルあたり2バイトは、ファイル内の最初の1683606バイトをスキップし、グリッドセルを取得するために2バイトを読み取る必要があることを意味します。データはビッグエンディアンです。つまり、Intelプラットフォームなどでは2バイトをスワップする必要があります。

サンプルプログラム

適切なデータを取得するための単純なPythonプログラムは次のようになります(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)

効率的なデータ取得は、もう少し洗練されたものにする必要があることに注意してください(たとえば、各サンプルごとにファイルを開かない)。

代替案

また、すぐに.hgtファイルを読み取ることができるプログラムを使用することもできます。しかし、それは退屈です。


それに私を打ち負かし、より詳細に起動してください!
改定

素敵な説明、愛しています。ご協力いただきありがとうございます。みなさん。
マルティンス

1
+1はい、行は北から南に並べられます。これは、ファイルの1つをマップするとすぐに明らかになります。また、その場所を囲む4つのセルの中心間の双一次補間を介して高さを取得することを検討してください。
whuber

この包括的な情報をありがとう!1つの質問があります:50°24'58.888の標高データを探しているときに、行を北から南に並べるときに、下端から行番号500を引くのはなぜですか?ありがとう!
ジョージ

私が間違っていなければ、(j-1)はjだけだと思います。値jの範囲は
0〜1200

6

GDALは、これらのラスター形式をSRTMHGTドライバーで読み書きできます。つまり、QGIS、ArcGISでラスターを表示したり、gdallocationinfoなどのGDALユーティリティを使用して、ポイントから値を取得したりできます。例:

DMSをDDに変換します。

  • 緯度:50°24'58.888 "N = 50 +(24/60)+(58.888 / 3600)= 50.4163577778
  • 長い:14°55'11.377 "E = 14 +(55/60)+(11.377 / 3600)= 14.9198269444

次に、シェルからgdallocationinfo file.hgt -wgs84 long lat

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

標高は216 mです。


1
南または西側の場所はどうですか?
モハメットアリアサン

2

QGISを使用する場合は、Pythonプラグイン「ポイントサンプリングツール」がインストールされているかどうかを確認してください。-> Enhancements(Python)-> Analyseにあります。

必要な位置のポイントレイヤーを選択してから、PSTを開始し、hgt(または任意のラスター/ポリゴンファイル)を選択して、出力用の新しいポイントシェイプを選択します。

それで全部です :-)

  Chris

0

Chrisの答えは、QGISのレイヤーからポイントをサンプリングすることは簡単であることを示しています。

ただし、私のコメントへの返信では、.hgtファイルから標高値を読み取る独自のプログラムを作成していることが明確になっているため、SRTMドキュメントのクイックスタートPDFをもう一度ご覧ください。標高データの保存方法について説明します。要約する:

  • SRTM3ファイルには、ビッグエンディアン整数値のシーケンスが含まれています。
  • 各整数値は、-32768データなしピクセルを示すの値を除き、「WGS84 / EGM96ジオイドを基準としたメートル単位の」標高を表します。
  • 1201サンプルの1201行があるため、整数値は1442401になります。

経度/緯度座標とピクセルの間で変換できると言うので、標高を取得するには、ファイル内の適切なオフセットから整数値を読み取る必要があります。ピクセル座標が与えられ、シーンの左上隅を基準にするxy、それは基本的にoffset = (y * 1201) + xです。ピクセル0,0はファイルの最初の整数で、ピクセル1200,1200はファイルの最後の整数です。


1
これは正しいですが、座標がセル中心に関連付けられているなど、bhellの答えで提供されるいくつかの重要な詳細が欠落しています。したがって、たとえば、N50E014.hgtの左上隅は、実際には経度13.99958 E、緯度51.00042 Nに位置しています。
whuber
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.