J'ai du mal à comprendre l'utilisation des index spatiaux avec RTree.
Exemple: J'ai 300 points tamponnés et j'ai besoin de connaître la zone d'intersection de chaque tampon avec un fichier de formes polygonal. Le fichier de formes des polygones contient> 20 000 polygones. Il a été suggéré d'utiliser des indices spatiaux pour accélérer le processus.
SO ... Si je crée un index spatial pour mon fichier de formes de polygones, sera-t-il "attaché" au fichier d'une manière ou d'une autre, ou l'index sera-t-il autonome? Autrement dit, après l'avoir créé, puis-je simplement exécuter ma fonction d'intersection sur le fichier polygonal et obtenir des résultats plus rapides? L'intersection "verra-t-elle" qu'il existe des indices spatiaux et saura-t-elle quoi faire? Ou, dois-je l'exécuter sur l'index, puis relier ces résultats à mon fichier polygonal d'origine via des FID ou quelque chose du genre?
La documentation RTree ne m'aide pas beaucoup (probablement parce que j'apprends juste la programmation). Ils montrent comment créer un index en lisant des points créés manuellement, puis en l'interrogeant sur d'autres points créés manuellement, ce qui renvoie les identifiants contenus dans la fenêtre. Logique. Mais, ils n'expliquent pas comment cela se rapporterait à un fichier d'origine dont proviendrait l'index.
Je pense que ça doit aller quelque chose comme ça:
- Tirez des bboxes pour chaque entité polygonale de mon fichier de formes de polygone et placez-les dans un index spatial, en leur donnant un identifiant identique à leur identifiant dans le fichier de formes.
- Recherchez cet index pour obtenir les identifiants qui se croisent.
- Ensuite, réexécutez mon intersection sur uniquement les entités de mon fichier de formes d'origine qui ont été identifiées en interrogeant mon index (je ne sais pas comment je ferais cette dernière partie).
Ai-je la bonne idée? Suis-je en train de manquer quelque chose?
En ce moment, j'essaie de faire fonctionner ce code sur un fichier de formes ponctuelles qui ne contient qu'une seule entité ponctuelle et un fichier de formes polygonales qui contient> 20 000 entités surfaciques.
J'importe les fichiers de formes à l'aide de Fiona, j'ajoute l'index spatial à l'aide de RTree et j'essaie de faire l'intersection à l'aide de Shapely.
Mon code de test ressemble à ceci:
#point shapefile representing location of desired focal statistic
traps = fiona.open('single_pt_speed_test.shp', 'r')
#polygon shapefile representing land cover of interest
gl = MultiPolygon([shape(pol['geometry']) for pol in fiona.open('class3_aa.shp', 'r')])
#search area
areaKM2 = 20
#create empty spatial index
idx = index.Index()
#set initial search radius for buffer
areaM2 = areaKM2 * 1000000
r = (math.sqrt(areaM2/math.pi))
#create spatial index from gl
for i, shape in enumerate(gl):
idx.insert(i, shape.bounds)
#query index for ids that intersect with buffer (will eventually have multiple points)
for point in traps:
pt_buffer = shape(point['geometry']).buffer(r)
intersect_ids = pt_buffer.intersection(idx)
Mais je reçois toujours TypeError: l'objet 'Polygon' n'est pas appelable
.qix
MapServer / GDAL / OGR / SpatiaLite quadtree est également disponibleTypeError: 'Polygon' object is not callable
votre exemple de mise à jour parce que vous écrasez lashape
fonction que vous avez importée de galbée avec un objet Polygon que vous créez avec cette ligne:for i, shape in enumerate(gl):
Réponses:
Voilà l'essentiel. L'arbre R vous permet de faire un premier passage très rapide et vous donne un ensemble de résultats qui auront des "faux positifs" (les boîtes englobantes peuvent se croiser lorsque les géométries ne le sont pas précisément). Ensuite, vous passez en revue l'ensemble des candidats (en les récupérant du fichier de formes par leur index) et effectuez un test d'intersection mathématiquement précis en utilisant, par exemple, Shapely. Il s'agit de la même stratégie que celle utilisée dans les bases de données spatiales comme PostGIS.
la source
Vous l'avez presque compris, mais vous avez fait une petite erreur. Vous devez utiliser la
intersection
méthode sur l'index spatial, plutôt que de passer l'index à laintersection
méthode sur le point tamponné. Une fois que vous avez trouvé une liste d'entités où les zones de délimitation se chevauchent, vous devez vérifier si votre point tamponné intersecte réellement les géométries.Si vous êtes intéressé à trouver des points qui se trouvent à une distance minimale de votre classe de terrain, vous pouvez utiliser la
distance
méthode à la place (remplacer la section appropriée de la précédente).Si la construction de votre index spatial prend beaucoup de temps et que vous allez le faire plusieurs fois, vous devriez envisager de sérialiser l'index dans un fichier. La documentation décrit comment procéder: http://toblerity.org/rtree/tutorial.html#serializing-your-index-to-a-file
Vous pouvez également regarder le chargement en masse des boîtes englobantes dans le rtree à l'aide d'un générateur, comme ceci:
la source
Oui, c'est l'idée. Voici un extrait de ce tutoriel sur l'utilisation d'un index spatial r-tree en Python , en utilisant shapely, Fiona et geopandas:
la source