Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3ad2d8b
refactor: consolidate submodules and Makefile as central command center
jdsika Mar 9, 2026
0952e3f
feat: input_manifest.json pipeline, EVES submodule, cross-platform ov…
jdsika Mar 10, 2026
5247dc1
feat: track generated/input blueprint with LFS, add 3d_preview assets
jdsika Mar 10, 2026
9974692
chore: update sl-5-8-asset-tools submodule (filename + bjson fixes)
jdsika Mar 10, 2026
c0a0273
feat: add opendriveconverter as submodule for Python re-implementation
jdsika Mar 10, 2026
fe0e4d4
docs: clarify internet only needed for geocoding, not SHACL/ontologies
jdsika Mar 10, 2026
808b370
chore: remove hand-crafted asset/, update submodule pointers
jdsika Mar 10, 2026
77b3f39
chore: update sl-5-8-asset-tools submodule pointer
jdsika Mar 10, 2026
d09e413
chore: update sl-5-8-asset-tools submodule, skip validate when no asset
jdsika Mar 11, 2026
4e3fa1b
chore: update submodule pointers
jdsika Mar 11, 2026
09dad83
chore: update sl-5-8-asset-tools submodule pointer
jdsika Mar 11, 2026
0931390
docs: fix stale references in copilot-instructions and remove pyproje…
jdsika Mar 11, 2026
89cb427
chore: update sl-5-8-asset-tools submodule pointer
jdsika Mar 11, 2026
a9f143e
fix: update filenames to match pipeline output renames
jdsika Mar 11, 2026
349d85a
chore: remove dead code and update stale references
jdsika Mar 11, 2026
4c74dda
refactor: cascade make setup to submodule Makefile
jdsika Mar 11, 2026
0692fbd
refactor: simplify Makefile — remove duplicated logic, drop make asse…
jdsika Mar 11, 2026
f6065b3
fix: EVES submodule to HTTPS, validate all generated assets
jdsika Mar 11, 2026
74f6c09
chore: remove orphan .flake8 (no Python files in root repo)
jdsika Mar 11, 2026
542c469
chore: update sl-5-8-asset-tools submodule pointer
jdsika Mar 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .flake8

This file was deleted.

4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Git LFS – track large binary assets in generated/input/
generated/input/**/*.png filter=lfs diff=lfs merge=lfs -text
generated/input/**/*.pdf filter=lfs diff=lfs merge=lfs -text
generated/input/**/*.xodr filter=lfs diff=lfs merge=lfs -text
56 changes: 56 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# HD-Map Asset Example — Copilot Instructions

## Project Overview

This is a **reference asset repository** for onboarding HD-Map simulation data into the ENVITED-X Dataspace. Users stage input files in `generated/input/`, then `make generate` runs the sl-5-8 pipeline to produce a complete, EVES-003-conformant asset in `generated/output/`.

