Skip to content

Geospatial Operations

Temp edited this page Oct 3, 2025 · 1 revision

Geospatial Operations

7 specialized tools for spatial queries, distance calculations, and GIS operations using PostGIS.

Requirements: PostGIS extension (v3.0+)


📊 Overview

Tool Purpose Geometry Type
spatial_search Find geometries within area Point, Polygon, LineString
distance_calculate Calculate distances Point-to-point, point-to-geometry
within_radius Find points within radius Point, Circle
geometry_validate Validate geometry data All types
coordinate_transform Transform coordinate systems SRID conversion
spatial_index_create Create spatial indexes GIST, BRIN
geo_stats Spatial statistics Area, length, bounds

🔧 Tool Details

spatial_search

Search for geometries within a specified area or bounding box.

Parameters:

  • table_name (string, required): Table with geometry column
  • geometry_column (string, required): Column containing geometries
  • search_geometry (string, required): WKT geometry to search within
  • operation (string, optional): within, intersects, contains (default: within)
  • limit (integer, optional): Maximum results

Returns:

  • Matching geometries
  • Distance/area calculations
  • Geometry properties

Example:

# Find points within polygon
result = spatial_search(
    table_name="locations",
    geometry_column="geom",
    search_geometry="POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))",
    operation="within"
)
# Returns: [
#   {"id": 1, "name": "Store A", "geom": "POINT(5 5)"},
#   {"id": 2, "name": "Store B", "geom": "POINT(7 3)"},
#   ...
# ]

# Find all geometries intersecting a line
result = spatial_search(
    table_name="roads",
    geometry_column="path",
    search_geometry="LINESTRING(0 0, 10 10)",
    operation="intersects"
)

Operations:

  • within - Geometries completely inside search area
  • intersects - Geometries that touch/cross search area
  • contains - Search area is completely inside geometry

Use Cases:

  • Store locator
  • Service area analysis
  • Delivery zone checking
  • Proximity queries

distance_calculate

Calculate distances between geometries or points.

Parameters:

  • table_name (string, required): Source table
  • geometry_column (string, required): Geometry column
  • reference_geometry (string, required): WKT reference point/geometry
  • unit (string, optional): meters, kilometers, miles, feet (default: meters)
  • limit (integer, optional): Nearest N results

Returns:

  • Distance values in specified unit
  • Sorted by distance (nearest first)

Example:

# Find nearest stores
result = distance_calculate(
    table_name="stores",
    geometry_column="location",
    reference_geometry="POINT(-122.4194 37.7749)",  # San Francisco
    unit="kilometers",
    limit=5
)
# Returns: [
#   {"id": 42, "name": "Downtown Store", "distance_km": 0.5},
#   {"id": 18, "name": "Market St Store", "distance_km": 1.2},
#   ...
# ]

# Calculate distance to all locations
result = distance_calculate(
    table_name="warehouses",
    geometry_column="location",
    reference_geometry="POINT(-74.0060 40.7128)",  # New York
    unit="miles"
)

Supported Units:

  • meters (default)
  • kilometers
  • miles
  • feet

Use Cases:

  • Nearest neighbor search
  • Distance-based sorting
  • Travel time estimation
  • Service radius verification

within_radius

Find all points within a specified radius.

Parameters:

  • table_name (string, required): Source table
  • geometry_column (string, required): Point geometry column
  • center_point (string, required): WKT center point
  • radius (number, required): Search radius
  • unit (string, optional): Distance unit (default: meters)

Returns:

  • Points within radius
  • Distance from center
  • Sorted by distance

Example:

# Find stores within 5km
result = within_radius(
    table_name="stores",
    geometry_column="location",
    center_point="POINT(-122.4194 37.7749)",
    radius=5,
    unit="kilometers"
)
# Returns: [
#   {
#     "id": 1,
#     "name": "Downtown Store",
#     "location": "POINT(-122.4183 37.7750)",
#     "distance_km": 0.12
#   },
#   ...
# ]

# Find all points within 1 mile
result = within_radius(
    table_name="customers",
    geometry_column="address_point",
    center_point="POINT(-74.0060 40.7128)",
    radius=1,
    unit="miles"
)

Use Cases:

  • Radius search
  • Geofencing
  • Coverage analysis
  • Service area definition

geometry_validate

Validate and check geometry data quality.

Parameters:

  • table_name (string, required): Table to validate
  • geometry_column (string, required): Geometry column
  • fix_invalid (boolean, optional): Attempt to fix invalid geometries

Returns:

  • Validation results
  • Error descriptions
  • Fixed geometries (if requested)

Example:

result = geometry_validate(
    table_name="parcels",
    geometry_column="boundary",
    fix_invalid=True
)
# Returns: {
#   "total_geometries": 1000,
#   "valid": 985,
#   "invalid": 15,
#   "fixed": 12,
#   "errors": [
#     {
#       "id": 42,
#       "error": "Self-intersection",
#       "fixed": True
#     },
#     {
#       "id": 108,
#       "error": "Ring Self-intersection",
#       "fixed": False
#     }
#   ]
# }

Common Validation Issues:

  • Self-intersecting polygons
  • Duplicate vertices
  • Invalid ring orientation
  • Unclosed polygons
  • Null geometries

Use Cases:

  • Data quality assurance
  • Import validation
  • GIS data cleaning
  • Topology correction

coordinate_transform

Transform geometries between coordinate reference systems (SRID).

Parameters:

  • table_name (string, required): Source table
  • geometry_column (string, required): Geometry column
  • source_srid (integer, required): Source SRID
  • target_srid (integer, required): Target SRID
  • update_table (boolean, optional): Update geometries in place

Returns:

  • Transformed geometries
  • Transformation statistics
  • SRID information

Example:

# Transform from WGS84 (4326) to Web Mercator (3857)
result = coordinate_transform(
    table_name="locations",
    geometry_column="geom",
    source_srid=4326,
    target_srid=3857,
    update_table=False
)

# Common transformations
# WGS84 (GPS): 4326
# Web Mercator (Google Maps): 3857
# UTM Zone 10N: 32610
# State Plane CA Zone 3: 2227

Common SRIDs:

  • 4326 - WGS84 (GPS coordinates, lat/lon)
  • 3857 - Web Mercator (Web maps)
  • 2163 - US National Atlas Equal Area
  • 32601-32660 - UTM Northern Hemisphere
  • 32701-32760 - UTM Southern Hemisphere

Use Cases:

  • Map projection conversion
  • GPS coordinate transformation
  • GIS data integration
  • Spatial analysis preparation

spatial_index_create

Create optimized spatial indexes for faster queries.

Parameters:

  • table_name (string, required): Target table
  • geometry_column (string, required): Geometry column
  • index_type (string, optional): gist (default) or brin
  • index_name (string, optional): Custom index name

Returns:

  • Index creation status
  • Estimated performance improvement
  • Index size

Example:

# GIST index (recommended for most cases)
result = spatial_index_create(
    table_name="locations",
    geometry_column="geom",
    index_type="gist"
)

# BRIN index (for very large, spatially sorted data)
result = spatial_index_create(
    table_name="sensor_readings",
    geometry_column="location",
    index_type="brin"
)

Index Types:

GIST (Generalized Search Tree):

  • Best for: Most spatial queries
  • Pros: Fast searches, good for mixed workloads
  • Cons: Larger index size, slower to build

BRIN (Block Range Index):

  • Best for: Very large, spatially clustered data
  • Pros: Small index size, fast to build
  • Cons: Slower searches, requires spatial clustering

Use Cases:

  • Query performance optimization
  • Large dataset handling
  • Production readiness

geo_stats

Calculate spatial statistics on geometry data.

Parameters:

  • table_name (string, required): Source table
  • geometry_column (string, required): Geometry column
  • include_area (boolean, optional): Calculate areas
  • include_length (boolean, optional): Calculate lengths
  • include_bounds (boolean, optional): Calculate bounding boxes

Returns:

  • Spatial statistics
  • Aggregate measurements
  • Distribution analysis

Example:

result = geo_stats(
    table_name="parcels",
    geometry_column="boundary",
    include_area=True,
    include_length=True,
    include_bounds=True
)
# Returns: {
#   "total_geometries": 5000,
#   "geometry_types": {
#     "POLYGON": 4850,
#     "MULTIPOLYGON": 150
#   },
#   "area_stats": {
#     "total_sqm": 5000000,
#     "avg_sqm": 1000,
#     "min_sqm": 50,
#     "max_sqm": 10000
#   },
#   "perimeter_stats": {
#     "total_m": 250000,
#     "avg_m": 50,
#     "min_m": 10,
#     "max_m": 500
#   },
#   "bounds": {
#     "min_x": -122.5,
#     "min_y": 37.7,
#     "max_x": -122.3,
#     "max_y": 37.8
#   },
#   "srid": 4326
# }

Use Cases:

  • Data inventory
  • Quality assessment
  • Area calculations
  • Spatial extent analysis

🎯 Common Workflows

Store Locator

# 1. Find stores within 10km
nearby = within_radius(
    table_name="stores",
    geometry_column="location",
    center_point="POINT(-122.4194 37.7749)",
    radius=10,
    unit="kilometers"
)

# 2. Get exact distances
distances = distance_calculate(
    table_name="stores",
    geometry_column="location",
    reference_geometry="POINT(-122.4194 37.7749)",
    unit="kilometers",
    limit=5
)

# 3. Find stores in delivery area
in_zone = spatial_search(
    table_name="stores",
    geometry_column="location",
    search_geometry="POLYGON(...)",  # Delivery zone
    operation="within"
)

Service Coverage Analysis

# 1. Validate service area geometries
validation = geometry_validate(
    table_name="service_areas",
    geometry_column="boundary",
    fix_invalid=True
)

# 2. Calculate coverage statistics
stats = geo_stats(
    table_name="service_areas",
    geometry_column="boundary",
    include_area=True
)

# 3. Find customers in service area
covered = spatial_search(
    table_name="customers",
    geometry_column="address_point",
    search_geometry="POLYGON(...)",  # Service area
    operation="within"
)

GIS Data Integration

# 1. Transform coordinates
transform = coordinate_transform(
    table_name="imported_data",
    geometry_column="geom",
    source_srid=4269,  # NAD83
    target_srid=4326,  # WGS84
    update_table=True
)

# 2. Create spatial index
index = spatial_index_create(
    table_name="imported_data",
    geometry_column="geom",
    index_type="gist"
)

# 3. Validate geometries
validate = geometry_validate(
    table_name="imported_data",
    geometry_column="geom",
    fix_invalid=True
)

🚀 Best Practices

1. Always Use Spatial Indexes

# Create index before running queries
spatial_index_create(
    table_name="locations",
    geometry_column="geom",
    index_type="gist"
)

2. Use Appropriate SRID

# WGS84 (4326) for GPS data
# Web Mercator (3857) for web maps
# UTM for accurate distance measurements

# Transform to appropriate SRID for your use case
coordinate_transform(
    table_name="data",
    geometry_column="geom",
    source_srid=4326,
    target_srid=32610  # UTM Zone 10N for California
)

3. Validate Before Processing

# Always validate imported data
geometry_validate(
    table_name="new_data",
    geometry_column="geom",
    fix_invalid=True
)

📚 Related Documentation


🔗 External Resources


See Home for more tool categories.

Clone this wiki locally