alas, poor ophelia27 downloadsGeoreference a map image: pin notes by latitude and longitude. A coordinate system over your picture, not a basemap.
Pin your notes to a map image inside Obsidian. The image never changes.
You place a few control points that say "this pixel is this latitude and longitude," Geb fits a transform, and every note in your vault that carries a coordinate lands on the image as a pin. Geb puts a coordinate system over your picture; it is not a basemap.

The map in these pictures is the United Kingdom relief location map by Alexrk2 on Wikimedia Commons, CC BY-SA 3.0. The pins are notes about Roman towns.
Read this first. It is the fastest way to know whether Geb is the tool you want.
Three kinds of file take part. None of them is special to Obsidian.
Copy main.js, manifest.json and styles.css from the latest release into <your vault>/.obsidian/plugins/geb/, then enable U+1316C Georeference under Settings → Community plugins. Obsidian 1.13 or later, desktop and mobile. Geb is not in the community plugin list yet.
lat, lng and both fields fill, or type the two values; decimal degrees with a point or a comma, or degrees-minutes-seconds such as 51°30'26″N, are all read. Coordinates come from a web map (right-click a place in Google Maps or OpenStreetMap and copy the pair), from Wikipedia, or from the map's own printed grid. If a place note already carries the coordinate, press Pick… and choose it.

Pan by dragging, zoom with the wheel or a pinch, Fit to see the whole image. Open maps on the ribbon lists every map in the vault; a georeference note's header gains an Open map action.
Geb reads a coordinate from the first of these forms it finds, in this order. One form is enough; the block shows them all.
lat: 53.9591 # Geb's own form: two plain decimals
lng: -1.0815
long: -1.0815 # read in place of lng
latitude: 53.9591 # the long spellings
longitude: -1.0815
location: [53.9591, -1.0815] # the Leaflet and Map View convention, a list or "lat, lng"
crs: earth # optional; only `earth` exists today
geb-uncertainty: 5000 # optional radius in meters, drawn as a ring around the pin
geb-certainty: disputed # optional: exact | approximate | disputed
geb-from: 71 # optional date text; a plain year under the default adapter
geb-to: 866
geb-calendar: gregorian # optional; names the adapter that reads the two above
Notes written for another tool may use other names, y and x or breite and länge. Add them in settings under Place note properties and Geb reads them as well, each as another name for one of the keys above. For a coordinate, the built-in name is read first: where a note has both and they disagree, the built-in one is used and the disagreement is reported, and a location holding a place name gives way to your own pair. For crs and the geb- keys, the first name present is read and the others are not looked at, so a built-in one that does not validate is reported and yours is not consulted.
A decimal comma is read (51,5074), and so is a location written as text. A location that could be either one number with a decimal comma or two coordinates is reported rather than guessed. A note with a coordinate problem is listed by the API's listProblems; a pin never vanishes silently. The view has no problems panel yet, so the list is reachable through the API or the developer console.
| Model | Needs | Better with | What it does |
|---|---|---|---|
| Affine | 3 points | 4 | Stretch, rotate and shear. Cannot bend. Suits a few points or a map drawn in one consistent projection. |
| Mercator (affine) | 3 points | 4 | An affine fitted after projecting coordinates the way web map tiles and modern atlases are drawn. Exact on a Mercator base, where a flat affine drifts. Points beyond 85° of latitude, north or south, are refused. |
| Polynomial (2nd order) | 6 points | 8 | Gentle curvature for maps that warp smoothly. Barely determined at 6 or 7. |
| Thin-plate spline | 3 points | 8 | Bends to pass exactly through every point. The default: it matches affine at 3 points and works well from about 6 well-spread points on scanned or hand-drawn maps. |
The status line and the fit report deliberately show the affine RMS in image pixels for every model: a spline passes exactly through its points and would read zero even with a mistyped coordinate. A low RMS means your points agree with each other, not that the map is right far from them. An RMS near your own placing precision, a pixel or two, is as good as it gets; what is large depends on the image's resolution. Leave-one-out leaves each point out in turn, refits, and reports in image pixels how far that point then lands from where you placed it; one point far above the rest is the one to check. The report also notes when your points fit a Mercator affine several times better than a flat one.
Pins outside the trusted area are drawn dashed and flagged as extrapolated.

What Geb writes, and all it ever writes:
geb-id: britain-5c
geb-image: "[[britain-5c.png]]"
geb-image-size: [622, 718]
geb-image-bytes: 295657
geb-image-hash: fnv1a64:67ea0caba549119d
geb-crs: earth
geb-fits:
- bounds: null
transform: { model: tps, lambda: 0 }
points:
- { px: 352, py: 364, lat: 54.953, lng: -3.213, label: Bowness-on-Solway }
Change the ID under geb-id if you like. Rename or move the image and the link follows. If the image was moved while Obsidian was closed, Geb finds it again by its bytes on the next start and tells you. If the image's content changed, the fit is kept as you saved it and the API reports the image as changed; open the map, check the points still sit on their features, and save again. A note Geb cannot read is reported, never skipped.

Put GeoJSON files in the vault folder Geb/reference (or the folder you choose in settings) and their lines are drawn through the fit over every map, so drift is visible while you place points. Coordinates are read as GeoJSON specifies them, longitude and latitude on WGS 84; lines, multi-lines and polygon outlines are drawn, points are ignored. The command Download Natural Earth coastline fetches Natural Earth's 1:10 million coastline, public domain and about 10 MB, into that folder after you confirm; the file is parsed before it is written. Reference lines are culled to the map's region and cut where the fit cannot be inverted reliably, far outside the trusted area.
y, breite for latitude. A name Geb already reads, or one you have given to another key, is ignored.
When a query asks for a moment, a place note with geb-from and geb-to is on the map only between those dates. Both ends are inclusive; a missing bound is open; a note with neither is always present, and so is every note when no moment is asked for. The built-in adapter reads plain signed years, astronomical style, so year 0 is 1 BC and -1 is 2 BC. Other calendars plug in through the API. There is no time slider in the view yet; the filter is reachable through the API.
app.plugins.plugins.geb.api converts between pixels and coordinates, lists maps and the notes they cover, and reports every problem it finds. Types ship in types/geb.d.ts. See API.md.
Multiple fits per image (insets and composite sheets), user-defined coordinate systems and maps that are not of Earth, antimeridian crossings, a time slider, a problems panel in the view, converting many points in one API call, and geodesic distance. The types are shaped for them; the features are not built.
MIT. The Natural Earth coastline is public domain.