A GPS coordinate is not intelligence. Neither is a polygon, a raster pixel, or a trajectory record. These are data — measurements of the physical world, precisely captured and faithfully stored. The gap between data and intelligence is the work of analysis: applying the right questions, the right methods, and the right interpretation to turn observations into understanding.

This article examines the analytical techniques that transform spatial data into actionable intelligence. It is practical — grounded in real methods, real tools, and real applications — but also conceptual, because understanding why a technique works is as important as knowing how to apply it.

# Spatial Clustering: Finding the Patterns You Did Not Know to Look For

Spatial clustering is among the most powerful and most frequently misapplied techniques in spatial analytics. At its core, it is the identification of locations where events or features are more concentrated than would be expected by chance. The application is finding patterns: crime hotspots, disease clusters, customer concentrations, accident blackspots.

# Kernel Density Estimation

Kernel Density Estimation (KDE) is the simplest and most intuitive approach. It places a smooth kernel function (typically Gaussian) over each point and sums the contributions across the study area to produce a continuous density surface. The result is a heatmap: high values where points are concentrated, low values where they are sparse.

KDE is excellent for visual exploration and for communicating spatial concentration to non-technical audiences. Its limitation is that it is purely descriptive — it tells you where events are concentrated but not whether that concentration is statistically significant.

from scipy.stats import gaussian_kde
import numpy as np
import geopandas as gpd

# Load point data
incidents = gpd.read_file('incidents.shp')
coords = np.vstack([incidents.geometry.x, incidents.geometry.y])

# Estimate density
kde = gaussian_kde(coords, bw_method='scott')

# Evaluate on a grid
grid_x, grid_y = np.meshgrid(
    np.linspace(incidents.total_bounds[0], incidents.total_bounds[2], 200),
    np.linspace(incidents.total_bounds[1], incidents.total_bounds[3], 200)
)
density = kde(np.vstack([grid_x.ravel(), grid_y.ravel()])).reshape(grid_x.shape)

# DBSCAN for Cluster Detection

DBSCAN (Density-Based Spatial Clustering of Applications with Noise) identifies clusters without requiring you to specify the number of clusters in advance. It finds regions where points exceed a minimum density threshold and labels all other points as noise. This makes it well suited to real-world spatial data, which rarely has the clean cluster structure that algorithms like K-means assume.

from sklearn.cluster import DBSCAN
import numpy as np

# DBSCAN on geographic coordinates
# epsilon in radians if using haversine metric
coords = np.radians(incidents[['geometry_y', 'geometry_x']].values)
db = DBSCAN(eps=0.5/6371, min_samples=5, algorithm='ball_tree', metric='haversine')
cluster_labels = db.fit_predict(coords)
incidents['cluster'] = cluster_labels
# -1 indicates noise (not in any cluster)

# Getis-Ord Gi*: Statistical Hotspots

The Getis-Ord Gi* statistic identifies statistically significant spatial clusters of high or low values. Unlike KDE or DBSCAN, it tests whether the clustering of high values is more extreme than you would expect if high and low values were randomly distributed across the study area. The output is a Z-score for each location: high positive values indicate hotspots (clusters of high values), high negative values indicate coldspots.

This is the technique behind most crime hotspot mapping done by law enforcement, and it is more defensible than simpler methods because it accounts for the baseline distribution of the underlying population.

# Movement Analysis: Intelligence from Trajectories

Movement data — GPS traces, ship tracks, vehicle telemetry, mobile phone location records — contains intelligence that static snapshot data cannot provide. Where things go, how fast they move, what routes they take, and when they deviate from expected patterns are all questions that can only be answered from trajectory data.

# Stop Detection

A fundamental operation on trajectory data is identifying where a moving object stopped. Stops are often the meaningful events in a trajectory: the customer visiting a store, the vehicle completing a delivery, the ship entering a port. Stop detection algorithms identify periods when the object’s movement falls below a threshold speed for a minimum duration.

import pandas as pd
from shapely.geometry import Point

def detect_stops(gdf, speed_threshold_kmh=2, min_duration_minutes=5):
    """
    Identify stops in a GPS trajectory.
    gdf must have columns: timestamp, geometry, speed_kmh
    """
    gdf = gdf.sort_values('timestamp')
    stops = []
    in_stop = False
    stop_start = None
    stop_points = []

    for _, row in gdf.iterrows():
        if row['speed_kmh'] < speed_threshold_kmh:
            if not in_stop:
                in_stop = True
                stop_start = row['timestamp']
                stop_points = [row['geometry']]
            else:
                stop_points.append(row['geometry'])
        else:
            if in_stop:
                duration = (row['timestamp'] - stop_start).total_seconds() / 60
                if duration >= min_duration_minutes:
                    # Compute centroid of stop cluster
                    from shapely.geometry import MultiPoint
                    centroid = MultiPoint(stop_points).centroid
                    stops.append({
                        'start': stop_start,
                        'end': row['timestamp'],
                        'duration_min': duration,
                        'location': centroid
                    })
                in_stop = False
                stop_points = []

    return pd.DataFrame(stops)

