Geolocalisation
ASecurityMap, geolocate, or produce a study-location map for a literature-review corpus from a BibTeX file: turn a .bib into study_locations.csv, a KML/GeoJSON/world-map figure, or answer a question about a corpus's geographic coverage, spatial distribution, or country breakdown. Trigger on: /geolocalisation, 'map the corpus', 'geolocate the studies', 'bib to map'. Also triggers on 'carte des études' and 'où ont eu lieu les études'. Extracts each paper's study / case-study location automatically (per-...
- 9 stars
- 0 votes
- 0 copies
- 0 views
- Added October 9, 2026
Works with
Security analysis
96/100- Installs packages at runtime which could introduce malicious dependencies
Pro scans all 6 files and shows the line behind each finding
npx -y skills add LARi-UQAC/ResearchTools --skill geolocalisation --agent claude-codeAre you the author of Geolocalisation?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/lari-uqac-geolocalisation-researchtools)---
name: geolocalisation
description: "Map, geolocate, or produce a study-location map for a literature-review corpus from a BibTeX file: turn a .bib into study_locations.csv, a KML/GeoJSON/world-map figure, or answer a question about a corpus's geographic coverage, spatial distribution, or country breakdown. Trigger on: /geolocalisation, 'map the corpus', 'geolocate the studies', 'bib to map'. Also triggers on 'carte des études' and 'où ont eu lieu les études'. Extracts each paper's study / case-study location automatically (per-DOI Scopus abstract + title + keywords, matched against an offline Natural Earth gazetteer), writes a reviewable draft table with a confidence column, lets a human curate or override it, then renders the corpus as CSV, KML (Google My Maps), GeoJSON (QGIS/Leaflet), a static world map PNG for the review figure, an interactive HTML map, and a per-country count table."
allowed-tools: [Read, Write, Edit, Bash]
permissions: [read]
---
# Geolocalisation — map a review corpus in space
Turn a corpus `.bib` into a set of geographic artifacts that show **where the studies of a
literature review were conducted**. The skill automates the extraction that used to be done by
hand, but keeps a human in the loop because a study's location is inferred from text and is never
certain. The extraction method, the confidence rubric, the override-file format, and the honest
limits are in [references/geocoding-protocol.md](references/geocoding-protocol.md) — read it before
running, it is the contract for what the numbers mean.
## What it produces
From one `.bib` (and its per-entry `THEME:` comments, if present), it produces up to six artifacts:
| File | Role |
|---|---|
| `study_locations.csv` | source table: `citekey, etude, ville, pays, lat, lon, theme, confidence, source, matched, evidence_field, evidence, provenance` |
| `provenance/<citekey>.md` | one audit note per located paper: resolved location, which field it was read from (title/abstract/keywords/full-text), the matched term, and the **verbatim snippet** copy-pasted from the article |
| `study_locations.kml` | same points, importable in Google My Maps (My Maps -> Create -> Import); evidence in the description |
| `study_locations.geojson` | open standard, loads in QGIS / Leaflet / any web map; evidence in the properties |
| `study_locations_map.png` | world map (Natural Earth basemap + points, per-country heatmap) for the review figure |
| `study_locations_map.html` | interactive zoomable map; each point's popup shows the evidence snippet + provenance file so the map itself is auditable. Needs `folium`; skipped with a logged note if absent |
| `country_counts.csv` | studies per country, feeds the heatmap and gives a citable table |
Every plotted point is traceable: the CSV carries `evidence_field` (where the location
was read) and `evidence` (the exact source sentence), `provenance/<citekey>.md` holds the
full audit note, and the HTML popup surfaces both so a reviewer can verify a point without
leaving the map.
## The critical caveat — read this first
A study's **case-study location is not a bibliographic field**. No API (Scopus included) returns
it. It lives in the paper's text. This skill infers it from the Scopus **abstract + title +
author/index keywords** by matching place names against an offline gazetteer. That inference is
heuristic:
- It misses studies whose abstract never names the site (global/methodological papers, benchmarks).
- It mislabels when the abstract names a place that is **not** the study site (an author's country,
a compared method's origin, a dataset's provenance). Author affiliation is **not** the study site.
Therefore the skill never emits a "final" map in one shot. It emits a **draft with a confidence
column**, the user reviews it, and a **manual override always wins** before rendering. Present the
draft honestly: say how many points are `high` vs `low` vs `none`, and that low/none rows need a
human eye. Do not silently promote a `low` guess to a plotted point without flagging it.
## Inputs
- **Required:** a corpus `.bib` path. Every entry needs a `doi` for the auto path to work; entries
without a DOI are carried through with an empty location for the user to fill.
- **Optional:** an override CSV (`--override`) whose rows replace or add points by `citekey`. This
is where curated / hand-checked locations live. Same columns as the output table; only
`citekey, ville, pays, lat, lon` are needed (theme is read from the bib if omitted).
- **Environment:** `SCOPUS_API_KEY` (or `.claude/skills/scopus/.scopus_key`) plus campus network or
UQAC VPN for the auto extraction. Without it, run in `--no-scopus` mode: the skill parses the bib
and produces an empty-location template for full manual entry.
## Workflow
Follow these steps in order. Steps 1 and 3 are scripts; step 2 is the human checkpoint that makes
the output trustworthy.
### Step 1 — Extract a draft table
```bash
python .claude/skills/geolocalisation/scripts/extract_locations.py \
--bib <corpus.bib> --out <dir> [--override <curated.csv>] [--full-text] \
[--email you@inst.edu] [--no-scopus] [--insttoken TOKEN]
```
This parses the bib (citekey, first-author label, theme), queries Scopus once per DOI (cached under
`<dir>/.scopus_cache/`), matches place names, writes `<dir>/study_locations.csv` with `confidence`,
`evidence_field`, and `evidence` columns, and drops one `provenance/<citekey>.md` audit note per
located paper. It prints a summary: N high / M medium / K low / U none.
**`--full-text`** raises recall for the studies whose abstract never names the site (the common
case for a case-study city stated only in the body). For every `none`/`low` abstract result it
downloads the paper through the scopus skill's `download_pdf.py` (Elsevier PDF, then the
open-access tiers; needs `--email` for Unpaywall), extracts the text with PyMuPDF, scans the
study-cue sentences first and the reference-list-stripped body second, and adopts the full-text
location only when it beats the abstract. Files are cached under `<dir>/refs/`, so a second run is
cheap. It is opt-in because it fetches PDFs; without it the skill is abstract-only and offline after
the Scopus calls.
### Step 2 — Human review (mandatory before rendering)
Show the user the draft, grouped by confidence. Ask them to correct or confirm — especially every
`low` and `none` row, and any `high` row where the matched term looks like an author country rather
than a study site. The cleanest way to persist corrections is an **override CSV**: the user edits it
(or you edit it on their instruction), then re-run step 1 with `--override` so their rows win. Never
skip this step; a map of wrong points is worse than no map. If the user explicitly says "just render
the draft", note in your reply that the map is unreviewed.
### Step 3 — Render the artifacts
```bash
python .claude/skills/geolocalisation/scripts/generate_geomap.py \
--csv <dir>/study_locations.csv --out <dir> [--formats csv,kml,geojson,png,html] \
[--title "..."] [--min-confidence low]
```
`--formats` selects the subset to emit (default: all available). `--min-confidence` drops points
below a threshold from the plotted map (they stay in the CSV). The basemap `world_countries.geojson`
(Natural Earth 110 m, public domain) is read from the skill's `data/` folder; if absent it is fetched
once (TLS verified) and cached there.
## Boundaries
- The skill **infers and renders**; it does not fabricate. A location it cannot support with a
matched term is left empty, not guessed.
- It does **not** validate the references themselves — that is the `scopus` skill / `bib-cleaner`.
Feed it a `.bib` that is already clean.
- Author affiliation mapping is a **different** deliverable (institution, not study site). If the
user actually wants that, say so and stop: it is a separate mode not built here.
## Dependencies
`matplotlib` (PNG). Optional: `folium` (HTML), `PyMuPDF` (the `--full-text` PDF scan; reuses the
scopus skill's `download_pdf.py`). No geopandas/GDAL — the basemap is drawn from raw GeoJSON.
Install and audit per the repo rule:
```bash
pip install -r .claude/skills/geolocalisation/scripts/requirements.txt
pip-audit -r .claude/skills/geolocalisation/scripts/requirements.txt
```
Files in this skill
- SKILL.md
- references/geocoding-protocol.md
- scripts/Test/test_extract_locations.py
- scripts/extract_locations.py
- scripts/generate_geomap.py
- scripts/requirements.txt
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.