Skip to content

Matdata-eu/apache-jena-fuseki-geosparql

Repository files navigation

Docker container for Apache Jena Fuseki with GeoSPARQL support

Docker Pulls Docker Stars Docker Image Size

Description

This Docker container provides Apache Jena Fuseki with built-in GeoSPARQL support, enabling spatial queries on RDF data. It includes:

  • Apache Jena Fuseki 5.4.0 - A robust SPARQL server and query engine
  • GeoSPARQL Extension - Support for spatial data queries and geometric operations
  • Full-text Search - Lucene-based text indexing for enhanced search capabilities
  • TDB Storage - High-performance triple store with union default graph
  • Security - Apache Shiro authentication with configurable admin access

Features

  • 🌍 Spatial Queries: GeoSPARQL 1.0 support for geometric and topological operations
  • �️ Coordinate Systems: Apache SIS tools for downloading EPSG datasets
  • �🔍 Text Search: Integrated Lucene indexing for SKOS labels and RDF literals
  • 📊 High Performance: TDB storage with optimized configurations
  • 🔐 Secure: Built-in authentication with configurable admin password
  • 🐳 Docker Ready: Production-ready container with proper security settings
  • 📡 REST API: Complete SPARQL endpoint with read/write capabilities
  • 🔄 Data Loading: Pre-configured tools for efficient data import

More information about the GeoSPARQL implementation of Apache Jena Fuseki can be found in the official documentation.

Note: This container includes Apache SIS command line tools to enable download of EPSG datasets. The SIS_DATA environment variable is configured to a directory inside /fuseki-base (recommended to mount as a docker volume).

Note 2: The GeoSPARQL extension of Apache Jena Fuseki 5.4.0 currently does not support geof:distance with a metric unit from a source EPSG that is not metric. You still need to use the vendor function spatialF:distance for this. Please see the example queries.

Usage

Quick Start

A docker image is available on Docker Hub.

# Run with default settings (port 3030)
docker run -p 3030:3030 mathiasvda/apache-jena-fuseki-geosparql

# Run with persistent data storage
docker run -p 3030:3030 -v /path/to/data:/fuseki-base mathiasvda/apache-jena-fuseki-geosparql

Accessing the Service

Once running, you can access:

Docker Compose Example

version: "3.8"
services:
  fuseki-geosparql:
    image: mathiasvda/apache-jena-fuseki-geosparql:latest
    ports:
      - "3030:3030"
    volumes:
      - fuseki_data:/fuseki-base
    restart: unless-stopped

volumes:
  fuseki_data:

Loading Data

You can load RDF data into the container using several methods:

1. Using the Web UI

You can access the Fuseki Web UI at http://localhost:3030 to upload your RDF data files directly.

2. Using Docker Volume Mounts

# Mount your data directory and use tdbloader
docker run -v /path/to/your/data:/data -v fuseki_data:/fuseki-base \
  mathiasvda/apache-jena-fuseki-geosparql \
  bash -c 'eval $TDBLOADER /data/*.ttl && java -cp "*:/javalibs/*" org.apache.jena.fuseki.main.cmds.FusekiServerCmd'

3. Using SPARQL Graph Store Protocol

# Upload a file via HTTP
curl -X POST -H "Content-Type: text/turtle" \
  --data-binary @your-data.ttl \
  http://localhost:3030/ds/data

4. Using SPARQL UPDATE

# Insert triples via SPARQL UPDATE (requires ENABLE_UPDATE=true)
curl -X POST -H "Content-Type: application/sparql-update" \
  --data "INSERT DATA { <http://example.org/subject> <http://example.org/predicate> <http://example.org/object> }" \
  http://localhost:3030/ds/update

GeoSPARQL Queries

Example spatial queries you can run:

PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX uom: <http://www.opengis.net/def/uom/OGC/1.0/>

# Test basic GeoSPARQL geometry functions without UOM
SELECT ?test_name ?point ?buffer_geom ?envelope_geom WHERE {

  VALUES (?test_name ?lat ?lon ?buffer_distance) {
    ("Amsterdam Central" 52.3791 4.9003 0.01)
    ("Rotterdam Port" 51.9225 4.4792 0.02)
    ("Utrecht Center" 52.0907 5.1214 0.015)
  }
    # Create point geometry from coordinates
  BIND(STRDT(CONCAT("<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(", STR(?lon), " ", STR(?lat), ")"), geo:wktLiteral) AS ?point)

  # Create a buffer around the point (simple circular buffer)
  BIND(geof:buffer(?point, ?buffer_distance, uom:degree) AS ?buffer_geom)

  # Get the envelope (bounding box) of the buffered geometry
  BIND(geof:envelope(?buffer_geom) AS ?envelope_geom)
}
ORDER BY ?test_name
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>

