Trích xuất độ cao từ tệp .HGT?


20

Tôi muốn chỉ định một vị trí dài / trễ cụ thể trên bản đồ cho độ cao từ các tệp dữ liệu SRTM3, nhưng không biết làm thế nào để tìm giá trị cụ thể. Vì vậy, tôi muốn một số ví dụ về cách tôi có thể tìm thấy ở độ cao N50E14.hgt đến 50 ° 24'58.888 "N, 14 ° 55'11.377" E.


1
Phần mềm nào bạn đang sử dụng? Có một số lưu ý về .hgtđịnh dạng tệp trong tài liệu SRTM , nhưng câu trả lời từng bước cụ thể tùy thuộc vào phần mềm bạn có sẵn.
yêu thích

1
Tôi không có phần mềm, tôi là lập trình viên c # và tôi đang viết ứng dụng của riêng mình. Tôi có thể căn chỉnh dài / lat cho mỗi pixel và bây giờ tôi muốn tìm kiếm độ cao đến từng điểm. Định dạng dữ liệu tốt nhất phải là một cái gì đó giống như tệp CSV. Vì vậy, trong một hàng tôi có thể tìm thấy kinh độ, vĩ độ, cao độ. Tôi đã tìm kiếm tài liệu SRTM, nhưng tôi vẫn không thể tưởng tượng được làm thế nào tôi có thể cung cấp khai thác dữ liệu trên tệp.
MartinS

Câu trả lời:


30

Định dạng dữ liệu

Tôi sẽ xem nó như một bài tập nhỏ trong cách lập trình trình đọc dữ liệu. Có một cái nhìn vào các tài liệu :

Dữ liệu SRTM được phân phối theo hai cấp độ: SRTM1 (đối với Hoa Kỳ và các lãnh thổ và sở hữu của nó) với dữ liệu được lấy mẫu ở các khoảng thời gian một giây cung theo vĩ độ và kinh độ và SRTM3 (đối với thế giới) được lấy mẫu ở ba giây.

Dữ liệu được chia thành từng ô một độ vĩ độ và kinh độ trong phép chiếu "địa lý", nghĩa là một bản trình bày raster với các khoảng vĩ độ và kinh độ bằng nhau không có phép chiếu nào cả nhưng dễ thao tác và khảm.

Tên tệp đề cập đến vĩ độ và kinh độ của góc dưới bên trái của ô - ví dụ: N37W105 có góc dưới bên trái của nó ở 37 độ vĩ bắc và 105 độ kinh tây. Nói chính xác hơn, các tọa độ này đề cập đến trung tâm hình học của pixel phía dưới bên trái, trong trường hợp dữ liệu SRTM3 sẽ có phạm vi khoảng 90 mét.

Các tệp chiều cao có phần mở rộng .HGT và được ký hai số nguyên byte. Các byte theo thứ tự "big endian" của Motorola với byte đáng kể đầu tiên, có thể đọc trực tiếp bởi các hệ thống như Sun SPARC, Đồ họa Silicon và máy tính Macintosh sử dụng bộ xử lý Power PC. DEC Alpha, hầu hết các máy tính PC và Macintosh được xây dựng sau năm 2006 đều sử dụng thứ tự Intel ("little endian") để có thể cần một số hoán đổi byte. Độ cao được tính bằng mét được tham chiếu đến Geoid WGS84 / EGM96. Khoảng trống dữ liệu được gán giá trị -32768.

Làm thế nào để tiến hành

Đối với vị trí của bạn, 50 ° 24'58.888 "N 14 ° 55'11.377" E, bạn đã tìm thấy ô chính xác, N50E14.hgt. Hãy tìm hiểu xem pixel nào bạn quan tâm. Vĩ độ đầu tiên, 50 ° 24'58.888 "N:

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

giây cung. Chia cho ba và làm tròn đến số nguyên gần nhất cho một hàng lưới 500. Tính toán tương tự cho kết quả kinh độ trong cột lưới 1104.

Tài liệu khởi động nhanh thiếu thông tin về cách tổ chức các hàng và cột trong tệp, nhưng trong tài liệu đầy đủ có ghi rằng

Dữ liệu được lưu trữ theo thứ tự chính hàng (tất cả dữ liệu cho hàng 1, tiếp theo là tất cả dữ liệu cho hàng 2, v.v.)

Hàng đầu tiên trong tệp rất có thể là hàng cực bắc, tức là nếu chúng ta quan tâm đến hàng 500 từ cạnh dưới , chúng ta thực sự phải xem hàng

1201 - 500 = 701

từ đầu nếu tập tin . Ô lưới của chúng tôi là số

(1201 * 700) + 1104 = 841804

từ đầu tệp (tức là bỏ qua 700 hàng và trong lần thứ 701, hãy lấy mẫu 1104). Hai byte cho mỗi mẫu có nghĩa là chúng ta phải bỏ qua 1683606 byte đầu tiên trong tệp và sau đó đọc hai byte để có được ô lưới của chúng ta. Dữ liệu là cuối lớn, có nghĩa là bạn cần trao đổi hai byte trên các nền tảng của Intel.

Chương trình mẫu

Một chương trình Python đơn giản để lấy đúng dữ liệu sẽ trông như thế này (xem các tài liệu để sử dụng mô-đun 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)

Lưu ý rằng việc truy xuất dữ liệu hiệu quả sẽ phải trông phức tạp hơn một chút (ví dụ: không mở tệp cho từng mẫu).

Lựa chọn thay thế

Bạn cũng có thể sử dụng một chương trình có thể đọc các tệp .hgt ra khỏi hộp. Nhưng đó là nhàm chán.


Đánh bại tôi với nó, và với nhiều chi tiết hơn để khởi động!
yêu thích

Đẹp giải thích, yêu em. Cảm ơn bạn đã giúp đỡ. Tất cả các bạn.
MartinS

1
+1 Có, các hàng được sắp xếp từ Bắc vào Nam. Điều này là rõ ràng ngay khi bạn ánh xạ một trong các tệp. Ngoài ra, hãy xem xét việc đạt được độ cao thông qua phép nội suy song tuyến giữa bốn trung tâm tế bào xung quanh vị trí.
whuber

Cảm ơn thông tin toàn diện này! Tôi có một câu hỏi: Khi chúng tôi đang tìm kiếm dữ liệu độ cao cho 50 ° 24'58.888, tại sao bạn lại trừ số hàng 500 từ cạnh dưới khi các hàng được sắp xếp theo hướng bắc xuống nam? Cảm ơn!
Georg

Nếu tôi không nhầm, tôi tin rằng (j-1) sẽ chỉ là j. Giá trị j dao động từ 0 đến 1200, do đó không cần phải trừ 1.
Malipivo

6

GDAL có thể đọc / ghi các định dạng raster này với trình điều khiển SRTMHGT . Điều này có nghĩa là bạn có thể xem raster với QGIS, ArcGIS hoặc sử dụng các tiện ích GDAL như gdallocationinfo để lấy các giá trị từ một điểm, ví dụ:

Chuyển đổi DMS sang DD:

  • Lat: 50 ° 24'58.888 "N = 50 + (24/60) + (58.888 / 3600) = 50.4163577778
  • Dài: 14 ° 55'11.377 "E = 14 + (55/60) + (11.377 / 3600) = 14.9198269444

Sau đó, từ một vỏ, sử dụng gdallocationinfo file.hgt -wgs84 long lat:

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

Độ cao là 216 m.


1
Làm thế nào về các vị trí ở phía nam hoặc phía tây?
Muhammet Ali Asan

2

Nếu bạn sử dụng QGIS, hãy kiểm tra xem plugin python "Point Sampling Tool" đã được cài đặt chưa. Bạn sẽ tìm thấy nó tại -> Cải tiến (Python) -> Phân tích.

Chọn lớp điểm của bạn trong các vị trí cần thiết, sau đó khởi động PST, chọn hgt (hoặc bất kỳ tệp raster / polygone nào) và chọn hình dạng điểm mới cho đầu ra.

Đó là tất cả :-)

  Chris

0

Câu trả lời của Chris chỉ ra rằng nó rất đơn giản đối với các điểm mẫu từ một lớp trong QGIS.

Tuy nhiên, vì câu trả lời của bạn cho nhận xét của tôi làm rõ rằng bạn đang viết chương trình của riêng mình để đọc các giá trị độ cao từ các .hgttệp, hãy có cái nhìn khác về Quickstart PDF trong tài liệu SRTM. Nó giải thích làm thế nào dữ liệu độ cao được lưu trữ. Để tóm tắt:

  • Các tệp SRTM3 chứa một chuỗi các giá trị nguyên lớn.
  • Mỗi giá trị số nguyên biểu thị độ cao "tính bằng mét được tham chiếu đến Geoid WGS84 / EGM96", ngoại trừ các giá trị -32768chỉ ra các pixel không có dữ liệu.
  • Có 1201 dòng của 1201 mẫu, do đó nên có 1442401 giá trị nguyên hoàn toàn.

Bạn nói rằng bạn có thể chuyển đổi giữa tọa độ lon / lat và pixel, do đó, việc tăng độ cao là vấn đề đọc giá trị nguyên từ phần bù thích hợp trong tệp. Cho tọa độ pixel xyliên quan đến góc trên bên trái của cảnh, về cơ bản offset = (y * 1201) + x. Pixel 0,0là số nguyên đầu tiên trong tệp và pixel 1200,1200là số nguyên cuối cùng trong tệp.


1
Điều này là chính xác, nhưng thiếu một vài chi tiết quan trọng được cung cấp bởi câu trả lời của bhell, bao gồm cả tọa độ được liên kết với các trung tâm tế bào . Do đó, ví dụ, góc trên bên trái của N50E014.hgt thực sự nằm ở kinh độ 13.99958 E, vĩ độ 51.00042 N.
whuber
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.