Як буферизувати векторний файл форми за допомогою 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). Здається, проблема полягає в тому, що я не розумію, які одиниці використовувати для буфера (). У сценарії я просто використав довільне значення 10, щоб перевірити, чи працює сценарій. Сценарій працює, але повертає населені місця з усіх районів Карибського басейну для названої країни "Ангола". В ідеалі, я хочу мати можливість вказати відстань буфера, скажімо, 500 км, але не можу розробити, як це зробити, оскільки я розумію, що буфер () використовує одиниці країни.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 кілометрів. Потім ви можете ввести функцію Buffer (). Ви повинні бути обережними, хоча, оскільки ступінь не має постійного метричного еквівалента. Це залежить від того, на якій широті ви знаходитесь. Ви можете перевірити формулу Haversine, якщо хочете пройти цей маршрут.

  2. Іншим варіантом було б запрограмувати файл форми в UTM. Таким чином, ви можете просто використовувати 500 кілометрів безпосередньо. Ви знайдете зону UTM для своєї області інтересів. (Яка повинна бути зона UTM 32S для Анголи, якщо я не помиляюся)


3
Немає "градусного еквівалента" 500 кілометрів, ані будь-якої іншої відстані, за винятком приблизно невеликих відстаней поблизу екватора: це тому, що залежність між відстанями та градусами змінюється як підшипником, так і широтою. Таким чином, перший варіант зазвичай не працює належним чином.
whuber

0
  1. Якщо ви хочете зробити буфер за допомогою градусів, то врахуйте, що градуси мають зовсім іншу відстань залежно від напрямку, коли ви не поруч із екватором. Широта залишається однаковою, але довгота на один градус набагато менша у великих широтах. Нижче - моя таблиця квадратів на 500 км у градусах в різних широтах. Я здогадуюсь, що для Анголи значення 4,4 може бути гарно здогадатися, якщо вам не потрібна висока точність.
  2. Ви можете перепроектувати об'єкти в python ogr (для нього функція Transform) під час читання, тоді не потрібно формувати перетворення файлів.
500 км при ширині 0,0 становить 4,491576420597608 х 4,486983030705042 град
500 км на відстані 10,0 становить 4,491576420597608 х 4,389054945583991 град.
500 км на відстані 20,0 становить 4,491576420597608 х 4,16093408959923 град
500 км на лат. 30,0 становить 4,451576420597608 х 3,8117296267699388 град.
500 км на ширині 40,0 становить 4,491576420597608 х 3,3535548944407267 град.
500 км на ширині 50,0 становить 4,491576420597608 х 2,8010165014556634 град.
500 км при ширині 60,0 становить 4,491576420597608 х 2,170722673038327 град
500 км на ширині 70,0 становить 4,491576420597608 x 1,4808232946314916 град
500 км на ширині 80,0 становить 4,451576420597608 х 0,7505852760718597 град
500 км на ширині 84,0 становить 4,491576420597608 x 0,4516575041056399 град

4
Користувач @Dave X зазначає, що ця таблиця помилкова: фіксована відстань охоплює більшу кількість градусів на більш високих широтах, а не меншу. Здається, вона могла бути побудована шляхом множення, де потрібне ділення. Тим не менш, це не повністю пояснює розбіжності: залишаються помилки на порядку кількох відсотків. Як саме ви обчислили ці числа?
whuber
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.