vibespatial.api.sindex

Attributes

Classes

SpatialIndex

A simple wrapper around Shapely's STRTree.

Module Contents

vibespatial.api.sindex.PREDICATES
vibespatial.api.sindex.OWNED_QUERY_PREDICATES
class vibespatial.api.sindex.SpatialIndex(geometry, geometry_array=None)

A simple wrapper around Shapely’s STRTree.

Parameters

geometrynp.array of Shapely geometries

Geometries from which to build the spatial index.

geometries
property valid_query_predicates

Returns valid predicates for the spatial index.

Returns

set

Set of valid predicates for this spatial index.

Examples

>>> from shapely.geometry import Point
>>> s = geopandas.GeoSeries([Point(0, 0), Point(1, 1)])
>>> s.sindex.valid_query_predicates
{None, "contains", "contains_properly", "covered_by", "covers", "crosses", "dwithin", "intersects", "overlaps", "touches", "within"}
query(geometry, predicate=None, sort=False, distance=None, output_format='indices', return_device=False)

Return 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.

The result can be returned as an array of ‘indices’ or a boolean ‘sparse’ or ‘dense’ array. This can be controlled using the output_format keyword. Options are as follows.

'indices'

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.

'sparse'

If the input geometry is a scalar, this returns a boolean scipy.sparse COO array of shape (len(tree), ) with boolean values marking whether the bounding box of a geometry in the tree intersects a bounding box of a given scalar. If the input geometry is an array_like, this returns a boolean scipy.sparse COO array with shape (len(tree), n) with boolean values marking whether the bounding box of a geometry in the tree intersects a bounding box of a given scalar.

'dense'

If the input geometry is a scalar, this returns a boolean numpy array of shape (len(tree), ) with boolean values marking whether the bounding box of a geometry in the tree intersects a bounding box of a given scalar. If the input geometry is an array_like, this returns a boolean numpy array with shape (len(tree), n) with boolean values marking whether the bounding box of a geometry in the tree intersects a bounding box of a given scalar.

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.

See the User Guide page ../../user_guide/spatial_indexing for more.

Parameters

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). Applicable only if output_format=”indices”.

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

output_format{“indices”, “sparse”, “dense”}, default “indices”

Type of the output format representing the result of the query. Private return_device=True callers must use "indices"; native consumers that need pair flow should use query_relation() because dense and sparse outputs are public compatibility exports.

Returns

If geometry is a scalar:

ndarray with shape (n,)

Integer indices for matching geometries from the spatial index tree geometries. If output_format="indices".

OR

scipy.sparse COO array with shape (len(tree), )

Boolean array aligned with array of geometries in the tree. If output_format="sparse".

OR

ndarray with shape (len(tree), )

Boolean array aligned with array of geometries in the tree. If output_format="dense".

If geometry is an array_like:

ndarray with shape (2, n)

The first subarray contains input geometry integer indices. The second subarray contains tree geometry integer indices. If output_format="indices".

OR

scipy.sparse COO array with shape (len(tree), n)

Boolean array aligned with array of geometries in the tree along axis 0 and with geometry along axis 1. If output_format="sparse".

OR

ndarray with shape (len(tree), n)

Boolean array aligned with array of geometries in the tree along axis 0 and with geometry along axis 1. If output_format="dense".

Examples

>>> 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")
array([2])

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")
array([[0],
       [3]])
>>> 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])

Returning boolean arrays:

>>> s.sindex.query(box(1, 1, 3, 3), output_format="sparse")
<COOrdinate sparse array of dtype 'bool'
    with 3 stored elements and shape (10,)>
>>> s.sindex.query(box(1, 1, 3, 3), output_format="dense")
array([False,  True,  True,  True, False, False, False, False, False,
       False])
>>> s.sindex.query(s2, output_format="sparse")
<COOrdinate sparse array of dtype 'bool'
    with 5 stored elements and shape (10, 2)>
