Skip to content

Georeference Annotations

Georeference Annotations are small JSON documents that describe how pixel coordinates on a digitized map relate to geographic coordinates. They contain the information that Allmaps needs to fetch an image through IIIF, select the map within that image, and display it on a world map.

The image stays on the institution’s IIIF server. The annotation stores the georeference data separately, so you can share or update that data without downloading the original image or saving a warped copy.

Georeference Annotations follow the IIIF Georeference Extension, an open standard based on the Web Annotation Data Model. Anyone can build software to create or use them.

What does an annotation contain?

A Georeference Annotation describes how one map relates to geographic coordinates. It contains:

  • IIIF resource: the Canvas or Image Service containing the map.
  • Ground control points (GCPs): pairs of image coordinates and geographic coordinates identifying the same locations.
  • Map mask: an optional region selecting the map within the resource, for example to exclude borders or separate an inset map.
  • Transformation: an optional preferred algorithm for calculating the relationship between image coordinates and geographic coordinates from the control points.

The resource and any mask are described in the annotation’s target. The control points and optional transformation are stored in its body.

The example below targets a IIIF Image Service and uses a polygon mask to select the map within the image.

Example: a map of Saigon

This example uses a map of Saigon from the Bibliothèque nationale de France (BnF), with six ground control points. You can view the georeferenced map in Allmaps Viewer.

georeference-annotation.json
{
"id": "https://annotations.allmaps.org/maps/1bfb1eb4198e7240",
"type": "Annotation",
"@context": [
"http://iiif.io/api/extension/georef/1/context.json",
"http://iiif.io/api/presentation/3/context.json"
],
"created": "2026-10-06T10:20:33.764Z",
"modified": "2026-10-06T10:20:33.764Z",
"motivation": "georeferencing",
"target": {
"type": "SpecificResource",
"source": {
"id": "https://gallica.bnf.fr/iiif/ark:/12148/btv1b530297676/f1",
"type": "ImageService3",
"height": 14859,
"width": 16267
},
"selector": {
"type": "SvgSelector",
"value": "<svg width=\"16267\" height=\"14859\"><polygon points=\"681,647 687,14255 13688,14181 13980,14304 14484,14304 15323,14183 15647,14183 15639,787 8166,765\" /></svg>"
}
},
"body": {
"type": "FeatureCollection",
"transformation": {
"type": "polynomial",
"options": {
"order": 1
}
},
"features": [
{
"type": "Feature",
"properties": {
"resourceCoords": [7279, 6817]
},
"geometry": {
"type": "Point",
"coordinates": [106.6974, 10.7791]
}
},
{
"type": "Feature",
"properties": {
"resourceCoords": [3626, 2403]
},
"geometry": {
"type": "Point",
"coordinates": [106.6861488, 10.792507]
}
},
{
"type": "Feature",
"properties": {
"resourceCoords": [10202, 2743]
},
"geometry": {
"type": "Point",
"coordinates": [106.7064, 10.7917]
}
},
{
"type": "Feature",
"properties": {
"resourceCoords": [10840, 12239]
},
"geometry": {
"type": "Point",
"coordinates": [106.7084, 10.7626]
}
},
{
"type": "Feature",
"properties": {
"resourceCoords": [6817, 5667]
},
"geometry": {
"type": "Point",
"coordinates": [106.6959, 10.7826]
}
},
{
"type": "Feature",
"properties": {
"resourceCoords": [8833, 8026]
},
"geometry": {
"type": "Point",
"coordinates": [106.7021, 10.7755]
}
}
]
}
}

IIIF source image

target.source identifies the IIIF Image Service that serves the original image. Its width and height describe the full image in pixels: 16267 × 14859. Allmaps uses this service to request the image regions it needs at the appropriate resolution.

Map mask

target.selector selects the map within the image. The SvgSelector contains an SVG polygon whose vertices are pixel coordinates in the original image. Allmaps uses this polygon as a mask when rendering the map, excluding the parts of the image outside it.

Transformation

body.transformation specifies an algorithm for transforming pixel coordinates into geographic coordinates. Here, polynomial with order: 1 selects a first-order polynomial transformation. Changing this setting can produce a different fit from the same control points.

Thin plate spline (thinPlateSpline), also called rubber sheeting, smoothly bends the image so each control point lands on its geographic location. It can account for local distortions in a historical map, and may introduce more stretching between control points.

Ground control points (GCPs)

The body is a GeoJSON FeatureCollection. Each feature represents one ground control point:

  • properties.resourceCoords stores pixel coordinates in [x, y] order, measured from the image’s top-left corner, with x increasing to the right and y increasing downwards.
  • geometry.coordinates stores the corresponding geographic coordinates in [longitude, latitude] order, in WGS84.

The first control point pairs pixel [7279, 6817] with longitude 106.6974, latitude 10.7791. The other five features use the same structure. Together, the control points allow Allmaps to calculate where the rest of the map belongs.

The annotation’s @context identifies the vocabularies used to interpret the document, and motivation: "georeferencing" describes its purpose.

Multiple maps

A single image can contain several maps, such as a main map and an inset. Each map can have its own Georeference Annotation, with a separate mask and control points.

Multiple annotations can be grouped in an Annotation Page: a JSON document with type: "AnnotationPage" and an items array containing the annotations. Allmaps uses this to share several maps together, including maps from different images in a IIIF Manifest.

Working with annotations

Allmaps Editor creates Georeference Annotations as you draw masks and add control points. You can export them and open them in Allmaps Viewer, use them with Allmaps’ mapping library plugins, or retrieve them through the Annotations API.