# Test GeoSPARQL spatial relationships without UOM namespace
# This query tests contains, intersects, and within relationships
SELECT ?relation ?geometry1_label ?geometry2_label ?result WHERE {

  # Define test geometries
  VALUES (?geometry1_label ?geometry1 ?geometry2_label ?geometry2 ?relation) {
    # Point within polygon test
    ("City Center" "POINT(4.9041 52.3676)"^^geo:wktLiteral "Amsterdam Bounds" "POLYGON((4.8 52.3, 5.0 52.3, 5.0 52.4, 4.8 52.4, 4.8 52.3))"^^geo:wktLiteral "within")

    # Line intersects polygon test
    ("Highway" "LINESTRING(4.85 52.32, 4.95 52.38)"^^geo:wktLiteral "Amsterdam Bounds" "POLYGON((4.8 52.3, 5.0 52.3, 5.0 52.4, 4.8 52.4, 4.8 52.3))"^^geo:wktLiteral "intersects")

    # Polygon contains point test
    ("Large Area" "POLYGON((4.7 52.2, 5.1 52.2, 5.1 52.5, 4.7 52.5, 4.7 52.2))"^^geo:wktLiteral "Small Point" "POINT(4.9 52.35)"^^geo:wktLiteral "contains")

    # Buffer test (point with buffer intersects line)
    ("Station" "POINT(4.9 52.37)"^^geo:wktLiteral "Train Line" "LINESTRING(4.88 52.36, 4.92 52.38)"^^geo:wktLiteral "intersects")
  }

  # Test the spatial relationship based on the relation type
  BIND(
    IF(?relation = "within", geof:sfWithin(?geometry1, ?geometry2),
    IF(?relation = "intersects", geof:sfIntersects(?geometry1, ?geometry2),
    IF(?relation = "contains", geof:sfContains(?geometry1, ?geometry2),
    false))) AS ?result
  )
}
ORDER BY ?relation ?geometry1_label
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX uom: <http://www.opengis.net/def/uom/OGC/1.0/>
PREFIX spatialf: <http://jena.apache.org/function/spatial#>

# Test GeoSPARQL distance calculation between two cities
SELECT ?city1 ?city2 ?distance_km WHERE {
  VALUES (?city1 ?point1 ?city2 ?point2) {
    ("London" "<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(-0.1276 51.5074)"^^geo:wktLiteral "Paris" "<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(2.3522 48.8566)"^^geo:wktLiteral)
    ("New York" "<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(-74.0060 40.7128)"^^geo:wktLiteral "Boston" "<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(-71.0588 42.3601)"^^geo:wktLiteral)
    ("Amsterdam" "<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(4.9041 52.3676)"^^geo:wktLiteral "Brussels" "<http://www.opengis.net/def/crs/EPSG/0/4326> POINT(4.3517 50.8503)"^^geo:wktLiteral)
  }

  # Calculate distance in kilometers
  # implementation of geof:distance in v5.4 does not support coordinate transformation to uom:metre for non-metric EPSG, so we use spatialf:distance
  BIND(spatialf:distance(?point1, ?point2, uom:metre) / 1000 AS ?distance_km)
}
ORDER BY ?distance_km

Building from Source

# Clone the repository
git clone https://github.com/matdata-eu/apache-jena-fuseki-geosparql.git
cd apache-jena-fuseki-geosparql

# Build the Docker image
docker build -t apache-jena-fuseki-geosparql .

# Run your custom build
docker run -p 3030:3030 apache-jena-fuseki-geosparql

or use the provided docker-compose.yml file:

docker-compose up --build

Configuration

The container uses several configuration files in the config/ directory:

  • assembler.ttl - Dataset and service configuration
  • fuseki-config.ttl - Server-wide settings and timeouts
  • shiro.ini - Security and authentication configuration
  • docker-entrypoint.sh - Container initialization script

Apache SIS Configuration

The container includes Apache SIS EPSG datasets for coordinate reference system support:

  • SIS_DATA Path: /fuseki-base/SIS_DATA
  • EPSG Database: Provides access to thousands of coordinate reference systems
  • Automatic Detection: SIS automatically detects and uses the EPSG database for transformations

You can override these by mounting your own configuration files:

docker run -p 3030:3030 \
  -v ./my-assembler.ttl:/fuseki-base/configuration/assembler.ttl \
  mathiasvda/apache-jena-fuseki-geosparql

Troubleshooting

Common Issues

  1. Permission Denied: Ensure your data volumes have proper permissions (the container runs as user 9008)
  2. Memory Issues: Increase Docker memory allocation for large datasets
  3. Connection Refused: Check that you're using the correct port (3030, not 8080)

Logs

# View container logs
docker logs <container-name>

# Follow logs in real-time
docker logs -f <container-name>

Health Check

# Check if Fuseki is responding
curl -f http://localhost:3030/$/ping

Contributing

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

LICENSE

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

About

Apache Jena Fuseki with built-in GeoSPARQL support, enabling spatial queries on RDF data.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •