gtfs-to-html 2.2.0 → 2.3.2

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.
@@ -4,7 +4,9 @@
4
4
  const maps = {};
5
5
 
6
6
  function formatRoute(route) {
7
- const html = route.route_url ? $('<a>').attr('href', route.route_url) : $('<div>');
7
+ const html = route.route_url
8
+ ? $('<a>').attr('href', route.route_url)
9
+ : $('<div>');
8
10
 
9
11
  html.addClass('route-item text-sm mb-2');
10
12
 
@@ -32,21 +34,14 @@ function formatStopPopup(feature) {
32
34
  .appendTo(html);
33
35
 
34
36
  if (feature.properties.stop_code ?? false) {
35
- $('<label>')
36
- .addClass('mr-1')
37
- .text('Stop Code:')
38
- .appendTo(html);
37
+ $('<label>').addClass('mr-1').text('Stop Code:').appendTo(html);
39
38
 
40
- $('<strong>')
41
- .text(feature.properties.stop_code)
42
- .appendTo(html);
39
+ $('<strong>').text(feature.properties.stop_code).appendTo(html);
43
40
  }
44
41
 
45
- $('<div>')
46
- .text('Routes Served:')
47
- .appendTo(html);
42
+ $('<div>').text('Routes Served:').appendTo(html);
48
43
 
49
- $(html).append(routes.map(route => formatRoute(route)));
44
+ $(html).append(routes.map((route) => formatRoute(route)));
50
45
 
51
46
  return html.prop('outerHTML');
52
47
  }
@@ -80,7 +75,7 @@ function createMap(id, geojson) {
80
75
  style: 'mapbox://styles/mapbox/light-v10',
81
76
  center: bounds.getCenter(),
82
77
  zoom: 12,
83
- preserveDrawingBuffer: true
78
+ preserveDrawingBuffer: true,
84
79
  });
85
80
 
86
81
  map.scrollZoom.disable();
@@ -92,9 +87,9 @@ function createMap(id, geojson) {
92
87
  top: 40,
93
88
  bottom: 40,
94
89
  left: 20,
95
- right: 40
90
+ right: 40,
96
91
  },
97
- duration: 0
92
+ duration: 0,
98
93
  });
99
94
 
100
95
  // Find the index of the first symbol layer in the map style
@@ -107,91 +102,103 @@ function createMap(id, geojson) {
107
102
  }
108
103
 
109
104
  // Add route line outline first
