.HGT dosyasından yükseklik alınıyor mu?


20

Bir harita üzerinde SRTM3 veri dosyalarından yükselmeye belirli bir uzun / lat konumu atamak istiyorum, ancak belirli bir değeri nasıl bulacağım hakkında hiçbir fikrim yok. Bu yüzden 50 ° 24'58.888 "N, 14 ° 55'11.377" E'ye kadar N50E14.hgt yüksekliğinde nasıl bulabileceğime bir örnek istiyorum.


1
Hangi yazılımı kullanıyorsun? SRTM belgelerinde.hgt dosya biçimi hakkında bazı notlar vardır , ancak belirli bir adım adım yanıt, elinizde bulunan yazılıma bağlıdır.
anoved

1
Yazılımım yok, c # programcısıyım ve kendi uygulamamı yazıyorum. Her piksele uzun / lat atayabilirim ve şimdi her noktaya yükseklik aramak istiyorum. En iyi veri formatı CSV dosyası gibi bir şey olmalıdır. Yani bir satırda boylam, enlem; yükseklik bulabilirim. SRTM belgelerini aradım, ancak yine de dosyada veri madenciliği nasıl sağlayabilirim hayal edemiyorum.
MartinS

Yanıtlar:


30

Veri formatı

Veri okuyucuyu nasıl programlayacağınız konusunda biraz alıştırma yapacağım. Belgelere bir göz atın :

SRTM verileri iki düzeyde dağıtılır: enlem ve boylamda bir yay-saniyelik aralıklarla örneklenen verilerle SRTM1 (ABD ve bölgeleri ve mülkleri için) ve üç yay-saniyede örneklenmiş SRTM3 (dünya için).

Veriler, "coğrafi" projeksiyonda bir dereceye kadar enlem ve boylam karolarına bölünür; bu, hiç bir projeksiyonda eşit enlem ve boylam aralıklarına sahip, manipüle edilmesi kolay ve mozaik olan bir raster sunumu anlamına gelir.

Dosya adları, döşemenin sol alt köşesinin enlem ve boylamını belirtir - örneğin N37W105'in sol alt köşesi 37 derece kuzey enleminde ve 105 derece batı boylamındadır. Daha kesin olmak gerekirse, bu koordinatlar, sol alt pikselin SRTM3 verisi durumunda yaklaşık 90 metre olacak şekilde geometrik merkezini ifade eder.

Yükseklik dosyaları .HGT uzantısına sahiptir ve iki bayt tamsayı ile imzalanmıştır. Baytlar Motorola "big-endian" düzenindedir ve en önemli bayt ilk sıradadır, Power PC işlemcileri kullanan Sun SPARC, Silicon Graphics ve Macintosh bilgisayarlar gibi sistemler tarafından doğrudan okunabilir. DEC Alpha, 2006'dan sonra üretilen çoğu PC ve Macintosh bilgisayarında Intel ("little-endian") sırası kullanılır, bu nedenle bazı bayt değiştirme gerekebilir. Yükseklikler, WGS84 / EGM96 geoidine referans olarak metre cinsindendir. Veri boşluklarına -32768 değeri atanır.

Nasıl devam edilir?

Pozisyonunuz için 50 ° 24'58.888 "N 14 ° 55'11.377" E, doğru döşemeyi zaten buldunuz, N50E14.hgt. Hangi pikselle ilgilendiğinizi bulalım. İlk enlem, 50 ° 24'58.888 "N:

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

ark saniye. Üçe bölünür ve en yakın tamsayıya yuvarlanır, 500 ızgara satırı verir. Boylam için aynı hesaplama, ızgara sütunu 1104'te elde edilir.

Hızlı başlangıç belgeleri satır ve sütun dosyasında nasıl düzenlendiği hakkında bilgi bulunmayan, ancak içinde tam dokümantasyon o belirtilmektedir

Veriler sıra ana sırasında depolanır (1. sıra için tüm veriler, ardından 2. sıra için tüm veriler vb.)

Dosyadaki ilk satır en kuzeydeki satırdır, yani alt kenardan 500. sıra ile ilgileniyorsak , aslında sıraya bakmalıyız

1201 - 500 = 701

başından itibaren dosya . Izgara hücremiz sayıdır

(1201 * 700) + 1104 = 841804

dosyanın başlangıcından itibaren (yani, 700 satırı atlayın ve 701. birincisinde örnek 1104'ü alın). Örnek başına iki bayt, dosyadaki ilk 1683606 baytı atlamamız ve ardından ızgara hücremizi almak için iki baytı okumamız gerektiği anlamına gelir. Veriler big-endian, yani Intel platformlarında iki baytı değiştirmeniz gerekiyor.

Örnek program

Doğru verileri almak için basit bir Python programı şöyle görünecektir ( struct modülünün kullanımı için belgelere bakın ):

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)

