Leaflet.annotate Logo Graphic

A Leaflet plugin to publish geographic maps in HTML as machine readable documents through integrating Schema.org and Dublin Core Metadata Elements in the Microdata Syntax.

View the Project on GitHub ifl-geovis/Leaflet.annotate

Introduction

This plugin extends the options for the LeafletJS Standard API elements Marker, CircleMarker, Popup, ImageOverlay and GeoJSON so you can publish these map elements in HTML semantically annotated ‐ and therewith machine readable web maps. While there is quite some effort already around the development of new geospatial data catalogs (which are awesome) this plugin turns the focus onto geographic web maps. Acknowleding that, de-facto, some maps already are data catalogs themselves, they are just not that well represented in HTML so that other programs can extract and re-use the information people collect in them.

Using this plugin you will not only to contribute to research of digital cartography but also make search engines and other applications (a) understand what is your map about, (b) what elements it is made of and (c) which parts of the world it explicitly deals with. Everything from just analyzing your maps representation in HTML.

Leaflet.annotate aims to ship the foundations for transforming the open source web mapping library LeafletJS into a semantic authoring environment for spatial data on the web. Users of Leaflet.annotate can focus on annotating the contents they want to map (or encode) as the knowledge about which cartographic specialities are in effect and which geographic markup fits best is already coded in Leaflet.

Your web map elements when published with semantic markup can become geo-referenced "resource descriptions", which in turn are:

Therefore we wrote this small script, integrating freeing you of caring much about the necessary syntax details.

Your feedback or contributions are very welcome. Please use this issue tracker to report any issues you experienced with it.

Overview & installation

The source code released contains two different components, one (the core) for generating the semantic markup and the other (an example) for reading and making the markup usable for visitors who want to systematically read and explore the map

  1. The core file is the semantic markup generating Leaflet Plugin in

    Leaflet.annotate.Microdata-0.3.0_en_US.min.js

    After loading this script you can start annotating Marker, CircleMarker, Popup, ImageOverlay and GeoJSON elements.

  2. The first add-on is a custom L.control which uses the semantic markup generated by the core, it can be installed through loading the files

    util/Leaflet.annotate.Viewer-0.3.0.min.js and
    css/viewer-style.css

    Using this add-on you can add a text based search control to your map allowing readers of it to magically list, search and focus all your annotated web map elements.

To assist you in the creation of valid semantic markup you can find existing JavaScript objects which help you to map user input to valid Schema.org type names (=Leaflet.annotate's itemtype option). These type names also allow you to map a label in your language to the schema.org type name.

Example: Photos of sculptures in Paris

Browse this example showing public sculptures in Paris.

This map is a good example of a so called "map mashup". In it you'll just find geo-referenced pictures representing public sculptures in the city of Paris. All web map elements are annotated as representing a Photographs depicting a specific contentLocation.

Here is the Leaflet code which produces the semantic markup explorable in the example. Bold elements are interpreted by the annotate plugin to produce proper markup.

L.circleMarker(coordinates, { weight: 2, opacity: 0.6,
  fillColor: "#a9a9a9", fillOpacity: 0.2, lineCap: 'square',
  color : "#8f1414", alt: "Photo of a sculpture named " + popupTitle,
  itemtype: 'Photograph', geoprop: 'contentLocation',
  url: photoURL, title: 'Picture of ' + popupTitle
}).setRadius(3)

If you copy & paste the generated markup into Googles Structured Data Testing Tool you will find out that it can identify/recognize ~400pictures were composed in this map.

The data for this map is fetched live with SPARQL from query.wikidata.org. Sculptures are shown when they are located in Paris (or one of its districts) and have a publicly licensed picture associated in wikmedia commons. The semantic annotation of the CircleMarker elements here happens in the SVG fragment created by Leaflet and, according to the standard, in a metadata element.

Example: Annotated GeoJSON-Layer

Browse this example to see the USA with "charmingly inaccurate" boundaries.

Usage

Automatic Annotation

Annotation happens automatically whenever you add a Marker, CircleMarker, Popup or ImageOverlay to your L.map and pass them a valid itemtype value as an option to Leaflets Standard API:

L.marker(coordinates, {
  title: 'Madison Square Garden', itemtype: 'CivicStructure'
})

Valid itemtype values are currently all the names of Schema.org terms which allow for at least one Place as one of their properties. Regarding the schema.org type you use you might be required to explicitly specify the desired geoprop option

L.circleMarker(coordinates, { title: 'The Catcher in the Rye',
  itemtype: 'Book', geoprop: 'locationCreated',
  sameAs: 'https://www.wikidata.org/wiki/Q183883'
})

For example when mapping CreativeWorks you can express a geographical dimension for the location it was created (locationCreated) or for the location it depicts (contentLocation) using the respective property names.

Here is another, more comple example, annotating an ImageOverlay:
L.imageOverlay(imageUrl, imageBounds, {
  "itemtype": "CreativeWork", 
  "geoprop": "contentLocation",
  "publisher": "The University of Texas",
  "source": "https://www.lib.utexas.edu/maps/new_jersey.html",
  "created": "Thu Jan 01 1920 01:00:00 GMT+0100 (CET)"
  "title": "Automobile Blue Book",
}).addTo(map)

Manual Annotation

On a GeoJSON element annotation happens whenever you call the .annotate() method on the GeoJSON layer and pass a valid code>itemtype value as an option:

L.geoJson(geojsonData, {
  title: 'Uganda', itemtype: 'Country',
  sameAs: 'https://www.wikidata.org/wiki/Q1036'
}).annotate()

This will markup the GeoJSON document as a map overlay representing the area for the Republic of Uganda. In Wikidata the URI for the concept/entity representing this country is https://www.wikidata.org/wiki/Q1036.

Another example of a semantically annotated GeoJSON overlay where the options used by Leaflet.annnotate to generate the semantic markup are highlighted in bold:

var statesBoundaries = L.geoJson(geoJsonData, {
    title: 'Charmingly Inaccurate - USA', itemtype: 'Country',
    description: 'A caricature of the lower 48 United States, '
      + 'this linework set is recognizable and friendly, but not concerned with ....” '
      + 'It’s that friend you have who’s always embellishing his stories. You never '
      + 'mind his lying, though, because the exaggerations make things more fun. '
      + 'Go ahead, enjoy the story your map is telling. (Version 1.1)',
    creator: 'Daniel P. Huffmann', publisher: 'Daniel P. Huffmann',
    published: '10/04/2013', modified: '10/04/2013',
    created: '3/24/2013', rights: 'Public Domain',
    derivedFrom: 'Derived from a 1920 broadside map entitled “The Rights of the People—Women'
      + 'are People: Suffrage Victory Map.” Equal Suffrage League of Virginia Papers, Acc. 22002, '
      + 'Library of Virginia.'}).addTo(map)
statesBoundaries.annotate()

API Documentation

You can find all options with which the Leaflet.annotate plugins extends the Standard API documented in the API section of the projects README.