Comment tamponner un fichier de formes vectorielles en utilisant python ogr?

10

J'essaie d'apprendre à utiliser l'ogr en python en utilisant les ensembles de données sur les pays et les lieux peuplés à partir de http://www.naturalearthdata.com/downloads/50m-cultural-vectors/. J'essaie d'utiliser des filtres et des tampons pour trouver des points (ne_50m_populated_places.shp) dans un tampon spécifié d'un pays nommé (filtré de la classe d'entités ADMIN dans ne_50m_admin_0_countries.shp). Le problème semble être que je ne comprends pas quelles unités utiliser pour buffer (). Dans le script, j'ai simplement utilisé une valeur arbitraire de 10 pour tester si le script fonctionne. Le script s'exécute mais renvoie des endroits peuplés de la région des Caraïbes pour le pays nommé 'Angola'. Idéalement, je veux être en mesure de spécifier une distance tampon, disons 500 km, mais je ne peux pas savoir comment le faire car ma compréhension est que buffer () utilise les unités de countries.shp qui seront au format wgs84 lat / long . Des conseils sur la méthode pour y parvenir seraient très appréciés.

# 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()
user1765941
la source

Réponses:

2

Je pense à deux options:

  1. Calculez l'équivalent en degrés de 500 kilomètres. Vous pouvez ensuite saisir la fonction Buffer (). Il faut cependant être prudent car un diplôme n'a pas d'équivalent métrique constant. Cela dépend de la latitude sur laquelle vous vous trouvez. Vous pouvez consulter la formule Haversine si vous souhaitez emprunter cette voie.

  2. Une autre option serait de re-projeter le fichier de formes vers UTM. De cette façon, vous pouvez utiliser directement 500 kilomètres. Vous trouverez cependant la zone UTM pour votre zone d'intérêt. (Ce qui devrait être la zone UTM 32S pour l'Angola si je ne me trompe pas)

RK
la source
3
Il n'y a pas d '"équivalent en degrés" de 500 kilomètres, ni d'aucune autre distance, sauf approximativement pour les petites distances près de l'équateur: c'est parce que la relation entre les distances et les degrés change avec le relèvement ainsi que la latitude. Ainsi, la première option ne fonctionnera généralement pas correctement.
whuber
0
  1. Si vous souhaitez créer un tampon à l'aide de degrés, considérez que les degrés ont une distance assez différente selon la direction lorsque vous n'êtes pas près de l'équateur. La latitude reste la même, mais un degré de longitude est beaucoup plus petit aux hautes latitudes. Ci-dessous, mon tableau des carrés de 500 km en degrés sous différentes latitudes. Je suppose que pour l'Angola, une valeur de 4,4 peut être une bonne estimation si vous n'avez pas besoin d'une haute précision.
  2. Vous pouvez reprojeter des objets en python ogr (il y a une fonction Transform pour cela) pendant la lecture, alors il n'est pas nécessaire de convertir les fichiers de formes.
500 km au lat 0.0 est 4.491576420597608 x 4.486983030705042 deg
500 km au lat 10.0 est 4.491576420597608 x 4.389054945583991 deg
500 km au lat 20.0 est 4.491576420597608 x 4.16093408959923 deg
500 km au lat 30.0 est 4.491576420597608 x 3.8117296267699388 deg
500 km au lat 40.0 est 4,491576420597608 x 3,3535548944407267 deg
500 km au lat 50,0 est 4,491576420597608 x 2,8010165014556634 deg
500 km au lat 60.0 est 4.491576420597608 x 2.170722673038327 deg
500 km au lat 70,0 est 4,491576420597608 x 1,4808232946314916 deg
500 km au lat 80.0 est 4,491576420597608 x 0,7505852760718597 deg
500 km au lat.84.0 est 4.491576420597608 x 0.4516575041056399 deg
JaakL
la source
4
L'utilisateur @Dave X note que ce tableau est erroné: une distance fixe s'étend sur un plus grand nombre de degrés à des latitudes plus élevées, pas moins. Il semble qu'il aurait pu être construit en faisant une multiplication là où une division est requise. Néanmoins, cela n'explique pas pleinement les écarts: il reste des erreurs de l'ordre de plusieurs pour cent. Comment avez-vous calculé ces chiffres exactement?
whuber