Skip to content
latentSource

What a Moving Dot Can Hide: Building an Oil-Spill Data Explorer

I combined vessel records, satellite layers, and a timeline in a geospatial app. Then I checked which parts of the animation were observations and which were interpolation.

··3 min read
Share

Explore the project

Saved data and examples you can inspect. This demonstration runs in your browser.

A moving dot looks convincing. Put it over a satellite image, draw a pipeline nearby, and it becomes very easy to tell a story that the data has not established.

I built a geospatial application to explore the Gulf oil-spill material collected in this project. It brings vessel records, satellite layers, infrastructure, and a timeline into one interface. The engineering problem I want to show here is how those sources become something a reader can inspect, including the gaps.

The repository contains the processing scripts and saved vessel data. The explorer above deliberately steps through saved points. It does not animate an invented position between them.

Build the pipeline before the story

The application uses React and MapLibre for the map. An Express proxy keeps external API credentials on the server. Saved Global Fishing Watch extracts supply vessel records, while the map can request Cerulean detections and satellite imagery through separate integrations.

The data-processing scripts turn heterogeneous event responses into per-vessel timelines. Loitering events, port visits, and other records do not have identical shapes. The processing step normalizes timestamps and coordinates before the frontend sorts and draws them.

This separation makes it possible to inspect a saved extraction without spending API calls or depending on a provider being available when someone opens the article.

Measure the holes

The saved arbol-grande.json file has 108 position records. Sorting their timestamps gives a range from January 31 to March 29, 2026. The largest interval between adjacent records is about 164.9 hours.

Those numbers are reproducible from the downloadable sample and summary. They describe this file. They do not establish complete AIS coverage, continuous anchoring, or a vessel's position throughout the interval.

The application's animation interpolates between sparse points. That helps someone follow a timeline, but a smooth transition must not acquire the authority of an observation. In this article's explorer I show one saved position at a time, with its timestamp. A reader can inspect the gap instead of watching it disappear into an animation.

What the layers can support

A radar detection is a candidate feature to investigate. SkyTruth documents lookalikes and false positives in Cerulean, so I do not treat every polygon as a confirmed oil spill. Cerulean guide

Likewise, Global Fishing Watch describes activity events as algorithmic interpretations of received AIS data. A missing interval alone does not establish deliberate transmitter disabling. GFW data caveats

Spatial coincidence is useful for deciding what to examine next. It does not assign responsibility. Connecting a vessel, a pipeline, and a detection requires independently checked locations and times, uncertainty estimates, and corroborating evidence.

The repository's narrative files use different dates for some events. This report does not resolve that disagreement by selecting the most convenient date. Its quantitative findings are limited to the timestamped extraction supplied with the project. Claims about spill extent, coastal impact, and cause need their own verified evidence before they belong in a results table.

A report someone can reproduce

The companion report includes the source revision, file hashes, timestamp range, record count, largest gap, and the calculation used. The sample contains saved records rather than refreshed API output, so someone inspecting it later can work with the same input.

For an engineering review, the useful questions are concrete. Which transformation changed this coordinate? Is this timestamp an observation or an event boundary? Which layer depends on a live service? Can the visual distinguish missing data from an absence of activity?

I want the interface to make those questions easier to answer. A polished animation earns its place when the reader can also inspect what it leaves out.