12

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.

Rotail
  • 1,025
  • 4
  • 19
  • 40
  • 1
    I also get a warning complaining about missing package `rtree`, even though I have that installed. – Rotail Nov 29 '18 at 20:09
  • UPDATE: It goes fine in my local machine when my geopandas is 0.3.0, not in my cloud env in which I have geopandas 0.4.0. – Rotail Nov 30 '18 at 14:57
  • Your example above works fine for me on both geopandas 0.3.0 and 0.4.0. You get the error with the above example? Can you show the full error traceback? – joris Dec 01 '18 at 07:38
  • 2
    I installed `rtree` package and it fixed the issue. `conda install rtree` – S.Perera Oct 14 '19 at 12:04

2 Answers2

26

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.

pedro regis
  • 316
  • 4
  • 6
  • 1
    For arch user: https://www.archlinux.org/packages/community/x86_64/spatialindex/ and pip install rtree – JOHN Jan 01 '20 at 04:35
1

Geopandas documentation tells what follows:

For historical reasons, the overlay method is also available as a top-level function overlay(). It is recommended to use the method as the function may be deprecated in the future.

For that reason, I'd do it this way:

df1.union(df2)

Miguel Gonzalez
  • 706
  • 7
  • 20