GeoJSON-LD - Embedding JSON-LD data into GeoJSON

Author
Bergwinkl Thomas, Zazuko GmbH

Introduction

The GitHub GeoJSON organization made a proposal about how to make GeoJSON data JSON-LD "enabled" [see here]. But converting the nested array structures of the geometry object doesn't work lossless and creates very complex RDF graphs [see here]. This proposal is compatible with both standards.

GeoJSON-LD

Embedding JSON-LD in GeoJSON properties

The properties object of a GeoJSON feature contains data attached to the geometry object. It's the first place a developer looks for data. We propose to use that object also for JSON-LD data. Using that object and not the whole GeoJSON object avoids the mentioned problem. It doesn't require any changes in the code of JSON-LD or the object.

Mapping the geometry into a triple using the @geometry property

Without changes the geometry is lost in the JSON-LD object. The @geometry property in the JSON-LD context could be used to define a mapping. The value of that property is mapped to the predicate of the triple or in JSON-LD to the JSON property. The datatype could be also given in the context to define the target format.

Example

The code to map the geometry to a triple is very simple.

Map a GeoJSON objecto to a JSON-LD object

    GeoJSON.toJSONLD = function (json) {
      var properties = _.clone(json.properties);

      if (_.has(properties, '@context.@geometry')) {
        var geometry = _.get(properties, '@context.@geometry')

        properties[geometry] = {
          '@value': JSON.stringify(_.omit(json, 'properties')),
          '@type': 'http://www.opengis.net/ont/geosparql#geoJSONLiteral'
        }
      }

      return properties;
    };

Map a JSON-LD object to a GeoJSON object

    GeoJSON.toGeoJSON = function (properties) {
      var json;

      if (_.has(properties, '@context.@geometry')) {
        var geometry = _.get(properties, '@context.@geometry')

        json = JSON.parse(properties[geometry]['@value']);
        json.properties = _.omit(properties, geometry);
      }

      return json;
    };

Leaflet

Here is a live example using Leaflet. The function to map the geometry to the JSON-LD object is also very simple and supports GeoJSON and WKT.

    function layerToJSONLD(layer) {
      var properties = _.clone(layer.feature.properties);

      // check if we have a geometry property in the context
      if (_.has(properties, '@context.@geometry')) {
        var geometry = _.get(properties, '@context.@geometry')

        // convert to GeoJSON using Leaflet core
        var geojsonLiteral = JSON.stringify(layer.toGeoJSON());

        // convert to WKT using Wicket
        var wkt = new Wkt.Wkt();
        wkt.fromObject(layer);
        var wktLiteral =wkt.write();

        properties[geometry] = [{
          '@value': geojsonLiteral,
          '@type': 'http://www.opengis.net/ont/geosparql#geoJSONLiteral'
        }, {
          '@value': wktLiteral,
          '@type': 'http://www.opengis.net/ont/geosparql#wktLiteral'
        }]
      }

      return properties;
    }