Summary
Add a new module (pg-geotag) that automatically sets GPS coordinates on photos by matching image timestamps against a GPX or KML track file. This enables photographers to geotag photos from cameras without built-in GPS by syncing with a GPS track recorded on a phone or dedicated GPS device.
Use Cases
- Geotagging photos from a professional camera using a GPS track from a smartphone
- Adding location data to action camera footage synced with a Garmin/Wahoo device
- Batch geotagging archived photos from a recorded route
Proposed Implementation
1. CLI Script: bin/pg-geotag
pg-geotag <files...> --track <gpx/kml file> [options]
Arguments:
<files...> - One or more files or directories to process
Options:
-t, --track <file> - GPX or KML track file (required)
--tolerance <seconds> - Maximum time offset for matching (default: 30)
--offset <seconds> - Manual time correction (camera vs GPS clock drift)
--interpolate - Interpolate position between track points (default: on)
--no-overwrite - Skip photos that already have GPS data
-n, --dry-run - Show what would be done without changes
-v, --verbose - Show detailed output
Examples:
# Geotag photos from a hike using a GPX from a phone
pg-geotag ./photos --track route.gpx
# Geotag with larger tolerance and camera offset correction
pg-geotag ./photos --track track.gpx --tolerance 60 --offset -15
# Preview without making changes
pg-geotag ./photos --track route.kml --dry-run
2. Web Module: web/modules/geotag/
module.yaml:
id: geotag
name: Geotag from Track
description: Set GPS coordinates from GPX/KML track file
icon: map-pin
order: 3
parameters:
- id: directory
type: positional
label: Directory
placeholder: ~/Pictures/PhotoLibrary/2026-01-24
required: true
inherit_from: target_directory
help: "Auto-filled from previous import step if available."
- id: track_file
type: path
label: Track File (GPX/KML)
placeholder: ~/Downloads/route.gpx
required: true
cli_flag: --track
- id: tolerance
type: number
label: Time Tolerance (seconds)
default: 30
cli_flag: --tolerance
help: "Maximum time difference between photo and track point."
- id: offset
type: number
label: Time Offset (seconds)
default: 0
cli_flag: --offset
help: "Correct camera/GPS clock difference. Positive = camera ahead."
- id: interpolate
type: boolean
label: Interpolate positions
default: true
cli_flag: --interpolate
- id: skip_existing
type: boolean
label: Skip photos with GPS
default: true
cli_flag: --no-overwrite
outputs:
- id: geotagged_count
type: number
description: Number of photos geotagged
- id: skipped_count
type: number
description: Number of photos skipped (no match or already tagged)
3. Python Library: lib/gpx_utils.py
New utility for parsing GPS track files:
class GPXParser:
"""Parse GPX/KML files and match timestamps to coordinates."""
def parse(self, filepath: Path) -> list[TrackPoint]
def find_position(self, timestamp: datetime, tolerance: int = 30) -> Optional[Coordinates]
def interpolate(self, timestamp: datetime, before: TrackPoint, after: TrackPoint) -> Coordinates
Technical Details
Track File Parsing:
- GPX: Parse
<trkpt> elements with lat, lon, and <time> attributes
- KML: Parse
<gx:Track> or <gx:coord> elements with associated timestamps
- Use Python's
xml.etree.ElementTree (no external dependencies)
Time Matching Algorithm:
- Read image timestamp from EXIF (
DateTimeOriginal)
- Apply manual offset correction if specified
- Find track points within tolerance window
- If
interpolate=true and two points bracket the timestamp, calculate linear interpolation
- If no match within tolerance, skip the image
GPS Coordinate Writing:
- Reuse existing
ExifTool.write() with gps parameter
- Write standard GPS EXIF tags:
GPSLatitude, GPSLongitude, GPSLatitudeRef, GPSLongitudeRef
Acceptance Criteria
Dependencies
exiftool (existing requirement)
- Python 3.9+ (existing requirement)
- No new external dependencies (use stdlib
xml.etree.ElementTree)
Related
- Extends existing
pg-exif functionality
- Integrates with workflow planner as new step type
Summary
Add a new module (
pg-geotag) that automatically sets GPS coordinates on photos by matching image timestamps against a GPX or KML track file. This enables photographers to geotag photos from cameras without built-in GPS by syncing with a GPS track recorded on a phone or dedicated GPS device.Use Cases
Proposed Implementation
1. CLI Script:
bin/pg-geotagArguments:
<files...>- One or more files or directories to processOptions:
-t, --track <file>- GPX or KML track file (required)--tolerance <seconds>- Maximum time offset for matching (default: 30)--offset <seconds>- Manual time correction (camera vs GPS clock drift)--interpolate- Interpolate position between track points (default: on)--no-overwrite- Skip photos that already have GPS data-n, --dry-run- Show what would be done without changes-v, --verbose- Show detailed outputExamples:
2. Web Module:
web/modules/geotag/module.yaml:
3. Python Library:
lib/gpx_utils.pyNew utility for parsing GPS track files:
Technical Details
Track File Parsing:
<trkpt>elements withlat,lon, and<time>attributes<gx:Track>or<gx:coord>elements with associated timestampsxml.etree.ElementTree(no external dependencies)Time Matching Algorithm:
DateTimeOriginal)interpolate=trueand two points bracket the timestamp, calculate linear interpolationGPS Coordinate Writing:
ExifTool.write()withgpsparameterGPSLatitude,GPSLongitude,GPSLatitudeRef,GPSLongitudeRefAcceptance Criteria
pg-geotagscript works with GPX filespg-geotagscript works with KML filesDependencies
exiftool(existing requirement)xml.etree.ElementTree)Related
pg-exiffunctionality