วิธีการบัฟเฟอร์ vectorfilefile โดยใช้ ogr python?


10

ฉันพยายามเรียนรู้วิธีใช้ ogr ใน python โดยใช้ประเทศและชุดข้อมูลสถานที่ที่มีประชากรจากhttp://www.naturalearthdata.com/downloads/50m-cultural-vectors/. ฉันกำลังพยายามใช้ตัวกรองและบัฟเฟอร์เพื่อค้นหาคะแนน (ne_50m_populated_places.shp) ภายในบัฟเฟอร์ที่ระบุของประเทศที่ตั้งชื่อ (กรองจาก ADMIN คลาสคุณลักษณะใน ne_50m_admin_0_countries.shp) ปัญหาดูเหมือนว่าฉันไม่เข้าใจหน่วยที่จะใช้สำหรับ buffer () ในสคริปท์ฉันใช้ค่า 10 โดยพลการเพื่อทดสอบว่าสคริปต์ทำงานหรือไม่ สคริปต์ทำงาน แต่ส่งคืนสถานที่ที่มีประชากรจากทั่วภูมิภาค Carribean สำหรับประเทศที่มีชื่อ 'Angola' เป็นการดีที่ฉันต้องการที่จะสามารถระบุระยะทางบัฟเฟอร์พูด 500km แต่ไม่สามารถหาวิธีการทำเช่นนี้เป็นความเข้าใจของฉันคือบัฟเฟอร์ () กำลังใช้หน่วยของ countries.shp ที่จะอยู่ในรูปแบบ wgs84 lat / long . คำแนะนำเกี่ยวกับวิธีการเพื่อให้บรรลุนี้จะได้รับการชื่นชม

# import modules
import ogr, os, sys


## data source
os.chdir('C:/data/naturalearth/50m_cultural')

# get the shapefile driver
driver = ogr.GetDriverByName('ESRI Shapefile')

# open ne_50m_admin_0_countries.shp and get the layer
admin = driver.Open('ne_50m_admin_0_countries.shp')
if admin is None:
  print 'Could not open ne_50m_admin_0_countries.shp'
  sys.exit(1)
adminLayer = admin.GetLayer()

# open ne_50m_populated_places.shp and get the layer
pop = driver.Open('ne_50m_populated_places.shp')
if pop is None:
  print 'could not open ne_50m_populated_places.shp'
  sys.exit(1)
popLayer = pop.GetLayer()

# use an attribute filter to restrict ne_50m_admin_0_countries.shp to "Angola"
adminLayer.SetAttributeFilter("ADMIN = ANGOLA")

# get the Angola geometry and buffer it by 10 units
adminFeature = adminLayer.GetFeature(0)
adminGeom = adminFeature.GetGeometryRef()
bufferGeom = adminGeom.Buffer(10)

# use bufferGeom as a spatial filter on ne_50m_populated_places.shp to get all places
# within 10 units of Angola
popLayer.SetSpatialFilter(bufferGeom)

# loop through the remaining features in ne_50m_populated_places.shp and print their
# id values
popFeature = popLayer.GetNextFeature()
while popFeature:
  print popFeature.GetField('NAME')
  popFeature.Destroy()
  popFeature = popLayer.GetNextFeature()

# close the shapefiles
admin.Destroy()
pop.Destroy()

คำตอบ:


2

สองตัวเลือกที่ฉันนึกได้คือ:

  1. คำนวณค่าเทียบเท่าระดับ 500 กิโลเมตร จากนั้นคุณสามารถป้อนฟังก์ชันบัฟเฟอร์ () คุณจะต้องระมัดระวังแม้ว่าการศึกษาระดับปริญญาจะไม่มีการวัดค่าคงที่เทียบเท่า ขึ้นอยู่กับละติจูดที่คุณใช้ คุณสามารถตรวจสอบสูตร Haversineหากคุณต้องการไปเส้นทางนี้

  2. อีกตัวเลือกหนึ่งคือการeproject shapefileไปที่ UTM ด้วยวิธีนี้คุณสามารถใช้ 500 กิโลเมตรโดยตรง คุณจะพบโซน UTM สำหรับพื้นที่ที่คุณสนใจ (ซึ่งควรเป็นUTM โซน 32Sสำหรับแองโกลาถ้าฉันไม่เข้าใจผิด)


3
ไม่มี "เทียบเท่าระดับ" 500 กิโลเมตรหรือระยะทางอื่นใดยกเว้นโดยประมาณสำหรับระยะทางเล็ก ๆ ใกล้เส้นศูนย์สูตรนั่นเป็นเพราะความสัมพันธ์ระหว่างระยะทางและองศาเปลี่ยนแปลงไปพร้อมกับการแบกและละติจูด ดังนั้นตัวเลือกแรกมักจะทำงานไม่ถูกต้อง
whuber

0
  1. หากคุณต้องการให้บัฟเฟอร์ใช้องศาให้พิจารณาว่าองศานั้นมีระยะทางที่แตกต่างกันมากขึ้นอยู่กับทิศทางเมื่อคุณไม่ได้อยู่ใกล้เส้นศูนย์สูตร Latitude ยังคงเหมือนเดิม แต่ลองจิจูดหนึ่งองศานั้นเล็กกว่ามากในละติจูดสูง ด้านล่างเป็นตารางสี่เหลี่ยมจัตุรัส 500 กม. ของฉันเป็นองศาในละติจูดที่ต่างกัน ฉันเดาว่าค่าของแองโกลา 4.4 อาจจะเป็นการเดาที่ดีถ้าคุณไม่ต้องการความแม่นยำสูง
  2. คุณสามารถปฏิเสธวัตถุใน python ogr (มีฟังก์ชั่นการแปลงสำหรับมัน) ในระหว่างการอ่านจากนั้นไม่จำเป็นต้องแปลงรูปร่างไฟล์
500 km ที่ lat 0.0 คือ 4.491576420597608 x 4.486983030705042 องศา
500 กม. ที่ lat 10.0 คือ 4.491576420597608 x 4.389054945583991 องศา
500 กม. ที่ละติจูด 20.0 คือ 4.491576420597608 x 4.16093408959923 องศา
500 กม. ที่ lat 30.0 คือ 4.491576420597608 x 3.8117296267699388 องศา
500 km ที่ lat 40.0 คือ 4.491576420597608 x 3.3535548944407267 องศา
500 กม. ที่ละติจูด 50.0 คือ 4.491576420597608 x 2.8010165014556634 องศา
500 กม. ที่ lat 60.0 คือ 4.491576420597608 x 2.170722673038327 องศา
500 กม. ที่ lat 70.0 คือ 4.491576420597608 x 1.4808232946314916 องศา
500 km ที่ lat 80.0 คือ 4.491576420597608 x 0.7505852760718597 องศา
500 กม. ที่ lat 84.0 คือ 4.491576420597608 x 0.4516575041056399 องศา

4
บันทึกผู้ใช้ @Dave X ที่ตารางนี้เป็นความผิดพลาด: คงมีช่วงระยะไกลมากขึ้นจำนวนองศาที่ละติจูดที่สูงขึ้นไม่ได้เป็นเลสเบี้ยน ดูเหมือนว่ามันอาจจะถูกสร้างขึ้นโดยการคูณที่จำเป็นต้องมีการแบ่ง ถึงกระนั้นก็ตามนั่นก็ไม่ได้อธิบายถึงความแตกต่างทั้งหมด: ยังคงมีข้อผิดพลาดในการสั่งซื้อหลายร้อยเปอร์เซ็นต์ คุณคำนวณตัวเลขเหล่านี้ได้อย่างไร
whuber
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.