gtfs 3.1.3 → 3.1.4

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.
Files changed (107) hide show
  1. package/.eslintrc.json +14 -19
  2. package/.husky/pre-commit +4 -0
  3. package/.prettierrc.js +4 -0
  4. package/CHANGELOG.md +156 -0
  5. package/README.md +113 -126
  6. package/bin/gtfs-export.js +4 -5
  7. package/bin/gtfs-import.js +6 -7
  8. package/config-sample-full.json +2 -7
  9. package/lib/db.js +4 -2
  10. package/lib/export.js +26 -9
  11. package/lib/file-utils.js +26 -9
  12. package/lib/geojson-utils.js +51 -38
  13. package/lib/gtfs/agencies.js +8 -2
  14. package/lib/gtfs/attributions.js +8 -2
  15. package/lib/gtfs/calendar-dates.js +8 -2
  16. package/lib/gtfs/calendars.js +8 -2
  17. package/lib/gtfs/fare-attributes.js +8 -2
  18. package/lib/gtfs/fare-rules.js +8 -2
  19. package/lib/gtfs/feed-info.js +8 -2
  20. package/lib/gtfs/frequencies.js +8 -2
  21. package/lib/gtfs/levels.js +8 -2
  22. package/lib/gtfs/pathways.js +8 -2
  23. package/lib/gtfs/routes.js +15 -4
  24. package/lib/gtfs/shapes.js +49 -18
  25. package/lib/gtfs/stop-times.js +8 -2
  26. package/lib/gtfs/stops.js +45 -16
  27. package/lib/gtfs/transfers.js +8 -2
  28. package/lib/gtfs/translations.js +8 -2
  29. package/lib/gtfs/trips.js +8 -2
  30. package/lib/gtfs-ride/board-alights.js +8 -2
  31. package/lib/gtfs-ride/ride-feed-infos.js +8 -2
  32. package/lib/gtfs-ride/rider-trips.js +8 -2
  33. package/lib/gtfs-ride/riderships.js +8 -2
  34. package/lib/gtfs-ride/trip-capacities.js +8 -2
  35. package/lib/import.js +198 -123
  36. package/lib/log-utils.js +8 -4
  37. package/lib/non-standard/directions.js +8 -2
  38. package/lib/non-standard/stop-attributes.js +8 -2
  39. package/lib/non-standard/timetable-notes-references.js +13 -3
  40. package/lib/non-standard/timetable-notes.js +8 -2
  41. package/lib/non-standard/timetable-pages.js +8 -2
  42. package/lib/non-standard/timetable-stop-order.js +13 -3
  43. package/lib/non-standard/timetables.js +8 -2
  44. package/lib/utils.js +22 -11
  45. package/models/gtfs/agency.js +11 -11
  46. package/models/gtfs/attributions.js +14 -14
  47. package/models/gtfs/calendar-dates.js +7 -7
  48. package/models/gtfs/calendar.js +12 -12
  49. package/models/gtfs/fare-attributes.js +9 -9
  50. package/models/gtfs/fare-rules.js +8 -8
  51. package/models/gtfs/feed-info.js +12 -12
  52. package/models/gtfs/frequencies.js +10 -10
  53. package/models/gtfs/levels.js +5 -5
  54. package/models/gtfs/pathways.js +14 -14
  55. package/models/gtfs/routes.js +14 -14
  56. package/models/gtfs/shapes.js +8 -8
  57. package/models/gtfs/stop-times.js +17 -17
  58. package/models/gtfs/stops.js +17 -17
  59. package/models/gtfs/transfers.js +7 -7
  60. package/models/gtfs/translations.js +10 -10
  61. package/models/gtfs/trips.js +12 -12
  62. package/models/gtfs-ride/board-alight.js +24 -24
  63. package/models/gtfs-ride/ride-feed-info.js +8 -8
  64. package/models/gtfs-ride/rider-trip.js +21 -21
  65. package/models/gtfs-ride/ridership.js +23 -23
  66. package/models/gtfs-ride/trip-capacity.js +10 -10
  67. package/models/models.js +1 -1
  68. package/models/non-standard/directions.js +6 -6
  69. package/models/non-standard/stop-attributes.js +5 -5
  70. package/models/non-standard/timetable-notes-references.js +9 -9
  71. package/models/non-standard/timetable-notes.js +5 -5
  72. package/models/non-standard/timetable-pages.js +5 -5
  73. package/models/non-standard/timetable-stop-order.js +6 -6
  74. package/models/non-standard/timetables.js +27 -27
  75. package/package.json +10 -2
  76. package/test/mocha/export-gtfs.js +63 -40
  77. package/test/mocha/get-agencies.js +11 -11
  78. package/test/mocha/get-attributions.js +1 -1
  79. package/test/mocha/get-board-alights.js +1 -1
  80. package/test/mocha/get-calendar-dates.js +22 -21
  81. package/test/mocha/get-calendars.js +8 -8
  82. package/test/mocha/get-db.js +9 -2
  83. package/test/mocha/get-directions.js +1 -1
  84. package/test/mocha/get-fare-attributes.js +3 -3
  85. package/test/mocha/get-fare-rules.js +8 -10
  86. package/test/mocha/get-feed-info.js +1 -1
  87. package/test/mocha/get-frequencies.js +1 -1
  88. package/test/mocha/get-levels.js +1 -1
  89. package/test/mocha/get-pathways.js +1 -1
  90. package/test/mocha/get-rider-trips.js +1 -1
  91. package/test/mocha/get-riderships.js +1 -1
  92. package/test/mocha/get-routes.js +9 -13
  93. package/test/mocha/get-shapes-as-geojson.js +3 -3
  94. package/test/mocha/get-shapes.js +28 -36
  95. package/test/mocha/get-stop-attributes.js +1 -1
  96. package/test/mocha/get-stops-as-geojson.js +2 -2
  97. package/test/mocha/get-stops.js +59 -48
  98. package/test/mocha/get-stoptimes.js +9 -7
  99. package/test/mocha/get-timetable-pages.js +1 -1
  100. package/test/mocha/get-timetable-stop-orders.js +1 -1
  101. package/test/mocha/get-timetables.js +1 -1
  102. package/test/mocha/get-transfers.js +1 -1
  103. package/test/mocha/get-translations.js +1 -1
  104. package/test/mocha/get-trip-capacities.js +1 -1
  105. package/test/mocha/get-trips.js +3 -3
  106. package/test/mocha/import-gtfs.js +59 -42
  107. package/test/test-config.js +9 -4
