strait — satellite vessel detection & port activity monitoring
A Python package for detecting vessels from Sentinel-1 SAR imagery and measuring port activity from satellite data — any port, any time.
The one thing
import strait
cutout = strait.Cutout(
module="sentinel1",
x=slice(103.4, 104.6),
y=slice(1.0, 1.6),
time=slice("2021-01", "2026-09"),
)
cutout.prepare() # download + process scenes
detections = cutout.detect() # CFAR vessel detection
monthly = cutout.aggregate(detections, zones={"eastern": (104.0, 1.24, 104.35, 1.40)})
That gives you monthly vessel counts per zone from free satellite radar.
Why this exists
Ports publish trade statistics with a 2-4 week lag. Satellite radar sees ships at anchor immediately, day or night, cloud or clear. This package turns that satellite data into economic indicators.
It was built for the Singapore Strait Observatory project, where radar-derived anchorage presence explains 48% of bunker sales variance (R²=0.478, detrended, weather-robust, validated against AIS).
Install
pip install strait-observatory
What it does
| Layer | What | Output |
|---|---|---|
Cutout |
Spatial/temporal subset + data source abstraction | xarray Dataset |
detect() |
Vessel detection (trimmed CFAR) | GeoDataFrame of detections |
aggregate() |
Zone × time aggregation | Monthly/weekly/daily counts |
AIS |
Validation against live/historical AIS | Precision/recall metrics |
Stats |
Join with official trade statistics | Correlation results |
Data sources
| Source | What | Auth |
|---|---|---|
| Copernicus Sentinel-1 | SAR radar imagery | Free CDSE account |
| AISStream.io | Live vessel AIS | Free API key |
| AISHub.net | Community AIS | Free membership |
| Mendeley (historical) | Port AIS datasets | Open download |
| S2Coast-2023 | 10m coastline (land mask) | Zenodo, open |
Quick start
pip install strait-observatory
export CDSE_USER=your@email
export CDSE_PASSWORD=your_password
import strait
# 1. Define your area and time
cutout = strait.Cutout(
module="sentinel1",
x=slice(103.4, 104.6), # longitude
y=slice(1.0, 1.6), # latitude
time=slice("2021-01", "2026-09"),
)
# 2. Download and process (first time takes ~1h for 5 years)
cutout.prepare()
# 3. Detect vessels
detections = cutout.detect(method="trimmed_cfar")
# 4. Define anchorage zones (or use built-in Singapore zones)
zones = strait.Zones.singapore_strait()
monthly = cutout.aggregate(detections, zones, freq="MS")
# 5. Validate against AIS (optional; pass any list of {lat, lon} dicts,
# e.g. a live AISStream.io snapshot — see experiments/ais_capture.py)
from strait import AISMatch
match = AISMatch(threshold_m=500).load("ais_snapshot.json").match(detections)
# Correlation with official statistics is not part of the package yet;
# see experiments/econ_join.py in the observatory repo for the join.
Architecture (inspired by atlite)
strait/
├── __init__.py # exports Cutout, Zones, AISMatch, detect, aggregate
├── cutout.py # Cutout class (spatial/temporal abstraction)
├── detect/
│ └── __init__.py # detect() dispatcher + presets + trimmed CFAR
├── data/
│ ├── __init__.py # data source registry
│ └── sentinel1.py # local scene cache (CDSE download: not bundled yet)
├── aggregate.py # zone × time aggregation
├── validate.py # SAR-AIS matching (KD-tree, precision/recall)
└── zones.py # built-in zone definitions
Built-in zones
# Singapore Strait (from the observatory project)
zones = strait.Zones.singapore_strait()
# Define your own
zones = strait.Zones.custom({
"my_anchorage": (104.0, 1.24, 104.35, 1.40), # lon_min, lat_min, lon_max, lat_max
"port_area": (103.68, 1.20, 104.02, 1.34),
})
License
MIT
Citation
If you use this in research, cite the Singapore Strait Observatory:
@software{strait_observatory_2026,
title = {strait: satellite vessel detection and port activity monitoring},
author = {Sivasubramanian, S.},
year = {2026},
url = {https://github.com/siva-sub/strait}
}
Documentation
Full documentation with use cases, API reference, data sources, interpretation guide, and economic context:
| Page | What it covers |
|---|---|
| Getting Started | Install, first run, building a local cache |
| Data Sources | Where to get Sentinel-1, AIS, land masks, official statistics |
| API Reference | Every class, function, and parameter |
| Use Cases | Port monitoring, congestion, dark vessels, bunkering, research |
| Interpreting Results | How to read detections, correlations, and what they mean |
| Economic Relevance | The Singapore case study and why this matters |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file strait_observatory-0.2.1.tar.gz.
File metadata
- Download URL: strait_observatory-0.2.1.tar.gz
- Upload date:
- Size: 20.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c4627a1e59b88a52a18b4962b5a9c8e9756fd78ebd5fc407e2d8ca35afceb9b
|
|
| MD5 |
1192eda32a2e39fc97fee852761a5134
|
|
| BLAKE2b-256 |
3b0f104c33aca24452e9767d7d4c99f73e917d7e26cc424c6702cbc00e32ed59
|
File details
Details for the file strait_observatory-0.2.1-py3-none-any.whl.
File metadata
- Download URL: strait_observatory-0.2.1-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b7299c0c9564f30ca479cdbfbc799a3b31e027cfcc349e745ec6a913ca6230e
|
|
| MD5 |
e72f0931738f97bee9da258cdba7e3ed
|
|
| BLAKE2b-256 |
0f3511aa5b0442282190a6f4784bf7e65e05bf1c85f680eaa24bddd2f0949300
|