Overview

To improve the interoperability of geospatial data in IIIF Georeference Viewer, we added support for data structures compliant with the Linked Places Format (LPF). This article describes the overview of LPF and the implementation details.

What is Linked Places Format (LPF)?

Linked Places Format is an interoperability format for gazetteer data established by the Pelagios Network. By extending GeoJSON and incorporating Linked Data (JSON-LD) concepts, it enables sharing and linking of place information across different datasets.

Features of LPF

  1. JSON-LD compatible: Semantic Web support using @id and @context
  2. GeoJSON extension: Adds metadata while maintaining standard GeoJSON structure
  3. Linking capability: References to external datasets expressed via the links array
  4. Temporal information: Description of temporal information through the when property

Official Specification

Comparison with the Previous Format

Previous Format (metadata object)

{
  "type": "Feature",
  "properties": {
    "resourceCoords": [6690, 7517]
  },
  "geometry": {
    "type": "Point",
    "coordinates": [139.7623182, 35.7151233]
  },
  "metadata": {
    "id": "http://example.org/place/123",
    "label": "Electrical Laboratory",
    "tags": ["Faculty of Engineering"],
    "url": "https://maps.app.goo.gl/dJdXXQEA8dWSptgt8",
    "xywh": "5936,6344,976,1384"
  }
}

The previous format stored all metadata within the metadata object. While simple, it had the following issues:

  • Low interoperability with other tools since it was not a standard format
  • Difficult to use as Linked Data
  • Unable to express different types of links to external resources (exact match, close match, etc.)
{
  "type": "Feature",
  "@id": "https://example.org/places/denki-jikkenshitsu",
  "properties": {
    "resourceCoords": [6690, 7517],
    "title": "Electrical Laboratory",
    "tags": ["Faculty of Engineering"],
    "xywh": "5936,6344,976,1384"
  },
  "links": [
    {
      "type": "primaryTopicOf",
      "identifier": "https://maps.app.goo.gl/dJdXXQEA8dWSptgt8"
    },
    {
      "type": "closeMatch",
      "identifier": "http://www.wikidata.org/entity/Q123456"
    }
  ],
  "geometry": {
    "type": "Point",
    "coordinates": [139.7623182, 35.7151233]
  }
}

Format Design Details

Placement of @id

The GeoJSON standard (RFC 7946) and Linked Places Format differ in where identifiers are placed:

FormatKeyLocationPurpose
GeoJSON standardidDirectly under FeatureSimple ID within the file
Linked Places Format@idDirectly under FeatureURI identifier for RDF/Linked Data

Checking the official LPF samples, @id is placed directly under Feature:

{
  "type": "FeatureCollection",
  "@context": "https://raw.githubusercontent.com/LinkedPasts/linked-places/master/linkedplaces-context-v1.1.jsonld",
  "features": [
    {
      "@id": "http://mygaz.org/places/p_12345",
      "type": "Feature",
      "properties": {
        "title": "Abingdon (UK)"
      },
      "links": [...]
    }
  ]
}

Placement of title

In LPF, title is placed inside properties. This design ensures that the information is retained as attribute data when loaded in GIS software (such as QGIS).

links is placed directly under Feature and expresses references to external resources. Each link has a type and identifier:

"links": [
  {"type": "exactMatch", "identifier": "http://vocab.getty.edu/tgn/7011944"},
  {"type": "closeMatch", "identifier": "http://somegaz.org/places/39847"},
  {"type": "primaryTopicOf", "identifier": "https://en.wikipedia.org/wiki/..."},
  {"type": "seeAlso", "identifier": "https://example.org/related"}
]
TypeDescriptionExample Use
exactMatchExactly the same resourceGetty TGN, GeoNames
closeMatchSimilar resourceOther gazetteers
primaryTopicOfWeb page about this placeWikipedia, Google Maps
subjectOfDocument mentioning this placeHistorical documents
seeAlsoRelated resourceRelated information

Implementation Details

Updated Type Definitions

// composables/useSettings.ts
interface FeatureLink {
  type: string; // e.g., "closeMatch", "primaryTopicOf", "exactMatch"
  identifier: string;
}

interface Feature {
  [x: string]: any;
  // Recommended: @id at top level (Linked Places Format / JSON-LD compatible)
  "@id"?: string;
  // Recommended: links at top level (Linked Places Format)
  links?: FeatureLink[];
  properties: {
    resourceCoords: number[];
    // Recommended: metadata in properties
    title?: string;
    tags?: string[];
    xywh?: string;
    [key: string]: any;
  };
  geometry: {
    type: string;
    coordinates: number[][];
  };
  // Legacy: metadata object (still supported for backwards compatibility)
  metadata?: {
    id?: string;
    label?: string;
    tags?: string[];
    url?: string;
    xywh?: string;
    [key: string]: any;
  };
}

ID Resolution Priority

To support both old and new formats, IDs are resolved in the following priority:

// composables/useDisplay.ts
// ID priority: @id (LPF) > id (GeoJSON) > properties.id > metadata.id > auto-generated
const predefinedId = feature["@id"] || feature.id || feature.properties?.id || feature.metadata?.id;

