SRTM3データファイルからの標高に、マップ上の特定のロング/緯度位置を割り当てたいのですが、特定の値を見つける方法がわかりません。それで、N50E14.hgtの高度が50°24'58.888 "N、14°55'11.377" Eである場合の見つけ方の例を示します。
SRTM3データファイルからの標高に、マップ上の特定のロング/緯度位置を割り当てたいのですが、特定の値を見つける方法がわかりません。それで、N50E14.hgtの高度が50°24'58.888 "N、14°55'11.377" Eである場合の見つけ方の例を示します。
回答:
これを、データリーダーのプログラミング方法の小さな演習として取り上げます。ドキュメントを見てください:
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ファイルを読み取ることができるプログラムを使用することもできます。しかし、それは退屈です。
GDALは、これらのラスター形式をSRTMHGTドライバーで読み書きできます。つまり、QGIS、ArcGISでラスターを表示したり、gdallocationinfoなどのGDALユーティリティを使用して、ポイントから値を取得したりできます。例:
DMSをDDに変換します。
次に、シェルからgdallocationinfo file.hgt -wgs84 long lat
:
$ gdallocationinfo N50E14.hgt -wgs84 14.9198269444 50.4163577778
Report:
Location: (1104P,700L)
Band 1:
Value: 216
標高は216 mです。
Chrisの答えは、QGISのレイヤーからポイントをサンプリングすることは簡単であることを示しています。
ただし、私のコメントへの返信では、.hgt
ファイルから標高値を読み取る独自のプログラムを作成していることが明確になっているため、SRTMドキュメントのクイックスタートPDFをもう一度ご覧ください。標高データの保存方法について説明します。要約する:
-32768
データなしピクセルを示すの値を除き、「WGS84 / EGM96ジオイドを基準としたメートル単位の」標高を表します。経度/緯度座標とピクセルの間で変換できると言うので、標高を取得するには、ファイル内の適切なオフセットから整数値を読み取る必要があります。ピクセル座標が与えられ、シーンの左上隅を基準にするx
とy
、それは基本的にoffset = (y * 1201) + x
です。ピクセル0,0
はファイルの最初の整数で、ピクセル1200,1200
はファイルの最後の整数です。
.hgt
ファイル形式に関する注意事項がいくつかありますが、具体的な段階的な回答は、使用可能なソフトウェアによって異なります。