Je veux simplement utiliser geopandas
pour obtenir une union et une intersection de deux zones polygonales. Je définis:
import geopandas as gpd
from shapely.geometry import Polygon
polys1 = gpd.GeoSeries([Polygon([(0,0), (2,0), (2,2), (0,2)]),
Polygon([(2,2), (4,2), (4,4), (2,4)])])
polys2 = gpd.GeoSeries([Polygon([(1,1), (3,1), (3,3), (1,3)]),
Polygon([(3,3), (5,3), (5,5), (3,5)])])
df1 = gpd.GeoDataFrame({'geometry': polys1, 'df1':[1,2]})
df2 = gpd.GeoDataFrame({'geometry': polys2, 'df2':[1,2]})
J'essaye ce qui suit pour obtenir le union
:
res_union = gpd.overlay(df1, df2, how='union')
et il échoue avec l'erreur suivante:
AttributeError: 'NoneType' object has no attribute 'intersection'
Je suis les instructions ici .
Bien que je ne connaisse pas le système opérationnel de l'OP, je pense que j'ai trouvé comment résoudre le problème, au moins pour les systèmes GNU/Linux (je ne suis pas en mesure de tester dans d'autres systèmes).
Explication directe
Pour pouvoir utiliser la fonction overlay
, vous avez besoin de plus que simplement installer geopandas
, vous devez installer rtree
, mais rtree
est un wrapper pour la bibliothèque C libspatialindex . Donc, pour utiliser la bibliothèque rtree
, vous devez installer la bibliothèque libspatialindex
C.
Pour installer libspatialindex
ouvrez un type d'extrémité de terminal:
Sudo apt-get update && apt-get install -y libspatialindex-dev
Remarque: en fait, vous n'avez besoin que du Sudo apt-get install libspatialindex-dev
, mais il est recommandé de mettre à jour le système, et l'indicateur -y est simplement de ne pas arrêter le processus d'installation pour demander de poursuivre l'installation ou non.
Maintenant, cela devrait résoudre votre problème. Remarque: assurez-vous que rtree
est installé sur votre système, vous pouvez le faire en utilisant pip3 freeze
(Je suppose que vous utilisez python3
).
Explication longue
J'ai fait face à la même erreur et j'ai passé beaucoup de temps à comprendre quel était le problème. La réponse à cette question libspatialindex et Rtree sur python donnez-moi une astuce sur la façon de résoudre le problème.
Considérez le code ci-dessous (l'exemple de code de l'OP) et enregistrez-le comme script.py
:
import geopandas as gpd
from shapely.geometry import Polygon
polys1 = gpd.GeoSeries([Polygon([(0,0), (2,0), (2,2), (0,2)]),
Polygon([(2,2), (4,2), (4,4), (2,4)])])
polys2 = gpd.GeoSeries([Polygon([(1,1), (3,1), (3,3), (1,3)]),
Polygon([(3,3), (5,3), (5,5), (3,5)])])
df1 = gpd.GeoDataFrame({'geometry': polys1, 'df1':[1,2]})
df2 = gpd.GeoDataFrame({'geometry': polys2, 'df2':[1,2]})
res_union = gpd.overlay(df1, df2, how='union')
Considérer ce qui suit requirements.txt
:
Shapely==1.6.4.post2
descartes==1.1.0
geopandas==0.4.0
matplotlib==3.0.2
Si vous essayez d'installer uniquement les bibliothèques dans le requirements.txt
et courir scrip.py
, et ne pas installer la bibliothèque rtree
selon requirements.txt
, il va afficher le message d'erreur suivant:
/usr/local/lib/python3.6/site-packages/geopandas/base.py:76: UserWarning: Cannot generate spatial index: Missing package `rtree`.
warn("Cannot generate spatial index: Missing package `rtree`.")
Traceback (most recent call last):
File "script.py", line 17, in <module>
res_union = gpd.overlay(df1, df2, how='union')
File "/usr/local/lib/python3.6/site-packages/geopandas/tools/overlay.py", line 371, in overlay
result = _overlay_union(df1, df2)
File "/usr/local/lib/python3.6/site-packages/geopandas/tools/overlay.py", line 298, in _overlay_union
dfinter = _overlay_intersection(df1, df2)
File "/usr/local/lib/python3.6/site-packages/geopandas/tools/overlay.py", line 212, in _overlay_intersection
sidx = bbox.apply(lambda x: list(spatial_index.intersection(x)))
File "/usr/local/lib/python3.6/site-packages/pandas/core/series.py", line 3194, in apply
mapped = lib.map_infer(values, f, convert=convert_dtype)
File "pandas/_libs/src/inference.pyx", line 1472, in pandas._libs.lib.map_infer
File "/usr/local/lib/python3.6/site-packages/geopandas/tools/overlay.py", line 212, in <lambda>
sidx = bbox.apply(lambda x: list(spatial_index.intersection(x)))
AttributeError: 'NoneType' object has no attribute 'intersection'
La dernière ligne du message d'erreur
AttributeError: 'NoneType' object has no attribute 'intersection'
n'est pas si utile. Mais si vous regardez la première ligne:
/usr/local/lib/python3.6/site-packages/geopandas/base.py:76: UserWarning: Cannot generate spatial index: Missing package
rtree.
il se plaint de la bibliothèque rtree
.
Permet donc d'installer rtree
et de voir ce qui se passe. requirements.txt
est maintenant mis à jour pour:
Shapely==1.6.4.post2
descartes==1.1.0
geopandas==0.4.0
matplotlib==3.0.2
rtree==0.8.3
Réexécutant le script.py
J'obtiens l'erreur suivante:
Traceback (most recent call last):
File "script.py", line 3, in <module>
import geopandas as gpd
File "/usr/local/lib/python3.6/site-packages/geopandas/__init__.py", line 1, in <module>
from geopandas.geoseries import GeoSeries
File "/usr/local/lib/python3.6/site-packages/geopandas/geoseries.py", line 12, in <module>
from geopandas.base import GeoPandasBase, _series_unary_op, _CoordinateIndexer
File "/usr/local/lib/python3.6/site-packages/geopandas/base.py", line 14, in <module>
from rtree.core import RTreeError
File "/usr/local/lib/python3.6/site-packages/rtree/__init__.py", line 1, in <module>
from .index import Rtree
File "/usr/local/lib/python3.6/site-packages/rtree/index.py", line 5, in <module>
from . import core
File "/usr/local/lib/python3.6/site-packages/rtree/core.py", line 125, in <module>
raise OSError("Could not find libspatialindex_c library file")
OSError: Could not find libspatialindex_c library file
La dernière ligne se plaint de libspatialindex_c
, comme expliqué dans la première partie de ma réponse, l '"Explication directe", il suffit d'exécuter le code ci-dessous pour installer libspatialindex
et le script.py
devrait marcher.
Sudo apt-get update && apt-get install -y libspatialindex-dev
Au moins pour moi, le problème est résolu.