TrailOne is a full-stack web application for working with GPX hiking and trail data. It lets you upload a GPX file, validate and analyze the route, and generate a new GPX file enriched with distance-based waypoints and key trail markers.
The application has two main parts:
- A FastAPI backend that parses GPX files, validates them, computes elevation and distance metrics, and generates enriched GPX output.
- A React + Vite frontend that provides a simple browser-based workflow for uploading a file and downloading the result.
This makes the workflow suitable for trail planning, route review, and creating navigational marker files for hiking routes.
- Upload and validate GPX files
- Analyze route structure and track statistics
- Calculate cumulative 3D distance along the route
- Generate waypoints at fixed kilometer intervals
- Add special markers for:
- trail head
- trail end
- highest point
- lowest point
- halfway point
- Download the enriched GPX file directly from the browser
- Expose the same functionality through a REST API for scripting or integration
- api/app/main.py — FastAPI application entry point
- api/app/api/routes.py — API endpoints for health, analysis, waypoint generation, and distance calculation
- api/app/services/gpx_processing.py — GPX parsing, validation, statistics, and waypoint generation logic
- frontend/src/components/WaypointGenerator.tsx — browser UI for generating waypoint-enriched GPX files
- frontend/src/api/client.ts — frontend client for calling the API
- docker-compose.yml — container orchestration for API and frontend
To run the application locally, you need:
- Docker Desktop or Docker Engine with Docker Compose
- Optional for local Python development:
- Python 3.11+
- Node.js 18+
The simplest way to run the full solution is with Docker.
docker compose up --build- Frontend: http://localhost:81
- API documentation: http://localhost:8000/docs
- API health endpoint: http://localhost:81/v1/gpx/health/ready
docker compose downcd api
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reloadThe API will be available at http://localhost:8000.
cd frontend
npm install
npm run devThe frontend will be available at http://localhost:5173.
- Open the frontend in your browser.
- Select a GPX file from your computer.
- Enter a trail prefix (for example,
LCST). - Set a step size in kilometers (for example,
1for 1 km markers). - Choose a distance method:
auto— recommended defaultgeodesic— more accurate geodesic approximationhaversine— faster approximate spherical calculation
- Click “Generate and download”.
The application will download a new GPX file with additional waypoints based on the selected interval.
The backend exposes the following endpoints:
GET /v1/gpx/health/liveGET /v1/gpx/health/readyPOST /v1/gpx/analyzePOST /v1/gpx/elevationPOST /v1/gpx/generate-waypointsPOST /v1/gpx/distance
curl http://localhost:8000/v1/gpx/health/readycurl -X POST \
-F "file=@trail.gpx" \
http://localhost:8000/v1/gpx/analyzecurl -X POST \
-F "file=@trail.gpx" \
-F "trail_prefix=LCST" \
-F "step_size=1" \
-F "distance_method=auto" \
http://localhost:8000/v1/gpx/generate-waypoints \
--output lcst_waypoints.gpxcurl -X POST http://localhost:8000/v1/gpx/distance \
-H "Content-Type: application/json" \
-d '{
"point1": {"latitude": 40.0, "longitude": -3.0, "elevation": 100.0},
"point2": {"latitude": 40.01, "longitude": -3.01, "elevation": 120.0},
"distance_method": "auto"
}'The GPX uploader expects:
- a valid GPX file with
.gpxextension - at least one track and one track segment
- at least two track points
- valid latitude and longitude values
The backend also enforces sensible limits for uploaded file size and number of points.
The backend uses environment variables with the TRAILONE_ prefix. The defaults are defined in api/app/core/config.py.
Useful settings include:
TRAILONE_APP_NAMETRAILONE_APP_VERSIONTRAILONE_DEBUGTRAILONE_LOG_LEVELTRAILONE_MAX_UPLOAD_SIZE_BYTESTRAILONE_MAX_POINTS
Example:
export TRAILONE_MAX_UPLOAD_SIZE_BYTES=52428800
export TRAILONE_LOG_LEVEL=DEBUGWhen waypoint generation succeeds, the downloaded GPX file contains:
- the original route geometry preserved from the uploaded GPX
- new waypoint entries inserted at the requested interval distance
- markers for the trail head, trail end, highest point, lowest point, and halfway point
- If the frontend cannot reach the API, confirm that both Docker services are running and that the frontend is using the same-origin proxy path.
- If uploads fail, verify that the file is a valid GPX file and that it is not too large.
- If the API returns validation errors, check that the GPX file contains track points and that the coordinates are valid.
- If you want to inspect the API behavior interactively, open the Swagger UI at http://localhost:8000/docs.
- The frontend proxies
/v1/*requests to the API over the Docker network, so browser requests do not need manual CORS configuration. - The API remains directly accessible on port
8000for debugging and direct integration use.