User Manual & Troubleshooting

Everything you need to use Bridleway Map and fix common problems.

Last edited: 7 June 2026

1. Overview

Bridleway Map shows your GPX ride history overlaid on council bridleway, byway, and BOAT data for 8 districts across the north of England. All path types — bridleways, BOATs, and byways — are shown for every district that has them. It calculates which paths you have ridden and tracks your progress toward completing them all.

It also tracks your progress on two structured cycling challenges: the Facey 50 (50 Kirklees road climbs) and the Calderdale 50 (50 Calderdale road climbs), automatically detecting which climbs you've completed from your GPX history.

Districts covered

Bradford, Calderdale, Derbyshire, Kirklees, Lancashire, Oldham, Rochdale, Wakefield

Path types

Bridleways (blue/green), BOATs (amber), Byways (purple)

2. Initial setup

  1. 1

    Place your GPX files

    Export rides from Strava (Settings → Export Account Data) and copy the .gpx files into data/gpx/activities/.

  2. 2

    Place bridleway data

    Copy council GeoJSON files into data/bridleways/ using the naming convention District-Type-JSON.json, e.g. Calderdale-Bridleways-JSON.json.

  3. 3

    Run the pipeline

    In the project directory, run:

    npm run prepare-data

    This parses GPX files, merges and builds the bridleway map data, runs the geospatial analysis, and detects Facey 50 and Calderdale 50 completions (~2 minutes).

  4. 4

    Start the app

    npm run dev

    Open http://localhost:4321 in your browser.

3. Using the map

Sidebar controls

Districts Tick the districts you want to see. Use the All Districts checkbox to toggle all at once. Your selection is remembered across sessions.
Path types Toggle bridleways, BOATs, and byways independently.
Show ride tracks Overlay your GPX tracks on the map in red.
Show unridden only Hides all paths you have already ridden, leaving only the ones still to do.
Filter by year Shows ride tracks from selected years only.

Basemap layer toggle

Two buttons in the top-right corner of the map switch the basemap:

OS 1:25k Default. Ordnance Survey raster map at 1:25,000 scale — shows rights of way, field boundaries, and detailed terrain. Requires an OS Maps API key.
OSM OpenStreetMap standard tiles. Useful as a fallback when no OS API key is configured.

Colour coding

Bridleway — ridden (GPS-detected)
Bridleway — ridden (manually marked)
Bridleway — unridden
BOAT — ridden
BOAT — unridden
Byway — ridden
Byway — unridden
Your ride tracks

Clicking a path

Click any path to see a popup with its reference number, ridden status, and (for unridden paths) a Mark as Ridden button. Click a ride track to see its name and date.

4. Adding & viewing rides

Uploading a new GPX file

  1. On the Map page, scroll to Add Ride at the bottom of the sidebar.
  2. Drag a .gpx file onto the drop zone, or click it to browse.
  3. Click Upload & re-parse rides. The file is saved and all rides are re-parsed (a few seconds).
  4. Click Re-run analysis in the Progress section to update the ridden stats for the new ride.

Bulk import

Copy any number of .gpx files directly into data/gpx/activities/, then run npm run prepare-data from the terminal.

Rides table

The Rides page lists every parsed ride with date, distance, duration, and elevation gain, grouped by year. Click a row to see the ride's GPS track on a map.

5. Marking paths as ridden

The geospatial analysis automatically detects ridden paths using a 15 m GPS buffer, but sometimes GPS noise or a brief detour means a path you rode isn't detected. You can mark it manually.

How to mark a path

  1. Load the relevant district on the map.
  2. Click the unridden path (shown in blue).
  3. In the popup, click ✓ Mark as Ridden.
  4. The path turns orange immediately and is hidden when "Show unridden only" is active.

How to unmark a path

  1. Click the orange (manually marked) path.
  2. In the popup, click ✕ Unmark.

Updating the stats

Manual marks are saved instantly to data/manual-ridden.json and reflected in the map immediately. To update the district progress percentages, click Re-run analysis in the sidebar's Progress section.

Note: GPS-detected rides (green) cannot be unmarked from the UI — they are determined by your GPX data. Re-running the analysis will always re-detect them.

6. Running the analysis

The analysis compares every GPS point in your ride tracks against every bridleway segment using a spatial grid index. A segment is marked ridden if any part of it falls within ~15 m of a GPS point.

Via the UI

Click Re-run analysis in the sidebar's Progress section. The button shows a running state while it works (~1–2 minutes) and reloads the page when done.

Via the terminal

npm run analyze

Then refresh the browser to see updated stats.

Updating climb completions

Facey 50 and Calderdale 50 completion data is updated separately. Run:

npm run analyze-climbs

