R-Tree spatial index for Python GIS
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Fundamental spatial indexing functionality that forms the foundation of Rtree's capabilities. These operations provide the essential CRUD (Create, Read, Update, Delete) functionality for spatial data.
Create spatial indexes with various configuration options.
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""
Creates a new index (R-Tree, MVR-Tree, or TPR-Tree).
Parameters:
- filename (str, optional): Path for file-based storage
- stream (iterable, optional): Input stream of index items
- storage (ICustomStorage, optional): Custom storage implementation
- interleaved (bool): Coordinate ordering format (default: True)
- properties (Property, optional): Index configuration object
- pagesize (int, optional): Page size for disk storage
- overwrite (bool, optional): Overwrite existing files
Returns:
None
"""Insert spatial objects into the index.
def insert(self, id: int, coordinates: Any, obj: object = None) -> None:
"""
Insert an item into the index.
Parameters:
- id (int): Unique identifier for the item
- coordinates (sequence): Spatial coordinates (minx, miny, maxx, maxy, ...)
- obj (object, optional): Python object to store with the item
Returns:
None
"""
def add(self, id: int, coordinates: Any, obj: object = None) -> None:
"""
Alias for insert method.
Parameters:
- id (int): Unique identifier for the item
- coordinates (sequence): Spatial coordinates
- obj (object, optional): Python object to store with the item
Returns:
None
"""Usage example:
from rtree import index
idx = index.Index()
# Insert basic spatial data
idx.insert(0, (0, 0, 1, 1)) # Rectangle from (0,0) to (1,1)
idx.insert(1, (0.5, 0.5, 1.5, 1.5)) # Overlapping rectangle
# Insert with associated objects
idx.insert(2, (2, 2, 3, 3), obj={"name": "Building A", "type": "commercial"})
idx.insert(3, (4, 4, 5, 5), obj="Simple string object")Query the index for spatial relationships.
def intersection(self, coordinates: Any, objects: bool | Literal["raw"] = False) -> Iterator[Item | int | object]:
"""
Find items that intersect with the given coordinates.
Parameters:
- coordinates (sequence): Query bounds (minx, miny, maxx, maxy, ...)
- objects (bool | "raw"): Return format
- False: Return item IDs only
- True: Return Item objects with id, object, bounds
- "raw": Return stored objects directly
Returns:
Iterator of IDs, Item objects, or stored objects
"""
def contains(self, coordinates: Any, objects: bool | Literal["raw"] = False) -> Iterator[Item | int | object] | None:
"""
Find items contained within the given coordinates.
Parameters:
- coordinates (sequence): Query bounds
- objects (bool | "raw"): Return format (same as intersection)
Returns:
Iterator of IDs, Item objects, or stored objects
"""
def nearest(self, coordinates: Any, num_results: int = 1, objects: bool | Literal["raw"] = False) -> Iterator[Item | int | object]:
"""
Find k-nearest items to the given coordinates.
Parameters:
- coordinates (sequence): Query point or bounds
- num_results (int): Maximum number of results to return
- objects (bool | "raw"): Return format (same as intersection)
Returns:
Iterator of IDs, Item objects, or stored objects (up to num_results)
"""
def count(self, coordinates: Any) -> int:
"""
Count items that intersect with the given coordinates.
Parameters:
- coordinates (sequence): Query bounds
Returns:
int: Number of intersecting items
"""Usage example:
from rtree import index
idx = index.Index()
idx.insert(0, (0, 0, 1, 1), obj="Rectangle 1")
idx.insert(1, (0.5, 0.5, 1.5, 1.5), obj="Rectangle 2")
idx.insert(2, (2, 2, 3, 3), obj="Rectangle 3")
# Intersection query - return IDs only
hits = list(idx.intersection((0.5, 0.5, 1.5, 1.5)))
print(hits) # [0, 1]
# Intersection query - return Item objects
for item in idx.intersection((0.5, 0.5, 1.5, 1.5), objects=True):
print(f"ID: {item.id}, Object: {item.object}, Bounds: {item.bounds}")
# Intersection query - return stored objects directly
objects = list(idx.intersection((0.5, 0.5, 1.5, 1.5), objects="raw"))
print(objects) # ["Rectangle 1", "Rectangle 2"]
# Nearest neighbor search
nearest_ids = list(idx.nearest((0.25, 0.25), 2))
print(nearest_ids) # [0, 1]
# Count intersections
count = idx.count((0, 0, 2, 2))
print(count) # 2Remove items from the index.
def delete(self, id: int, coordinates: Any) -> None:
"""
Delete an item from the index.
Parameters:
- id (int): Unique identifier of the item to delete
- coordinates (sequence): Spatial coordinates of the item
Returns:
None
Note:
Both ID and coordinates must match the inserted item exactly.
"""Usage example:
from rtree import index
idx = index.Index()
idx.insert(0, (0, 0, 1, 1))
idx.insert(1, (2, 2, 3, 3))
print(len(idx)) # 2
# Delete item with matching ID and coordinates
idx.delete(0, (0, 0, 1, 1))
print(len(idx)) # 1
# Verify deletion
hits = list(idx.intersection((0, 0, 1, 1)))
print(hits) # []Get information about the index state and contents.
def __len__(self) -> int:
"""
Get the number of items in the index.
Returns:
int: Number of items in the index
"""
def get_size(self) -> int:
"""
Get the number of items in the index (deprecated).
Returns:
int: Number of items in the index
Note:
This method is deprecated. Use len(index) instead.
"""
def valid(self) -> bool:
"""
Check if the index is in a valid state.
Returns:
bool: True if index is valid, False otherwise
"""
def get_bounds(self, coordinate_interleaved=None):
"""
Get the bounding box of all items in the index.
Parameters:
- coordinate_interleaved (bool, optional): Return format
- True: Interleaved format [minx, miny, maxx, maxy, ...]
- False/None: Non-interleaved format [minx, maxx, miny, maxy, ...]
Returns:
list: Bounding box coordinates or None if empty
"""
@property
def bounds(self):
"""
Property for getting index bounds.
Returns:
list: Bounding box in non-interleaved format or None if empty
"""Usage example:
from rtree import index
idx = index.Index()
idx.insert(0, (0, 0, 1, 1))
idx.insert(1, (2, 2, 3, 3))
# Check index size
print(len(idx)) # 2
print(idx.valid()) # True
# Get overall bounds
print(idx.bounds) # [0.0, 3.0, 0.0, 3.0] (minx, maxx, miny, maxy)
print(idx.get_bounds(coordinate_interleaved=True)) # [0.0, 0.0, 3.0, 3.0]Rtree supports two coordinate ordering formats controlled by the interleaved attribute:
[minx, miny, maxx, maxy, minz, maxz, ...][minx, maxx, miny, maxy, minz, maxz, ...]@classmethod
def interleave(cls, deinterleaved: Sequence[float]) -> list[float]:
"""
Convert non-interleaved coordinates to interleaved format.
Parameters:
- deinterleaved (sequence): Non-interleaved coordinates
Returns:
list: Interleaved coordinates
"""
@classmethod
def deinterleave(cls, interleaved: Sequence[object]) -> list[object]:
"""
Convert interleaved coordinates to non-interleaved format.
Parameters:
- interleaved (sequence): Interleaved coordinates
Returns:
list: Non-interleaved coordinates
"""Control index persistence and memory management.
def flush(self) -> None:
"""
Force a flush of pending operations to storage.
Returns:
None
"""
def close(self) -> None:
"""
Close the index and free all resources.
Returns:
None
Note:
Index becomes inaccessible after closing.
"""
def clearBuffer(self) -> None:
"""
Clear the index buffer.
Returns:
None
"""Core indexing operations can raise RTreeError exceptions for various error conditions:
from rtree import index
from rtree.exceptions import RTreeError
idx = index.Index()
try:
# This will raise RTreeError due to invalid bounds
idx.insert(0, (1.0, 1.0, 0.0, 0.0)) # minx > maxx
except RTreeError as e:
print(f"Index error: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-rtree