PageSourceSearch

https://trailo.io/assets/app-viz-map.js?v=99

js trailo.io collected 2026-10-02 01:03:30 UTC 5,059 bytes, 138 lines download raw bytes

1/* app-viz-map.js — initializes a small Leaflet map inside every .appviz__map.
2   Depot + 3 stops + pre-computed OSRM polyline (no interactivity).
3   - Carto Positron @2x tiles (clean, muted; brand-blue route pops)
4   - Route via L.polyline → renders in overlayPane (z=400), automatically
5     stays BELOW markers (z=600) — no z-index war.
6   - fitBounds called AFTER invalidateSize so the container has real
7     dimensions when the zoom level is computed (otherwise Leaflet sees a
8     0-width container and over-zooms onto a single point).
9   - maxZoom cap prevents zoom 18/19 close-ups when the bounds are small. */
10(function () {
11  if (typeof window === 'undefined') return;
12  if (typeof window.L === 'undefined') return;
13  var L = window.L;
14
15  var DEPOT = { lat: 48.1605, lng: 11.5862 };
16  var STOPS = [
17    { n: 1, lat: 48.1431, lng: 11.4631, kind: 'brand' },
18    { n: 2, lat: 48.1395, lng: 11.4994, kind: 'brand' },
19    { n: 3, lat: 48.1542, lng: 11.5430, kind: 'amber' }
20  ];
21  // Pre-computed OSRM route: depot → 1 → 2 → 3 → depot
22  var ROUTE = [
23    [48.16053,11.58606],[48.16181,11.5864],[48.16278,11.57978],[48.16249,11.57473],
24    [48.16035,11.57505],[48.16122,11.56899],[48.16093,11.56515],[48.16154,11.55731],
25    [48.16146,11.55111],[48.15397,11.53689],[48.15186,11.53677],[48.15305,11.53345],
26    [48.15178,11.52742],[48.15102,11.52033],[48.14554,11.52017],[48.14141,11.51868],
27    [48.14327,11.50367],[48.14506,11.48268],[48.14555,11.46987],[48.14664,11.46135],
28    [48.14405,11.46106],[48.1431,11.46309],[48.14034,11.4677],[48.14226,11.47494],
29    [48.13965,11.49939],[48.13894,11.51796],[48.14554,11.52017],[48.15102,11.52033],
30    [48.15178,11.52742],[48.15302,11.53332],[48.15187,11.53615],[48.15129,11.53932],
31    [48.15361,11.54115],[48.15388,11.54164],[48.15329,11.54241],[48.15385,11.54343],
32    [48.15401,11.54406],[48.15329,11.54241],[48.15535,11.53988],[48.16133,11.55138],
33    [48.16131,11.5583],[48.16001,11.56151],[48.15765,11.57438],[48.15781,11.57989],
34    [48.15725,11.58446],[48.16053,11.58606]
35  ];
36
37  function pinIcon(text, kind) {
38    return L.divIcon({
39      html: '<div class="appviz__lpin appviz__lpin--' + kind + '">
39' + text + '</div>',
40      className: 'appviz__lmarker',
41      iconSize: [28, 28],
42      iconAnchor: [14, 14]
43    });
44  }
45
46  function initMap(el) {
47    if (!el || el.__avLeaflet) return;
48    el.__avLeaflet = true;
49
50    // Drop the static SVG fallback before Leaflet builds its DOM
51    el.innerHTML = '';
52
53    var map = L.map(el, {
54      center: [48.150, 11.524],
55      zoom: 11,
56      zoomControl: false,
57      attributionControl: true,
58      scrollWheelZoom: false,
59      doubleClickZoom: false,
60      dragging: false,
61      touchZoom: false,
62      boxZoom: false,
63      keyboard: false,
64      fadeAnimation: false,
65      zoomAnimation: false
66    });
67
68    // CARTO Positron @2x mit kostenlosem Basemap-Key (public by design;
69    // gleicher Key wie in app.js) — forced @2x for crispness even when
70    // the parent stage is transform-scaled by --av-s.
71    L.tileLayer('https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png?key=cb1_2a4g_1_e414ae310fadb94c6e5539b0', {
72      maxZoom: 19,
73      attribution: '© OpenStreetMap © CARTO',
74      crossOrigin: true,
75      detectRetina: false
76    }).addTo(map);
77
78    // Route polyline — renders in overlayPane (z=400), guaranteed BELOW
79    // markers (z=600). White halo for visibility on busy tile sections,
80    // brand blue on top.
81    L.polyline(ROUTE, {
82      color: '#ffffff',
83      weight: 8,
84      opacity: 0.95,
85      lineCap: 'round',
86      lineJoin: 'round',
87      interactive: false
88    }).addTo(map);
89    L.polyline(ROUTE, {
90      color: '#4f72e3',
91      weight: 4.5,
92      opacity: 1,
93      lineCap: 'round',
94      lineJoin: 'round',
95      interactive: false
96    }).addTo(map);
97
98    // Markers: depot + 3 stops (markerPane z=600 → always on top of route)
99    L.marker([DEPOT.lat, DEPOT.lng], {
100      icon: pinIcon('S', 'start'),
101      interactive: false,
102      keyboard: false
103    }).addTo(map);
104    STOPS.forEach(function (s) {
105      L.marker([s.lat, s.lng], {
106        icon: pinIcon(String(s.n), s.kind),
107        interactive: false,
108        keyboard: false
109      }).addTo(map);
110    });
111
112    // Fit AFTER invalidateSize so Leaflet sees real container dimensions
113    // (otherwise it over-zooms onto a single point). Cap zoom so the
114    // route stays well in frame.
115    var all = STOPS.map(function (s) { return [s.lat, s.lng]; });
116    all.push([DEPOT.lat, DEPOT.lng]);
117    var bounds = L.latLngBounds(all);
118
119    function settle() {
120      map.invalidateSize({ animate: false });
121      map.fitBounds(bounds, { padding: [18, 18], maxZoom: 12, animate: false });
122    }
123    settle();
124    setTimeout(settle, 120);
125    setTimeout(settle, 500);
126  }
127
128  function initAll() {
129    var maps = document.querySelectorAll('.appviz__map');
130    Array.prototype.forEach.call(maps, initMap);
131  }
132
133  if (document.readyState === 'loading') {
134    document.addEventListener('DOMContentLoaded', initAll);
135  } else {
136    initAll();
137  }
138})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.