Or include it in the full pipeline with npm run prepare-data.

When to re-run

  • After uploading a new GPX ride
  • After manually marking or unmarking paths
  • After adding new bridleway GeoJSON files

7. Progress & statistics

The Progress page shows per-district stats: total miles of rights of way, miles ridden, and percentage complete. The sidebar on the Map page shows the same bars at a glance.

Both GPS-detected and manually marked rides contribute to the mileage totals after analysis is re-run.

8. Facey 50

The Facey 50 page tracks your progress on the 50 Kirklees road climbs defined by the Facey Fifty challenge. Completions are detected automatically from your GPX history.

How completion is detected

A climb is counted as completed if a ride track passes within 200 m of the climb start and within 300 m of the climb end. Only rides within the Kirklees area bounding box are checked.

Viewing a climb

Click any row in the table to open a detail panel showing:

  • Distance, ascent, and average gradient
  • A map of the climb route (orange line)
  • Completion date(s) and number of attempts
  • A link to the Strava segment

Updating completions

npm run analyze-climbs

Run this after uploading new GPX files to pick up any newly completed climbs.

9. Calderdale 50

The Calderdale 50 page tracks your progress on the 50 Calderdale road climbs from calderdale50.wordpress.com. It follows the same detection approach as the Facey 50.

Area filter

The 50 climbs are grouped into 13 areas (Cornholme, Greetland, Halifax, Hebden Bridge, and so on). Click an area pill at the top of the page to filter the table to that area only. Each pill shows a done / total count for that area. Click All to show everything.

Viewing a climb

Click any row to open a detail panel showing the climb map, stats, completion info, and a link to the plotaroute.com route definition.

Updating completions

npm run analyze-climbs

This updates both Facey 50 and Calderdale 50 completion data in one command.

10. Troubleshooting

Paths I've ridden show as unridden

  • The 15 m GPS buffer may not have caught the path if your GPS drifted or you passed at a distance. Use Mark as Ridden in the popup, then re-run analysis.
  • Make sure you've run the analysis recently — the map reflects whatever progress.json was last generated.
  • Check that the GPX file for that ride is in data/gpx/activities/ and ends in .gpx.

A climb shows as incomplete when I've ridden it

  • The detection requires passing within 200 m of the start and 300 m of the end. If your GPS track deviated significantly near either point, it may not trigger.
  • Re-run npm run analyze-climbs after adding the relevant GPX file.

A whole district is missing from the progress bars

  • Check that the bridleway JSON files for that district exist in data/bridleways/ with the correct naming: District-Bridleways-JSON.json.
  • Re-run npm run analyze and look at the terminal output for error lines beginning with .

Mark as Ridden gives a SyntaxError

  • This usually means a stale dev server is running. Stop all Node processes and restart: npm run dev.
  • On Windows you can check Task Manager for lingering node.exe processes on port 4321.

Re-run analysis button says "Analysis failed"

  • The error detail is shown below the button. Common causes: a missing or malformed bridleway JSON file, or a GPX file that couldn't be parsed.
  • Run npm run analyze in the terminal for the full output.

GPX upload fails

  • Only .gpx files are accepted.
  • The file must contain a track (<trk> element) with at least 2 track points.
  • If the upload succeeds but the ride doesn't appear, check the terminal — the parse script prints a warning for files it skips.

The map is blank / districts don't load

  • Open the browser console (F12) and look for failed network requests. District GeoJSON files must be in public/data/bridleways/.
  • Run npm run setup-bridleways to merge and build them from the source files in data/bridleways/.

No ride tracks appear on the map

  • Ensure Show ride tracks is checked in the sidebar.
  • Check the year filter — all years must be ticked to see all rides.
  • Run npm run parse-gpx if you haven't yet.

Map tiles don't load (grey squares)

  • Check your internet connection — map tiles are fetched from OpenStreetMap and Ordnance Survey servers.
  • The OS 1:25k layer requires a valid OS Maps API key. If tiles stop loading, check your monthly quota at osdatahub.os.uk (free tier: 3,000 transactions/month).

Analysis is slow or hangs

The full analysis across all districts takes 1–2 minutes. If it hangs for more than 5 minutes, kill the process and re-run — a single malformed GPX file can cause a loop. Check the terminal output line by line to identify which district stalled.

11. Data & privacy

All ride and bridleway data stays on your machine. Nothing is sent to any external service.

GPX filesdata/gpx/activities/ — gitignored
Bridleway GeoJSONdata/bridleways/ — gitignored (Open Government Licence)
Manual marksdata/manual-ridden.json — gitignored
Generated datadata/generated/ and public/data/ — gitignored

Map tiles are fetched from external servers — only tile coordinates (not your location or ride data) are sent: