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