spatial.spatial_query
spatial.spatial_query(
geometry,
table='mupolygon',
return_type='tabular',
spatial_relation='intersects',
what=None,
geom_column=None,
client=None,
)Execute a spatial query against SSURGO data (CANONICAL FUNCTION).
This is the primary and recommended spatial query function for py-soildb. It is similar to soilDB::SDA_spatialQuery() in R and supports arbitrary input geometries with flexible table and return type options.
WHEN TO USE THIS: - You need to query spatial features (map units, survey areas, features) - You have point, polygon, line, or bounding box geometry - You want tabular or spatial results - You prefer a single unified function for all spatial queries
DESIGN: - Canonical function: ALL spatial queries should use this function - Supports multiple geometry input formats (WKT, shapely, bbox dict) - Flexible table selection (mupolygon, sapolygon, featpoint, featline) - Flexible return types (tabular for analysis, spatial with geometry) - Configurable spatial relationships (intersects, contains, within, etc.)
PERFORMANCE NOTES: - Tabular queries use optimized UDFs when possible (faster than spatial joins) - Spatial queries with geometry return large result sets; use selective bounding boxes - Complex geometries (many vertices) may timeout; simplify when possible - Point queries are fastest; polygon queries scale with geometry complexity - Bounding box queries are fast and recommended for large areas
TABLE TYPES: - “mupolygon”: Map unit polygons (most common) - “sapolygon”: Survey area polygons - “mupoint”: Map unit points - “muline”: Map unit lines - “featpoint”: Feature points (e.g., soil pits, monuments) - “featline”: Feature lines (e.g., linear features) - “mapunit”: Map unit table (spatial join required) - “legend”: Legend table (for legend-based queries)
SPATIAL RELATIONSHIPS: - “intersects”: Overlaps or touches (default, most common) - “contains”: Query geometry contains SSURGO feature - “within”: Query geometry within SSURGO feature - “touches”: Features share a boundary but don’t overlap - “crosses”: Features cross each other - “overlaps”: Features overlap but one doesn’t contain the other
RETURN TYPES: - “tabular”: Returns attribute data as DataFrame (lighter weight, faster) - “spatial”: Returns with geometry column (heavier, for mapping/analysis)
GEOMETRY INPUT FORMATS: - WKT string: “POINT(-94.68 42.03)” or “POLYGON((-94.7 42.0, …))” - Shapely geometry: geometry.Point(-94.68, 42.03) - Bounding box dict: {“xmin”: -94.7, “ymin”: 42.0, “xmax”: -94.6, “ymax”: 42.1}
Args: geometry: Input geometry as WKT string, shapely geometry object, or bbox dict table: Target SSURGO table (default: “mupolygon”). See TABLE TYPES above. return_type: “tabular” for data only (default), “spatial” for with geometry spatial_relation: Type of spatial relationship to test (default: “intersects”) what: Custom comma-separated column list (e.g., “mukey,muname,musym”). If None, uses sensible defaults based on table and return_type. geom_column: Custom geometry column name (e.g., “geometry”, “the_geom”). If None, auto-detected based on table. client: Optional SDA client instance. If not provided, a temporary client is created and closed automatically.
Returns: SDAResponse: Query results with methods like .to_pandas(), .to_geodataframe()
Raises: ValueError: If geometry cannot be parsed
Examples: # Example 1: Get map unit info for a point (simplest case) python point_wkt = "POINT(-94.6859 42.0285)" response = await spatial_query(point_wkt, "mupolygon", "tabular") df = response.to_pandas() print(df[['mukey', 'muname', 'musym']])
# Example 2: Get spatial polygons in a bounding box (for mapping)
```python
bbox = {"xmin": -94.7, "ymin": 42.0, "xmax": -94.6, "ymax": 42.1}
response = await spatial_query(bbox, "mupolygon", "spatial")
gdf = response.to_geodataframe()
gdf.plot() # Visualize map units
```
# Example 3: Get survey areas intersecting a custom polygon
```python
polygon_wkt = "POLYGON((-94.7 42.0, -94.6 42.0, -94.6 42.1, -94.7 42.1, -94.7 42.0))"
response = await spatial_query(polygon_wkt, "sapolygon", "tabular")
df = response.to_pandas()
print(df[['areasymbol', 'areaname', 'areaacres']])
```
# Example 4: Use shapely geometry
```python
from shapely.geometry import Point
location = Point(-94.68, 42.03)
response = await spatial_query(location, "mupolygon", "tabular")
```
# Example 5: Get feature points within area (archeological/historical sites)
```python
response = await spatial_query(point_wkt, "featpoint", "spatial")
gdf = response.to_geodataframe()
```
# Example 6: Custom columns and spatial relationship
```python
response = await spatial_query(
bbox,
table="mupolygon",
return_type="tabular",
spatial_relation="within",
what="mukey,muname,musym,compname,comppct_r"
)
```
COMPARISON WITH CONVENIENCE FUNCTIONS:
For common use cases, consider using these instead: - point_query(lat, lon, table, return_type) - Simplified point queries - bbox_query(xmin, ymin, xmax, ymax, table, return_type) - Simplified bbox queries
DEPRECATION NOTE: - SpatialQueryBuilder is an internal implementation detail; use spatial_query() instead.
SEE ALSO: - point_query() - Simplified point-based queries - bbox_query() - Simplified bounding box queries - Query builder (query.py) - For non-spatial attribute queries - soilDB R package documentation - For additional spatial query patterns