gtfs-to-html 2.9.15 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtfs-to-html",
3
- "version": "2.9.15",
3
+ "version": "2.10.0",
4
4
  "private": false,
5
5
  "description": "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
6
6
  "keywords": [
@@ -53,7 +53,7 @@
53
53
  "cli-table": "^0.3.11",
54
54
  "csv-stringify": "^6.5.1",
55
55
  "express": "^5.0.1",
56
- "gtfs": "^4.15.2",
56
+ "gtfs": "^4.15.3",
57
57
  "gtfs-realtime-pbf-js-module": "^1.0.0",
58
58
  "insane": "^2.6.2",
59
59
  "js-beautify": "^1.15.1",
@@ -63,7 +63,7 @@
63
63
  "pbf": "^4.0.1",
64
64
  "pretty-error": "^4.0.0",
65
65
  "pug": "^3.0.3",
66
- "puppeteer": "^23.5.3",
66
+ "puppeteer": "^23.6.0",
67
67
  "sanitize-filename": "^1.6.3",
68
68
  "sqlstring": "^2.3.3",
69
69
  "timer-machine": "^1.1.0",
@@ -79,7 +79,7 @@
79
79
  "@types/js-beautify": "^1.14.3",
80
80
  "@types/lodash-es": "^4.17.12",
81
81
  "@types/morgan": "^1.9.9",
82
- "@types/node": "^20.16.11",
82
+ "@types/node": "^20.16.13",
83
83
  "@types/pug": "^2.0.10",
84
84
  "@types/puppeteer": "^7.0.4",
85
85
  "@types/sanitize-filename": "^1.6.3",
@@ -166,23 +166,23 @@ a:hover {
166
166
  width: 100%;
167
167
  }
168
168
 
169
- .overview-map .mapboxgl-popup-content .popup-title {
169
+ .overview-map .maplibregl-popup-content .popup-title {
170
170
  margin: 0 20px 5px 0;
171
171
  font-size: 16px;
172
172
  font-weight: bold;
173
173
  }
174
174
 
175
- .overview-map .mapboxgl-popup-content .popup-label {
175
+ .overview-map .maplibregl-popup-content .popup-label {
176
176
  border-bottom: 1px solid #e0e0e0;
177
177
  padding-top: 0.5rem;
178
178
  }
179
179
 
180
- .overview-map .mapboxgl-popup-content .route-list {
180
+ .overview-map .maplibregl-popup-content .route-list {
181
181
  margin-bottom: 1rem;
182
182
  margin-top: 0.25rem;
183
183
  }
184
184
 
185
- .overview-map .mapboxgl-popup-content .map-route-item {
185
+ .overview-map .maplibregl-popup-content .map-route-item {
186
186
  display: flex;
187
187
  align-items: center;
188
188
  font-size: 0.75rem;
@@ -191,14 +191,14 @@ a:hover {
191
191
  gap: 0.5rem;
192
192
  }
193
193
 
194
- .overview-map .mapboxgl-popup-content .map-route-item:hover {
194
+ .overview-map .maplibregl-popup-content .map-route-item:hover {
195
195
  text-decoration: none;
196
196
  }
197
197
 
198
- .overview-map .mapboxgl-popup-content a.map-route-item .underline-hover:hover {
198
+ .overview-map .maplibregl-popup-content a.map-route-item .underline-hover:hover {
199
199
  text-decoration: underline;
200
200
  }
201
201
 
202
- .overview-map .mapboxgl-popup-content .mapboxgl-popup-close-button {
202
+ .overview-map .maplibregl-popup-content .maplibregl-popup-close-button {
203
203
  padding: 0 5px;
204
204
  }
@@ -453,24 +453,24 @@ a:hover {
453
453
  }
454
454
  }
455
455
 
456
- .timetable-page .map .mapboxgl-popup-content .popup-title {
456
+ .timetable-page .map .maplibregl-popup-content .popup-title {
457
457
  margin: 0 20px 5px 0;
458
458
  font-size: 1rem;
459
459
  font-weight: 700;
460
460
  line-height: 1;
461
461
  }
462
462
 
463
- .timetable-page .map .mapboxgl-popup-content .popup-label {
463
+ .timetable-page .map .maplibregl-popup-content .popup-label {
464
464
  border-bottom: 1px solid #e0e0e0;
465
465
  padding-top: 0.5rem;
466
466
  }
467
467
 
468
- .timetable-page .map .mapboxgl-popup-content .route-list {
468
+ .timetable-page .map .maplibregl-popup-content .route-list {
469
469
  margin-bottom: 1rem;
470
470
  margin-top: 0.25rem;
471
471
  }
472
472
 
473
- .timetable-page .map .mapboxgl-popup-content .map-route-item {
473
+ .timetable-page .map .maplibregl-popup-content .map-route-item {
474
474
  display: flex;
475
475
  align-items: center;
476
476
  font-size: 0.75rem;
@@ -479,23 +479,23 @@ a:hover {
479
479
  gap: 0.5rem;
480
480
  }
481
481
 
482
- .timetable-page .map .mapboxgl-popup-content .map-route-item:hover {
482
+ .timetable-page .map .maplibregl-popup-content .map-route-item:hover {
483
483
  text-decoration: none;
484
484
  }
485
485
 
486
486
  .timetable-page
487
487
  .map
488
- .mapboxgl-popup-content
488
+ .maplibregl-popup-content
489
489
  a.map-route-item
490
490
  .underline-hover:hover {
491
491
  text-decoration: underline;
492
492
  }
493
493
 
494
- .timetable-page .map .mapboxgl-popup-content .mapboxgl-popup-close-button {
494
+ .timetable-page .map .maplibregl-popup-content .maplibregl-popup-close-button {
495
495
  padding: 0 5px;
496
496
  }
497
497
 
498
- .timetable-page .map .mapboxgl-popup-content .upcoming-stops {
498
+ .timetable-page .map .maplibregl-popup-content .upcoming-stops {
499
499
  display: grid;
500
500
  grid-template-columns: auto 1fr;
501
501
  gap: 0.5rem;
@@ -505,7 +505,7 @@ a:hover {
505
505
 
506
506
  .timetable-page
507
507
  .map
508
- .mapboxgl-popup-content
508
+ .maplibregl-popup-content
509
509
  .upcoming-stops div:nth-child(1) {
510
510
  font-weight: bold;
511
511
  border-bottom: 1px solid #dddddd;
@@ -515,7 +515,7 @@ a:hover {
515
515
 
516
516
  .timetable-page
517
517
  .map
518
- .mapboxgl-popup-content
518
+ .maplibregl-popup-content
519
519
  .upcoming-stops div:nth-child(2) {
520
520
  font-weight: bold;
521
521
  border-bottom: 1px solid #dddddd;
@@ -525,20 +525,20 @@ a:hover {
525
525
 
526
526
  .timetable-page
527
527
  .map
528
- .mapboxgl-popup-content
528
+ .maplibregl-popup-content
529
529
  .upcoming-stops
530
530
  div:nth-child(2n-1) {
531
531
  text-align: right;
532
532
  font-weight: bold;
533
533
  }
534
534
 
535
- .timetable-page .map .mapboxgl-popup-content .vehicle-updated {
535
+ .timetable-page .map .maplibregl-popup-content .vehicle-updated {
536
536
  padding-top: 5px;
537
537
  font-size: 10px;
538
538
  text-align: right;
539
539
  }
540
540
 
541
- .timetable-page .map .vehicle-popup .mapboxgl-popup-content {
541
+ .timetable-page .map .vehicle-popup .maplibregl-popup-content {
542
542
  padding-bottom: 5px;
543
543
  }
544
544
 
@@ -550,7 +550,7 @@ a:hover {
550
550
  padding: 10px;
551
551
  position: absolute;
552
552
  left: 10px;
553
- bottom: 35px;
553
+ bottom: 10px;
554
554
  z-index: 1;
555
555
  }
556
556
 
@@ -97,12 +97,13 @@
97
97
  }
98
98
 
99
99
  return {
100
+ gtfsRealtimeUrls,
101
+ mapStyleUrl: config.mapStyleUrl,
100
102
  pageData: {
101
103
  routeIds: _.uniq(_.flatMap(timetablePage.consolidatedTimetables, timetable => timetable.routes.map(route => route.route_id))),
102
104
  tripIds: _.uniq(_.flatMap(timetablePage.consolidatedTimetables, timetable => timetable.orderedTrips.map(trip => trip.trip_id))),
103
105
  stopIds: Object.keys(stopData),
104
106
  geojsons,
105
- gtfsRealtimeUrls,
106
107
  },
107
108
  routeData,
108
109
  stopData,
@@ -1,8 +1,6 @@
1
- /* global window, document, _, $, mapboxgl */
1
+ /* global document, jQuery, _, maplibregl, geojson, mapStyleUrl */
2
2
  /* eslint prefer-arrow-callback: "off", no-unused-vars: "off" */
3
3
 
4
- const maps = {};
5
-
6
4
  function formatRouteColor(route) {
7
5
  return route.route_color || '#000000';
8
6
  }
@@ -95,7 +93,7 @@ function formatStopPopup(feature) {
95
93
  }
96
94
 
97
95
  function getBounds(geojson) {
98
- const bounds = new mapboxgl.LngLatBounds();
96
+ const bounds = new maplibregl.LngLatBounds();
99
97
  for (const feature of geojson.features) {
100
98
  if (feature.geometry.type.toLowerCase() === 'point') {
101
99
  bounds.extend(feature.geometry.coordinates);
@@ -115,7 +113,7 @@ function getBounds(geojson) {
115
113
  return bounds;
116
114
  }
117
115
 
118
- function createSystemMap(id, geojson) {
116
+ function createSystemMap() {
119
117
  const defaultRouteColor = '#000000';
120
118
  const lineLayout = {
121
119
  'line-join': 'round',
@@ -128,9 +126,9 @@ function createSystemMap(id, geojson) {
128
126
  }
129
127
 
130
128
  const bounds = getBounds(geojson);
131
- const map = new mapboxgl.Map({
132
- container: id,
133
- style: 'mapbox://styles/mapbox/light-v11',
129
+ const map = new maplibregl.Map({
130
+ container: 'system_map',
131
+ style: mapStyleUrl,
134
132
  center: bounds.getCenter(),
135
133
  zoom: 12,
136
134
  });
@@ -141,16 +139,67 @@ function createSystemMap(id, geojson) {
141
139
  }
142
140
 
143
141
  map.scrollZoom.disable();
144
- map.addControl(new mapboxgl.NavigationControl());
142
+ map.addControl(new maplibregl.NavigationControl());
143
+ map.addControl(new maplibregl.FullscreenControl());
144
+
145
+ addGeocoder(map, bounds);
145
146
 
146
147
  map.on('load', () => {
147
148
  fitMapToBounds(map, bounds);
148
149
  disablePointsOfInterest(map);
149
150
  addMapLayers(map, geojson, defaultRouteColor, lineLayout);
150
- setupEventListeners(map, id, routes);
151
+ setupEventListeners(map, routes);
151
152
  });
153
+ }
152
154
 
153
- maps[id] = map;
155
+ function addGeocoder(map, bounds) {
156
+ map.addControl(
157
+ new MaplibreGeocoder(
158
+ {
159
+ forwardGeocode: async (config) => {
160
+ const features = [];
161
+ try {
162
+ const request = `https://nominatim.openstreetmap.org/search?q=${
163
+ config.query
164
+ }&format=geojson&polygon_geojson=1&addressdetails=1&viewbox=${bounds.getWest()},${bounds.getSouth()},${bounds.getEast()},${bounds.getNorth()}&bounded=1`;
165
+ const response = await fetch(request);
166
+ const geojson = await response.json();
167
+ for (const feature of geojson.features) {
168
+ const center = [
169
+ feature.bbox[0] + (feature.bbox[2] - feature.bbox[0]) / 2,
170
+ feature.bbox[1] + (feature.bbox[3] - feature.bbox[1]) / 2,
171
+ ];
172
+ const point = {
173
+ type: 'Feature',
174
+ geometry: {
175
+ type: 'Point',
176
+ coordinates: center,
177
+ },
178
+ place_name: feature.properties.display_name,
179
+ properties: feature.properties,
180
+ text: feature.properties.display_name,
181
+ place_type: ['place'],
182
+ center,
183
+ };
184
+ features.push(point);
185
+ }
186
+ } catch (e) {
187
+ console.error(`Failed to forwardGeocode with error: ${e}`);
188
+ }
189
+
190
+ return {
191
+ features,
192
+ type: 'FeatureCollection',
193
+ };
194
+ },
195
+ },
196
+ {
197
+ maplibregl,
198
+ zoom: 12,
199
+ },
200
+ ),
201
+ 'top-left',
202
+ );
154
203
  }
155
204
 
156
205
  function fitMapToBounds(map, bounds) {
@@ -161,23 +210,32 @@ function fitMapToBounds(map, bounds) {
161
210
  }
162
211
 
163
212
  function disablePointsOfInterest(map) {
164
- map.setLayoutProperty('poi-label', 'visibility', 'none');
213
+ const layers = map.getStyle().layers;
214
+ const poiLayerIds = layers
215
+ .filter((layer) => layer.id.startsWith('poi'))
216
+ ?.map((layer) => layer.id);
217
+ poiLayerIds.forEach((layerId) => {
218
+ map.setLayoutProperty(layerId, 'visibility', 'none');
219
+ });
165
220
  }
166
221
 
167
222
  function addMapLayers(map, geojson, defaultRouteColor, lineLayout) {
168
- const firstSymbolId = getFirstSymbolLayerId(map);
169
-
170
- addRouteLineShadow(map, geojson, lineLayout, firstSymbolId);
171
- addHighlightedRouteLineShadow(map, geojson, lineLayout, firstSymbolId);
172
- addRouteLineOutline(map, geojson, lineLayout, firstSymbolId);
173
- addHighlightedRouteLineOutline(map, geojson, lineLayout, firstSymbolId);
174
- addRouteLine(map, geojson, defaultRouteColor, lineLayout, firstSymbolId);
223
+ const layers = map.getStyle().layers;
224
+ const firstLabelLayerId = layers.find(
225
+ (layer) => layer.type === 'symbol' && layer.id.includes('label'),
226
+ )?.id;
227
+
228
+ addRouteLineShadow(map, geojson, lineLayout, firstLabelLayerId);
229
+ addHighlightedRouteLineShadow(map, geojson, lineLayout, firstLabelLayerId);
230
+ addRouteLineOutline(map, geojson, lineLayout, firstLabelLayerId);
231
+ addHighlightedRouteLineOutline(map, geojson, lineLayout, firstLabelLayerId);
232
+ addRouteLine(map, geojson, defaultRouteColor, lineLayout, firstLabelLayerId);
175
233
  addHighlightedRouteLine(
176
234
  map,
177
235
  geojson,
178
236
  defaultRouteColor,
179
237
  lineLayout,
180
- firstSymbolId,
238
+ firstLabelLayerId,
181
239
  );
182
240
  addStops(map, geojson);
183
241
  addHighlightedStops(map, geojson);
@@ -450,10 +508,10 @@ function addRouteLabels(map, geojson) {
450
508
  });
451
509
  }
452
510
 
453
- function setupEventListeners(map, id, routes) {
511
+ function setupEventListeners(map, routes) {
454
512
  map.on('mousemove', (event) => handleMouseMove(event, map, routes));
455
513
  map.on('click', (event) => handleClick(event, map));
456
- setupTableHoverListeners(id, map, routes);
514
+ setupTableHoverListeners(map);
457
515
  }
458
516
 
459
517
  function handleMouseMove(event, map, routes) {
@@ -504,7 +562,7 @@ function handleClick(event, map) {
504
562
  }
505
563
 
506
564
  function showStopPopup(map, feature) {
507
- new mapboxgl.Popup()
565
+ new maplibregl.Popup()
508
566
  .setLngLat(feature.geometry.coordinates)
509
567
  .setHTML(formatStopPopup(feature))
510
568
  .addTo(map);
@@ -516,7 +574,7 @@ function showRoutePopup(map, features, lngLat) {
516
574
  (feature) => Number.parseInt(feature.properties.route_short_name, 10),
517
575
  );
518
576
 
519
- new mapboxgl.Popup()
577
+ new maplibregl.Popup()
520
578
  .setLngLat(lngLat)
521
579
  .setHTML(formatRoutePopup(routes))
522
580
  .addTo(map);
@@ -612,7 +670,7 @@ function unHighlightRoutes(map, zoom) {
612
670
  }
613
671
  }
614
672
 
615
- function setupTableHoverListeners(id, map, routes) {
673
+ function setupTableHoverListeners(map) {
616
674
  jQuery(() => {
617
675
  jQuery('.overview-list a').hover((event) => {
618
676
  const routeIdString = jQuery(event.target).data('route-ids');
@@ -1,4 +1,4 @@
1
- /* global document, jQuery, mapboxgl, Pbf, stopData, routeData, routeIds, tripIds, geojsons, gtfsRealtimeUrls */
1
+ /* global document, jQuery, maplibregl, Pbf, mapStyleUrl, stopData, routeData, routeIds, tripIds, geojsons, gtfsRealtimeUrls */
2
2
  /* eslint prefer-arrow-callback: "off", no-unused-vars: "off" */
3
3
 
4
4
  const maps = {};
@@ -110,7 +110,8 @@ function getStopPopupHtml(feature, stop) {
110
110
  tripUpdate.trip_update.stop_time_update.filter(
111
111
  (stopTimeUpdate) =>
112
112
  stopTimeUpdate.stop_id === stop.stop_id &&
113
- stopTimeUpdate.departure !== null &&
113
+ (stopTimeUpdate.departure !== null ||
114
+ stopTimeUpdate.arrival !== null) &&
114
115
  stopTimeUpdate.schedule_relationship !== 3,
115
116
  );
116
117
  if (stopTimeUpdatesForStop.length > 0) {
@@ -146,7 +147,11 @@ function getStopPopupHtml(feature, stop) {
146
147
  const departureTimes = stopTimeUpdates[direction].map(
147
148
  (stopTimeUpdate) =>
148
149
  Math.round(
149
- (stopTimeUpdate.departure.time - Date.now() / 1000) / 60,
150
+ ((stopTimeUpdate.departure
151
+ ? stopTimeUpdate.departure.time
152
+ : stopTimeUpdate.arrival.time) -
153
+ Date.now() / 1000) /
154
+ 60,
150
155
  ),
151
156
  );
152
157
 
@@ -187,7 +192,7 @@ function getStopPopupHtml(feature, stop) {
187
192
  }
188
193
 
189
194
  function getBounds(geojson) {
190
- const bounds = new mapboxgl.LngLatBounds();
195
+ const bounds = new maplibregl.LngLatBounds();
191
196
  for (const feature of geojson.features) {
192
197
  if (feature.geometry.type.toLowerCase() === 'point') {
193
198
  bounds.extend(feature.geometry.coordinates);
@@ -454,7 +459,10 @@ function addVehicleMarker(vehiclePosition, vehicleTripUpdate) {
454
459
  ];
455
460
 
456
461
  // Add marker to map
457
- const vehicleMarker = new mapboxgl.Marker(el)
462
+ const vehicleMarker = new maplibregl.Marker({
463
+ element: el,
464
+ anchor: 'center',
465
+ })
458
466
  .setLngLat(coordinates)
459
467
  .addTo(maps[visibleTimetableId]);
460
468
 
@@ -704,9 +712,9 @@ function createMap(id) {
704
712
  }
705
713
 
706
714
  const bounds = getBounds(geojson);
707
- const map = new mapboxgl.Map({
715
+ const map = new maplibregl.Map({
708
716
  container: `map_timetable_id_${id}`,
709
- style: 'mapbox://styles/mapbox/light-v11',
717
+ style: mapStyleUrl,
710
718
  center: bounds.getCenter(),
711
719
  zoom: 12,
712
720
  preserveDrawingBuffer: true,
@@ -715,7 +723,8 @@ function createMap(id) {
715
723
  map.initialize = () => fitMapToBounds(map, bounds);
716
724
 
717
725
  map.scrollZoom.disable();
718
- map.addControl(new mapboxgl.NavigationControl());
726
+ map.addControl(new maplibregl.NavigationControl());
727
+ map.addControl(new maplibregl.FullscreenControl());
719
728
 
720
729
  map.on('load', () => {
721
730
  fitMapToBounds(map, bounds);
@@ -735,24 +744,28 @@ function fitMapToBounds(map, bounds) {
735
744
  }
736
745
 
737
746
  function disablePointsOfInterest(map) {
738
- map.setLayoutProperty('poi-label', 'visibility', 'none');
747
+ const layers = map.getStyle().layers;
748
+ const poiLayerIds = layers
749
+ .filter((layer) => layer.id.startsWith('poi'))
750
+ ?.map((layer) => layer.id);
751
+ poiLayerIds.forEach((layerId) => {
752
+ map.setLayoutProperty(layerId, 'visibility', 'none');
753
+ });
739
754
  }
740
755
 
741
756
  function addMapLayers(map, geojson, defaultRouteColor, lineLayout) {
742
- const firstSymbolId = getFirstSymbolLayerId(map);
757
+ const layers = map.getStyle().layers;
758
+ const firstLabelLayerId = layers.find(
759
+ (layer) => layer.type === 'symbol' && layer.id.includes('label'),
760
+ )?.id;
743
761
 
744
- addRouteLineShadow(map, geojson, lineLayout, firstSymbolId);
745
- addRouteLineOutline(map, geojson, lineLayout, firstSymbolId);
746
- addRouteLine(map, geojson, defaultRouteColor, lineLayout, firstSymbolId);
762
+ addRouteLineShadow(map, geojson, lineLayout, firstLabelLayerId);
763
+ addRouteLineOutline(map, geojson, lineLayout, firstLabelLayerId);
764
+ addRouteLine(map, geojson, defaultRouteColor, lineLayout, firstLabelLayerId);
747
765
  addStops(map, geojson);
748
766
  addHighlightedStops(map, geojson);
749
767
  }
750
768
 
751
- function getFirstSymbolLayerId(map) {
752
- const layers = map.getStyle().layers;
753
- return layers.find((layer) => layer.type === 'symbol').id;
754
- }
755
-
756
769
  function addRouteLineShadow(map, geojson, lineLayout, firstSymbolId) {
757
770
  map.addLayer(
758
771
  {
@@ -919,7 +932,7 @@ function handleClick(event, map) {
919
932
  }
920
933
 
921
934
  function showStopPopup(map, feature) {
922
- new mapboxgl.Popup()
935
+ new maplibregl.Popup()
923
936
  .setLngLat(feature.geometry.coordinates)
924
937
  .setHTML(getStopPopupHtml(feature, stopData[feature.properties.stop_id]))
925
938
  .addTo(map);
@@ -1038,18 +1051,27 @@ function createMaps() {
1038
1051
  gtfsRealtimeUrls?.realtimeVehiclePositions?.url
1039
1052
  ) {
1040
1053
  // Popup for realtime vehicle locations
1041
- vehiclePopup = new mapboxgl.Popup({
1054
+ const markerHeight = 20;
1055
+ const markerRadius = 10;
1056
+ const linearOffset = 15;
1057
+ vehiclePopup = new maplibregl.Popup({
1042
1058
  closeOnClick: false,
1043
1059
  className: 'vehicle-popup',
1044
1060
  offset: {
1045
- top: [0, 10],
1046
- bottom: [0, -10],
1047
- left: [10, 0],
1048
- right: [-10, 0],
1049
- 'top-left': [10, 10],
1050
- 'top-right': [-10, 10],
1051
- 'bottom-left': [10, -10],
1052
- 'bottom-right': [-10, -10],
1061
+ top: [0, 0],
1062
+ 'top-left': [0, 0],
1063
+ 'top-right': [0, 0],
1064
+ bottom: [0, -markerHeight],
1065
+ 'bottom-left': [
1066
+ linearOffset,
1067
+ (markerHeight - markerRadius + linearOffset) * -1,
1068
+ ],
1069
+ 'bottom-right': [
1070
+ -linearOffset,
1071
+ (markerHeight - markerRadius + linearOffset) * -1,
1072
+ ],
1073
+ left: [markerRadius, (markerHeight - markerRadius) * -1],
1074
+ right: [-markerRadius, (markerHeight - markerRadius) * -1],
1053
1075
  },
1054
1076
  });
1055
1077
 
@@ -21,7 +21,6 @@ include formatting_functions.pug
21
21
 
22
22
  //- Use !{variable} format to inject values from pug to client side js
23
23
  script.
24
- (function() {
25
- const geojson = !{JSON.stringify(geojson) || '\'\''};
26
- createSystemMap('system_map', geojson);
27
- })();
24
+ const geojson = !{JSON.stringify(geojson) || '\'\''};
25
+ const mapStyleUrl = '#{config.mapStyleUrl}';
26
+ createSystemMap();
@@ -6,11 +6,11 @@ block extraHeader
6
6
  if config.showMap
7
7
  script(src="https://unpkg.com/jquery@3.7.1/dist/jquery.min.js" crossorigin="anonymous")
8
8
  script(src="https://unpkg.com/lodash@4.17.21/lodash.min.js" crossorigin="anonymous")
9
- script(src="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.js")
10
- script.
11
- mapboxgl.accessToken = '#{config.mapboxAccessToken}';
9
+ script(src="https://unpkg.com/maplibre-gl@^4.7.1/dist/maplibre-gl.js")
10
+ script(src="https://unpkg.com/@maplibre/maplibre-gl-geocoder@1.5.0/dist/maplibre-gl-geocoder.min.js")
12
11
  script(src=`${config.assetPath}js/system-map.js`)
13
12
 
14
- link(href="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.css" rel="stylesheet")
13
+ link(href="https://unpkg.com/maplibre-gl@^4.7.1/dist/maplibre-gl.css" rel="stylesheet")
14
+ link(href="https://unpkg.com/@maplibre/maplibre-gl-geocoder@1.5.0/dist/maplibre-gl-geocoder.css" rel="stylesheet")
15
15
 
16
16
  link(rel="stylesheet" href=`${config.assetPath}css/overview_styles.css`)
@@ -68,5 +68,5 @@ include formatting_functions.pug
68
68
 
69
69
  if config.showMap
70
70
  script.
71
- const { routeData, stopData, pageData: { routeIds, tripIds, stopIds, geojsons, gtfsRealtimeUrls } } = !{JSON.stringify(prepareMapData(timetablePage, config))};
71
+ const { gtfsRealtimeUrls, mapStyleUrl, routeData, stopData, pageData: { routeIds, tripIds, stopIds, geojsons } } = !{JSON.stringify(prepareMapData(timetablePage, config))};
72
72
  createMaps();
@@ -13,10 +13,8 @@ block extraHeader
13
13
  script(src=`${config.assetPath}js/gtfs-realtime.browser.proto.js`)
14
14
 
15
15
  if config.showMap
16
- link(href="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.css" rel="stylesheet")
17
- script(src="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.js")
18
- script.
19
- mapboxgl.accessToken = '#{config.mapboxAccessToken}';
16
+ link(href="https://unpkg.com/maplibre-gl@^4.7.1/dist/maplibre-gl.css" rel="stylesheet")
17
+ script(src="https://unpkg.com/maplibre-gl@^4.7.1/dist/maplibre-gl.js")
20
18
  script(src=`${config.assetPath}js/timetable-map.js`)
21
19
 
22
20
  if config.hasGtfsRealtimeAlerts