Come bufferizzare un file di forma vettoriale usando ogr python?


10

Sto cercando di imparare come usare ogr in python usando i set di dati del paese e dei luoghi popolati da http://www.naturalearthdata.com/downloads/50m-cultural-vectors/. Sto tentando di utilizzare filtri e buffer per trovare punti (ne_50m_populated_places.shp) all'interno di un buffer specificato di un Paese denominato (filtrato dalla classe di caratteristiche ADMIN in ne_50m_admin_0_countries.shp). Il problema sembra essere che non capisco quali unità utilizzare per buffer (). Nello script ho semplicemente usato un valore arbitrario di 10 per verificare se lo script funziona. La sceneggiatura viene eseguita ma restituisce luoghi popolati da tutta la regione dei Caraibi per il paese denominato "Angola". Idealmente, voglio essere in grado di specificare una distanza di buffer, diciamo 500km, ma non riesco a capire come farlo poiché la mia comprensione è buffer () sta usando le unità di country.shp che saranno nel formato wgs84 lat / long . I consigli sul metodo per raggiungere questo obiettivo sarebbero molto apprezzati.

# 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()

Risposte:


2

Due opzioni a cui riesco a pensare sono:

  1. Calcola l'equivalente in gradi di 500 chilometri. È quindi possibile inserire la funzione Buffer (). Dovresti stare attento anche se un grado non ha un equivalente metrico costante. Dipende dalla latitudine in cui ti trovi. Puoi dare un'occhiata alla formula Haversine se vuoi seguire questa strada.

  2. Un'altra opzione sarebbe quella di riprogrammare lo shapefile in UTM. In questo modo, puoi semplicemente utilizzare 500 chilometri direttamente. Tuttavia, troverai la zona UTM per la tua area di interesse. (Quale dovrebbe essere la zona UTM 32S per l'Angola se non sbaglio)


3
Non esiste un "equivalente in gradi" di 500 chilometri, né di qualsiasi altra distanza, tranne approssimativamente per le piccole distanze vicino all'equatore: questo perché la relazione tra distanze e gradi cambia con il rilevamento e la latitudine. Pertanto, la prima opzione di solito non funziona correttamente.
whuber

0
  1. Se vuoi creare un buffer usando Gradi, considera che i gradi hanno una distanza abbastanza diversa a seconda della direzione quando non sei vicino all'equatore. La latitudine rimane la stessa, ma la longitudine di un grado è molto più piccola alle alte latitudini. Di seguito la mia tabella di quadrati di 500 km in gradi a diverse latitudini. Immagino che per l'Angola un valore di 4,4 possa essere una buona ipotesi se non hai bisogno di alta precisione.
  2. Puoi riproiettare oggetti in python ogr (c'è la funzione Trasforma per esso) durante la lettura, quindi non è necessario modellare le conversioni.
500 km a lat 0.0 sono 4.491576420597608 x 4.486983030705042 gradi
500 km a lat 10.0 sono 4,491576420597608 x 4,389054945583991 gradi
500 km a lat 20.0 è 4,491576420597608 x 4,16093408959923 gradi
500 km a lat 30.0 sono 4.491576420597608 x 3.8117296267699388 gradi
500 km a lat 40.0 sono 4.491576420597608 x 3.3535548944407267 deg
500 km a lat 50.0 sono 4,491576420597608 x 2,8010165014556634 gradi
500 km a lat 60.0 sono 4.491576420597608 x 2.170722673038327 gradi
500 km a lat 70,0 sono 4,491576420597608 x 1,4808232946314916 gradi
500 km a lat 80.0 sono 4.491576420597608 x 0.7505852760718597 gradi
500 km a lat 84.0 sono 4.491576420597608 x 0.4516575041056399 gradi

4
L'utente @Dave X nota che questa tabella è errata: una distanza fissa abbraccia un numero maggiore di gradi a latitudini più elevate, non una minore. Sembra che potrebbe essere stato costruito facendo una moltiplicazione dove è richiesta una divisione. Anche così, ciò non spiega completamente le discrepanze: permangono errori nell'ordine del diversi percento. Esattamente come hai calcolato questi numeri?
whuber
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.