Design & media

Geo Tag Photos

Try it

Recover lost GPS metadata for JPG photos by recognizing landmarks via vision and writing GPS coordinates back into EXIF. Default dry-run; explicit --write wi...

What it does

Recover GPS metadata for JPG photos. The model identifies landmarks visually, the script geocodes those landmarks via Nominatim (OpenStreetMap) and writes the coordinates back into EXIF.

The skill document

geo-tag-photos

Recover GPS metadata for JPG photos. The model identifies landmarks visually, the script geocodes those landmarks via Nominatim (OpenStreetMap) and writes the coordinates back into EXIF.

Use only on your own photos

This skill infers location from visual content. Do not use it to track other people, surveil private individuals, or de-anonymize photos that were intentionally stripped of location data. Inferred coordinates are best-guess estimates and must not be used for legal, forensic, evidentiary, or law-enforcement purposes.

What it can and cannot do

CanCannot
Identify global public landmarks (Eiffel, Opera House, Taj Mahal …)Identify ordinary streets, residences, interiors, plain portraits, generic nature
Reach city- / landmark-level precisionProvide street- or building-level precision
Process JPG / JPEGProcess HEIC / PNG / TIFF / RAW (convert first)
Write GPS + ImageDescription + UserCommentModify any other EXIF field
Handle a few hundred photos at a timeReliably batch thousands (rate limits + cache hit-rate degrade)

Setup

cd 
pip install -r requirements.txt

The script will refuse to run if any of piexif, Pillow, requests is missing.

Workflow (5 phases)

You must walk the user through these phases in order. Each phase has a clear output the user can inspect.

Phase 1: scan

Identify which photos already have GPS (skip them) and which need inference.

python scripts/photo_geolocator.py scan --dir  --out exif_status.csv

Read the CSV: any row with note=NO_GPS is a candidate for inference. Anything with note=NOT_JPG must be skipped (or converted by the user first).

Phase 2: AI vision (you do this directly)

For every JPG with NO_GPS, use the Read tool to view the image and extract:

  • landmark — the landmark name (e.g. "Eiffel Tower"). If no recognizable landmark, leave empty.
  • city — best-guess city, or empty.
  • country — best-guess country, or empty.
  • confidence — high / medium / low. Be honest. low rows will be skipped on write by default.
  • evidence — short text: visual cues you used (architecture style, signage language, flags, geography).

Aggregate into a JSON file ai_results.json:

[
  {"filename": "p1.jpg", "landmark": "Eiffel Tower", "city": "Paris",
   "country": "France", "confidence": "high", "evidence": "Iron lattice tower visible"},
  {"filename": "p2.jpg", "landmark": "", "city": "", "country": "",
   "confidence": "low", "evidence": "interior, no landmarks"}
]

Photos with no recognizable landmark: set confidence: low and empty strings. The pipeline will skip them on write.

Phase 3: geocode

python scripts/photo_geolocator.py geocode --input ai_results.json --out geocoded.csv

This calls Nominatim (rate-limited to 1 req / 1.1 s) and caches results locally. Failures are recorded in the CSV — they do not stop the run.

Phase 4: report

python scripts/photo_geolocator.py report \
  --dir  --geocoded geocoded.csv --out report.csv

The report shows every photo and what action will be taken: WRITE, SKIP_HAS_GPS, SKIP_NOT_JPG, SKIP_LOW_CONFIDENCE, SKIP_NO_GEOCODE, SKIP_AI_UNKNOWN.

Show the report path to the user. Tell them to review it. Wait for explicit confirmation before phase 5.

Phase 5: write (only after user confirms)

First, dry-run to print the planned changes (no files modified):

python scripts/photo_geolocator.py write --dir  --csv report.csv

Then, after user confirmation, the real write:

python scripts/photo_geolocator.py write --dir  --csv report.csv \
  --write --backup-dir .bak

--backup-dir is mandatory and the script refuses if it's non-empty or inside the source directory. Maximum 500 photos per invocation.

After writing, run scan again and compare to the report. The script also verifies internally and reports any roundtrip mismatches.

Hard limits enforced by the script

  • JPG-only — non-JPG files are listed in scan but never written
  • --write without --backup-dir → exit code 2
  • Backup dir must be empty or non-existent → exit code 2
  • Backup dir cannot be inside source dir → exit code 2
  • Maximum 500 photos per write invocation → exit code 2
  • confidence: low rows skipped unless --include-low
  • Photos that already have GPS skipped unless --overwrite-existing (with warning)

Privacy

The script sends only text (landmark, city, country) to Nominatim. Photos never leave your machine via the script. The AI vision step happens inside your Claude session; whether the photos leave the machine for that step is governed by your Claude setup, not by this skill.

Troubleshooting

  • Geocoding returns wrong coordinates. Nominatim is fuzzy with ambiguous names (e.g. "Springfield"). Refine the AI step: include city + country with the landmark.
  • Cache holds bad entries. python scripts/photo_geolocator.py cache --clear
  • exif_io.EXIFError: not a JPG. Convert your HEIC / PNG / TIFF / RAW to JPG first (e.g. magick mogrify -format jpg *.heic).
  • Many photos report SKIP_AI_UNKNOWN. Phase 2 didn't emit entries for every photo — re-run vision for the missing ones.

Related skills

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván559 installs18 stars

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai22 installs8 stars

Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.

by fly0pants4.3k installs296 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

More from ucsdzehualiu

Browse all skills

云产品技术文档对比工具,自动抓取阿里云、华为云、AWS、腾讯云官方文档,生成结构化对比资料,辅助技术选型和学习

by ucsdzehualiu24 installs1 stars

基于 Bing 国内版 / DuckDuckGo 的联网搜索工具,中文环境优化,可按需抓取目标网页正文,返回结构化结果。仅在用户明确请求联网搜索时调用。

by ucsdzehualiu124 installs1 stars

Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For...

by ucsdzehualiu20 installs

Iterative prompt optimizer for complex tasks. Strictly implements ACON's two-stage iterative optimization + APE automatic prompt engineering. Only triggers w...

by ucsdzehualiu18 installs

股票、ETF、指数、大宗商品市场分析工具,整合实时行情、技术指标、市场情绪和财经新闻。适用于美股综合分析、止盈止损建议、估值判断场景。Stock/ETF/index/commodity market analysis, sentiment, technical indicators.

by ucsdzehualiu19 installs

实用提示词优化工具 - 检测原提示词缺失要素(角色/步骤/格式/约束),智能补全后输出清晰易懂的优化版,帮助用户的意图更容易被 AI 理解执行。Use when user says 优化提示词 / 改进prompt / 优化一下 / optimize prompt.

by ucsdzehualiu19 installs