Skip to content

feat(gpx): ✨ adding 3D GPX rendering#124

Draft
dvorka wants to merge 5 commits into
dev/1.60.0from
feat-122/gpx-3d
Draft

feat(gpx): ✨ adding 3D GPX rendering#124
dvorka wants to merge 5 commits into
dev/1.60.0from
feat-122/gpx-3d

Conversation

@dvorka

@dvorka dvorka commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator
Screenshot from 2026-06-30 16-50-57

Tasks:

  • code review (docstrings, --- / === removal, speed up)
  • simplify help below the image to (i), keep license
  • verify CREDITS.md

This PR brings 3D GPX rendering - after many iterations, several approaches tried, this implementation finally seems to be OKish.

Related:

@dvorka dvorka self-assigned this Jun 30, 2026
<script>
document.addEventListener("DOMContentLoaded", function () {
// Initialize all tooltips
if (typeof bootstrap === 'undefined') { return; }

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

@dvorka
dvorka marked this pull request as draft June 30, 2026 15:48
@dvorka
dvorka requested a review from Copilot July 1, 2026 08:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new 3D GPX terrain viewer feature in MyTraL: a backend pipeline that converts stored activity recordings into seam-safe, textured glTF terrain meshes + GeoJSON overlays, and a Babylon.js-based frontend page that renders and interacts with the result (including slope-colored track + linked elevation profile). It is surfaced from the activity page behind a new GPX_3D_MAP feature flag and includes tests, docs, and third‑party license updates.

Changes:

  • Added mytral.gpx_terrain backend modules (SRTM loading, tile selection, mesh building, glTF assembly, caching) plus comprehensive unit tests.
  • Added a new Flask blueprint and UI/JS assets for the 3D viewer page (terrain rendering, controls, fly-through, and a standalone SVG elevation/gradient chart).
  • Updated feature flag wiring, dependencies, changelog/docs, and third‑party license/credits entries.

Reviewed changes

Copilot reviewed 28 out of 30 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/test_gpx_terrain.py New unit test suite covering the 3D terrain pipeline modules.
pyproject.toml Adds runtime deps needed by the new terrain pipeline (numpy, srtm.py).
mytral/templates/macros/maps.html Adds an optional “3D” action button to the activity map card.
mytral/templates/layout.html Guards tooltip initialization when Bootstrap is absent.
mytral/templates/activity-view3d.html New 3D viewer page (controls, canvas, attribution, script wiring).
mytral/templates/activity-get.html Passes activity key + feature-flag state into the map macro for the 3D button.
mytral/static/js/terrain3d.js New Babylon.js scene implementation (terrain load, track drape, hover, camera presets, fly-through).
mytral/static/js/gpx-profile-chart.js New standalone SVG elevation/gradient profile renderer used by the 3D page.
mytral/run.py Registers the new 3D terrain blueprint in the web server entrypoint.
mytral/run_desktop.py Registers the new 3D terrain blueprint in the desktop entrypoint.
mytral/releng.py Adds GPX_3D_MAP feature flag + env var.
mytral/gpx_terrain/tile_cache.py New on-disk raster tile cache for offline/repeat-view performance.
mytral/gpx_terrain/terrain_service.py New orchestrator that generates GeoJSON + seam-safe glTF from track points.
mytral/gpx_terrain/mesh_builder.py New NumPy mesh generator (indices/verts/normals/UVs + enclosure walls).
mytral/gpx_terrain/map_tile.py New Web Mercator tile math + auto-zoom selection within tile budget.
mytral/gpx_terrain/hgt_loader.py New SRTM HGT loading and stitched grid sampling with void filling.
mytral/gpx_terrain/gpx_worker.py New track extraction from canonical Parquet + RDP simplification + stats + GeoJSON serialization.
mytral/gpx_terrain/gltf_writer.py New glTF 2.0 JSON assembler with embedded base64 buffers + mostly-emissive map material.
mytral/gpx_terrain/coordinates.py New coordinate utilities (haversine, bounding box, metres-per-degree).
mytral/gpx_terrain/init.py Exposes TerrainService as the package public API.
mytral/blueprints/gpx_terrain_views.py New routes: 3D page, GeoJSON/glTF APIs, and same-origin tile proxy with caching.
Makefile Enables the new feature flag in run-dev recipes.
licenses/srtm.txt Adds third‑party license text for srtm.py.
licenses/numpy.txt Adds third‑party license text for NumPy.
licenses/babylonjs.txt Adds third‑party license text for Babylon.js.
docs/FEATURE_GPC_3D.md New detailed design/feature documentation for the 3D GPX viewer.
CREDITS.md Adds attributions for CubeTrek inspiration and new dependencies.
CHANGELOG.md Documents the new 3D terrain viewer feature and its flag gating.

@@ -0,0 +1,370 @@
# MyTraL: my trailing log
Comment on lines +109 to +112
user_id = _require_user()
if not user_id:
return flask.redirect(flask.url_for("login"))

Comment on lines +118 to +121
maptype = flask.request.args.get("maptype", "osm")
if maptype not in ("osm", "standard", "satellite"):
maptype = "osm"

Comment on lines +142 to +145
user_id = _require_user()
if not user_id:
return flask.abort(401)

Comment on lines +182 to +185
user_id = _require_user()
if not user_id:
return flask.abort(401)

Comment on lines +259 to +262
user_id = _require_user()
if not user_id:
return flask.abort(401)

Comment on lines +296 to +299
headers={
"Cache-Control": "public, max-age=86400",
},
)
Comment on lines +68 to +70
if proxy_base:
return f"tiles/{tile_type}/{{z}}/{{x}}/{{y}}.png"
# direct CDN URLs (no proxy) — kept for tests and CLI usage
Comment on lines +288 to +289
template = _tile_template(tile_type, self._tile_proxy_base)

Comment thread tests/test_gpx_terrain.py
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

"""Tests for mytral.gpx_terrain modules (no network, no disk I/O)."""
@dvorka
dvorka changed the base branch from dev/1.57.0 to dev/1.58.0 July 6, 2026 07:06
@dvorka
dvorka changed the base branch from dev/1.58.0 to dev/1.60.0 July 20, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants