กำลังคลายระดับความสูงจากไฟล์. GHT หรือไม่


20

ฉันต้องการกำหนดตำแหน่ง long / lat เฉพาะบนแผนที่ให้สูงจากไฟล์ข้อมูล SRTM3 แต่ไม่ทราบวิธีหาค่าเฉพาะ ดังนั้นฉันต้องการตัวอย่างของวิธีที่ฉันสามารถหาได้ใน N50E14.hgt ระดับความสูงเป็น 50 ° 24'58.888 "N, 14 ° 55'11.377" E


1
คุณใช้ซอฟต์แวร์อะไร มีหมายเหตุเกี่ยวกับ.hgtรูปแบบไฟล์ในเอกสารคู่มือSRTMแต่คำตอบทีละขั้นตอนที่เฉพาะเจาะจงขึ้นอยู่กับซอฟต์แวร์ที่คุณมี
anoved

1
ฉันไม่มีซอฟต์แวร์ฉันเป็นโปรแกรมเมอร์ c # และฉันกำลังเขียนใบสมัครของฉันเอง ฉันสามารถกำหนดให้ยาว / lat ทุกพิกเซลและตอนนี้ฉันต้องการค้นหาระดับความสูงของแต่ละจุด รูปแบบข้อมูลที่ดีที่สุดควรเป็นไฟล์ CSV ดังนั้นในแถวหนึ่งฉันสามารถพบลองจิจูดลองจิจูดความสูง ฉันได้ค้นหาเอกสาร SRTM แล้ว แต่ฉันก็ยังนึกไม่ออกว่าจะจัดทำ data ในไฟล์ได้อย่างไร
MartinS

คำตอบ:


30

รูปแบบข้อมูล

ฉันจะใช้เป็นแบบฝึกหัดเล็กน้อยในการตั้งโปรแกรมตัวอ่านข้อมูล ดูที่เอกสารประกอบ :

ข้อมูล SRTM มีการกระจายในสองระดับ: SRTM1 (สำหรับสหรัฐอเมริกาและดินแดนและการครอบครอง) โดยมีการสุ่มตัวอย่างข้อมูลในหนึ่งช่วงอาร์ควินาทีในละติจูดและลองจิจูดและ SRTM3 (สำหรับโลก) สุ่มตัวอย่างที่สามอาร์ควินาที

ข้อมูลถูกแบ่งออกเป็นหนึ่งโดยหนึ่งองศาละติจูดและลองจิจูดแผ่นในประมาณการ "ทางภูมิศาสตร์" ซึ่งจะกล่าวว่างานนำเสนอแรสเตอร์ที่มีช่วงเวลาที่เท่าเทียมกันของละติจูดและลองจิจูดโดยไม่ต้องฉายภาพเลย แต่ง่ายต่อการจัดการและโมเสก

ชื่อไฟล์อ้างถึงละติจูดและลองจิจูดของมุมซ้ายล่างของแผ่นกระเบื้อง - เช่น N37W105 มีมุมซ้ายล่างที่ละติจูด 37 องศาเหนือและลองจิจูดละติจูด 105 องศาทางตะวันตก เพื่อความแม่นยำยิ่งขึ้นพิกัดเหล่านี้อ้างถึงศูนย์กลางทางเรขาคณิตของพิกเซลซ้ายล่างซึ่งในกรณีของข้อมูล SRTM3 จะอยู่ที่ประมาณ 90 เมตร

ไฟล์ Height มีนามสกุล. HGT และมีการเซ็นชื่อเป็นจำนวนเต็มสองไบต์ ไบต์อยู่ในลำดับโมโตโรล่า "big-endian" ที่มีไบต์ที่สำคัญที่สุดก่อนสามารถอ่านได้โดยตรงโดยระบบเช่น Sun SPARC, Silicon Graphics และคอมพิวเตอร์ Macintosh โดยใช้โปรเซสเซอร์ Power PC DEC Alpha คอมพิวเตอร์ส่วนใหญ่และคอมพิวเตอร์ Macintosh ที่สร้างขึ้นหลังจากปี 2006 ใช้คำสั่ง Intel ("little-endian") ดังนั้นอาจจำเป็นต้องมีการแลกเปลี่ยนไบต์ ความสูงมีหน่วยเป็นเมตรอ้างอิงถึงพิกัด WGS84 / EGM96 Data voids ถูกกำหนดค่า -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 แถวและใน 701st หนึ่งใช้ตัวอย่าง 1104) สองไบต์ต่อตัวอย่างหมายความว่าเราต้องข้าม 1683606 ไบต์แรกในไฟล์แล้วอ่านสองไบต์เพื่อรับกริดเซลล์ของเรา ข้อมูลมีขนาดใหญ่ซึ่งหมายความว่าคุณต้องสลับทั้งสองไบต์เช่นแพลตฟอร์มของ 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 ได้จากกล่อง แต่นั่นน่าเบื่อ


เอาชนะฉันไปได้และมีรายละเอียดมากขึ้นในการบูต!
anoved

นีซอธิบายรักคุณ ขอบคุณสำหรับความช่วยเหลือของคุณ. พวกคุณทุกคน
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:

  • Lat: 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
วิธีการเกี่ยวกับสถานที่ในภาคใต้หรือฝั่งตะวันตก?
Muhammet Ali Asan

2

หากคุณใช้ QGIS ให้ตรวจสอบว่ามีการติดตั้งปลั๊กอินหลาม "เครื่องมือเก็บตัวอย่างจุด" หรือไม่ คุณจะพบได้ที่ -> การปรับปรุง (Python) -> วิเคราะห์

เลือกเลเยอร์จุดของตำแหน่งที่ต้องการจากนั้นเริ่ม PST เลือก hgt (หรือไฟล์ raster / polygone ใด ๆ ) แล้วเลือกรูปร่างจุดใหม่สำหรับเอาต์พุต

นั่นคือทั้งหมด :-)

  Chris

0

คำตอบของ Chris บ่งบอกว่ามันตรงไปตรงมาที่จะเก็บตัวอย่างคะแนนจากเลเยอร์ใน QGIS

อย่างไรก็ตามเนื่องจากการตอบกลับความคิดเห็นของฉันชี้แจงว่าคุณกำลังเขียนโปรแกรมของคุณเองเพื่ออ่านค่าระดับความสูงจาก.hgtไฟล์ให้ดูที่Quickstart PDFในเอกสาร SRTM มันอธิบายถึงวิธีการจัดเก็บข้อมูลระดับความสูง เพื่อสรุป:

  • ไฟล์ SRTM3 มีลำดับของค่าจำนวนเต็มขนาดใหญ่สุด
  • แต่ละค่าจำนวนเต็มแสดงถึงการยกระดับ "หน่วยเป็นเมตรอ้างอิงถึง WGS84 / EGM96 geoid" ยกเว้นค่า-32768ที่ระบุถึงพิกเซลข้อมูลที่ไม่มีข้อมูล
  • มี 1201 ตัวอย่าง 1201 ตัวอย่างดังนั้นควรมีค่าจำนวนเต็ม 1442401 ทั้งหมด

คุณบอกว่าคุณสามารถแปลงระหว่างพิกัด lon / lat และพิกเซลเพื่อให้ได้ระดับความสูงเป็นเรื่องของการอ่านค่าจำนวนเต็มจากออฟเซ็ตที่เหมาะสมในไฟล์ พิกัดพิกเซลxและสัมพันธ์กับมุมบนซ้ายของฉากที่เป็นพื้นy offset = (y * 1201) + xPixel 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.