110
- map.addLayer({
111
- id: 'route-line-outline',
112
- type: 'line',
113
- source: {
114
- type: 'geojson',
115
- data: geojson
116
- },
117
- paint: {
118
- 'line-color': '#FFFFFF',
119
- 'line-opacity': 1,
120
- 'line-width': 6
121
- },
122
- layout: {
123
- 'line-join': 'round',
124
- 'line-cap': 'round'
125
- },
126
- filter: ['!has', 'stop_id']
127
- }, firstSymbolId);
128
-
129
- map.addLayer({
130
- id: 'route-line',
131
- type: 'line',
132
- source: {
133
- type: 'geojson',
134
- data: geojson
135
- },
136
- paint: {
137
- 'line-color': ['to-color', ['get', 'route_color'], defaultRouteColor],
138
- 'line-opacity': 1,
139
- 'line-width': 2
140
- },
141
- layout: {
142
- 'line-join': 'round',
143
- 'line-cap': 'round'
144
- },
145
- filter: ['!has', 'stop_id']
146
- }, firstSymbolId);
147
-
148
- map.addLayer({
149
- id: 'stops',
150
- type: 'circle',
151
- source: {
152
- type: 'geojson',
153
- data: geojson
105
+ map.addLayer(
106
+ {
107
+ id: 'route-line-outline',
108
+ type: 'line',
109
+ source: {
110
+ type: 'geojson',
111
+ data: geojson,
112
+ },
113
+ paint: {
114
+ 'line-color': '#FFFFFF',
115
+ 'line-opacity': 1,
116
+ 'line-width': 6,
117
+ },
118
+ layout: {
119
+ 'line-join': 'round',
120
+ 'line-cap': 'round',
121
+ },
122
+ filter: ['!has', 'stop_id'],
154
123
  },
155
- paint: {
156
- 'circle-radius': {
157
- stops: [
158
- [9, 2],
159
- [13, 4],
160
- [15, 6]
161
- ]
124
+ firstSymbolId
125
+ );
126
+
127
+ map.addLayer(
128
+ {
129
+ id: 'route-line',
130
+ type: 'line',
131
+ source: {
132
+ type: 'geojson',
133
+ data: geojson,
134
+ },
135
+ paint: {
136
+ 'line-color': ['to-color', ['get', 'route_color'], defaultRouteColor],
137
+ 'line-opacity': 1,
138
+ 'line-width': 2,
162
139
  },
163
- 'circle-stroke-width': 1,
164
- 'circle-stroke-color': '#363636',
165
- 'circle-color': '#363636'
140
+ layout: {
141
+ 'line-join': 'round',
142
+ 'line-cap': 'round',
143
+ },
144
+ filter: ['!has', 'stop_id'],
166
145
  },
167
- filter: ['has', 'stop_id']
168
- }, firstSymbolId);
169
-
170
- map.addLayer({
171
- id: 'stops-highlighted',
172
- type: 'circle',
173
- source: {
174
- type: 'geojson',
175
- data: geojson
146
+ firstSymbolId
147
+ );
148
+
149
+ map.addLayer(
150
+ {
151
+ id: 'stops',
152
+ type: 'circle',
153
+ source: {
154
+ type: 'geojson',
155
+ data: geojson,
156
+ },
157
+ paint: {
158
+ 'circle-radius': {
159
+ stops: [
160
+ [9, 2],
161
+ [13, 4],
162
+ [15, 6],
163
+ ],
164
+ },
165
+ 'circle-stroke-width': 1,
166
+ 'circle-stroke-color': '#363636',
167
+ 'circle-color': '#363636',
168
+ },
169
+ filter: ['has', 'stop_id'],
176
170
  },
177
- paint: {
178
- 'circle-radius': {
179
- stops: [
180
- [9, 3],
181
- [13, 4],
182
- [15, 7]
183
- ]
171
+ firstSymbolId
172
+ );
173
+
174
+ map.addLayer(
175
+ {
176
+ id: 'stops-highlighted',
177
+ type: 'circle',
178
+ source: {
179
+ type: 'geojson',
180
+ data: geojson,
181
+ },
182
+ paint: {
183
+ 'circle-radius': {
184
+ stops: [
185
+ [9, 3],
186
+ [13, 4],
187
+ [15, 7],
188
+ ],
189
+ },
190
+ 'circle-stroke-width': 2,
191
+ 'circle-stroke-color': '#666666',
192
+ 'circle-color': '#888888',
184
193
  },
185
- 'circle-stroke-width': 2,
186
- 'circle-stroke-color': '#666666',
187
- 'circle-color': '#888888'
194
+ filter: ['==', 'stop_id', ''],
188
195
  },
189
- filter: ['==', 'stop_id', '']
190
- }, firstSymbolId);
196
+ firstSymbolId
197
+ );
191
198
 
192
- map.on('mousemove', event => {
199
+ map.on('mousemove', (event) => {
193
200
  const features = map.queryRenderedFeatures(event.point, {
194
- layers: ['stops']
201
+ layers: ['stops'],
195
202
  });
196
203
  if (features.length > 0) {
197
204
  map.getCanvas().style.cursor = 'pointer';
@@ -202,14 +209,14 @@ function createMap(id, geojson) {
202
209
  }
203
210
  });
204
211
 
205
- map.on('click', event => {
212
+ map.on('click', (event) => {
206
213
  // Set bbox as 5px rectangle area around clicked point
207
214
  const bbox = [
208
215
  [event.point.x - 5, event.point.y - 5],
209
- [event.point.x + 5, event.point.y + 5]
216
+ [event.point.x + 5, event.point.y + 5],
210
217
  ];
211
218
  const features = map.queryRenderedFeatures(bbox, {
212
- layers: ['stops']
219
+ layers: ['stops'],
213
220
  });
214
221
 
215
222
  if (!features || features.length === 0) {
@@ -238,7 +245,7 @@ function createMap(id, geojson) {
238
245
  }
239
246
 
240
247
  // On table hover, highlight stop on map
241
- $('th, td', $('#' + id + ' table')).hover(event => {
248
+ $('th, td', $('#' + id + ' table')).hover((event) => {
242
249
  let stopId;
243
250
  const table = $(event.target).parents('table');
244
251
  if (table.data('orientation') === 'vertical') {
@@ -19,20 +19,44 @@ $(() => {
19
19
  }
20
20
 
21
21
  $('#day_list_selector input[name="dayList"]').each((index, element) => {
22
- $(element).parents('label').toggleClass('text-white bg-blue-600', $(element).is(':checked'));
23
- $(element).parents('label').toggleClass('text-gray-600 bg-gray-300', $(element).is(':not(:checked)'));
22
+ $(element)
23
+ .parents('label')
24
+ .toggleClass('text-white bg-blue-600', $(element).is(':checked'));
25
+ $(element)
26
+ .parents('label')
27
+ .toggleClass(
28
+ 'text-gray-600 bg-gray-300',
29
+ $(element).is(':not(:checked)')
30
+ );
24
31
  });
25
32
 
26
- $('#direction_name_selector input[name="directionName"]').each((index, element) => {
27
- $(element).parents('label').toggleClass('text-white bg-blue-600', $(element).is(':checked'));
28
- $(element).parents('label').toggleClass('text-gray-600 bg-gray-300', $(element).is(':not(:checked)'));
29
- });
33
+ $('#direction_name_selector input[name="directionName"]').each(
34
+ (index, element) => {
35
+ $(element)
36
+ .parents('label')
37
+ .toggleClass('text-white bg-blue-600', $(element).is(':checked'));
38
+ $(element)
39
+ .parents('label')
40
+ .toggleClass(
41
+ 'text-gray-600 bg-gray-300',
42
+ $(element).is(':not(:checked)')
43
+ );
44
+ }
45
+ );
30
46
 
31
47
  const dayList = $('#day_list_selector input[name="dayList"]:checked').val();
32
- const directionName = $('#direction_name_selector input[name="directionName"]:checked').val();
48
+ const directionName = $(
49
+ '#direction_name_selector input[name="directionName"]:checked'
50
+ ).val();
33
51
 
34
52
  $('.timetable').hide();
35
- const id = $('.timetable[data-day-list="' + dayList + '"][data-direction-name="' + directionName + '"]').attr('id');
53
+ const id = $(
54
+ '.timetable[data-day-list="' +
55
+ dayList +
56
+ '"][data-direction-name="' +
57
+ directionName +
58
+ '"]'
59
+ ).attr('id');
36
60
  showTimetable(id);
37
61
  }
38
62
 
@@ -11,23 +11,6 @@
11
11
  return summary;
12
12
  }
13
13
 
14
- function formatTripName(trip, idx, timetable) {
15
- let tripName = '';
16
- if (timetable.routes.length > 1) {
17
- tripName = trip.route_short_name;
18
- } else if (trip.trip_short_name) {
19
- tripName += trip.trip_short_name;
20
- } else {
21
- tripName += `Run #${idx + 1}`;
22
- }
23
-
24
- if (timetableHasDifferentDays(timetable)) {
25
- tripName += ` ${trip.dayList}`;
26
- }
27
-
28
- return tripName;
29
- }
30
-
31
14
  function formatRouteName(route) {
32
15
  const hasLongName = route.route_long_name !== '' && route.route_long_name !== null;
33
16
 
@@ -6,9 +6,9 @@ block extraHeader
6
6
  if config.showMap
7
7
  script(src="https://unpkg.com/jquery@3.6.0/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/v2.5.0/mapbox-gl.js")
9
+ script(src="https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.js")
10
10
  script.
11
11
  mapboxgl.accessToken = '#{config.mapboxAccessToken}';
12
12
  script(src=`${config.assetPath}js/system-map.js`)
13
13
 
14
- link(href="https://api.mapbox.com/mapbox-gl-js/v2.5.0/mapbox-gl.css" rel="stylesheet")
14
+ link(href="https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.css" rel="stylesheet")
@@ -9,10 +9,10 @@ block extraHeader
9
9
  script(src=`${config.assetPath}js/timetable-menu.js`)
10
10
 
11
11
  if config.showMap
12
- script(src="https://api.mapbox.com/mapbox-gl-js/v2.5.0/mapbox-gl.js")
12
+ script(src="https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.js")
13
13
  script.
14
14
  mapboxgl.accessToken = '#{config.mapboxAccessToken}';
15
15
  script(src=`${config.assetPath}js/timetable-map.js`)
16
16
 
17
- link(href="https://api.mapbox.com/mapbox-gl-js/v2.5.0/mapbox-gl.css" rel="stylesheet")
17
+ link(href="https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.css" rel="stylesheet")
18
18
 
@@ -0,0 +1,26 @@
1
+ ---
2
+ slug: timetables_as_csv
3
+ title: New Feature - GTFS timetables as CSV
4
+ author: Brendan Nee
5
+ author_url: https://github.com/brendannee
6
+ author_image_url: https://avatars3.githubusercontent.com/u/96217?s=400&v=4
7
+ tags: [csv]
8
+ ---
9
+
10
+ GTFS-to-HTML Version 2.3.0 adds support for exporting timetables as CSV. Setting the [outputFormat](https://gtfstohtml.com/docs/configuration#outputformat) configuration to `csv` will generate CSV files instead of HTML. One CSV file per timetable will be generated.
11
+
12
+ An example of a CSV timetable:
13
+
14
+ ```
15
+ ,San Francisco Ferry Building,Vallejo Ferry Terminal,Mare Island Ferry Terminal
16
+ Run #1,10:30am,11:30am,
17
+ Run #2,11:30am,12:30pm,
18
+ Run #3,1:50pm,2:50pm,
19
+ Run #4,2:50pm,3:50pm,
20
+ Run #5,4:10pm,5:10pm,5:25pm
21
+ Run #6,5:10pm,6:10pm,6:25pm
22
+ Run #7,6:30pm,7:30pm,
23
+ Run #8,8:50pm,9:50pm,10:05pm
24
+ ```
25
+
26
+ Timetables in CSV respect the `orientation` set in `timetables.txt` or `defaultOrientation` in `config.json`, they can be either `horizontal` or `vertical`.