Overly Function from GeoPandas Not Working

Rotail picture Rotail · Nov 29, 2018 · Viewed 8.6k times · Source

I simply want to use geopandas to get a union and intersection of two polygonal areas. I define:

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]})

I try the following to get the union:

res_union = gpd.overlay(df1, df2, how='union')

and it fails with the following ERROR:

AttributeError: 'NoneType' object has no attribute 'intersection'

I am following the instructions here.

Answer

pedro regis picture pedro regis · Jan 13, 2019

Despite I don't know the OP's operational system I think that I figured out how to solve the problem, at least for GNU/Linux systems (I'm not able to test in other systems).

Direct explanation

To be able to use the overlay function you need more than just install geopandas, you need install rtree, but rtree is a wrapper to the C library libspatialindex. So to use rtree library you need to install libspatialindex C library.

To install libspatialindex open a terminal end type:

sudo apt-get update && apt-get install -y libspatialindex-dev

Note: actually you only need the sudo apt-get install libspatialindex-dev, but it is good practice update the system, and the -y flag is just to don't stop the installation process to ask for continue with the installation or not.

Now it should solve your problem. Note: make sure you have rtree installed in your system, you can do this using pip3 freeze (I am supposing that you use python3).

Long explanation

I faced the same error, and spent a lot of time to figure out what was the problem. The answer to this question libspatialindex and Rtree on python give to me a tip on how to solve the problem.

Consider the bellow code (the OP's code example) and save named as 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')

Consider the following requirements.txt:

Shapely==1.6.4.post2
descartes==1.1.0
geopandas==0.4.0
matplotlib==3.0.2

If you try to only install the libraries in the requirements.txt and run scrip.py, and not install rtree library according to the requirements.txt, it is going to show the following error message:

/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'

The last line of the error message

AttributeError: 'NoneType' object has no attribute 'intersection'

is not so useful. But if you look to the first line:

/usr/local/lib/python3.6/site-packages/geopandas/base.py:76: UserWarning: Cannot generate spatial index: Missing packagertree.

it is complaining about the rtree library.

So lets install rtree and see what happens. requirements.txt now is updated to:

Shapely==1.6.4.post2
descartes==1.1.0
geopandas==0.4.0
matplotlib==3.0.2
rtree==0.8.3

Runing again the script.py I get the following error:

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

The last line complain about libspatialindex_c, so as explained in the first part of my answer, the "Direct explanation", just run the bellow code to install libspatialindex and the script.py should work.

sudo apt-get update && apt-get install -y libspatialindex-dev

At least for me the problem is solved.