SpatialIndex.query(geometry, predicate=None, sort=False, distance=None)[source]#

Return the integer indices of all combinations of each input geometry and tree geometries where the bounding box of each input geometry intersects the bounding box of a tree geometry.

If the input geometry is a scalar, this returns an array of shape (n, ) with the indices of the matching tree geometries. If the input geometry is an array_like, this returns an array with shape (2,n) where the subarrays correspond to the indices of the input geometries and indices of the tree geometries associated with each. To generate an array of pairs of input geometry index and tree geometry index, simply transpose the result.

If a predicate is provided, the tree geometries are first queried based on the bounding box of the input geometry and then are further filtered to those that meet the predicate when comparing the input geometry to the tree geometry: predicate(geometry, tree_geometry).

The ‘dwithin’ predicate requires GEOS >= 3.10.

Bounding boxes are limited to two dimensions and are axis-aligned (equivalent to the bounds property of a geometry); any Z values present in input geometries are ignored when querying the tree.

Any input geometry that is None or empty will never match geometries in the tree.

geometryshapely.Geometry or array-like of geometries (numpy.ndarray, GeoSeries, GeometryArray)

A single shapely geometry or array of geometries to query against the spatial index. For array-like, accepts both GeoPandas geometry iterables (GeoSeries, GeometryArray) or a numpy array of Shapely geometries.

predicate{None, “contains”, “contains_properly”, “covered_by”, “covers”, “crosses”, “intersects”, “overlaps”, “touches”, “within”, “dwithin”}, optional

If predicate is provided, the input geometries are tested using the predicate function against each item in the tree whose extent intersects the envelope of the input geometry: predicate(input_geometry, tree_geometry). If possible, prepared geometries are used to help speed up the predicate operation.

sortbool, default False

If True, the results will be sorted in ascending order. In case of 2D array, the result is sorted lexicographically using the geometries’ indexes as the primary key and the sindex’s indexes as the secondary key. If False, no additional sorting is applied (results are often sorted but there is no guarantee).

distancenumber or array_like, optional

Distances around each input geometry within which to query the tree for the ‘dwithin’ predicate. If array_like, shape must be broadcastable to shape of geometry. Required if predicate='dwithin'.

ndarray with shape (n,) if geometry is a scalar

Integer indices for matching geometries from the spatial index tree geometries.

ndarray with shape (2, n) if geometry is an array_like

The first subarray contains input geometry integer indices. The second subarray contains tree geometry integer indices.


In the context of a spatial join, input geometries are the “left” geometries that determine the order of the results, and tree geometries are “right” geometries that are joined against the left geometries. This effectively performs an inner join, where only those combinations of geometries that can be joined based on overlapping bounding boxes or optional predicate are returned.


>>> from shapely.geometry import Point, box
>>> s = geopandas.GeoSeries(geopandas.points_from_xy(range(10), range(10)))
>>> s
0    POINT (0 0)
1    POINT (1 1)
2    POINT (2 2)
3    POINT (3 3)
4    POINT (4 4)
5    POINT (5 5)
6    POINT (6 6)
7    POINT (7 7)
8    POINT (8 8)
9    POINT (9 9)
dtype: geometry

Querying the tree with a scalar geometry:

>>> s.sindex.query(box(1, 1, 3, 3))
array([1, 2, 3])
>>> s.sindex.query(box(1, 1, 3, 3), predicate="contains")

Querying the tree with an array of geometries:

>>> s2 = geopandas.GeoSeries([box(2, 2, 4, 4), box(5, 5, 6, 6)])
>>> s2
0    POLYGON ((4 2, 4 4, 2 4, 2 2, 4 2))
1    POLYGON ((6 5, 6 6, 5 6, 5 5, 6 5))
dtype: geometry
>>> s.sindex.query(s2)
array([[0, 0, 0, 1, 1],
       [2, 3, 4, 5, 6]])
>>> s.sindex.query(s2, predicate="contains")
>>> s.sindex.query(box(1, 1, 3, 3), predicate="dwithin", distance=0)
array([1, 2, 3])
>>> s.sindex.query(box(1, 1, 3, 3), predicate="dwithin", distance=2)
array([0, 1, 2, 3, 4])