package/lib/export.js CHANGED
@@ -17,7 +17,7 @@ import { setDefaultConfig } from './utils.js';
17
17
 
18
18
  const stringify = promisify(csvStringify);
19
19
 
20
- const exportGtfs = async initialConfig => {
20
+ const exportGtfs = async (initialConfig) => {
21
21
  const config = setDefaultConfig(initialConfig);
22
22
  const log = _log(config);
23
23
  const logWarning = _logWarning(config);
@@ -26,20 +26,34 @@ const exportGtfs = async initialConfig => {
26
26
  // Get agency name for export folder from first line of agency.txt
27
27
  const agencies = await db.all('SELECT agency_name FROM agency;').catch(() => {
28
28
  if (config.sqlitePath === ':memory:') {
29
- throw new Error('No agencies found in SQLite. You are using an in-memory database - if running this from command line be sure to specify a value for `sqlitePath` in config.json other than ":memory:".');
29
+ throw new Error(
30
+ 'No agencies found in SQLite. You are using an in-memory database - if running this from command line be sure to specify a value for `sqlitePath` in config.json other than ":memory:".'
31
+ );
30
32
  }
31
33
 
32
- throw new Error('No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`');
34
+ throw new Error(
35
+ 'No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`'
36
+ );
33
37
  });
34
38
 
35
39
  const agencyCount = agencies.length;
36
40
  if (agencyCount === 0) {
37
- throw new Error('No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`');
41
+ throw new Error(
42
+ 'No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`'
43
+ );
38
44
  } else if (agencyCount > 1) {
39
- logWarning('More than one agency is defined in config.json. Export will merge all into one GTFS file.');
45
+ logWarning(
46
+ 'More than one agency is defined in config.json. Export will merge all into one GTFS file.'
47
+ );
40
48
  }
41
49
 
42
- log(`Starting GTFS export for ${pluralize('agency', agencyCount, true)} using SQLite database at ${config.sqlitePath}`);
50
+ log(
51
+ `Starting GTFS export for ${pluralize(
52
+ 'agency',
53
+ agencyCount,
54
+ true
55
+ )} using SQLite database at ${config.sqlitePath}`
56
+ );
43
57
 
44
58
  const folderName = generateFolderName(agencies[0].agency_name);
45
59
  const defaultExportPath = path.join(process.cwd(), 'gtfs-export', folderName);
@@ -48,7 +62,7 @@ const exportGtfs = async initialConfig => {
48
62
  await prepDirectory(exportPath);
49
63
 
50
64
  // Loop through each GTFS file
51
- const exportedFiles = await mapSeries(models, async model => {
65
+ const exportedFiles = await mapSeries(models, async (model) => {
52
66
  const filepath = path.join(exportPath, `${model.filenameBase}.txt`);
53
67
  const tableName = sqlString.escapeId(model.filenameBase);
54
68
  const lines = await db.all(`SELECT * FROM ${tableName};`);
@@ -72,10 +86,13 @@ const exportGtfs = async initialConfig => {
72
86
  'boarding_timestamp',
73
87
  'alighting_timestamp',
74
88
  'ridership_start_timestamp',
75
- 'ridership_end_timestamp'
89
+ 'ridership_end_timestamp',
76
90
  ];
77
91
 
78
- const columns = without(model.schema.map(column => column.name), ...excludeColumns);
92
+ const columns = without(
93
+ model.schema.map((column) => column.name),
94
+ ...excludeColumns
95
+ );
79
96
  const fileText = await stringify(lines, { columns, header: true });
80
97
  await writeFile(filepath, fileText);
81
98
 
package/lib/file-utils.js CHANGED
@@ -15,13 +15,24 @@ export async function getConfig(argv) {
15
15
  if (argv.configPath) {
16
16
  // If a `configPath` is specified, try to read it and throw error if it doesn't exist
17
17
  try {
18
- const data = await readFile(path.resolve(untildify(argv.configPath)), 'utf8').catch(error => {
19
- console.error(new Error(`Cannot find configuration file at \`${argv.configPath}\`. Use config-sample.json as a starting point, pass --configPath option.`));
18
+ const data = await readFile(
19
+ path.resolve(untildify(argv.configPath)),
20
+ 'utf8'
21
+ ).catch((error) => {
22
+ console.error(
23
+ new Error(
24
+ `Cannot find configuration file at \`${argv.configPath}\`. Use config-sample.json as a starting point, pass --configPath option.`
25
+ )
26
+ );
20
27
  throw error;
21
28
  });
22
29
  config = Object.assign(JSON.parse(data), argv);
23
30
  } catch (error) {
24
- console.error(new Error(`Cannot parse configuration file at \`${argv.configPath}\`. Check to ensure that it is valid JSON.`));
31
+ console.error(
32
+ new Error(
33
+ `Cannot parse configuration file at \`${argv.configPath}\`. Check to ensure that it is valid JSON.`
34
+ )
35
+ );
25
36
  throw error;
26
37
  }
27
38
  } else if (existsSync(path.resolve('./config.json'))) {
@@ -31,7 +42,11 @@ export async function getConfig(argv) {
31
42
  config = Object.assign(JSON.parse(data), argv);
32
43
  console.log('Using configuration from ./config.json');
33
44
  } catch (error) {
34
- console.error(new Error('Cannot parse configuration file at `./config.json`. Check to ensure that it is valid JSON.'));
45
+ console.error(
46
+ new Error(
47
+ 'Cannot parse configuration file at `./config.json`. Check to ensure that it is valid JSON.'
48
+ )
49
+ );
35
50
  throw error;
36
51
  }
37
52
  } else if (argv.gtfsPath || argv.gtfsUrl) {
@@ -39,22 +54,24 @@ export async function getConfig(argv) {
39
54
  const agencies = [];
40
55
  if (argv.gtfsPath) {
41
56
  agencies.push({
42
- path: argv.gtfsPath
57
+ path: argv.gtfsPath,
43
58
  });
44
59
  }
45
60
 
46
61
  if (argv.gtfsUrl) {
47
62
  agencies.push({
48
- url: argv.gtfsUrl
63
+ url: argv.gtfsUrl,
49
64
  });
50
65
  }
51
66
 
52
67
  config = {
53
68
  agencies,
54
- ...omit(argv, ['path', 'url'])
69
+ ...omit(argv, ['path', 'url']),
55
70
  };
56
71
  } else {
57
- const error = new Error('Cannot find configuration file. Use config-sample.json as a starting point, pass --configPath option.');
72
+ const error = new Error(
73
+ 'Cannot find configuration file. Use config-sample.json as a starting point, pass --configPath option.'
74
+ );
58
75
  console.error(error);
59
76
  throw error;
60
77
  }
@@ -78,7 +95,7 @@ export function unzip(zipfilePath, exportPath) {
78
95
  /* eslint-disable new-cap */
79
96
  return createReadStream(zipfilePath)
80
97
  .pipe(Extract({ path: exportPath }))
81
- .on('entry', entry => entry.autodrain())
98
+ .on('entry', (entry) => entry.autodrain())
82
99
  .promise();
83
100
  /* eslint-enable new-cap */
84
101
  }
@@ -1,4 +1,12 @@
1
- import { cloneDeep, filter, groupBy, last, omit, sortBy, omitBy } from 'lodash-es';
1
+ import {
2
+ cloneDeep,
3
+ filter,
4
+ groupBy,
5
+ last,
6
+ omit,
7
+ sortBy,
8
+ omitBy,
9
+ } from 'lodash-es';
2
10
  import { feature, featureCollection } from '@turf/helpers';
3
11
 
4
12
  function isValidLineString(lineString) {
@@ -11,7 +19,11 @@ function isValidLineString(lineString) {
11
19
  }
12
20
 
13
21
  // Reject linestrings with two identical points
14
- if (lineString.length === 2 && lineString[0][0] === lineString[1][0] && lineString[0][1] === lineString[1][1]) {
22
+ if (
23
+ lineString.length === 2 &&
24
+ lineString[0][0] === lineString[1][0] &&
25
+ lineString[0][1] === lineString[1][1]
26
+ ) {
15
27
  return false;
16
28
  }
17
29
 
@@ -20,22 +32,18 @@ function isValidLineString(lineString) {
20
32
 
21
33
  function consolidateShapes(shapes) {
22
34
  const keys = new Set();
23
- const segmentsArray = shapes.map(shape => shape.reduce((memo, point, idx) => {
24
- if (idx > 0) {
25
- memo.push([
26
- [
27
- shape[idx - 1].shape_pt_lon,
28
- shape[idx - 1].shape_pt_lat
29
- ],
30
- [
31
- point.shape_pt_lon,
32
- point.shape_pt_lat
33
- ]
34
- ]);
35
- }
35
+ const segmentsArray = shapes.map((shape) =>
36
+ shape.reduce((memo, point, idx) => {
37
+ if (idx > 0) {
38
+ memo.push([
39
+ [shape[idx - 1].shape_pt_lon, shape[idx - 1].shape_pt_lat],
40
+ [point.shape_pt_lon, point.shape_pt_lat],
41
+ ]);
42
+ }
36
43
 
37
- return memo;
38
- }, []));
44
+ return memo;
45
+ }, [])
46
+ );
39
47
 
40
48
  const consolidatedLineStrings = [];
41
49
 
@@ -75,42 +83,47 @@ function formatHexColor(color) {
75
83
 
76
84
  function formatProperties(properties) {
77
85
  const formattedProperties = {
78
- ...cloneDeep(omitBy(properties, value => value === null)),
86
+ ...cloneDeep(omitBy(properties, (value) => value === null)),
79
87
  route_color: formatHexColor(properties.route_color),
80
- route_text_color: formatHexColor(properties.route_text_color)
88
+ route_text_color: formatHexColor(properties.route_text_color),
81
89
  };
82
90
 
83
91
  if (properties.routes) {
84
- formattedProperties.routes = properties.routes.map(route => formatProperties(route));
92
+ formattedProperties.routes = properties.routes.map((route) =>
93
+ formatProperties(route)
94
+ );
85
95
  }
86
96
 
87
97
  return formattedProperties;
88
98
  }
89
99
 
90
100
  export function shapesToGeoJSONFeatures(shapes, properties = {}) {
91
- const shapeGroups = Object.values(groupBy(shapes, 'shape_id')).map(shapeGroup => sortBy(shapeGroup, 'shape_pt_sequence'));
101
+ const shapeGroups = Object.values(groupBy(shapes, 'shape_id')).map(
102
+ (shapeGroup) => sortBy(shapeGroup, 'shape_pt_sequence')
103
+ );
92
104
  const lineStrings = consolidateShapes(shapeGroups);
93
105
 
94
- return lineStrings.map(lineString => feature(
95
- {
96
- type: 'LineString',
97
- coordinates: lineString
98
- },
99
- formatProperties(properties)
100
- ));
106
+ return lineStrings.map((lineString) =>
107
+ feature(
108
+ {
109
+ type: 'LineString',
110
+ coordinates: lineString,
111
+ },
112
+ formatProperties(properties)
113
+ )
114
+ );
101
115
  }
102
116
 
103
117
  export function stopsToGeoJSON(stops) {
104
- const features = stops.map(stop => feature(
105
- {
106
- type: 'Point',
107
- coordinates: [
108
- stop.stop_lon,
109
- stop.stop_lat
110
- ]
111
- },
112
- formatProperties(omit(stop, ['stop_lat', 'stop_lon']))
113
- ));
118
+ const features = stops.map((stop) =>
119
+ feature(
120
+ {
121
+ type: 'Point',
122
+ coordinates: [stop.stop_lon, stop.stop_lat],
123
+ },
124
+ formatProperties(omit(stop, ['stop_lat', 'stop_lon']))
125
+ )
126
+ );
114
127
 
115
128
  return featureCollection(features);
116
129
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import agency from '../../models/gtfs/agency.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getAgencies(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import attributions from '../../models/gtfs/attributions.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getAttributions(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import calendarDates from '../../models/gtfs/calendar-dates.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getCalendarDates(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import calendars from '../../models/gtfs/calendar.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getCalendars(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import fareAttributes from '../../models/gtfs/fare-attributes.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getFareAttributes(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import fareRules from '../../models/gtfs/fare-rules.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getFareRules(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import feedInfo from '../../models/gtfs/feed-info.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getFeedInfo(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import frequencies from '../../models/gtfs/frequencies.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getFrequencies(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import levels from '../../models/gtfs/levels.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getLevels(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import pathways from '../../models/gtfs/pathways.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getPathways(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }
@@ -3,7 +3,12 @@ import sqlString from 'sqlstring-sqlite';
3
3
 
4
4
  import { getDb } from '../db.js';
5
5
 
6
- import { formatOrderByClause, formatSelectClause, formatWhereClause, formatWhereClauses } from '../utils.js';
6
+ import {
7
+ formatOrderByClause,
8
+ formatSelectClause,
9
+ formatWhereClause,
10
+ formatWhereClauses,
11
+ } from '../utils.js';
7
12
  import routes from '../../models/gtfs/routes.js';
8
13
 
9
14
  function buildStoptimeSubquery(query) {
@@ -12,7 +17,9 @@ function buildStoptimeSubquery(query) {
12
17
  }
13
18
 
14
19
  function buildTripSubquery(query) {
15
- return `SELECT DISTINCT route_id FROM trips WHERE trip_id IN (${buildStoptimeSubquery(query)})`;
20
+ return `SELECT DISTINCT route_id FROM trips WHERE trip_id IN (${buildStoptimeSubquery(
21
+ query
22
+ )})`;
16
23
  }
17
24
 
18
25
  /*
@@ -29,7 +36,9 @@ export async function getRoutes(query = {}, fields = [], orderBy = []) {
29
36
  const routeQuery = omit(query, ['stop_id']);
30
37
  const stoptimeQuery = pick(query, ['stop_id']);
31
38
 
32
- const whereClauses = Object.entries(routeQuery).map(([key, value]) => formatWhereClause(key, value));
39
+ const whereClauses = Object.entries(routeQuery).map(([key, value]) =>
40
+ formatWhereClause(key, value)
41
+ );
33
42
 
34
43
  if (Object.values(stoptimeQuery).length > 0) {
35
44
  whereClauses.push(`route_id IN (${buildTripSubquery(stoptimeQuery)})`);
@@ -39,5 +48,7 @@ export async function getRoutes(query = {}, fields = [], orderBy = []) {
39
48
  whereClause = `WHERE ${whereClauses.join(' AND ')}`;
40
49
  }
41
50
 
42
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
51
+ return db.all(
52
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
53
+ );
43
54
  }
@@ -4,7 +4,12 @@ import { featureCollection } from '@turf/helpers';
4
4
 
5
5
  import { getDb } from '../db.js';
6
6
 
7
- import { formatOrderByClause, formatSelectClause, formatWhereClause, formatWhereClauses } from '../utils.js';
7
+ import {
8
+ formatOrderByClause,
9
+ formatSelectClause,
10
+ formatWhereClause,
11
+ formatWhereClauses,
12
+ } from '../utils.js';
8
13
  import { shapesToGeoJSONFeatures } from '../geojson-utils.js';
9
14
  import shapes from '../../models/gtfs/shapes.js';
10
15
  import { getAgencies } from './agencies.js';
@@ -28,10 +33,22 @@ export async function getShapes(query = {}, fields = [], orderBy = []) {
28
33
  let whereClause = '';
29
34
  const orderByClause = formatOrderByClause(orderBy);
30
35
 
31
- const shapeQuery = omit(query, ['route_id', 'trip_id', 'service_id', 'direction_id']);
32
- const tripQuery = pick(query, ['route_id', 'trip_id', 'service_id', 'direction_id']);
33
-
34
- const whereClauses = Object.entries(shapeQuery).map(([key, value]) => formatWhereClause(key, value));
36
+ const shapeQuery = omit(query, [
37
+ 'route_id',
38
+ 'trip_id',
39
+ 'service_id',
40
+ 'direction_id',
41
+ ]);
42
+ const tripQuery = pick(query, [
43
+ 'route_id',
44
+ 'trip_id',
45
+ 'service_id',
46
+ 'direction_id',
47
+ ]);
48
+
49
+ const whereClauses = Object.entries(shapeQuery).map(([key, value]) =>
50
+ formatWhereClause(key, value)
51
+ );
35
52
 
36
53
  if (Object.values(tripQuery).length > 0) {
37
54
  whereClauses.push(`shape_id IN (${buildTripSubquery(tripQuery)})`);
@@ -41,7 +58,9 @@ export async function getShapes(query = {}, fields = [], orderBy = []) {
41
58
  whereClause = `WHERE ${whereClauses.join(' AND ')}`;
42
59
  }
43
60
 
44
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
61
+ return db.all(
62
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
63
+ );
45
64
  }
46
65
 
47
66
  /*
@@ -60,18 +79,30 @@ export async function getShapesAsGeoJSON(query = {}) {
60
79
  const routes = await getRoutes(routeQuery);
61
80
  const features = [];
62
81
 
63
- await Promise.all(routes.map(async route => {
64
- const shapeQuery = { route_id: route.route_id, ...omit(query, 'route_id') };
65
- const shapes = await getShapes(shapeQuery, ['shape_id', 'shape_pt_sequence', 'shape_pt_lon', 'shape_pt_lat']);
66
-
67
- const agency = agencies.find(agency => agency.agency_id === route.agency_id);
68
-
69
- const routeProperties = {
70
- agency_name: agency ? agency.agency_name : undefined,
71
- ...route
72
- };
73
- features.push(...shapesToGeoJSONFeatures(shapes, routeProperties));
74
- }));
82
+ await Promise.all(
83
+ routes.map(async (route) => {
84
+ const shapeQuery = {
85
+ route_id: route.route_id,
86
+ ...omit(query, 'route_id'),
87
+ };
88
+ const shapes = await getShapes(shapeQuery, [
89
+ 'shape_id',
90
+ 'shape_pt_sequence',
91
+ 'shape_pt_lon',
92
+ 'shape_pt_lat',
93
+ ]);
94
+
95
+ const agency = agencies.find(
96
+ (agency) => agency.agency_id === route.agency_id
97
+ );
98
+
99
+ const routeProperties = {
100
+ agency_name: agency ? agency.agency_name : undefined,
101
+ ...route,
102
+ };
103
+ features.push(...shapesToGeoJSONFeatures(shapes, routeProperties));
104
+ })
105
+ );
75
106
 
76
107
  return featureCollection(features);
77
108
  }
@@ -2,7 +2,11 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import stopTimes from '../../models/gtfs/stop-times.js';
7
11
 
8
12
  /*
@@ -15,5 +19,7 @@ export async function getStoptimes(query = {}, fields = [], orderBy = []) {
15
19
  const whereClause = formatWhereClauses(query);
16
20
  const orderByClause = formatOrderByClause(orderBy);
17
21
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
22
+ return db.all(
23
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
24
+ );
19
25
  }