>>> s.sindex.query(s2, output_format="dense")
array([[False, False],
       [False, False],
       [ True, False],
       [ True, False],
       [ True, False],
       [False,  True],
       [False,  True],
       [False, False],
       [False, False],
       [False, False]])

Notes

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.

query_aggregate(geometry, aggregations: collections.abc.Mapping[str, str | tuple[object, str]], *, predicate=None, distance=None) pandas.DataFrame

Aggregate spatial-index matches without exporting relation pairs.

Parameters

geometryshapely.Geometry or array-like of geometries

Input geometries queried against the indexed tree geometries. Output rows preserve this input order and, for a GeoSeries, index.

aggregationsmapping

Output-column names mapped either to "size" for the number of matches or to (values, "sum"). values must be a numeric one-dimensional public Series or array aligned with the indexed tree geometries.

predicatestr, optional

Exact spatial predicate with the same meaning as query().

distancenumber or array-like, optional

Distance for the "dwithin" predicate.

Returns

pandas.DataFrame

One eager, pandas-compatible row per input geometry. Empty groups have size and sum equal to zero.

Notes

This vibeSpatial extension is a public eager reduction API, not a lazy relation or proxy dataframe. Device-backed inputs lower to a NativeRelation grouped reduction. The computed input-sized columns remain device-backed through ordinary public Series arithmetic and transfer only when a caller explicitly requests host values. Unsupported inputs use the exact observable CPU path.

query_any(geometry, *, predicate=None, distance=None) pandas.Series

Return whether each input geometry has any spatial-index match.

This is an eager, input-sized public reduction. The result preserves the input order and GeoSeries index without exposing or materializing the underlying relation pairs. Device-backed inputs retain a native boolean column until an explicit public host export.

Parameters

geometryshapely.Geometry or array-like of geometries

Input geometries queried against the indexed tree geometries.

predicatestr, optional

Exact spatial predicate with the same meaning as query().

distancenumber or array-like, optional

Distance for the "dwithin" predicate.

Returns

pandas.Series

One eager boolean value per input geometry.

query_pair_aggregate(other, geometry, *, predicate=None, distance=None) pandas.DataFrame

Aggregate common query matches for two aligned spatial indexes.

self and other must index the same number of position-aligned geometries. For every indexed row, the result contains the number of matches from each index and the number of query geometries matched by both indexed geometries at that row position. Query-row duplicates and overlapping query geometries retain their ordinary spatial-join multiplicity.

The eager pandas result has a RangeIndex aligned to indexed row positions and columns left_count, right_count, and shared_count. Device-backed inputs consume both native relations without exporting pair arrays; computed columns remain device-backed until an explicit public scalar or array export.

query_relation(geometry, *, predicate=None, sort=False, distance=None, source_token: str | None = None, query_token: str | None = None, query_row_count: int | None = None, return_device: bool = True, tree_shapely: numpy.ndarray | None = None, query_shapely: numpy.ndarray | None = None, precomputed_query_bounds: numpy.ndarray | None = None)

Query this spatial index as private native relation row flow.

Physical shape: candidate/predicate pair generation over cached NativeSpatialIndex state. Native input carriers are NativeSpatialIndex plus owned/query geometry or NativeFrameState; the native output carrier is NativeRelation.

query_left_semijoin(geometry, *, predicate=None, distance=None, source_token: str | None = None, query_token: str | None = None, query_row_count: int | None = None, precomputed_query_bounds=None)

Query this index directly into private matched-left row flow.

query_left_antijoin(geometry, *, predicate=None, distance=None, source_token: str | None = None, query_token: str | None = None, query_row_count: int | None = None, precomputed_query_bounds=None)

Query this index directly into private unmatched-left row flow.

query_left_match_count_expression(geometry, *, predicate=None, distance=None, source_token: str | None = None, query_token: str | None = None, query_row_count: int | None = None, precomputed_query_bounds=None)

Query this index directly into private per-left match counts.

query_right_semijoin(geometry, *, predicate=None, distance=None, source_token: str | None = None, query_row_count: int | None = None, precomputed_query_bounds=None)

