Skip to content

Repository files navigation

yasgui-geo-plugin

This is an independent fork of https://github.com/Thib-G/yasgui-geo-tg

A geographic extension for YASGUI. This plugin allows the visualisation of SPARQL results on a map. It depends on Leaflet and now uses betterknown instead of wellknown.

Description

This package extends the YASGUI (Yet Another SPARQL GUI) interface with geographic data visualization capabilities.

Features

  • WKT, GeoJSON, GML, GeoHash and DBpedia/WGS84 geometry rendering on a Leaflet map
  • On-the-fly reprojection using proj4 — 15+ embedded SRIDs plus automatic fetch from epsg.io for unknown ones
  • OGC URN, CRS84 and SRID= prefix support
  • Auto-detection of numeric ?lat/?lon column pairs (no WKT required)
  • One toggleable overlay per geometry column in the layers control
  • Persisted style control for default color, opacity, fill, stroke width and marker radius; per-feature ?wktColor still overrides color
  • Marker clustering for large point sets (leaflet.markercluster)
  • Optional heatmap rendering (leaflet.heat)
  • Drawing tools that emit a ready-to-paste GeoSPARQL sfWithin filter
  • Geometry simplification via turf-simplify with a live tolerance slider
  • Export current results to GeoJSON, KML, CSV or map PNG, or copy GeoJSON to the clipboard
  • Permalink mode: map view, basemap and visible geometry columns encoded in the URL hash
  • Time slider for result sets with ?time / ?date bindings, including play/pause animation
  • Live coordinate readout and distance-measure tool
  • Dark-mode-aware default basemap
  • Background maps without API keys (OpenStreetMap, OSM Humanitarian, CyclOSM, OpenTopoMap, Esri imagery/topo/light/dark gray), a None option to hide the background, and OpenRailwayMap / place-name overlays
  • Describe entities: Ctrl+click (Cmd+click on macOS) a feature or an IRI in its popup to list the triples where it is the subject; add Shift for the triples where it is the object. Shown in the host's shared describe panel when the host has one, else in the plugin's own modal (see Host compatibility)
  • Hover highlight and labels: the hovered feature is outlined and brought to the front, its label (?label, ?name, ?xLabel, …) shows on hover, and a Labels control toggles permanent labels on the map
  • Plugin toolbar on hosts that offer one: background map, point display, labels, spatial filter, export and View settings sit above the map instead of on it
  • Safe popups: SPARQL bindings rendered as DOM (no XSS), with IRI linkification and inline image previews; long IRIs wrap, geometry literals are collapsed behind a "show more" toggle, and tall popups scroll
  • Accessibility: keyboard-focusable popups, real buttons, ARIA-labeled plugin icon
  • TypeScript declarations included
  • Configurable basemaps, default view, clustering thresholds, simplification tolerance, etc. — see docs/options.md

Host compatibility

The plugin works with both today's published Yasgui packages and the new MatGUI. It detects what the host offers (yasr.hostApi) and never checks version numbers.

Hosts with the yasr host API (new MatGUI) Other hosts (published @matdata/yasgui, @zazuko/yasgui)
Settings Plugin toolbar above the map (yasr.getPluginToolbar()) Leaflet controls on the map, as before
Describe (Ctrl+click) Host's shared describe panel (yasr.describe(iri, { direction, source: "Map" })) Plugin's own describe modal

In the plugin toolbar:

  • Background select: the background map (overlays such as OpenRailwayMap and the per-column layers stay in the layers control on the map)
  • Points select: clustered, all points or heatmap
  • Labels button: permanent feature labels
  • Rectangle, Polygon and clear buttons: the spatial filter
  • Export menu: copy GeoJSON, or save as GeoJSON, PNG, KML or CSV
  • View settings (far right): style (stroke colour, opacities, thickness, marker size) and geometry simplification

Zoom, the layers control (overlays), the distance measure, the coordinate readout, the time slider and the spatial-filter snippet stay on the map on every host, because they act on the map itself.

The plugin's own describe modal and map settings controls are kept as the fallback for hosts without the host API. They are deprecated and will be removed in the next major version. All icons are inline Lucide SVGs drawn in the current text colour, and the plugin's CSS reads the host's --yasgui-* theme variables with fallbacks.

Additional documentation

Getting started

Installation of dependencies

You need to have a YasGUI installed. You can use @zazuko/yasgui or yasgui. See instructions on their respective pages to get started with that package.

npm install @matdata/yasgui
npm install git+https://github.com/Matdata-eu/yasgui-geo-plugin.git

Registering plugin with Yasgui

import GeoPlugin from 'yasgui-geo-tg';
import '@zazuko/yasgui/build/yasgui.min.css';
import Yasgui from '@zazuko/yasgui';

//Register the plugin to Yasr
Yasgui.Yasr.registerPlugin('geo', GeoPlugin);

Use the plugin with Yasgui

