Витяг висоти з .HGT-файла?


20

Я хочу призначити на карті певне довге / лат положення на висоті від файлів даних SRTM3, але не маю уявлення, як знайти конкретне значення. Тому я хочу приклад того, як я можу знайти висоту N50E14.hgt до 50 ° 24'58.888 "N, 14 ° 55'11.377" E.


1
Яке програмне забезпечення ви використовуєте? У документації.hgt на SRTM є деякі примітки щодо формату файлу , але конкретна покрокова відповідь залежить від наявного програмного забезпечення.
зголошено

1
У мене немає програмного забезпечення, я програміст c # і пишу власну заявку. Я можу привласнити long / lat кожному пікселю, і тепер я хочу шукати висоту для кожної точки. Найкращий формат даних повинен бути чимось на зразок файлу CSV. Так в одному ряду я можу знайти довготу; широту; висоту. Я шукав документацію SRTM, але я все ще не можу уявити, як я можу забезпечити пошук даних для файлу.
MartinS

Відповіді:


30

Формат даних

Я сприйматиму це як невелику вправу програмування зчитувача даних. Погляньте на документацію :

Дані SRTM розподіляються у двох рівнях: SRTM1 (для США та її територій та володінь) з даними, відібраними з інтервалом дуги-секунди за широтою та довготою, та SRTM3 (для світу), відібраними у три дуги-секунди.

Дані поділяються на "по одному градусу широти та довготи" в "географічній" проекції, тобто растрове представлення з рівними інтервалами широти та довготи взагалі без проекції, але просто маніпулювати та мозаїчно.

Назви файлів відносяться до широти та довготи нижнього лівого кута плитки - наприклад, N37W105 має нижній лівий кут на 37 градусах північної широти та 105 градусів на західній довготі. Якщо точніше, ці координати відносяться до геометричного центру лівого нижнього пікселя, який у випадку даних SRTM3 становитиме близько 90 метрів.

Файли висоти мають розширення .HGT і підписані двома байтовими цілими числами. Байти перебувають у Motorola в "великому ендіанському" порядку з першим найважливішим байтом, який легко читається такими системами, як Sun SPARC, Silicon Graphics та Macintosh, що використовують процесори Power PC. DEC Alpha, більшість комп'ютерів та комп'ютерів Macintosh, побудовані після 2006 року, використовують замовлення 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"

дуга секунд. Розділене на три і закруглене до найближчого цілого числа дає сітку рядка 500. Такий же розрахунок для довготи приводить до колонки 1104 сітки.

У документації для швидкого запуску відсутня інформація про впорядкування рядків і стовпців у файлі, але в повній документації зазначено, що

Дані зберігаються в основному порядку рядків (усі дані для рядка 1, а потім усі дані для рядка 2 тощо)

Перший рядок у файлі є, найімовірніше, самим північним, тобто, якщо нас цікавить рядок 500 з нижнього краю , ми насправді мусимо подивитися на рядок

1201 - 500 = 701

з початку, якщо файл . Наша комірка сітки - номер

(1201 * 700) + 1104 = 841804

з початку файлу (тобто пропустити 700 рядків, а в 701-му взяти зразок 1104). Два байти на зразок означає, що ми повинні пропустити перші 1683606 байтів у файл, а потім прочитати два байти, щоб отримати нашу комірку сітки. Дані є big-endian, що означає, що вам потрібно поміняти два байти, наприклад, на платформах Intel.

Зразок програми

Спрощена програма 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 файли з вікна. Але це нудно.


Побийте мене до цього, і з більш детальною інформацією про завантаження!
зголошено

Приємно пояснити, люблю тебе. Спасибі за вашу допомогу. Всі ви, хлопці
MartinS

1
+1 Так, ряди впорядковані з півночі на південь. Це зрозуміло, як тільки ви картографуєте один із файлів. Також розглянути можливість отримання висоти за допомогою білінеарної інтерполяції серед чотирьох клітинних центрів, що оточують місце розташування.
whuber

Дякуємо за цю вичерпну інформацію! У мене є одне питання: Коли ми шукаємо дані висоти для 50 ° 24'58.888, чому ви віднімаєте рядок номер 500 від нижнього краю, коли рядки впорядковані з півночі на південь? Спасибі!
Георг

Якщо я не помиляюся, я вважаю, що (j-1) буде просто j. Значення j коливається від 0 до 1200, тому немає необхідності віднімати 1.
Malipivo

6

GDAL може читати / записувати ці растрові формати з драйвером SRTMHGT . Це означає, що ви можете переглянути растр за допомогою QGIS, ArcGIS або використовувати утиліти GDAL, такі як gdallocationinfo, щоб отримати значення з точки, наприклад:

Перетворити 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 м.


1
Як щодо місця в південній чи західній сторонах?
Мухаммет Алі Асан

2

Якщо ви використовуєте QGIS, перевірте, чи встановлений плагін python "Інструмент точкового відбору". Ви знайдете це за адресою -> Розширення (Python) -> Аналіз.

Виберіть точковий шар необхідних позицій, потім запустіть PST, виберіть hgt (або будь-який растровий / полігонний файл) та оберіть нову форму точки для виведення.

Це все :-)

  Chris

0

Відповідь Кріса вказує, що вибірки очок із шару в QGIS нескладно.

Однак, оскільки ваша відповідь на мій коментар пояснює, що ви пишете власну програму для зчитування значень висоти з .hgtфайлів, по-новому подивіться на PDF Quickstart у документах SRTM. Він пояснює, як зберігаються дані висоти. Узагальнити:

  • Файли SRTM3 містять послідовність значень цілих значень великого рівня.
  • Кожне ціле значення являє собою висоту "у метрах, на які посилається геоїд WGS84 / EGM96", за винятком значень -32768, які вказують на пікселі без даних.
  • Існує 1201 рядок з 1201 вибірки, тому загалом повинно бути 1442401 цілих значень.

Ви кажете, що можете конвертувати між координатами lon / lat і пікселями, тому отримання висоти - це питання зчитування цілого значення з відповідного зміщення у файлі. Враховуючи координати пікселів xта yвідносно верхнього лівого кута сцени, це в основному offset = (y * 1201) + x. Піксель 0,0- це перше ціле число у файлі, а піксель 1200,1200- це останнє ціле число у файлі.


1
Це правильно, але не вистачає кількох важливих деталей, наданих відповіддю Бхеля, в тому числі, що координати пов'язані з центрами клітин . Так, наприклад, верхній лівий кут N50E014.hgt насправді розташований на довготі 13,99958 E, широта 51,00042 N.
whuber
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.