Query this index directly into private matched-index row flow.

nearest(geometry, return_all=True, max_distance=None, return_distance=False, exclusive=False, k=1, _return_execution_mode=False)

Return the nearest geometry in the tree for each input geometry in geometry.

If multiple tree geometries have the same distance from an input geometry, multiple results will be returned for that input geometry by default. Specify return_all=False to only get a single nearest geometry (non-deterministic which nearest is returned).

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. If max_distance is not set, this will effectively be a left join because every geometry in geometry will have a nearest geometry in the tree. However, if max_distance is used, this becomes an inner join, since some geometries in geometry may not have a match in the tree.

For performance reasons, it is highly recommended that you set the max_distance parameter.

Parameters

geometry{shapely.geometry, GeoSeries, GeometryArray, numpy.array of Shapely geometries}

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

return_allbool, default True

If there are multiple equidistant or intersecting nearest geometries, return all those geometries instead of a single nearest geometry.

max_distancefloat, optional

Maximum distance within which to query for nearest items in tree. Must be greater than 0. By default None, indicating no distance limit.

return_distancebool, optional

If True, will return distances in addition to indexes. By default False

exclusivebool, optional

if True, the nearest geometries that are equal to the input geometry will not be returned. By default False. Requires Shapely >= 2.0.

kint, default 1

Number of nearest tree geometries to return per input geometry. Values greater than one require the native device k-NN path and return_all=False; exactly k rows are returned when enough tree geometries exist.

Returns

Indices or tuple of (indices, distances)

Indices is an ndarray of shape (2,n) and distances (if present) an ndarray of shape (n). The first subarray of indices contains input geometry indices. The second subarray of indices contains tree geometry indices.

Examples

>>> from shapely.geometry import Point, box
>>> s = geopandas.GeoSeries(geopandas.points_from_xy(range(10), range(10)))
>>> s.head()
0    POINT (0 0)
1    POINT (1 1)
2    POINT (2 2)
3    POINT (3 3)
4    POINT (4 4)
dtype: geometry
>>> s.sindex.nearest(Point(1, 1))
array([[0],
       [1]])
>>> s.sindex.nearest([box(4.9, 4.9, 5.1, 5.1)])
array([[0],
       [5]])
>>> s2 = geopandas.GeoSeries(geopandas.points_from_xy([7.6, 10], [7.6, 10]))
>>> s2
0    POINT (7.6 7.6)
1    POINT (10 10)
dtype: geometry
>>> s.sindex.nearest(s2)
array([[0, 1],
       [8, 9]])
nearest_relation(geometry, *, return_all=True, max_distance=None, exclusive=False, k=1, source_token: str | None = None, query_token: str | None = None, query_row_count: int | None = None)

Return nearest query output as private NativeRelation state.

Physical shape: nearest candidate/refine relation production. Native input carriers are owned query/tree geometry buffers; the native output carrier is NativeRelation with device pair arrays and fp64 device distances. Public nearest callers still use nearest() and export NumPy arrays at the compatibility boundary.

intersection(coordinates)

Compatibility wrapper for rtree.index.Index.intersection, use query instead.

Parameters

coordinatessequence or array

Sequence of the form (min_x, min_y, max_x, max_y) to query a rectangle or (x, y) to query a point.

Examples

>>> 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
>>> s.sindex.intersection(box(1, 1, 3, 3).bounds)
array([1, 2, 3])

Alternatively, you can use query:

>>> s.sindex.query(box(1, 1, 3, 3))
array([1, 2, 3])
property size

Size of the spatial index.

Number of leaves (input geometries) in the index.

Examples

>>> from shapely.geometry import Point
>>> 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
>>> s.sindex.size
10
property is_empty

Check if the spatial index is empty.

Examples

>>> from shapely.geometry import Point
>>> 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
>>> s.sindex.is_empty
False
>>> s2 = geopandas.GeoSeries()
>>> s2.sindex.is_empty
True