A Python script that uses the Global Fishing Watch API to retrieve AIS event locations for a vessel and then uses Google Earth Engine to download matching Sentinel‑2 satellite imagery. It generates geospatial metadata files for each image and applies basic enhancements like upscaling, sharpening, and gamma correction. The output is a set of georeferenced, processed satellite images aligned to vessel activity.
Methodology Summary (First‑Person)
1. Importing Libraries and Setting Up Parameters
I started by importing all the geospatial, image‑processing, and API libraries I needed, including Earth Engine, geemap, pandas, cartopy, PIL, cv2, and others. Then I defined my working parameters: the vessel name, MMSI, date range, and a base directory for storing outputs.
The notebook includes values such as:
vessel_mmsi = '310627000'max_downloads = 20000
This gave me a clean, reproducible setup.
2. Authenticating and Querying the Global Fishing Watch API
I loaded my GFW API access token from an environment file and created the client. I wrote an async function to resolve the MMSI into GFW vessel IDs. The API returned:
“Matched: aa07f2db7‑7996‑d07b‑0940‑9bc1947f130e | QUEEN MARY 2”
With the vessel IDs, I fetched all port‑visit, encounter, and loitering events within my date range. I flattened the geometry into simple lat and lon columns and produced a clean DataFrame of AIS events.
3. Preparing Earth Engine and Downloading Sentinel‑2 Imagery
After converting the date strings into datetime.date objects, I authenticated Earth Engine. For each AIS event, I created a buffered bounding box around its coordinates.
I queried the COPERNICUS/S2_SR_HARMONIZED collection, filtered by date and cloud cover, selected RGB bands, and downloaded all matching images as JPEGs.
Example log entry:
“Row 2: downloading image 1/2 → row2_20260119T160201…jpg”
4. Generating Geospatial Sidecar Files
For each downloaded JPEG, I generated:
- a
.jgwworld file - a
.prjprojection file (EPSG:4326) - a
.geojsonmetadata file containing bounding box, acquisition date, cloud percentage, and AIS event metadata
This ensured every image remained geospatially referenced.
5. Image Upscaling
I upscaled each JPEG by 4× using Lanczos resampling. After resizing, I recalculated the world‑file pixel size to maintain correct geospatial alignment.
Example log:
“Upscaled row10… to (840, 896)”
6. Image Sharpening (Unsharp Mask)
I applied an unsharp mask with:
- radius 2
- percent 150
- threshold 3
Sidecar files were copied unchanged.
Example log:
“Sharpened row39_20260705T155129…jpg”
7. Gamma Correction
I applied gamma correction (γ = 0.8) to brighten midtones. Geospatial metadata remained untouched.
Example log:
“Gamma corrected row41… (gamma=0.8)”
8. Additional Enhancements (Exploratory)
I experimented with vibrance, saturation, contrast, and white balance adjustments, but decided they didn’t meaningfully improve the imagery.
9. Final Output Structure
By the end of the workflow, I had a complete, geospatially accurate dataset of Sentinel‑2 imagery aligned to AIS vessel events, organised into:
- raw downloads
- upscaled images
- sharpened images
- gamma‑corrected images
- full geospatial metadata for each file
This workflow provides a reproducible pipeline for linking AIS events to satellite imagery and enhancing the results for analysis or visualisation.