if (!feature.id) {
  if (predefinedId) {
    feature.id = predefinedId;
  } else {
    feature.id = `feature_${itemIndex + 1}_${featureIndex + 1}`;
  }
}

// label priority: properties.title (recommended) > metadata.label (legacy)
if (!feature.label) {
  feature.label = feature.properties?.title || feature.metadata?.label || "";
}

Updated Popup Display

// components/panes/Map.vue
// Support both new format (LPF/properties) and old format (metadata)
const metadata = feature.metadata || {};
const props = feature.properties || {};

// ID: @id (LPF) > id (GeoJSON) > metadata.id (legacy)
const displayId = feature["@id"] || feature.id || metadata.id;
// title: properties.title (recommended) > metadata.label (legacy)
const displayTitle = props.title || metadata.label;
// tags: properties.tags (recommended) > metadata.tags (legacy)
const displayTags = props.tags || metadata.tags;
// links: feature.links (LPF) > metadata.url (legacy)
const displayLinks = feature.links || [];
const legacyUrl = metadata.url;

// Generate links display
let linksHtml = '';
if (displayLinks.length > 0) {
  linksHtml = displayLinks.map((link: any) =>
    `link.identifier}">${link.type}`
  ).join(' | ');
} else if (legacyUrl) {
  linksHtml = `legacyUrl}">${t("detail")}`;
}

GeoJSON Conversion for MapGL

// components/panes/MapGL.vue
const geojsonFeatures = features.map((feature: any) => {
  const metadata = feature.metadata || {};
  const props = feature.properties || {};

  // ID: @id (LPF) > id (GeoJSON) > metadata.id (legacy)
  const displayId = feature["@id"] || feature.id || metadata.id;
  // title: properties.title (recommended) > metadata.label (legacy)
  const displayTitle = props.title || metadata.label || '';
  // tags: properties.tags (recommended) > metadata.tags (legacy)
  const displayTags = props.tags || metadata.tags || [];
  // links: feature.links (LPF)
  const displayLinks = feature.links || [];
  // url: metadata.url (legacy)
  const legacyUrl = metadata.url || '';

  return {
    type: 'Feature',
    properties: {
      id: displayId,
      label: displayTitle,
      tags: displayTags,
      links: displayLinks,
      url: legacyUrl
    },
    geometry: {
      type: 'Point',
      coordinates: [feature.geometry?.coordinates?.[0] || 0, feature.geometry?.coordinates?.[1] || 0]
    }
  };
});

Backward Compatibility

To avoid breaking existing data, the previous metadata object format continues to be supported. Even when old and new formats are mixed, everything works correctly:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "@id": "https://example.org/places/new-format",
      "properties": {
        "resourceCoords": [100, 200],
        "title": "New format example"
      },
      "links": [{"type": "primaryTopicOf", "identifier": "https://..."}],
      "geometry": {"type": "Point", "coordinates": [139.0, 35.0]}
    },
    {
      "type": "Feature",
      "properties": {"resourceCoords": [300, 400]},
      "geometry": {"type": "Point", "coordinates": [140.0, 36.0]},
      "metadata": {
        "label": "Old format example",
        "url": "https://..."
      }
    }
  ]
}

Benefits of Adopting LPF

1. Improved Interoperability

LPF is designed for data exchange between gazetteers. It facilitates integration with projects such as:

2. Linked Data Support

By using @id, each place can be uniquely identified by URI and used as Linked Data. This enables:

  • Easy conversion to RDF
  • Querying via SPARQL
  • Integration into the Semantic Web

The links array allows explicit expression of relationships with external resources:

  • exactMatch: “This place is identical to this entry in Getty TGN”
  • closeMatch: “This place is similar to this entity in Wikidata”
  • primaryTopicOf: “For this place, refer to this Wikipedia article”

4. Compatibility with GIS Tools

By placing title and tags inside properties, they are displayed as attribute tables when loaded in GIS tools such as QGIS.

Future Prospects

Temporal Information Support

LPF allows describing temporal information with the when property:

{
  "@id": "http://example.org/places/old-building",
  "properties": {
    "title": "Former Main Hall"
  },
  "when": {
    "timespans": [
      {"start": {"in": "1877"}, "end": {"in": "1923"}}
    ]
  }
}

In the future, we plan to add a timeline display feature that leverages this temporal information.

FeatureCollection-level @context

As part of full LPF support, we also plan to support @context specification at the FeatureCollection level:

{
  "type": "FeatureCollection",
  "@context": "https://raw.githubusercontent.com/LinkedPasts/linked-places/master/linkedplaces-context-v1.1.jsonld",
  "features": [...]
}

Summary

By adopting the Linked Places Format, IIIF Georeference Viewer has significantly improved the interoperability of geospatial data. By incorporating Linked Data concepts while maintaining backward compatibility with existing data, richer metadata expression and integration with external resources are now possible.

We expect this to facilitate the sharing and referencing of place information across different datasets in historical geography research and digital archive projects.

References