feat: add per-trip use_gpx and autoconnect toggles

Adds two configurable toggles to the trip blueprint (Admin2 Trip tab):
- use_gpx: show/hide GPX tracks on all maps (default: enabled)
- autoconnect: draw connector lines between markers (default: enabled)

When use_gpx is off, GPX files are not fetched or rendered on any map
(home, map, trip, dailies). The stats panel in trip.html.twig still
reads GPX_URLS directly and is unaffected.

When autoconnect is off, buildJourneySegments suppresses all
auto-connectors; only entries with force_connect:true still draw a
line — making force_connect behaviour independent of both settings.

Also refactors the inline Promise.all in trip.html.twig to use the
shared renderGpxJourney utility (reducing duplication).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vgmzx8VTTTmCskSpQtsLTr
This commit is contained in:
2026-06-21 11:20:25 +02:00
parent 7c2303c4e8
commit 21b572677e
6 changed files with 54 additions and 36 deletions
@@ -53,6 +53,8 @@
<script>
var FEED_ENTRIES = {{ map_entries|json_encode|raw }};
var GPX_URLS = {{ gpx_urls|json_encode|raw }};
var USE_GPX = {{ trip_page.header.use_gpx ?? true ? 'true' : 'false' }};
var AUTOCONNECT = {{ trip_page.header.autoconnect ?? true ? 'true' : 'false' }};
var feedMap = new maplibregl.Map({
container: 'feed-map',
@@ -87,7 +89,7 @@ feedMap.on('load', function () {
feedMap.fitBounds(bounds, { padding: 60, maxZoom: 11 });
}
Promise.all(GPX_URLS.map(function (url, idx) {
Promise.all((USE_GPX ? GPX_URLS : []).map(function (url) {
return fetch(url)
.then(function (r) { return r.text(); })
.then(function (text) {
@@ -101,7 +103,7 @@ feedMap.on('load', function () {
});
})).then(function (allTrackpoints) {
var validTrackpoints = allTrackpoints.filter(function (tp) { return tp.length > 0; });
var segments = MapUtils.buildJourneySegments(FEED_ENTRIES, validTrackpoints, 10);
var segments = MapUtils.buildJourneySegments(FEED_ENTRIES, validTrackpoints, 10, { autoconnect: AUTOCONNECT });
MapUtils.addJourneySegments(feedMap, segments, 'feed-journey');
});
});
+3 -1
View File
@@ -151,6 +151,8 @@
<script>
var HOME_ENTRIES = {{ map_entries|json_encode|raw }};
var HOME_GPX_URLS = {{ home_gpx_urls|json_encode|raw }};
var USE_GPX = {{ trip and trip.header.use_gpx is not null ? (trip.header.use_gpx ? 'true' : 'false') : 'true' }};
var AUTOCONNECT = {{ trip and trip.header.autoconnect is not null ? (trip.header.autoconnect ? 'true' : 'false') : 'true' }};
var homeMap = new maplibregl.Map({
container: 'home-map',
@@ -192,7 +194,7 @@ homeMap.on('load', function () {
setTimeout(function () { homeMap.resize(); }, 100);
MapUtils.renderGpxJourney(homeMap, HOME_GPX_URLS, HOME_ENTRIES, 'home-gpx', 'home-journey');
MapUtils.renderGpxJourney(homeMap, USE_GPX ? HOME_GPX_URLS : [], HOME_ENTRIES, 'home-gpx', 'home-journey', { autoconnect: AUTOCONNECT });
});
</script>
{% endif %}
+5 -3
View File
@@ -42,8 +42,10 @@
<script src="{{ url('theme://js/maplibre-utils.js') }}"></script>
<script>
var ENTRIES = {{ map_entries|json_encode|raw }};
var GPX_URLS = {{ gpx_urls|json_encode|raw }};
var ENTRIES = {{ map_entries|json_encode|raw }};
var GPX_URLS = {{ gpx_urls|json_encode|raw }};
var USE_GPX = {{ trip_page.header.use_gpx ?? true ? 'true' : 'false' }};
var AUTOCONNECT = {{ trip_page.header.autoconnect ?? true ? 'true' : 'false' }};
var map = new maplibregl.Map({
container: 'trip-map',
@@ -92,7 +94,7 @@ map.on('load', function () {
}
/* ── GPX tracks + journey segments ─────────────────────────── */
MapUtils.renderGpxJourney(map, GPX_URLS, ENTRIES, 'gpx', 'journey');
MapUtils.renderGpxJourney(map, USE_GPX ? GPX_URLS : [], ENTRIES, 'gpx', 'journey', { autoconnect: AUTOCONNECT });
});
</script>
{% endblock %}
+4 -25
View File
@@ -298,7 +298,9 @@
<script src="{{ url('theme://js/maplibre-utils.js') }}"></script>
<script>
var TRIP_ENTRIES = {{ map_entries|json_encode|raw }};
var GPX_URLS = {{ gpx_urls|json_encode|raw }};
var GPX_URLS = {{ gpx_urls|json_encode|raw }};
var USE_GPX = {{ page.header.use_gpx ?? true ? 'true' : 'false' }};
var AUTOCONNECT = {{ page.header.autoconnect ?? true ? 'true' : 'false' }};
var tripMap = new maplibregl.Map({
container: 'trip-map',
@@ -349,30 +351,7 @@ tripMap.on('load', function () {
}
/* ── GPX tracks + journey segments ─────────────────────────── */
Promise.all(GPX_URLS.map(function (url, idx) {
return fetch(url)
.then(function (r) { return r.text(); })
.then(function (text) {
var xml = new DOMParser().parseFromString(text, 'text/xml');
var geojson = toGeoJSON.gpx(xml);
var sid = 'gpx-' + idx;
tripMap.addSource(sid, { type: 'geojson', data: geojson });
tripMap.addLayer({
id: sid + '-line', type: 'line', source: sid,
layout: { 'line-join': 'round', 'line-cap': 'round' },
paint: { 'line-color': MapUtils.ACCENT, 'line-width': 2, 'line-opacity': 0.7 }
});
return MapUtils.extractTrackpoints(geojson);
})
.catch(function (err) {
console.warn('GPX load failed:', url, err);
return [];
});
})).then(function (allTrackpoints) {
var validTrackpoints = allTrackpoints.filter(function (tp) { return tp.length > 0; });
var segments = MapUtils.buildJourneySegments(TRIP_ENTRIES, validTrackpoints, 10);
MapUtils.addJourneySegments(tripMap, segments, 'trip-journey');
});
MapUtils.renderGpxJourney(tripMap, USE_GPX ? GPX_URLS : [], TRIP_ENTRIES, 'gpx', 'trip-journey', { autoconnect: AUTOCONNECT });
});
setTimeout(function () { tripMap.resize(); }, 100);