Assets follow the [EVES-003](https://ascs-ev.github.io/EVES/EVES-003/eves-003.html) specification.

## Repository Structure

- `generated/input/` — Staged pipeline inputs (manifest, `.xodr` files, media, docs)
- `generated/output/` — Pipeline output: complete EVES-003 asset ready for validation and release
- `submodules/sl-5-8-asset-tools/` — Asset creation and processing tools (git submodule from [openMSL/sl-5-8-asset-tools](https://github.com/openMSL/sl-5-8-asset-tools))
- `submodules/ontology-management-base/` — Nested submodule: SHACL shapes, OWL ontologies, JSON-LD contexts, and Python validation tools (from [ASCS-eV/ontology-management-base](https://github.com/ASCS-eV/ontology-management-base))

## Setup and Validation

```bash
make setup
make validate
```

All commands are exposed via `make` targets -- run `make help` for the full list.

## Linting (pre-commit hooks)

Configured in `.pre-commit-config.yaml` — all hooks delegate to `make` targets.

## Key Conventions

### Asset Structure (EVES-003)

Every asset must contain: `simulation-data/`, `metadata/`, `media/`, `documentation/`, and a `manifest.json` at the root. Optional: `validation-reports/`.

### JSON-LD Metadata

- `manifest.json` — Content registry linking all asset files with access roles (`isOwner`, `isRegistered`, `isPublic`) and categories (`isSimulationData`, `isMetadata`, `isMedia`, etc.)
- `metadata/hdmap.json` — Domain-specific metadata (format, content, quantity, quality, data source, georeference) conforming to the HD-Map SHACL shapes from ontology-management-base

Both files use typed `@value`/`@type` pairs for literals and reference ontologies via `@context` prefixes like `hdmap:`, `manifest:`, `envited-x:`, `georeference:`, `gx:`.

### Submodules

Only one direct submodule: `submodules/sl-5-8-asset-tools` (which contains `ontology-management-base` as a nested submodule). After cloning, initialize with:

```bash
make setup
```

### Commits

This project uses [DCO sign-off](CONTRIBUTING.md). All commits require `Signed-off-by` — use `git commit -s`. Do **not** add `Co-authored-by: Copilot` trailers.

## Release Workflow

The GitHub Actions workflow (`.github/workflows/release.yml`) triggers on version tags (`v*.*.*`), runs `make setup && make generate && make validate`, and uploads the pipeline-generated `asset.zip` as a GitHub release artifact.
48 changes: 18 additions & 30 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,36 @@ on:
tags:
- 'v*.*.*' # Triggers the workflow on version tags

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest

steps:
- name: Checkout repository (+ download lfs dependencies)
- name: Checkout repository
uses: actions/checkout@v4
with:
lfs: true
submodules: recursive

- name: Checkout LFS objects
run: git lfs checkout

- name: Set up Node.js
uses: actions/setup-node@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
node-version: '20'

- name: Install zip
run: sudo apt-get install -y zip
python-version: '3.12'

- name: Create zip file
- name: Setup, generate, and validate
run: |
cd asset
zip -r ../Testfeld_Niedersachsen_ALKS_xodr_sample.zip ./*

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false

- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
make setup
make generate
make validate

- name: Create Release and Upload Asset
uses: softprops/action-gh-release@v2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Testfeld_Niedersachsen_ALKS_xodr_sample.zip
asset_name: Testfeld_Niedersachsen_ALKS_xodr_sample.zip
asset_content_type: application/zip
files: "generated/output/**/*.zip"
generate_release_notes: true
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/.venv/
output.log
*.zip
/generated/output/
!/generated/input/
10 changes: 7 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[submodule "ontology-management-base"]
path = ontology-management-base
url = https://github.com/GAIA-X4PLC-AAD/ontology-management-base.git
[submodule "submodules/sl-5-8-asset-tools"]
path = submodules/sl-5-8-asset-tools
url = https://github.com/openMSL/sl-5-8-asset-tools.git
branch = main
[submodule "submodules/EVES"]
path = submodules/EVES
url = https://github.com/ASCS-eV/EVES.git
46 changes: 5 additions & 41 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,9 @@
repos:
- repo: local
hooks:
- id: black
name: black
entry: black
- id: validate
name: validate asset JSON-LD
entry: make validate
language: system
types: [python]
args: ["--config=pyproject.toml"]
pass_filenames: true
exclude: ontology-management-base/

- id: isort
name: isort
entry: isort
language: system
types: [python]
args: ["--settings=pyproject.toml"]
pass_filenames: true
exclude: ontology-management-base/

- id: flake8
name: flake8
entry: flake8
language: system
types: [python]
args: ["--config=.flake8"]
pass_filenames: true
exclude: ontology-management-base/

- id: jsonld-lint
name: JSON-LD Linter
entry: python ontology-management-base/src/jsonld_lint.py
language: system
types: [json]
files: \.json$
exclude: ontology-management-base/

- id: turtle-lint
name: Turtle Linter
entry: python ontology-management-base/src/turtle_lint.py
language: system
types: [text]
files: \.(ttl)$
exclude: ontology-management-base/
pass_filenames: false
always_run: true
178 changes: 178 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Makefile for hd-map-asset-example
# Build command center for common development tasks

# Allow parent makefiles to override the venv path/tooling.
VENV ?= .venv

# Submodule path aliases (hide deep paths)
ASSET_TOOLS := submodules/sl-5-8-asset-tools
OMB := $(ASSET_TOOLS)/submodules/ontology-management-base

# OS detection for cross-platform support (Windows vs Unix)
ifeq ($(OS),Windows_NT)
VENV_BIN := $(VENV)/Scripts
PYTHON ?= $(VENV_BIN)/python.exe
BOOTSTRAP_PYTHON ?= python
else
VENV_BIN := $(VENV)/bin
PYTHON ?= $(VENV_BIN)/python3
BOOTSTRAP_PYTHON ?= python3
endif
ACTIVATE_SCRIPT := $(VENV_BIN)/activate

# Generated asset directory
GENERATED_DIR := generated
GEN_INPUT := $(GENERATED_DIR)/input
GEN_OUTPUT := $(GENERATED_DIR)/output
GEN_CONFIGS := $(ASSET_TOOLS)/configs

# ── Subcommand support ───────────────────────────────────────────────
# Enables: make generate clean, make setup qc
SUBCMD = $(word 2,$(MAKECMDGOALS))

# ── Guards ───────────────────────────────────────────────────────────
define check_dev_setup
@"$(PYTHON)" -c "True" 2>/dev/null || { \
echo ""; \
echo "[ERR] Development environment not set up."; \
echo " Run: make setup"; \
echo ""; \
exit 1; \
}
endef

.PHONY: all setup install lint format validate generate clean help

# Default target
all: lint validate

# ── Setup & Install ──────────────────────────────────────────────────

setup: $(ACTIVATE_SCRIPT)
ifeq ($(SUBCMD),qc)
$(call check_dev_setup)
@echo "[INFO] Installing quality checker runtime dependencies..."
@"$(PYTHON)" -m pip install -e "$(ASSET_TOOLS)[qc-deps]" --quiet
@echo "[INFO] Installing quality checker packages (--no-deps to avoid upstream lxml/numpy constraints)..."
@"$(PYTHON)" -m pip install poetry-core --quiet 2>/dev/null || true
@"$(PYTHON)" -m pip install --no-deps \
"asam-qc-baselib@git+https://github.com/asam-ev/qc-baselib-py@main" \
"asam-qc-opendrive@git+https://github.com/asam-ev/qc-opendrive@main" \
"asam-qc-openscenarioxml@git+https://github.com/asam-ev/qc-openscenarioxml@main" \
"openmsl-qc-opendrive@git+https://github.com/openMSL/sl-5-9-openmsl-qc-opendrive@main"
@echo "[OK] Quality checkers installed"
else
@$(MAKE) -C "$(ASSET_TOOLS)" setup VENV="$(CURDIR)/$(VENV)" PYTHON="$(CURDIR)/$(PYTHON)"
@"$(PYTHON)" -m pre_commit install --allow-missing-config >/dev/null 2>&1 || true
@echo "[OK] Setup complete. Activate with: source $(ACTIVATE_SCRIPT)"
endif

$(PYTHON):
@echo "[INFO] Creating virtual environment at $(VENV)..."
@"$(BOOTSTRAP_PYTHON)" -m venv "$(VENV)"
@"$(PYTHON)" -m pip install --upgrade pip

$(ACTIVATE_SCRIPT): $(PYTHON)
@$(MAKE) -C "$(ASSET_TOOLS)" setup VENV="$(CURDIR)/$(VENV)" PYTHON="$(CURDIR)/$(PYTHON)"
@touch "$(ACTIVATE_SCRIPT)"

install:
$(call check_dev_setup)
@$(MAKE) -C "$(ASSET_TOOLS)" install VENV="$(CURDIR)/$(VENV)" PYTHON="$(CURDIR)/$(PYTHON)"
@echo "[OK] Install complete"

# ── Lint & Format ────────────────────────────────────────────────────
# Root repo has no Python files — lint validates JSON-LD asset data.

lint: validate

format:
$(call check_dev_setup)
@echo "[INFO] Nothing to format (no Python files in root repo)"

# ── Validate ─────────────────────────────────────────────────────────
# Validates JSON-LD files for every generated asset in the output directory.

validate:
ifneq ($(firstword $(MAKECMDGOALS)),generate)
$(call check_dev_setup)
@"$(PYTHON)" -c "\
import pathlib, sys; \
out = pathlib.Path('$(GEN_OUTPUT)'); \
dirs = sorted(d for d in out.iterdir() if d.is_dir()) if out.exists() else []; \
sys.exit('[SKIP] No generated asset found (run: make generate)') if not dirs else None; \
bad = [str(d) for d in dirs if not [p for p in [d / 'manifest.json', d / 'metadata' / 'hdmap.json'] if p.exists()]]; \
sys.exit('[ERR] No manifest or metadata found in: ' + ', '.join(bad)) if bad else None; \
all_paths = [str(p) for d in dirs for p in [d / 'manifest.json', d / 'metadata' / 'hdmap.json'] if p.exists()]; \
print(' '.join(all_paths)); \
" > .validate_paths 2>&1 && \
"$(PYTHON)" -m src.tools.validators.validation_suite \
--run check-data-conformance \
--data-paths $$(cat .validate_paths) \
--artifacts "$(OMB)/artifacts" && \
rm -f .validate_paths && \
echo "[OK] Validation complete" || \
{ cat .validate_paths 2>/dev/null; rm -f .validate_paths; exit 1; }
endif

# ── Generate (full pipeline) ─────────────────────────────────────────

generate:
ifeq ($(SUBCMD),clean)
@echo "[INFO] Removing generated/output/ directory..."
@"$(PYTHON)" -c "import shutil; shutil.rmtree('$(GEN_OUTPUT)', ignore_errors=True)"
@echo "[OK] Generated output removed (input/ blueprint preserved)"
else ifeq ($(SUBCMD),validate)
@$(MAKE) validate
else
$(call check_dev_setup)
@"$(PYTHON)" -c "\
import pathlib, sys; \
im = pathlib.Path('$(GEN_INPUT)') / 'input_manifest.json'; \
sys.exit('[ERR] No input_manifest.json in $(GEN_INPUT)/. Stage input files first.') if not im.exists() else None; \
"
@mkdir -p "$(GEN_OUTPUT)" 2>/dev/null || "$(PYTHON)" -c "import pathlib; pathlib.Path('$(GEN_OUTPUT)').mkdir(parents=True, exist_ok=True)"
@echo "[INFO] Running asset creation pipeline..."
@cd "$(GEN_INPUT)" && "$(CURDIR)/$(PYTHON)" -m asset_extraction.main \
input_manifest.json \
-config "$(CURDIR)/$(GEN_CONFIGS)" \
-out "$(CURDIR)/$(GEN_OUTPUT)"
@echo ""
@echo "[OK] Asset generated in $(GEN_OUTPUT)/"
endif

# ── Clean ────────────────────────────────────────────────────────────

clean:
ifneq ($(firstword $(MAKECMDGOALS)),generate)
@echo "[INFO] Cleaning..."
@rm -rf build/ dist/ .pytest_cache/ .mypy_cache/ "$(GENERATED_DIR)"
@find . -maxdepth 3 -type d -name __pycache__ -not -path "*/$(ASSET_TOOLS)/*" -exec rm -rf {} + 2>/dev/null || true
@find . -maxdepth 1 -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true
@rm -f *.zip
@echo "[OK] Cleaned"
endif

# ── Help ─────────────────────────────────────────────────────────────

help:
@echo "hd-map-asset-example -- Available Commands"
@echo ""
@echo " make setup Create venv and install all dependencies"
@echo " make setup qc Also install quality checker tools (optional, slow)"
@echo " make install Install packages"
@echo ""
@echo " make generate Run full pipeline: .xodr -> generated/ asset + zip"
@echo " make generate validate Validate the generated asset"
@echo " make generate clean Remove generated/output/ directory"
@echo ""
@echo " make lint Lint (validates asset JSON-LD)"
@echo " make validate Validate generated/output/ asset against SHACL"
@echo ""
@echo " make clean Remove all build artifacts, caches, and generated/"

# ── Catch-all for subcommand arguments ───────────────────────────────
ifneq ($(filter setup generate,$(firstword $(MAKECMDGOALS))),)
%:
@:
endif
Loading