Launch any SPARQL query on a GeoSPARQL enabled endpoint returning geometries as WKT literals (http://www.opengis.net/ont/geosparql#wktLiteral) and select the "geo" plugin in the results area.

Here's an example SPARQL query:

PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX spatialf: <http://jena.apache.org/function/spatial#>

# Test transforming between coordinate systems using Jena vendor functions
SELECT * WHERE {  
  VALUES (?name ?lat ?lon ?wktColor) {
    ("Antwerpen Centraal" 51.2133 4.4231 "blue")
    ("Charleroi Central" 50.4050 4.4396 "red")
    ("Leuven Station" 50.8830 4.7147 "green")
  }
  # Create point geometry from coordinates
  BIND(STRDT(CONCAT("POINT(", STR(?lon), " ", STR(?lat), ")"), geo:wktLiteral) AS ?point_no_crs_defined)
  BIND(STRDT(CONCAT("SRID=4326;POINT(", STR(?lon), " ", STR(?lat), ")"), geo:wktLiteral) AS ?point_ewkt_4326)
  BIND(STRDT(CONCAT("<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(", STR(?lat), " ", STR(?lon), ")"), geo:wktLiteral) AS ?point_opengis_4326)
  BIND(spatialf:transformSRS(?point_opengis_4326, "http://www.opengis.net/def/crs/EPSG/0/25831") AS ?point_utm_zone_31N)
  BIND(spatialf:transformSRS(?point_opengis_4326, "http://www.opengis.net/def/crs/EPSG/0/31370") AS ?point_lambert_belge_72)
  BIND(?name AS ?wktTooltip)
  BIND(CONCAT("Station: ", ?name) AS ?wktLabel)
}

Alternative: Using the Minified Bundle in a Browser (HTML/JS)

After building the project (or downloading the release assets), you can include the minified IIFE bundle directly in a plain HTML page. The bundle exposes the plugin on a global variable named YasguiGeoPlugin (or YasguiGeoPlugin.default depending on how the bundler/runtime handles default exports).

Minimal example:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>YASGUI Geo Demo</title>
    <!-- Leaflet CSS & JS (from CDN) -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
    <!-- YASGUI CSS & JS (from CDN or local build) -->
    <link rel="stylesheet" href="https://unpkg.com/@zazuko/yasgui@4.6.0/build/yasgui.min.css" />
    <script src="https://unpkg.com/@zazuko/yasgui@4.6.0/dist/yasgui.min.js"></script>
  </head>
  <body>
    <div id="yasgui" style="height:600px"></div>

    <!-- Plugin bundle built with esbuild -->
    <script src="/dist/yasgui-geo-tg.min.js"></script>

    <script>
      // The bundle exposes the plugin constructor on window.YasguiGeoPlugin
      const GeoPlugin = window.YasguiGeoPlugin && (window.YasguiGeoPlugin.default || window.YasguiGeoPlugin);

      // Register the plugin with YASR before creating Yasgui
      Yasgui.Yasr.registerPlugin('geo', GeoPlugin);

      const yasgui = new Yasgui(document.getElementById('yasgui'), {
        requestConfig: { endpoint: 'https://dbpedia.org/sparql' },
        yasr: { pluginOrder: ['table','response','geo'], defaultPlugin: 'geo' },
      });
    </script>
  </body>
</html>

Development & testing

In order to test and develop the plugin, you can use the demo environment provided.

Clone this repository locally and install its dependencies:

npm install

Then run the local dev server (uses vite):

npm run dev

Then go to http://localhost:3000/index.html to see the demo. Its Host select switches the mock yasr between a published-yasgui host (settings on the map, own describe modal) and a host with the yasr host API (plugin toolbar, shared describe panel). This environment will be updated while you make changes to the code. You can also add this configuration in VS Code (in .vscode/launch.json) to launch the demo directly from the debugger:

{
  "version": "0.2.0",
  "configurations": [
      {
          "type": "msedge",
          "request": "launch",
          "name": "Launch Demo",
          "url": "http://localhost:3000/index.html",
          "webRoot": "${workspaceFolder}"
      }
  ]
}

Online demo

Crazy Query

Plugin options

The plugin accepts configuration via Yasgui's yasr.plugins.geo slot — basemaps, default color, initial view, etc. See docs/options.md for the full reference.

Coordinate Transformations

  • Supported SRIDs (embedded): 4326, 3857, 31370, 4258, 3035, 25831, 25832, 25833, 2154, 27700, 28992, 3006, 2056, 4269, 3978.
  • Behavior: The plugin accepts WKT literals (and Geosparql WKT strings) and will following the GeoSPARQL standard. Note that when EPSG:4326 is specified, the coordinate order should be latitude, longitude. When it isn't specified, the order should be longitude, latitude.
  • Auto download of CRS: CRS definitions will be automatically downloaded from https://epsg.io/ when not embedded (see next section).

Auto-loading proj4 Definitions

  • The package includes embedded proj4 definitions for common SRIDs listed above and registers them at module initialization.
  • For SRIDs not embedded, the helper ensureProjDef(srid) can be used to fetch a proj4 definition from https://epsg.io/<srid>.proj4 and register it with proj4 at runtime. After fetching, re-render the plugin (call the plugin's draw() or updateMap() method) to apply reprojection.

API notes:

  • ensureProjDef(srid): Async helper to fetch and register a proj4 definition for a numeric SRID (exported).

Example (in application code):

import { ensureProjDef } from 'yasgui-geo-tg';
// ensure EPSG:25832 is registered, then redraw the plugin
await ensureProjDef('25832');
geoPlugin.draw();

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

Releases

Used by

Contributors

Languages