UNPKG

@allmaps/annotation

Version:

Functions for generating and parsing IIIF georeference annotations

253 lines (156 loc) 7.42 kB
# @allmaps/annotation Parsing and Generating Georeference Annotations. ## How it works This module that can generate and parse [Georeference Annotations](https://iiif.io/api/extension/georef/). A **Georeference Annotation** is a [Web Annotation](https://www.w3.org/TR/annotation-model/) that stores the metadata needed to [georeference](https://en.wikipedia.org/wiki/Georeferencing) a [IIIF image](https://iiif.io/api/image/3.0/). See this [example](./examples/annotation.example.json). A Georeference Annotation contains the following data: * The [URI of an IIIF Image](https://iiif.io/api/image/3.0/#3-identifier), as well as its dimensions in pixels. * A polygonal resource mask that defines the cartographic part of the image. * A list of ground control points (GCPs) that define the mapping between resource coordinates and geospatial coordinates. Multiple maps can be defined in an **Annotation Page** (see [spec](https://iiif.io/api/presentation/3.0/#2-resource-type-overview)). Allmaps offers apps and packages for working with Georeference Annotations. [Allmaps Viewer](../../apps/viewer/) can [for example](https://viewer.allmaps.org/#data=data%3Atext%2Fx-url%2Chttps%3A%2F%2Fraw.githubusercontent.com%2Fallmaps%2Fannotation%2Fdevelop%2Fexamples%2Fannotation.example.json) warp IIIF maps in the browser, just by loading a Georeference Annotation. A **Georeferenced Map** is the format Allmaps uses internally to describe a map and pass it between functions and packages. It contains the same information in a more practical form. See this [example](./examples/map.example.json). This module allows **parsing** Georeference Annotations to Georeferenced Maps and **generating** Georeference Annotations from Georeferenced Maps. This module is written in TypeScript and is built using Zod. <!-- TODO: create Observable notebook that allows you to try out this module! --> ## Installation This is an ESM-only module that works in browsers and in Node.js. Node.js: Install with npm: ```sh npm install @allmaps/annotation ``` Browser: ```html <script type="module"> import { Annotation } from 'https://unpkg.com/@allmaps/annotation?module' </script> ``` ## Usage ```js import { parseAnnotation, generateAnnotation } from '@allmaps/annotation' // Fetch an annotation const annotation = await fetch(annoationUrl).then((response) => response.json()) // Create a georeferencedMap from the annotation const georeferencedMaps = parseAnnotation(annotation) const georeferencedMap = georeferencedMaps[0] // Use or modify the georeferencedMap(s) // ... // Generate Georeference Annotation // Note: returns an annotation or annotation page based on input const georeferenceAnnotation = generateAnnotation(georeferencedMap) const georeferenceAnnotationPage = generateAnnotation(georeferencedMaps) ``` See the API below for more details. ## License MIT ## API ### `Annotation` ###### Type ```ts { type: "Annotation"; target: { type: "SpecificResource"; source: { type: "ImageService1" | "ImageService2" | "ImageService3"; height: number; width: number; '@id': string; partOf?: Array<PartOfItem> | undefined; } | { ...; } | { ...; }; selector: { ...; }; }; ... 5 more ...; motivation?: string | undefined; } ``` ### `AnnotationPage` ###### Type ```ts { type: "AnnotationPage"; items: Array<{ type: "Annotation"; target: { type: "SpecificResource"; source: { type: "ImageService1" | "ImageService2" | "ImageService3"; height: number; width: number; '@id': string; partOf?: Array<PartOfItem> | undefined; } | { ...; } | { ...; }; selector: { ...; }; }; ... 5 more ...; m... ``` ### `AnnotationPageSchema` ###### Type ```ts AnnotationPage1Schema ``` ### `AnnotationSchema` ###### Type ```ts Annotation1Schema ``` ### `FeaturePropertiesSchema` ###### Type ```ts Annotation1FeaturePropertiesSchema ``` ### `GCPSchema` ###### Type ```ts GeoreferencedMap2GCPSchema ``` ### `GeoreferencedMap` ###### Type ```ts { type: "GeoreferencedMap"; resource: { type: "ImageService1" | "ImageService2" | "ImageService3" | "Canvas"; id: string; height?: number | undefined; width?: number | undefined; partOf?: Array<PartOfItem> | undefined; }; ... 7 more ...; resourceCrs?: { ...; } | undefined; } ``` ### `GeoreferencedMapSchema` ###### Type ```ts GeoreferencedMap2Schema ``` ### `GeoreferencedMapsSchema` ###### Type ```ts GeoreferencedMaps2Schema ``` ### `PartOf` ###### Type ```ts Array<PartOfItem> | undefined ``` ### `PartOfItem` ###### Type ```ts { type: string id: string label?: Record<string, Array<string | number | boolean>> | undefined } & {partOf?: PartOfItem[]} ``` ### `ResourceSchema` ###### Type ```ts GeoreferencedMap2ResourceSchema ``` ### `SvgSelectorSchema` ###### Type ```ts SvgSelector1Schema ``` ### `generateAnnotation(mapOrMaps)` Generates a Georeference Annotation from a single Georeferenced Map or an Annotation Page containing multiple Georeference Annotations from an array of Georeferenced Maps. ###### Parameters * `mapOrMaps` (`unknown`) * Single Georeferenced Map, or an array of Georeferenced Maps ###### Returns Georeference Annotation or Annotation Page (`{ type: "Annotation"; target: { type: "SpecificResource"; source: { type: "ImageService1" | "ImageService2" | "ImageService3"; height: number; width: number; '@id': string; partOf?: Array<PartOfItem> | undefined; } | { ...; } | { ...; }; selector: { ...; }; }; ... 5 more ...; motivation?: string | undefined; } | { ....`). ###### Examples ```ts import fs from 'fs' import { generateAnnotation } from '@allmaps/annotation' const map = JSON.parse(fs.readFileSync('./examples/map.example.json')) const annotation = generateAnnotation(map) ``` ### `parseAnnotation(annotation)` Parses a Georeference Annotation or an Annotation Page containing multiple Georeference Annotations and returns an array of Georeferenced Maps. ###### Parameters * `annotation` (`unknown`) * Georeference Annotation or Annotation Page containing multiple Georeference Annotations ###### Returns Array of maps (`Array<{ type: "GeoreferencedMap"; resource: { type: "ImageService1" | "ImageService2" | "ImageService3" | "Canvas"; id: string; height?: number | undefined; width?: number | undefined; partOf?: Array<PartOfItem> | undefined; }; ... 7 more ...; resourceCrs?: { ...; } | undefined; }>`). ###### Examples ```ts import fs from 'fs' import { parseAnnotation } from '@allmaps/annotation' const annotation = JSON.parse(fs.readFileSync('./examples/annotation.example.json')) const maps = parseAnnotation(annotation) ``` ### `validateAnnotation(annotation)` ###### Parameters * `annotation` (`unknown`) ###### Returns `{ type: "Annotation"; target: { type: "SpecificResource"; source: { type: "ImageService1" | "ImageService2" | "ImageService3"; height: number; width: number; '@id': string; partOf?: Array<PartOfItem> | undefined; } | { ...; } | { ...; }; selector: { ...; }; }; ... 5 more ...; motivation?: string | undefined; } | { ....`. ### `validateGeoreferencedMap(mapOrMaps)` ###### Parameters * `mapOrMaps` (`unknown`) ###### Returns `{ type: "GeoreferencedMap"; resource: { type: "ImageService1" | "ImageService2" | "ImageService3" | "Canvas"; id: string; height?: number | undefined; width?: number | undefined; partOf?: Array<PartOfItem> | undefined; }; ... 7 more ...; resourceCrs?: { ...; } | undefined; } | Array<{ type: "GeoreferencedMap"; resou...`.