The core verbs of spatial analysis. Spatial joins, buffers, intersections, and dissolve — taught with launch-site and airspace-exclusion-zone data.
Spatial analysis is the verbs of GIS: combining geometries to answer questions. This week introduces the five operations that show up in every space-domain workflow — spatial joins, buffers, intersections, dissolve, and overlay.
A spatial join attaches attributes from one layer to another based on a spatial relationship, not a key-value match. The classic example: given launch detection points and country polygons, attach each detection's country (so you can ask "which country had the most launches this year?"). In geopandas:
import geopandas as gpd
detections = gpd.read_file('detections.geojson').to_crs(epsg=4326)
countries = gpd.read_file('countries.geojson').to_crs(epsg=4326)
joined = detections.sjoin(countries, how='left', predicate='within')
The predicate can be within, intersects, contains, touches, or crosses. Choose carefully — within is exclusive of the boundary, intersects includes it. For a launch detection on a coastal border, this matters.
A buffer expands a geometry by a distance. The catch in space GIS: distance on the Earth's curved surface is not the same as Euclidean distance in a projected plane. A 50 km planar buffer in Web Mercator at 60° latitude is actually a ~25 km buffer on the ground. Every range-safety exclusion zone is a geodesic buffer, computed on the WGS84 ellipsoid.
from shapely.geometry import Point
from shapely.ops import transform
from pyproj import Geod
geod = Geod(ellps='WGS84')
# Buffer Cape Canaveral by 50 km on the ellipsoid
lat, lon = 28.6, -80.6
exclusion = [geod.fwd(lon, lat, az, 50_000)[:2] for az in range(0, 360, 5)]
Once you have two polygons, you can ask three questions:
Dissolve merges multiple features into one based on a shared attribute. A dataset of every Falcon 9 launch detection can be dissolved by year, producing one polygon (or multi-point) per year for time-series visualization. In geopandas:
by_year = detections.dissolve(by='launch_year', aggfunc='sum')
Overlay combines two layers with all four operations at once (intersection / union / identity / symmetric difference) producing a new layer where each output polygon has attributes from both inputs. Use it sparingly — overlays explode geometry counts and can be slow on big inputs.
Every Falcon 9 launch from Cape Canaveral produces a NOTMAR (Notice to Mariners) defining a maritime exclusion zone for the launch corridor. The lab reconstructs one of these: take the predicted trajectory polyline, geodesically buffer by 50 km, intersect with global AIS shipping lanes (from MarineCadastre.gov), and output the exclusion polygon as GeoJSON. The output is directly comparable to the published NOTMAR.
This is the same logic LaunchDetect's AIS layer uses in production — minus the real-time AIS feed, which is Week 19.
Take a Falcon 9 launch from Cape Canaveral. Buffer the predicted downrange trajectory by 50 km. Intersect with shipping lanes from AIS data. Output the maritime exclusion polygon as GeoJSON.
Test yourself. Answer key on the certificate-track page (Gold-tier feature: progress tracking and auto-grading).