A JavaScript/TypeScript library that renders JSON-LD feature data as interactive HTML tables and enriches them with semantic metadata (labels, descriptions) fetched from RDF sources.
npm install @opengeospatial/jsonld-ui-utils
# or
yarn add @opengeospatial/jsonld-ui-utilsjsonld is
an optional peer dependency. Install it if you need to fetch and resolve
JSON-LD contexts by URL:
npm install jsonldproj4
is an optional peer dependency required only when using the Leaflet
plugin with non-WGS84 data:
npm install proj4<!-- optional: library-provided styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils.css"/>
<!-- optional: jsonld peer dep (needed for context URL resolution) -->
<script src="https://cdn.jsdelivr.net/npm/jsonld@8/dist/jsonld.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils.min.js"></script>This exposes jsonldUIUtils as a global variable.
import { loadFeature, createPropertiesTable, augment } from '@opengeospatial/jsonld-ui-utils';
const { feature, context } = await loadFeature('https://example.org/features/my-feature.json');
const container = document.getElementById('feature');
createPropertiesTable(feature, container);
await augment(container, context);const { feature, context } = await loadFeature(featureUrl);loadFeature fetches the document at
featureUrl, extracts its @context, recursively
loads and merges any referenced context URLs, and returns both the raw
feature object and the resolved context.
const container = document.getElementById('feature');
createPropertiesTable(feature, container);This builds a nested HTML table structure inside
container. By default it reads from the
properties field of the feature object. Pass
propertiesField: null to use the entire feature object
instead:
createPropertiesTable(feature, container, { propertiesField: null });The generated elements carry CSS classes you can style:
| Class | Applied to |
|---|---|
.object-properties |
Wrapper <div> around the top-level table |
.object-table |
<table> elements |
.object-property |
Property name cells |
.object-value |
Property value cells |
.literal-value |
Scalar (non-object) values |
.array-entry |
Entries within an array value |
Include dist/jsonld-ui-utils.css (or the CDN link above)
for default styling of these classes.
await augment(container, context, {
fallbackSparqlEndpoints: 'https://example.org/sparql',
});augment walks the table, resolves each property name and
value to its full URI via the JSON-LD context, fetches RDF data for
those URIs, and updates the HTML elements with human-readable labels,
descriptions, and links.
During and after augmentation, elements receive additional CSS classes:
| Class | Meaning |
|---|---|
.resource-loading |
Fetch in progress |
.resource-resolved |
Label successfully retrieved |
.resource-error |
Fetch failed |
.resource-link |
<a> added with the resolved URI |
createPropertiesTable(feature, container, options?)| Option | Type | Default | Description |
|---|---|---|---|
propertiesField |
string or null |
'properties' |
Property on feature to use as the root object. Set to
null to use the entire feature. |
augment(rootElem, context, options?)| Option | Type | Default | Description |
|---|---|---|---|
replaceElements |
boolean |
true |
Replace element text with the resolved label. |
labelPredicates |
string[] |
SKOS prefLabel, DCT/DC title, SDO/FOAF name, RDFS label | RDF predicates checked when extracting a label. |
descriptionPredicates |
string[] |
SKOS definition, DCT/DC description, RDFS comment | RDF predicates checked when extracting a description. |
fallbackRainbowInstances |
string or string[] |
— | One or more RAINBOW proxy base URLs tried in order when a direct fetch returns no label. |
fallbackSparqlEndpoints |
string or string[] |
— | One or more SPARQL endpoint URLs tried in order as a last resort
(DESCRIBE <uri>). |
fetchResource(uri, options?)Fetch RDF metadata for a single URI and return a
ResourceData object:
interface ResourceData {
uri: string;
label: string | null;
description?: string | null;
}const data = await fetchResource('https://example.org/vocab/MyTerm', {
fallbackSparqlEndpoints: 'https://example.org/sparql',
});
console.log(data.label); // e.g. "My Term"loadContext(context)Load and merge one or more JSON-LD contexts. Accepts a context object, a URL string, or an array of either:
const merged = await loadContext([
'https://example.org/context1.json',
'https://example.org/context2.json',
]);The Leaflet plugin creates a L.GeoJSON layer that
automatically renders popup tables for each feature and augments them
with RDF metadata.
Same package as above — no separate install needed. Import the plugin entry point:
import { createJsonLDGeoJSONLayer } from '@opengeospatial/jsonld-ui-utils/leaflet';<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils.css"/>
<!-- optional: required only for non-WGS84 data (must come before the plugin) -->
<script src="https://unpkg.com/proj4@latest/dist/proj4.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@opengeospatial/jsonld-ui-utils@latest/dist/jsonld-ui-utils-leaflet.min.js"></script>This exposes jsonldUIUtilsLeaflet as a global
variable.
createJsonLDGeoJSONLayer returns a
Promise<L.GeoJSON>:
const layer = await createJsonLDGeoJSONLayer(L, geojsonData, {
ldContext: 'https://example.org/context.jsonld',
popupOptions: { maxWidth: 420 },
augmentOptions: {
fallbackSparqlEndpoints: 'https://example.org/sparql',
},
});
layer.addTo(map);Or with .then():
createJsonLDGeoJSONLayer(L, geojsonData, options).then(layer => {
layer.addTo(map);
map.fitBounds(layer.getBounds());
});properties object gets a
popup with a rendered table.id, it is shown as a hover
tooltip automatically.ldContext is provided.The plugin can render data in coordinate reference systems other than WGS84 by transforming geometries to WGS84 before passing them to Leaflet.
The CRS is detected automatically from the input data in priority order:
coordRefSys — a URI string, a
{ "type": "Reference", "href": "...", "epoch": ... }
object, or an array of these (compound CRS; the first EPSG entry is
used)crs —
{ "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::XXXX" } }If the detected CRS is not already registered with proj4, the plugin fetches its definition from epsg.io on first use and caches it for the lifetime of the page.
Requirements: proj4js must be available. In ESM/CJS
projects install it as a peer dependency
(npm install proj4). In browser IIFE usage, load the proj4
script before the plugin (see snippet above) so that
window.proj4 is present.
// CRS is read automatically from data.crs or data.coordRefSys
const layer = await createJsonLDGeoJSONLayer(L, dataInEpsg5514, options);
// Or supply a CRS explicitly, bypassing auto-detection:
const layer = await createJsonLDGeoJSONLayer(L, data, {
...options,
coordRefSys: 'EPSG:5514',
});Per the JSON-FG scoping rules, a coordRefSys on an
individual feature overrides the collection-level value for that
feature’s geometry.
Note: Coordinate epochs (present on some dynamic CRS references) are not supported by proj4js and are silently ignored with a console warning.
JsonLDGeoJSONOptions)| Option | Type | Default | Description |
|---|---|---|---|
ldContext |
string, object, or array |
— | JSON-LD context (URL, object, or array) used to resolve property URIs. |
popupOptions |
object |
{ maxWidth: 400 } |
Options passed to Leaflet’s bindPopup. |
augmentOptions |
object |
{} |
Options passed to augment() (see above). |
onEachFeature |
function |
— | Called for every feature before the plugin’s own logic, matching
Leaflet’s onEachFeature signature. |
coordRefSys |
string |
— | Override CRS detection with an explicit URI
(e.g. "EPSG:5514"). |
proj4 |
object |
— | Inject a specific proj4 instance instead of using the auto-resolved one. |
Any other options are forwarded to L.geoJSON.
yarn install
yarn build # produces dist/
yarn dev # start dev server with live reloadSee LICENSE.