Verimli veri alımının biraz daha karmaşık görünmesi gerektiğini unutmayın (örneğin, her örnek için dosyayı açmamak).

Alternatifler

.Hgt dosyalarını kutudan çıkarabilen bir program da kullanabilirsiniz. Ama bu sıkıcı.


Beni yendi ve önyükleme yapmak için daha fazla ayrıntıyla!
12'de

Güzel açıklama, seni seviyorum. Yardımın için teşekkürler. Hepiniz beyler.
MartinS

1
+1 Evet, sıralar kuzeyden güneye doğru sıralanıyor. Dosyalardan birini eşlediğinizde bu açıktır. Ayrıca, konumu çevreleyen dört hücre merkezi arasında bilinear enterpolasyon yoluyla yükseklik elde etmeyi düşünün.
whuber

Bu kapsamlı bilgi için teşekkürler! Bir sorum var: 50 ° 24'58.888 için yükseklik verileri ararken, satırlar kuzeyden güneye sıralandığında 500 numaralı satırı neden alt kenardan çıkarıyorsunuz? Teşekkürler!
Georg

Yanılmıyorsam, (j-1) 'in sadece j olacağına inanıyorum. J değeri 0 ile 1200 arasında değişir, bu nedenle 1 çıkarmaya gerek yoktur.
Malipivo

6

GDAL bu tarama formatlarını SRTMHGT sürücüsü ile okuyabilir / yazabilir . Bu, rasterleri QGIS, ArcGIS ile görüntüleyebileceğiniz veya bir noktadan değer almak için gdallocationinfo gibi GDAL yardımcı programlarını kullanabileceğiniz anlamına gelir , örneğin:

DMS'yi DD'ye dönüştürün:

  • Enlem: 50 ° 24'58.888 "N = 50 + (24/60) + (58.888 / 3600) = 50.4163577778
  • Uzun: 14 ° 55'11.377 "E = 14 + (55/60) + (11.377 / 3600) = 14.9198269444

Sonra bir kabuktan şunu kullanın gdallocationinfo file.hgt -wgs84 long lat:

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

Yükseklik 216 m'dir.


1
Peki ya güney ya da batı yakasındaki yerler?
Muhammet Ali Asan

2

QGIS kullanıyorsanız, python eklentisi "Nokta Örnekleme Aracı" nın kurulu olup olmadığını kontrol edin. -> Geliştirmeler (Python) -> Analizde bulabilirsiniz.

Gerekli konumların nokta katmanınızı seçin, ardından PST'yi başlatın, hgt'yi (veya herhangi bir raster / çokgen dosyasını) seçin ve çıktı için yeni bir nokta şekli seçin.

Bu kadar :-)

  Chris

0

Chris'in cevabı, QGIS'deki bir katmandan nokta örneklemenin kolay olduğunu gösteriyor.

Ancak, yorumuma verdiğiniz yanıt, .hgtdosyalardan yükseklik değerlerini okumak için kendi programınızı yazdığınızı açıkladığı için , SRTM belgelerindeki Quickstart PDF'ye bir göz atın . Yükseklik verilerinin nasıl saklandığını açıklar. Özetlemek:

  • SRTM3 dosyaları bir dizi büyük endian tamsayı değeri içerir.
  • Her tamsayı değeri -32768, veri içermeyen pikselleri belirten değerler hariç, "WGS84 / EGM96 geoidine referans gösterilen metre cinsinden" bir yükselişi temsil eder .
  • 1201 numunenin 1201 satırı vardır, bu nedenle toplamda 1442401 tamsayı değeri olmalıdır.

Lon / lat koordinatları ve pikseller arasında dönüştürme yapabileceğinizi söylüyorsunuz, bu nedenle yükseklik elde etmek, dosyadaki uygun ofsetten tamsayı değerini okumakla ilgilidir. Piksel koordinatları xve ysahnenin sol üst köşesine göre, bu temelde offset = (y * 1201) + x. Piksel 0,0, dosyadaki ilk tam sayı ve piksel 1200,1200, dosyadaki son tam sayıdır.


1
Bu doğrudur, ancak koordinatların hücre merkezleri ile ilişkili olması da dahil olmak üzere, kabuğun cevabı tarafından sağlanan birkaç önemli ayrıntıyı kaçırmaktadır . Böylece, örneğin, N50E014.hgt'nin sol üst köşesi aslında 13.99958 E boylamında, 51.00042 N. enleminde bulunur.
whuber
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.