Skip to content

Matdata-eu/apache-jena-fuseki-geosparql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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