# Origin-Destination Analysis

Origin-destination (OD) matrices describe the flow of movement between locations. An OD matrix for a city might record how many people travel from each neighbourhood to each other neighbourhood on a typical working day. These matrices are fundamental inputs to transport planning, retail catchment analysis, and logistics optimisation.

Building OD matrices from GPS data requires spatial discretisation: assigning each GPS point to a zone (a postcode, a grid cell, an administrative area) and counting the transitions between zones. The result is a table of origin zone, destination zone, and flow count, which can be visualised as desire lines, flow maps, or chord diagrams.

# Anomaly Detection in Movement Patterns

One of the most valuable applications of movement intelligence is detecting deviations from expected behaviour. A vessel that goes dark (stops transmitting AIS signals) in open water, a vehicle that takes an unusual route, a person whose movement patterns change significantly — these deviations can indicate everything from equipment failure to deliberate evasion.

Anomaly detection on trajectories typically involves:

  1. Building a model of “normal” behaviour for each entity or entity class
  2. Scoring new trajectories against the normal model
  3. Flagging trajectories whose score falls below a threshold

The model can be as simple as a set of historical statistics (average speed, typical routes, usual stop locations) or as complex as a learned neural network representation of trajectory sequences. The right choice depends on the anomaly types you are trying to detect and the volume of data available for training.

# Spatial Joins: Context Enrichment at Scale

A spatial join combines datasets based on their spatial relationship — containment, intersection, proximity — rather than a shared key. It is one of the most commonly needed operations in spatial analytics and one of the most powerful ways to enrich non-spatial data with context.

# Point-in-Polygon Joins

The simplest spatial join: for each point in one dataset, find which polygon in another dataset contains it. This operation underlies many enrichment workflows: assigning transactions to catchment zones, assigning sensor readings to administrative areas, classifying events by land use type.

PostGIS makes this efficient:

-- Assign each incident to its local authority district
UPDATE incidents i
SET local_authority = la.name
FROM local_authority_districts la
WHERE ST_Contains(la.geometry, i.location);

# Buffer Analysis

Buffer analysis creates a zone of influence around a feature and then identifies other features within that zone. Applications include infrastructure planning (what buildings are within 100 metres of a proposed development?), environmental assessment (which sensitive receptors are within 500 metres of a pollution source?), and retail analysis (what is the catchment population within a 20-minute drive of this location?).

The distinction between Euclidean buffers (simple distance) and network buffers (distance along a road network) is significant and often misunderstood. A 2km Euclidean buffer around a point is a circle. A 2km network buffer is an irregular shape that follows the road network — and it is much more representative of real accessibility. Network analysis requires tools beyond basic PostGIS, typically pgRouting or a cloud routing service.

# Predictive Spatial Analytics

Moving from descriptive analytics (what happened, where?) to predictive analytics (what will happen, where?) requires models that incorporate spatial relationships.

# Spatial Regression

Ordinary least squares regression assumes that residuals are independent. In spatial data, this assumption is almost always violated: if a model’s prediction is wrong in one location, it is typically also wrong in nearby locations (spatial autocorrelation). Ignoring spatial autocorrelation produces biased parameter estimates and overconfident standard errors.

Spatial regression models — spatial lag models, spatial error models, geographically weighted regression (GWR) — explicitly account for spatial dependence. GWR is particularly useful because it allows model parameters to vary across space, revealing how relationships between variables differ geographically.

# Geospatial Machine Learning

Machine learning methods can be applied to spatial prediction tasks, but with important caveats. Standard cross-validation assumes that training and test observations are independent; spatial cross-validation (spatial blocking) is necessary when nearby observations are correlated, to avoid overestimating model performance.

Random forests with spatial features (coordinates, distance to significant features, spatial lag of the target variable) have been shown to perform well on many spatial prediction tasks — predicting property values, estimating crop yields, modelling species distributions.

The emerging field of spatial foundation models — large neural networks pre-trained on satellite imagery and other spatial data — is beginning to produce powerful capabilities for tasks like land cover classification, change detection, and infrastructure detection that previously required large labelled training datasets for each specific application.

# Making Intelligence Actionable

Spatial analysis produces its value when it changes decisions. This requires more than technical correctness — it requires communication that connects the analysis to the decision context.

Effective spatial intelligence communication focuses on uncertainty: a hotspot map without confidence intervals is misleading. It uses appropriate visual encodings: not every spatial pattern is best communicated on a map. It is honest about what the analysis can and cannot establish: spatial correlation is not causation.

The organisations that are most effective at turning location data into intelligence are those that have invested in the complete pipeline: from data acquisition and quality management, through rigorous analysis, to clear communication that reaches the people whose decisions the analysis should inform.


Related reading: Understanding Spatial Data Intelligence: A Modern Framework · The Future of Geointelligence: AI and Spatial Analytics · Low-Cost, High-Flexibility Spatial Architecture Patterns