Toblerity/rtree

ArgumentError: expected LP_LP_c_long instance instead of pointer to LP_c_long

nicolozambon opened this issue · 8 comments

I am using rtree as a dependency of GeoPandas Python module. Running Django on Apache VPS, I often get this error:

ArgumentError
argument 5: <class 'TypeError'>: expected LP_LP_c_long instance instead of pointer to LP_c_long
...
Exception Location:     /opt/bitnami/python/lib/python3.8/site-packages/rtree/index.py, line 688, in intersection
Python Executable:      /opt/bitnami/python/bin/python3
Python Version:         3.8.12
Python Path:            ['/opt/bitnami/projects/demo',
 '/opt/bitnami/python/lib/python38.zip',
 '/opt/bitnami/python/lib/python3.8',
 '/opt/bitnami/python/lib/python3.8/lib-dynload',
 '/opt/bitnami/python/lib/python3.8/site-packages',
 '/opt/bitnami/python/lib/python3.8/site-packages/setuptools-46.4.0-py3.8.egg',
 '/opt/bitnami/python/lib/python3.8/site-packages/pip-21.3.1-py3.8.egg',
 '/opt/bitnami/python/lib/python3.8/site-packages/six-1.16.0-py3.8.egg',
 '/opt/bitnami/python/lib/python3.8/site-packages/platformdirs-2.4.1-py3.8.egg',
 '/opt/bitnami/python/lib/python3.8/site-packages/filelock-3.4.2-py3.8.egg',
 '/opt/bitnami/python/lib/python3.8/site-packages/distlib-0.3.4-py3.8.egg']

In rtree/index.py starting at line 688 there is:

core.rt.Index_Intersects_id(self.handle,
                                    p_mins,
                                    p_maxs,
                                    self.properties.dimension,
                                    ctypes.byref(it),
                                    ctypes.byref(p_num_results))

I undertand that the problem is related to the argument ctypes.byref(it).

hobu commented

Can you please provide a scenario that demonstrates this issue?

@hobu Thanks for the reply, the scenario is the following. First of all, here is the list of the versions that I am using:

  • Python 3.8.12
  • Django 4.0.2
  • GeoPandas 0.10.2
  • NumPy 1.22.2
  • Shapely 1.8.1.post1
  • Rtree 0.9.7
  • libspatialindex 1.9.0-1

I am running it on a Bitnami instance on a Debian GNU/Linux 10 (buster) VPS. When I run it locally, on macOS, this error never appears.

I have a view in Django that calls this code:

import geopandas as gpd
from shapely.geometry import Polygon

# ... omitted part ...

# Load a .zip shapefile
shp_data = gpd.GeoDataFrame.from_file(path)

# Set coordinates bounds for test
bounds = [(1.0, 20.0), (1.0, 50.0), (9.0, 50.0), (9.0, 20.0), (1.0, 20.0)]

# Build the Polygon instance
polygon = Polygon(bounds)

# Line that raises the error
subset = shp_data.clip(polygon)

Here there is the last part of the Traceback:

  File "/opt/bitnami/projects/demo/api/classes/[omitted]/[omitted]/shapefile/shapefile.py", line 25, in getCoverage
    subset = shp_data.clip(polygon)
  File "/opt/bitnami/python/lib/python3.8/site-packages/geopandas/geodataframe.py", line 2106, in clip
    return geopandas.clip(self, mask=mask, keep_geom_type=keep_geom_type)
  File "/opt/bitnami/python/lib/python3.8/site-packages/geopandas/tools/clip.py", line 139, in clip
    clipped = _clip_gdf_with_polygon(gdf, poly)
  File "/opt/bitnami/python/lib/python3.8/site-packages/geopandas/tools/clip.py", line 36, in _clip_gdf_with_polygon
    gdf_sub = gdf.iloc[gdf.sindex.query(poly, predicate="intersects")]
  File "/opt/bitnami/python/lib/python3.8/site-packages/geopandas/sindex.py", line 472, in query
    tree_idx = list(self.intersection(bounds))
  File "/opt/bitnami/python/lib/python3.8/site-packages/geopandas/sindex.py", line 604, in intersection
    return super().intersection(coordinates, objects=False)
  File "/opt/bitnami/python/lib/python3.8/site-packages/rtree/index.py", line 688, in intersection
    core.rt.Index_Intersects_id(self.handle,

Currently, instead of using geopandas.clip() I am using geopandas.intersection() that is a viable workaround for my purpose.

hobu commented

Thanks for the example, but you will have to pull geopandas out of it. I would think if the intersection method for Rtree was always passing in the wrong thing, we would have a lot of bugs in the repository. The code that calls that intersection method hasn't changed for 10+ years either.

Maybe @martinfleis or @jorisvandenbossche could work this issue with this scenario and example data that demonstrates it.

@nicolozambon can you try to provide a fully reproducible example?

For example, does running the following using the naturalearth example dataset fail as well for you?

import geopandas
from shapely.geometry import Polygon

df = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))

>>> df.clip(Polygon([(1.0, 20.0), (1.0, 50.0), (9.0, 50.0), (9.0, 20.0), (1.0, 20.0)]))
      pop_est continent         name iso_a3  gdp_md_est                                           geometry
52   17885245    Africa         Mali    MLI     38090.0  POLYGON ((1.82323 20.61081, 2.06099 20.14223, ...
55   19245344    Africa        Niger    NER     20150.0  POLYGON ((8.57289 21.56566, 9.00000 21.80323, ...
82   40969443    Africa      Algeria    DZA    609400.0  POLYGON ((1.46692 36.60565, 3.16170 36.78390, ...
...

@jorisvandenbossche thank you for your interest. I tried the code you suggested and I confirm that, with the environment described above, the problem arises.

The strangest thing is that the error does not always show up. I tried calling the web page about ten times: the first two returned the correct output while the rest showed the error.

If you want to try simulating my environment you could set up Django on an AWS Lightsail instance.

Can you reproduce this without Django and/or outside of the AWS instance? Or only with this specific situation?

@jorisvandenbossche outside Django it seems working. I tried to run the commands directly from the python shell on AWS and it works.

hobu commented

Closing this issue here as it doesn't seem to be an Rtree thing.