Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ target/
**/*.rs.bk
*.pdb

# Secrets / environment
.env
.env.*
!.env.example

# Python
.venv/
__pycache__/
Expand Down
59 changes: 31 additions & 28 deletions .github/agents/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
# tp-lib Development Guidelines

Auto-generated from all feature plans. Last updated: 2026-01-09

## Active Technologies

- Rust 1.75+ (edition 2021) (002-train-path-calculation)

## Project Structure

```text
# tp-lib Development Guidelines

Auto-generated from all feature plans. Last updated: 2026-01-09

## Active Technologies
- Rust 2021 edition, latest stable (1.80+) (003-path-review-webapp)
- File-based (GeoJSON network, CSV train path, CSV GNSS positions) — no database (003-path-review-webapp)

- Rust 1.75+ (edition 2021) (002-train-path-calculation)

## Project Structure

```text
src/
tests/
```

## Commands

cargo test; cargo clippy

## Code Style

Rust 1.75+ (edition 2021): Follow standard conventions

## Recent Changes

- 002-train-path-calculation: Added Rust 1.75+ (edition 2021)

<!-- MANUAL ADDITIONS START -->
<!-- MANUAL ADDITIONS END -->
tests/
```

## Commands

cargo test; cargo clippy

## Code Style

Rust 1.75+ (edition 2021): Follow standard conventions

## Recent Changes
- 003-path-review-webapp: Added Rust 2021 edition, latest stable (1.80+)

- 002-train-path-calculation: Added Rust 1.75+ (edition 2021)

<!-- MANUAL ADDITIONS START -->
<!-- MANUAL ADDITIONS END -->
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"tp-core",
"tp-cli",
"tp-py",
"tp-webapp",
]
resolver = "2"

Expand Down Expand Up @@ -56,6 +57,12 @@ pyo3 = { version = "0.21", features = ["extension-module"] }
criterion = { version = "0.5", features = ["html_reports"] }
quickcheck = "1.0"

# Web server
axum = "0.8"
tokio = { version = "1", features = ["full"] }
rust-embed = { version = "8", features = ["debug-embed"] }
open = "5"

[profile.dev]
debug = 2
opt-level = 0
Expand Down
84 changes: 82 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Train positioning library excels in post-processing the GNSS positions of your m
- 🚄 **High Performance**: R-tree spatial indexing for O(log n) nearest-track search
- 📍 **Accurate Projection**: Haversine distance and geodesic calculations with geo-rs
- 🛤️ **Train Path Calculation**: Probabilistic path calculation through rail networks using topology
- 🗺️ **Interactive Path Review**: Browser-based map webapp to visually review and edit calculated paths before projection
- 🌍 **CRS Aware**: Explicit coordinate reference system handling (EPSG codes)
- ⏰ **Timezone Support**: RFC3339 timestamps with explicit timezone offsets; timezone-less ISO 8601 datetimes assumed UTC
- 📊 **Multiple Formats**: CSV and GeoJSON input/output
Expand Down Expand Up @@ -47,6 +48,12 @@ tp-cli simple-projection --gnss positions.csv --network network.geojson --output

# Use pre-calculated path for projection
tp-cli --gnss positions.csv --network network.geojson --train-path path.csv --output result.csv

# Review calculated path in browser before projection (integrated mode)
tp-cli --gnss positions.csv --network network.geojson --output result.csv --review

# Launch standalone webapp to review/edit a path file
tp-cli webapp --network network.geojson --train-path path.csv --output reviewed_path.csv
```

### Debug Output
Expand All @@ -72,13 +79,70 @@ See **[DEBUG.md](DEBUG.md)** for a full description of the debug output files, t
- **Scalability**: Sub-linear scaling with R-tree spatial indexing
- **Memory**: Handles 10,000+ positions efficiently

## Train Path Review Webapp

The library ships a companion browser-based map webapp (`tp-webapp`) that lets you visually inspect and edit a calculated train path before using it for projection. No npm, no Node.js, no frontend build step required — the web assets are embedded in the binary at compile time using `rust-embed`.

### Modes

| Mode | Command | Use case |
|------|---------|----------|
| **Standalone** | `tp-cli webapp` | Review/edit an existing path file; save result to disk; server stays alive |
| **Integrated** | `tp-cli … --review` | Pause the projection pipeline after path calculation; confirm or abort in the browser |

### What You Can Do in the Browser

- View all network segments on a Leaflet map (OpenStreetMap basemap, toggleable)
- Path segments are highlighted with a colour-coded confidence scale
- **Add** a netelement to the path by clicking it on the map — snapped to the correct topological position
- **Remove** a path segment by clicking it — segment reverts to the default style
- Sidebar shows an ordered list of segments with probability scores
- **Dark mode** toggle (auto-activates from OS `prefers-color-scheme`)
- **Close Tab** button for clean exit after the server shuts down

### Standalone Usage

```sh
tp-cli webapp \
--network network.geojson \
--train-path path.csv \
--output reviewed_path.csv
```

A browser opens at `http://127.0.0.1:8765`. Click **Save** to write the reviewed path; the server stays alive for further edits. Press Ctrl+C when done.

The saved file is accepted directly by `--train-path`:

```sh
tp-cli --gnss positions.csv --network network.geojson \
--train-path reviewed_path.csv --output result.csv
```

### Integrated Usage

```sh
tp-cli --gnss positions.csv --network network.geojson \
--output result.csv --review
```

1. CLI calculates the train path
2. Browser opens automatically — review and edit the path
3. Click **Confirm** → path artifact saved as `result-path.csv`; projection continues
4. Click **Abort** → CLI exits with non-zero code

### Build Without Web Server

```sh
cargo build --package tp-cli --no-default-features
```

## Project Structure

```
tp-lib/ # Rust workspace root
├── tp-core/ # Core Rust library
│ ├── src/
│ │ ├── models/ # Data models (GnssPosition, Netelement, ProjectedPosition)
│ │ ├── models/ # Data models (GnssPosition, Netelement, ProjectedPosition, PathOrigin)
│ │ ├── projection/ # Projection algorithms (geom, spatial indexing)
│ │ ├── path/ # Train path calculation (candidate, probability, graph, viterbi)
│ │ ├── io/ # Input/output (CSV, GeoJSON, Arrow)
Expand All @@ -90,6 +154,7 @@ tp-lib/ # Rust workspace root
│ │ └── integration/ # Integration tests
│ └── benches/ # Performance benchmarks
├── tp-cli/ # Command-line interface
├── tp-webapp/ # Interactive path review web server (axum + Leaflet.js)
└── tp-py/ # Python bindings (PyO3)
```

Expand Down Expand Up @@ -383,13 +448,28 @@ xdg-open target/doc/index.html # Linux

### Specification Documents

**Feature 001 — GNSS Projection**
- [Feature Specification](specs/001-gnss-projection/spec.md)
- [Implementation Plan](specs/001-gnss-projection/plan.md)
- [Data Model](specs/001-gnss-projection/data-model.md)
- [CLI Contract](specs/001-gnss-projection/contracts/cli.md)
- [API Contracts](specs/001-gnss-projection/contracts/)
- [Tasks](specs/001-gnss-projection/tasks.md)

**Feature 002 — Train Path Calculation**
- [Feature Specification](specs/002-train-path-calculation/spec.md)
- [Implementation Plan](specs/002-train-path-calculation/plan.md)
- [Data Model](specs/002-train-path-calculation/data-model.md)
- [Tasks](specs/002-train-path-calculation/tasks.md)

**Feature 003 — Train Path Review Webapp**
- [Feature Specification](specs/003-path-review-webapp/spec.md)
- [Implementation Plan](specs/003-path-review-webapp/plan.md)
- [Data Model](specs/003-path-review-webapp/data-model.md)
- [REST API Contract](specs/003-path-review-webapp/contracts/api.md)
- [CLI Contract](specs/003-path-review-webapp/contracts/cli.md)
- [Quickstart](specs/003-path-review-webapp/quickstart.md)
- [Tasks](specs/003-path-review-webapp/tasks.md)

### CI/CD & Workflows

This project uses automated workflows for continuous integration and deployment:
Expand Down
6 changes: 6 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ ignore = [
# Updating to 0.24.1+ causes memory allocation issues during compilation
# Will be resolved once polars supports newer pyo3 versions
{ id = "RUSTSEC-2025-0020", reason = "pyo3 upgrade to 0.24.1+ blocked by polars dependency compatibility" },

# bytes 1.11.0 integer overflow in BytesMut::reserve; only exploitable with
# intentional usize::MAX-sized allocations and overflow-wrapping builds.
# Upgrade to bytes 1.10.1+ blocked by tokio/axum transitive constraint - will
# be resolved when the dependency graph allows a compatible bytes upgrade.
{ id = "RUSTSEC-2026-0007", reason = "bytes 1.11.0 integer overflow in BytesMut::reserve; transitive dependency via tokio/axum, upgrade tracked" },
]

# This section is considered when running `cargo deny check licenses`
Expand Down
36 changes: 36 additions & 0 deletions specs/003-path-review-webapp/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Specification Quality Checklist: Train Path Review Webapp

**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: March 21, 2026
**Feature**: [spec.md](../spec.md)

## Content Quality

- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified

## Feature Readiness

- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification

## Notes

- All items pass. Spec is ready for `/speckit.clarify` or `/speckit.plan`.
- Domain format terms (GeoJSON, CSV) are intentional — they refer to established contracts from prior features, not implementation choices.
- CLI syntax in FR-015/FR-016 is required to specify the user interface contract; it does not prescribe implementation.
Loading
Loading