Skip to content
Closed
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
101 changes: 82 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
# GPX Route Mapper
# GPX Route Editor

A 100% client-side tool to **draw ferry / sailing routes on OpenStreetMap and export them as GPX** — built for [ferry.hk](https://www.ferry.hk) to hand-plot the sea routes that automated routing can't get right.
A 100% client-side editor for **drawing, importing, reshaping, inspecting and exporting GPX tracks on OpenStreetMap**. Adjust route geometry and supported point metadata without uploading the file or sending its recorded locations anywhere.

Two things set it apart from a plain map drawer:
It is a [Ferry La](https://www.ferry.hk) × [Stealth Co.](https://stealth-company.co) open-source project, but it is not limited to ferry routes. Use it for walking, cycling, driving, sailing or any custom track that you want to shape manually. Optional OpenStreetMap ferry data remains available as one reference source.

- **An "Artistic" basemap** — the same OSM data rendered in ferry.hk's monochrome green + fine-line house style, toggleable against the standard map.
- **A live OSM ferry-route overlay, with bilingual (中文 · English) names** — the real published sailing lines drawn underneath your cursor, so you can *trace* them instead of guessing.
[Open the GPX Route Editor](https://stealth-engine.github.io/gpx-route-editor/)

No API keys, no backend, no build step — the whole app is one `index.html`, deliberately simpler than the big route-planning tools. Open the file and go.
No API keys, no backend and no build step are required. The whole app is one `index.html`, deliberately simpler than a full route-planning service: you control the track geometry and the editor does not invent turn-by-turn directions.

## Features

- **OpenStreetMap basemap** via [MapLibre GL JS](https://maplibre.org/) + [OpenFreeMap](https://openfreemap.org/) vector tiles — no key required.
- **Artistic (ferry.hk) basemap** — monochrome deep-green land/water with hairline roads and coastline, generated as a custom MapLibre style over the same vector data.
- **OSM ferry routes overlay** — real `route=ferry` lines drawn as a cyan dashed reference, **with bilingual labels** (`name:zh-Hant · name:en`, falling back gracefully). Works on *both* basemaps. Toggle on/off.
- **Edit a route** — click the map to append points, use the `+` handles to insert points between existing ones, select and drag points to move them, and remove the selection with the visible Delete button or keyboard. Undo with **⌘/Ctrl+Z** and redo with **⌘/Ctrl+Y** or **⌘/Ctrl+Shift+Z**.
- **Standard and Artistic basemaps** — switch between the normal map and Ferry La's monochrome deep-green MapLibre style over the same OpenStreetMap vector data.
- **Optional OSM ferry references** — load or overlay real `route=ferry` lines, with bilingual labels where available, when a sailing line is useful to the track you are editing.
- **Edit a route** — click the map to append points, use the `+` handles to insert points between existing ones, and select a point to reveal contextual **Edit** and **Delete** actions directly on the map. Drag the selected point to move it. Undo with **⌘/Ctrl+Z** and redo with **⌘/Ctrl+Y** or **⌘/Ctrl+Shift+Z**.
- **Route shaping** — keep the original line, apply Catmull-Rom smoothing, or snap control points onto nearby OSM roads, paths, tracks, and ferry sailings. Snap follows mapped geometry across vector-tile boundaries; ferry matching also bridges small fragment gaps and can change lines at visible sailing-route intersections.
- **Place search** — Google-style start + optional destination boxes ([Nominatim](https://nominatim.org/) geocoding) that drop start/end markers and frame the view.
- **Import GPX tracks and routes** — load a local `.gpx` file as editable points without uploading it. Disconnected track segments remain disconnected.
- **Point metadata inspection** — hover an imported point to see available elevation, time, speed, heart rate, cadence, temperature, accuracy, and vendor-extension values.
- **Point metadata editing** — select a point and press **Edit** to update standard GPX fields and recognised scalar sensor readings, with validation, original-value indicators, reset, undo, and redo.
- **Mobile map controls** — on narrow screens the editor becomes a scrollable control sheet that can collapse to leave the map clear; entering Draw mode collapses it automatically.
- **Zoom + scale controls.**
- **Export GPX** — prompts for a route name, **pre-filled intelligently**: from your start/destination if set, otherwise reverse-geocoded from the drawn endpoints, otherwise a dated fallback. The name is used for both the filename and the GPX `<name>`.
- **Export GPX** — prompts for a route name, **pre-filled intelligently**: from your start/destination if set, otherwise reverse-geocoded from the drawn endpoints, otherwise a dated fallback. In Original mode, imported point metadata and segment boundaries are preserved.

## Run it

Expand All @@ -31,15 +34,75 @@ python3 -m http.server 8000
```

- Or open `index.html` directly in a browser.
- Or enable **GitHub Pages** (Settings → Pages → deploy from `main`) to host it at a public URL.
- Or use the hosted editor at **https://stealth-engine.github.io/gpx-route-editor/**.
- To host your own fork, enable **GitHub Pages** (Settings → Pages → deploy from `main`).

## Using it
## How to use the editor

1. Under **Route source**, use **Search** to find a start and optional destination, or choose **Ferry route** to fetch and load an OSM sailing route in the current map view.
2. Flip the basemap to **Artistic** if you want the ferry.hk look; keep **Show OSM ferry routes** ticked to see the real sailings.
3. Click **✎ Draw**, then click along the map to lay your route. Use a `+` handle to add detail between points; select a point to drag or delete it.
4. Choose **Original**, **Smooth**, or **Snap** under Route shaping. Snap works best when you draw close to a visible mapped path or ferry line; points without a nearby match stay unchanged.
5. **Export GPX**, confirm/edit the name, and download.
### 1. Choose a route source

Open **Route source** and choose one of these options:

- **Search** — find a starting place and, optionally, a destination. The map adds markers and frames both places, but it does not generate the route between them.
- **Ferry route** — load a published `route=ferry` relation from OpenStreetMap as a starting line.
- **GPX file** — choose a local `.gpx` track or route. The file is parsed in your browser and is not uploaded.

### 2. Set up the map

- Choose **Standard** for the normal OpenStreetMap appearance or **Artistic** for the Ferry La house style.
- Keep **Show ferry routes** enabled when you want existing OSM sailing lines as a tracing reference.
- Use **Explore** when you only want to pan and zoom the map.

### 3. Draw or adjust the route

1. Press **Draw**. On a phone, this automatically collapses the control sheet so the map remains usable.
2. Tap or click the map to append a route point.
3. Select an existing point to reveal the on-map **Edit** and **Delete** actions.
4. Drag the selected point to move it. On touchscreens, a small movement threshold prevents an ordinary tap from shifting the point accidentally.
5. Press a `+` handle between two points to insert another point.
6. Use **Undo** and **Redo** for experimental changes, or **Clear** to remove the whole route.

Keyboard users can delete the selected point with Delete or Backspace. Undo and redo use **⌘/Ctrl+Z**, **⌘/Ctrl+Y**, or **⌘/Ctrl+Shift+Z**.

### 4. Choose route shaping

- **Original** — keeps the control points and line exactly as edited. Use this mode when imported GPX metadata must be preserved.
- **Smooth** — rounds corners using a Catmull–Rom curve.
- **Snap** — follows nearby OSM roads, paths, tracks, and ferry lines. Draw close to the intended mapped feature; unmatched points remain unchanged.

Switching shaping modes is reversible. It does not replace the original control points.

### 5. Inspect and edit GPX metadata

- On a desktop, hover over an imported point to inspect its recorded metadata.
- On any device, select the point and press **Edit** to open the metadata editor.
- Save the fields you want to change, leave a field blank to remove it, or use **Reset original** to restore the imported values.

Read [Editing imported metadata safely](#editing-imported-metadata-safely) before changing recorded timestamps, elevation, speed, or sensor data.

### 6. Export the route

1. Choose **Original**, **Smooth**, or **Snap** for the geometry you want to export.
2. Press **Export GPX**.
3. Confirm or change the suggested route name.
4. Download the generated `.gpx` file.

The editor warns before export when the selected shaping mode cannot safely preserve imported point metadata.

### Mobile controls

Use **Map** to collapse the control sheet and **Controls** to reopen it. When a point is selected, its **Edit** and **Delete** actions stay directly above the collapsed sheet, so you do not need to reopen the controls.

## Editing imported metadata safely

- In **Original** shaping mode, existing point metadata is retained when a point is moved. Newly inserted points have no recorded metadata, and deleting a point deletes its metadata with it.
- Select a point and press **Edit** to change elevation, timestamp, name, comment, description, symbol, and type. Recognised speed, course, heart-rate, cadence, temperature, and power values appear under **Advanced sensor values**.
- GPS fix, satellite count, dilution-of-precision values, DGPS fields, and unrecognised vendor structures are read-only. This avoids presenting manually changed accuracy data as if it came from the recording device.
- Blank an editable field to remove it. **Reset original**, Undo, and Redo retain the imported values so experimental edits remain reversible.
- Elevation, timestamps, speed, sensor readings, and accuracy values describe the original recording. If you move a point, the editor flags that those values may no longer match its new position.
- **Smooth** and **Snap** generate a different set of output points. The editor does not invent or interpolate timestamps, elevation, speed, or sensor readings for those points, so point metadata is omitted from that shaped export. Switch back to **Original** before export to preserve it.
- GPX 1.0 core speed/course fields and GPX 1.1 vendor extensions are preserved as XML. Extension field meanings and units can be vendor-specific, so check the originating device/app schema when those values matter operationally.
- The preservation guarantee covers point-level metadata and segment boundaries. File-level author/copyright data and track-level descriptions/extensions are not copied; files containing multiple `<trk>` elements are exported as one track with separate segments.

## Data & attribution

Expand All @@ -50,8 +113,8 @@ python3 -m http.server 8000

## Notes

- Ferry **labels appear only where OSM has a name** for the route. Major services (Star Ferry, Sun Ferry to the outlying islands) are named; some minor kaito services aren't and show only the dashed line.
- Everything runs in the browser — the only network calls are to the public OSM tile/geocoding services above.
- The ferry source and overlay are optional map references, not a restriction on the kinds of GPX tracks you can edit. Ferry labels appear only where OpenStreetMap provides a route name.
- Everything runs in the browser — the only network calls are to the public OSM tile and geocoding services above.

## License

Expand Down
8 changes: 8 additions & 0 deletions app-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading