gtfs-to-html 2.5.7 → 2.5.9
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/CHANGELOG.md +26 -0
- package/lib/gtfs-to-html.js +16 -16
- package/lib/log-utils.js +3 -3
- package/lib/utils.js +17 -11
- package/package.json +7 -7
- package/public/js/system-map.js +85 -98
- package/public/js/timetable-map.js +55 -52
- package/views/default/overview_full.pug +3 -3
- package/views/default/timetablepage_full.pug +3 -3
- package/www/package.json +3 -3
- package/www/yarn.lock +1085 -1278
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.5.9] - 2024-01-24
|
|
9
|
+
|
|
10
|
+
### Updated
|
|
11
|
+
|
|
12
|
+
- Move stop markers above map labels
|
|
13
|
+
- Update to Mapbox GL JS v3
|
|
14
|
+
- Dependency updates
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Handle routes with no route_short_name in map marker popups
|
|
19
|
+
|
|
20
|
+
## [2.5.8] - 2024-01-02
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Improved warning logging
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Handle case where a calendar_date is both included and excluded
|
|
29
|
+
|
|
30
|
+
### Updated
|
|
31
|
+
|
|
32
|
+
- Dependency updates
|
|
33
|
+
|
|
8
34
|
## [2.5.7] - 2023-11-07
|
|
9
35
|
|
|
10
36
|
### Updated
|
package/lib/gtfs-to-html.js
CHANGED
|
@@ -51,7 +51,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
51
51
|
} catch (error) {
|
|
52
52
|
if (error instanceof Error && error.code === 'SQLITE_CANTOPEN') {
|
|
53
53
|
config.logError(
|
|
54
|
-
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json
|
|
54
|
+
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json.`,
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -84,7 +84,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
84
84
|
const timetablePages = [];
|
|
85
85
|
const timetablePageIds = map(
|
|
86
86
|
getTimetablePagesForAgency(config),
|
|
87
|
-
'timetable_page_id'
|
|
87
|
+
'timetable_page_id',
|
|
88
88
|
);
|
|
89
89
|
await prepDirectory(exportPath);
|
|
90
90
|
|
|
@@ -95,7 +95,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
95
95
|
const bar = progressBar(
|
|
96
96
|
`${agencyKey}: Generating ${config.outputFormat.toUpperCase()} timetables {bar} {value}/{total}`,
|
|
97
97
|
timetablePageIds.length,
|
|
98
|
-
config
|
|
98
|
+
config,
|
|
99
99
|
);
|
|
100
100
|
|
|
101
101
|
/* eslint-disable no-await-in-loop */
|
|
@@ -103,15 +103,9 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
103
103
|
try {
|
|
104
104
|
const timetablePage = await getFormattedTimetablePage(
|
|
105
105
|
timetablePageId,
|
|
106
|
-
config
|
|
106
|
+
config,
|
|
107
107
|
);
|
|
108
108
|
|
|
109
|
-
if (timetablePage.consolidatedTimetables.length === 0) {
|
|
110
|
-
throw new Error(
|
|
111
|
-
`No timetables found for timetable_page_id=${timetablePage.timetable_page_id}`
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
109
|
for (const timetable of timetablePage.timetables) {
|
|
116
110
|
for (const warning of timetable.warnings) {
|
|
117
111
|
outputStats.warnings.push(warning);
|
|
@@ -119,6 +113,12 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
119
113
|
}
|
|
120
114
|
}
|
|
121
115
|
|
|
116
|
+
if (timetablePage.consolidatedTimetables.length === 0) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`No timetables found for timetable_page_id=${timetablePage.timetable_page_id}`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
122
|
outputStats.timetables += timetablePage.consolidatedTimetables.length;
|
|
123
123
|
outputStats.timetablePages += 1;
|
|
124
124
|
|
|
@@ -130,7 +130,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
130
130
|
|
|
131
131
|
timetablePage.relativePath = path.join(
|
|
132
132
|
datePath,
|
|
133
|
-
sanitize(timetablePage.filename)
|
|
133
|
+
sanitize(timetablePage.filename),
|
|
134
134
|
);
|
|
135
135
|
|
|
136
136
|
if (config.outputFormat === 'csv') {
|
|
@@ -139,7 +139,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
139
139
|
const csvPath = path.join(
|
|
140
140
|
exportPath,
|
|
141
141
|
datePath,
|
|
142
|
-
generateCSVFileName(timetable, timetablePage)
|
|
142
|
+
generateCSVFileName(timetable, timetablePage),
|
|
143
143
|
);
|
|
144
144
|
await writeFile(csvPath, csv);
|
|
145
145
|
}
|
|
@@ -148,7 +148,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
148
148
|
const htmlPath = path.join(
|
|
149
149
|
exportPath,
|
|
150
150
|
datePath,
|
|
151
|
-
sanitize(timetablePage.filename)
|
|
151
|
+
sanitize(timetablePage.filename),
|
|
152
152
|
);
|
|
153
153
|
await writeFile(htmlPath, html);
|
|
154
154
|
|
|
@@ -192,19 +192,19 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
192
192
|
|
|
193
193
|
const fullExportPath = path.join(
|
|
194
194
|
exportPath,
|
|
195
|
-
config.zipOutput ? '/timetables.zip' : ''
|
|
195
|
+
config.zipOutput ? '/timetables.zip' : '',
|
|
196
196
|
);
|
|
197
197
|
|
|
198
198
|
// Print stats
|
|
199
199
|
config.log(
|
|
200
|
-
`${agencyKey}: ${config.outputFormat.toUpperCase()} timetables created at ${fullExportPath}
|
|
200
|
+
`${agencyKey}: ${config.outputFormat.toUpperCase()} timetables created at ${fullExportPath}`,
|
|
201
201
|
);
|
|
202
202
|
|
|
203
203
|
logStats(outputStats, config);
|
|
204
204
|
|
|
205
205
|
const seconds = Math.round(timer.time() / 1000);
|
|
206
206
|
config.log(
|
|
207
|
-
`${agencyKey}: ${config.outputFormat.toUpperCase()} timetable generation required ${seconds} seconds
|
|
207
|
+
`${agencyKey}: ${config.outputFormat.toUpperCase()} timetable generation required ${seconds} seconds`,
|
|
208
208
|
);
|
|
209
209
|
|
|
210
210
|
timer.stop();
|
package/lib/log-utils.js
CHANGED
|
@@ -110,7 +110,7 @@ export function formatError(error) {
|
|
|
110
110
|
const messageText = error instanceof Error ? error.message : error;
|
|
111
111
|
const errorMessage = `${colors.underline('Error')}: ${messageText.replace(
|
|
112
112
|
'Error: ',
|
|
113
|
-
''
|
|
113
|
+
'',
|
|
114
114
|
)}`;
|
|
115
115
|
return colors.red(errorMessage);
|
|
116
116
|
}
|
|
@@ -136,7 +136,7 @@ export function logStats(stats, config) {
|
|
|
136
136
|
['🔄 Routes', stats.routes],
|
|
137
137
|
['🚍 Trips', stats.trips],
|
|
138
138
|
['🛑 Stops', stats.stops],
|
|
139
|
-
['⛔️ Warnings', stats.warnings.length]
|
|
139
|
+
['⛔️ Warnings', stats.warnings.length],
|
|
140
140
|
);
|
|
141
141
|
|
|
142
142
|
config.log(table.toString());
|
|
@@ -209,7 +209,7 @@ export function progressBar(formatString, barTotal, config) {
|
|
|
209
209
|
interrupt(text) {
|
|
210
210
|
// Log two lines to avoid overwrite by progress bar
|
|
211
211
|
config.logWarning(text);
|
|
212
|
-
config.
|
|
212
|
+
config.log('');
|
|
213
213
|
},
|
|
214
214
|
increment() {
|
|
215
215
|
barProgress += 1;
|
package/lib/utils.js
CHANGED
|
@@ -292,26 +292,32 @@ const getCalendarDatesForTimetable = (timetable, config) => {
|
|
|
292
292
|
);
|
|
293
293
|
const start = fromGTFSDate(timetable.start_date);
|
|
294
294
|
const end = fromGTFSDate(timetable.end_date);
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
includedDates: [],
|
|
298
|
-
};
|
|
295
|
+
const excludedDates = [];
|
|
296
|
+
const includedDates = [];
|
|
299
297
|
|
|
300
298
|
for (const calendarDate of calendarDates) {
|
|
301
299
|
if (moment(calendarDate.date, 'YYYYMMDD').isBetween(start, end)) {
|
|
302
300
|
if (calendarDate.exception_type === 1) {
|
|
303
|
-
|
|
304
|
-
formatDate(calendarDate, config.dateFormat),
|
|
305
|
-
);
|
|
301
|
+
includedDates.push(formatDate(calendarDate, config.dateFormat));
|
|
306
302
|
} else if (calendarDate.exception_type === 2) {
|
|
307
|
-
|
|
308
|
-
formatDate(calendarDate, config.dateFormat),
|
|
309
|
-
);
|
|
303
|
+
excludedDates.push(formatDate(calendarDate, config.dateFormat));
|
|
310
304
|
}
|
|
311
305
|
}
|
|
312
306
|
}
|
|
313
307
|
|
|
314
|
-
|
|
308
|
+
// Remove dates that are both included and excluded from both lists
|
|
309
|
+
const includedAndExcludedDates = excludedDates.filter((date) =>
|
|
310
|
+
includedDates.includes(date),
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
excludedDates: excludedDates.filter(
|
|
315
|
+
(date) => !includedAndExcludedDates.includes(date),
|
|
316
|
+
),
|
|
317
|
+
includedDates: includedDates.filter(
|
|
318
|
+
(date) => !includedAndExcludedDates.includes(date),
|
|
319
|
+
),
|
|
320
|
+
};
|
|
315
321
|
};
|
|
316
322
|
|
|
317
323
|
/*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtfs-to-html",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
|
|
6
6
|
"keywords": [
|
|
@@ -40,16 +40,16 @@
|
|
|
40
40
|
"archiver": "^6.0.1",
|
|
41
41
|
"cli-table": "^0.3.11",
|
|
42
42
|
"copy-dir": "^1.3.0",
|
|
43
|
-
"csv-stringify": "^6.4.
|
|
43
|
+
"csv-stringify": "^6.4.5",
|
|
44
44
|
"express": "^4.18.2",
|
|
45
|
-
"gtfs": "^4.
|
|
45
|
+
"gtfs": "^4.6.0",
|
|
46
46
|
"js-beautify": "^1.14.11",
|
|
47
47
|
"lodash-es": "^4.17.21",
|
|
48
|
-
"moment": "^2.
|
|
48
|
+
"moment": "^2.30.1",
|
|
49
49
|
"morgan": "^1.10.0",
|
|
50
50
|
"pretty-error": "^4.0.0",
|
|
51
51
|
"pug": "^3.0.2",
|
|
52
|
-
"puppeteer": "^21.
|
|
52
|
+
"puppeteer": "^21.9.0",
|
|
53
53
|
"sanitize-filename": "^1.6.3",
|
|
54
54
|
"sqlstring": "^2.3.3",
|
|
55
55
|
"timer-machine": "^1.1.0",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"husky": "^8.0.3",
|
|
63
|
-
"lint-staged": "^15.0
|
|
64
|
-
"prettier": "^3.
|
|
63
|
+
"lint-staged": "^15.2.0",
|
|
64
|
+
"prettier": "^3.2.4"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">= 18.0.0"
|
package/public/js/system-map.js
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
|
|
4
4
|
const maps = {};
|
|
5
5
|
|
|
6
|
+
function formatRouteName(route) {
|
|
7
|
+
let routeName = '';
|
|
8
|
+
if (route.route_short_name !== undefined) {
|
|
9
|
+
routeName += route.route_short_name;
|
|
10
|
+
} else if (route.route_long_name !== undefined) {
|
|
11
|
+
routeName += route.route_long_name;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return routeName;
|
|
15
|
+
}
|
|
16
|
+
|
|
6
17
|
function formatRoute(route) {
|
|
7
18
|
const html = route.route_url
|
|
8
19
|
? $('<a>').attr('href', route.route_url)
|
|
@@ -17,9 +28,7 @@ function formatRoute(route) {
|
|
|
17
28
|
.appendTo(html);
|
|
18
29
|
}
|
|
19
30
|
|
|
20
|
-
$('<span>')
|
|
21
|
-
.text(`${route.route_short_name} ${route.route_long_name}`)
|
|
22
|
-
.appendTo(html);
|
|
31
|
+
$('<span>').text(formatRouteName(route)).appendTo(html);
|
|
23
32
|
|
|
24
33
|
return html.prop('outerHTML');
|
|
25
34
|
}
|
|
@@ -107,10 +116,10 @@ function createSystemMap(id, geojson) {
|
|
|
107
116
|
duration: 0,
|
|
108
117
|
});
|
|
109
118
|
|
|
110
|
-
// Turn
|
|
119
|
+
// Turn off Points of Interest labels
|
|
111
120
|
map.setLayoutProperty('poi-label', 'visibility', 'none');
|
|
112
121
|
|
|
113
|
-
// Find the index of the first symbol layer in the map style
|
|
122
|
+
// Find the index of the first symbol layer in the map style to put the route lines underneath
|
|
114
123
|
let firstSymbolId;
|
|
115
124
|
for (const layer of map.getStyle().layers) {
|
|
116
125
|
if (layer.type === 'symbol') {
|
|
@@ -149,7 +158,7 @@ function createSystemMap(id, geojson) {
|
|
|
149
158
|
layout: lineLayout,
|
|
150
159
|
filter: ['!has', 'stop_id'],
|
|
151
160
|
},
|
|
152
|
-
firstSymbolId
|
|
161
|
+
firstSymbolId,
|
|
153
162
|
);
|
|
154
163
|
|
|
155
164
|
// Add highlighted route drop shadow outlines next
|
|
@@ -182,7 +191,7 @@ function createSystemMap(id, geojson) {
|
|
|
182
191
|
layout: lineLayout,
|
|
183
192
|
filter: ['==', ['get', 'route_id'], 'none'],
|
|
184
193
|
},
|
|
185
|
-
firstSymbolId
|
|
194
|
+
firstSymbolId,
|
|
186
195
|
);
|
|
187
196
|
|
|
188
197
|
// Add white outlines to routes next
|
|
@@ -208,7 +217,7 @@ function createSystemMap(id, geojson) {
|
|
|
208
217
|
layout: lineLayout,
|
|
209
218
|
filter: ['has', 'route_id'],
|
|
210
219
|
},
|
|
211
|
-
firstSymbolId
|
|
220
|
+
firstSymbolId,
|
|
212
221
|
);
|
|
213
222
|
|
|
214
223
|
// Add highlighted route white outlines next
|
|
@@ -234,7 +243,7 @@ function createSystemMap(id, geojson) {
|
|
|
234
243
|
layout: lineLayout,
|
|
235
244
|
filter: ['==', ['get', 'route_id'], 'none'],
|
|
236
245
|
},
|
|
237
|
-
firstSymbolId
|
|
246
|
+
firstSymbolId,
|
|
238
247
|
);
|
|
239
248
|
|
|
240
249
|
// Add route lines next
|
|
@@ -260,7 +269,7 @@ function createSystemMap(id, geojson) {
|
|
|
260
269
|
layout: lineLayout,
|
|
261
270
|
filter: ['has', 'route_id'],
|
|
262
271
|
},
|
|
263
|
-
firstSymbolId
|
|
272
|
+
firstSymbolId,
|
|
264
273
|
);
|
|
265
274
|
|
|
266
275
|
// Add highlighted route lines next
|
|
@@ -286,96 +295,74 @@ function createSystemMap(id, geojson) {
|
|
|
286
295
|
layout: lineLayout,
|
|
287
296
|
filter: ['==', ['get', 'route_id'], 'none'],
|
|
288
297
|
},
|
|
289
|
-
firstSymbolId
|
|
298
|
+
firstSymbolId,
|
|
290
299
|
);
|
|
291
300
|
|
|
292
301
|
// Add stops when zoomed in
|
|
293
|
-
map.addLayer(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
[22, 100],
|
|
308
|
-
],
|
|
309
|
-
},
|
|
310
|
-
'circle-stroke-color': '#3F4A5C',
|
|
311
|
-
'circle-stroke-width': 2,
|
|
312
|
-
'circle-opacity': [
|
|
313
|
-
'interpolate',
|
|
314
|
-
['linear'],
|
|
315
|
-
['zoom'],
|
|
316
|
-
13,
|
|
317
|
-
0,
|
|
318
|
-
13.5,
|
|
319
|
-
1,
|
|
320
|
-
],
|
|
321
|
-
'circle-stroke-opacity': [
|
|
322
|
-
'interpolate',
|
|
323
|
-
['linear'],
|
|
324
|
-
['zoom'],
|
|
325
|
-
13,
|
|
326
|
-
0,
|
|
327
|
-
13.5,
|
|
328
|
-
1,
|
|
302
|
+
map.addLayer({
|
|
303
|
+
id: 'stops',
|
|
304
|
+
type: 'circle',
|
|
305
|
+
source: {
|
|
306
|
+
type: 'geojson',
|
|
307
|
+
data: geojson,
|
|
308
|
+
},
|
|
309
|
+
paint: {
|
|
310
|
+
'circle-color': '#fff',
|
|
311
|
+
'circle-radius': {
|
|
312
|
+
base: 1.75,
|
|
313
|
+
stops: [
|
|
314
|
+
[12, 4],
|
|
315
|
+
[22, 100],
|
|
329
316
|
],
|
|
330
317
|
},
|
|
331
|
-
|
|
318
|
+
'circle-stroke-color': '#3F4A5C',
|
|
319
|
+
'circle-stroke-width': 2,
|
|
320
|
+
'circle-opacity': ['interpolate', ['linear'], ['zoom'], 13, 0, 13.5, 1],
|
|
321
|
+
'circle-stroke-opacity': [
|
|
322
|
+
'interpolate',
|
|
323
|
+
['linear'],
|
|
324
|
+
['zoom'],
|
|
325
|
+
13,
|
|
326
|
+
0,
|
|
327
|
+
13.5,
|
|
328
|
+
1,
|
|
329
|
+
],
|
|
332
330
|
},
|
|
333
|
-
|
|
334
|
-
);
|
|
331
|
+
filter: ['has', 'stop_id'],
|
|
332
|
+
});
|
|
335
333
|
|
|
336
334
|
// Layer for highlighted stops
|
|
337
|
-
map.addLayer(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
[22, 125],
|
|
352
|
-
],
|
|
353
|
-
},
|
|
354
|
-
'circle-stroke-width': 2,
|
|
355
|
-
'circle-stroke-color': '#3f4a5c',
|
|
356
|
-
'circle-opacity': [
|
|
357
|
-
'interpolate',
|
|
358
|
-
['linear'],
|
|
359
|
-
['zoom'],
|
|
360
|
-
13,
|
|
361
|
-
0,
|
|
362
|
-
13.5,
|
|
363
|
-
1,
|
|
364
|
-
],
|
|
365
|
-
'circle-stroke-opacity': [
|
|
366
|
-
'interpolate',
|
|
367
|
-
['linear'],
|
|
368
|
-
['zoom'],
|
|
369
|
-
13,
|
|
370
|
-
0,
|
|
371
|
-
13.5,
|
|
372
|
-
1,
|
|
335
|
+
map.addLayer({
|
|
336
|
+
id: 'stops-highlighted',
|
|
337
|
+
type: 'circle',
|
|
338
|
+
source: {
|
|
339
|
+
type: 'geojson',
|
|
340
|
+
data: geojson,
|
|
341
|
+
},
|
|
342
|
+
paint: {
|
|
343
|
+
'circle-color': '#fff',
|
|
344
|
+
'circle-radius': {
|
|
345
|
+
base: 1.75,
|
|
346
|
+
stops: [
|
|
347
|
+
[12, 5],
|
|
348
|
+
[22, 125],
|
|
373
349
|
],
|
|
374
350
|
},
|
|
375
|
-
|
|
351
|
+
'circle-stroke-width': 2,
|
|
352
|
+
'circle-stroke-color': '#3f4a5c',
|
|
353
|
+
'circle-opacity': ['interpolate', ['linear'], ['zoom'], 13, 0, 13.5, 1],
|
|
354
|
+
'circle-stroke-opacity': [
|
|
355
|
+
'interpolate',
|
|
356
|
+
['linear'],
|
|
357
|
+
['zoom'],
|
|
358
|
+
13,
|
|
359
|
+
0,
|
|
360
|
+
13.5,
|
|
361
|
+
1,
|
|
362
|
+
],
|
|
376
363
|
},
|
|
377
|
-
|
|
378
|
-
);
|
|
364
|
+
filter: ['==', 'stop_id', ''],
|
|
365
|
+
});
|
|
379
366
|
|
|
380
367
|
// Add labels
|
|
381
368
|
map.addLayer({
|
|
@@ -406,14 +393,14 @@ function createSystemMap(id, geojson) {
|
|
|
406
393
|
map.getCanvas().style.cursor = 'pointer';
|
|
407
394
|
highlightRoutes(
|
|
408
395
|
_.compact(
|
|
409
|
-
_.uniq(features.map((feature) => feature.properties.route_id))
|
|
410
|
-
)
|
|
396
|
+
_.uniq(features.map((feature) => feature.properties.route_id)),
|
|
397
|
+
),
|
|
411
398
|
);
|
|
412
399
|
|
|
413
400
|
if (features.some((feature) => feature.layer.id === 'stops')) {
|
|
414
401
|
highlightStop(
|
|
415
402
|
features.find((feature) => feature.layer.id === 'stops').properties
|
|
416
|
-
.stop_id
|
|
403
|
+
.stop_id,
|
|
417
404
|
);
|
|
418
405
|
}
|
|
419
406
|
} else {
|
|
@@ -451,10 +438,10 @@ function createSystemMap(id, geojson) {
|
|
|
451
438
|
const routes = _.orderBy(
|
|
452
439
|
_.uniqBy(
|
|
453
440
|
routeFeatures,
|
|
454
|
-
(feature) => feature.properties.route_short_name
|
|
441
|
+
(feature) => feature.properties.route_short_name,
|
|
455
442
|
),
|
|
456
443
|
(feature) =>
|
|
457
|
-
Number.parseInt(feature.properties.route_short_name, 10)
|
|
444
|
+
Number.parseInt(feature.properties.route_short_name, 10),
|
|
458
445
|
);
|
|
459
446
|
|
|
460
447
|
new mapboxgl.Popup()
|
|
@@ -505,11 +492,11 @@ function createSystemMap(id, geojson) {
|
|
|
505
492
|
map.setPaintProperty(
|
|
506
493
|
'route-line-shadows',
|
|
507
494
|
'line-opacity',
|
|
508
|
-
routeLineOpacity
|
|
495
|
+
routeLineOpacity,
|
|
509
496
|
);
|
|
510
497
|
|
|
511
498
|
const highlightedFeatures = geojson.features.filter((feature) =>
|
|
512
|
-
routeIds.includes(feature.properties.route_id)
|
|
499
|
+
routeIds.includes(feature.properties.route_id),
|
|
513
500
|
);
|
|
514
501
|
|
|
515
502
|
if (highlightedFeatures.length > 0 && zoom) {
|
|
@@ -546,7 +533,7 @@ function createSystemMap(id, geojson) {
|
|
|
546
533
|
map.setPaintProperty(
|
|
547
534
|
'route-line-shadows',
|
|
548
535
|
'line-opacity',
|
|
549
|
-
routeLineOpacity
|
|
536
|
+
routeLineOpacity,
|
|
550
537
|
);
|
|
551
538
|
|
|
552
539
|
if (zoom) {
|
|
@@ -566,7 +553,7 @@ function createSystemMap(id, geojson) {
|
|
|
566
553
|
|
|
567
554
|
$('.overview-list').hover(
|
|
568
555
|
() => {},
|
|
569
|
-
() => unHighlightRoutes(true)
|
|
556
|
+
() => unHighlightRoutes(true),
|
|
570
557
|
);
|
|
571
558
|
});
|
|
572
559
|
});
|