gtfs 3.1.1 → 3.2.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/.eslintrc.json +14 -19
- package/.husky/pre-commit +4 -0
- package/@types/index.d.ts +269 -0
- package/@types/tests.ts +26 -0
- package/@types/tsconfig.json +17 -0
- package/CHANGELOG.md +182 -1
- package/README.md +168 -149
- package/bin/gtfs-export.js +4 -5
- package/bin/gtfs-import.js +6 -7
- package/config-sample-full.json +2 -7
- package/docs/images/node-gtfs-logo.svg +18 -0
- package/lib/db.js +63 -12
- package/lib/export.js +27 -13
- package/lib/file-utils.js +26 -9
- package/lib/geojson-utils.js +51 -38
- package/lib/gtfs/agencies.js +15 -4
- package/lib/gtfs/attributions.js +15 -4
- package/lib/gtfs/calendar-dates.js +15 -4
- package/lib/gtfs/calendars.js +15 -4
- package/lib/gtfs/fare-attributes.js +15 -4
- package/lib/gtfs/fare-rules.js +15 -4
- package/lib/gtfs/feed-info.js +15 -4
- package/lib/gtfs/frequencies.js +15 -4
- package/lib/gtfs/levels.js +15 -4
- package/lib/gtfs/pathways.js +15 -4
- package/lib/gtfs/routes.js +22 -6
- package/lib/gtfs/shapes.js +59 -23
- package/lib/gtfs/stop-times.js +15 -4
- package/lib/gtfs/stops.js +57 -23
- package/lib/gtfs/transfers.js +15 -4
- package/lib/gtfs/translations.js +15 -4
- package/lib/gtfs/trips.js +15 -4
- package/lib/gtfs-ride/board-alights.js +15 -4
- package/lib/gtfs-ride/ride-feed-infos.js +15 -4
- package/lib/gtfs-ride/rider-trips.js +15 -4
- package/lib/gtfs-ride/riderships.js +15 -4
- package/lib/gtfs-ride/trip-capacities.js +15 -4
- package/lib/import.js +203 -128
- package/lib/log-utils.js +8 -4
- package/lib/non-standard/directions.js +15 -4
- package/lib/non-standard/stop-attributes.js +15 -4
- package/lib/non-standard/timetable-notes-references.js +15 -4
- package/lib/non-standard/timetable-notes.js +15 -4
- package/lib/non-standard/timetable-pages.js +15 -4
- package/lib/non-standard/timetable-stop-order.js +15 -4
- package/lib/non-standard/timetables.js +15 -4
- package/lib/utils.js +26 -12
- package/models/gtfs/agency.js +11 -11
- package/models/gtfs/attributions.js +14 -14
- package/models/gtfs/calendar-dates.js +7 -7
- package/models/gtfs/calendar.js +12 -12
- package/models/gtfs/fare-attributes.js +9 -9
- package/models/gtfs/fare-rules.js +8 -8
- package/models/gtfs/feed-info.js +12 -12
- package/models/gtfs/frequencies.js +10 -10
- package/models/gtfs/levels.js +5 -5
- package/models/gtfs/pathways.js +14 -14
- package/models/gtfs/routes.js +14 -14
- package/models/gtfs/shapes.js +8 -8
- package/models/gtfs/stop-times.js +17 -17
- package/models/gtfs/stops.js +17 -17
- package/models/gtfs/transfers.js +7 -7
- package/models/gtfs/translations.js +10 -10
- package/models/gtfs/trips.js +12 -12
- package/models/gtfs-ride/board-alight.js +24 -24
- package/models/gtfs-ride/ride-feed-info.js +8 -8
- package/models/gtfs-ride/rider-trip.js +21 -21
- package/models/gtfs-ride/ridership.js +23 -23
- package/models/gtfs-ride/trip-capacity.js +10 -10
- package/models/models.js +1 -1
- package/models/non-standard/directions.js +6 -6
- package/models/non-standard/stop-attributes.js +5 -5
- package/models/non-standard/timetable-notes-references.js +9 -9
- package/models/non-standard/timetable-notes.js +5 -5
- package/models/non-standard/timetable-pages.js +5 -5
- package/models/non-standard/timetable-stop-order.js +6 -6
- package/models/non-standard/timetables.js +27 -27
- package/package.json +35 -13
- package/test/mocha/export-gtfs.js +74 -44
- package/test/mocha/get-agencies.js +20 -14
- package/test/mocha/get-attributions.js +10 -4
- package/test/mocha/get-board-alights.js +10 -4
- package/test/mocha/get-calendar-dates.js +31 -24
- package/test/mocha/get-calendars.js +17 -11
- package/test/mocha/get-db.js +71 -5
- package/test/mocha/get-directions.js +10 -4
- package/test/mocha/get-fare-attributes.js +12 -6
- package/test/mocha/get-fare-rules.js +17 -13
- package/test/mocha/get-feed-info.js +10 -4
- package/test/mocha/get-frequencies.js +10 -4
- package/test/mocha/get-levels.js +4 -4
- package/test/mocha/get-pathways.js +10 -4
- package/test/mocha/get-ride-feed-infos.js +9 -3
- package/test/mocha/get-rider-trips.js +10 -4
- package/test/mocha/get-riderships.js +10 -4
- package/test/mocha/get-routes.js +12 -16
- package/test/mocha/get-shapes-as-geojson.js +12 -6
- package/test/mocha/get-shapes.js +31 -39
- package/test/mocha/get-stop-attributes.js +10 -4
- package/test/mocha/get-stops-as-geojson.js +11 -5
- package/test/mocha/get-stops.js +62 -51
- package/test/mocha/get-stoptimes.js +18 -10
- package/test/mocha/get-timetable-pages.js +10 -4
- package/test/mocha/get-timetable-stop-orders.js +10 -4
- package/test/mocha/get-timetables.js +10 -4
- package/test/mocha/get-transfers.js +10 -4
- package/test/mocha/get-translations.js +10 -4
- package/test/mocha/get-trip-capacities.js +10 -4
- package/test/mocha/get-trips.js +6 -6
- package/test/mocha/import-gtfs.js +63 -46
- package/test/test-config.js +9 -4
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
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
|
/*
|
|
9
13
|
* Returns an array of all fare attributes that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getFareAttributes(
|
|
12
|
-
|
|
15
|
+
export async function getFareAttributes(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(fareAttributes.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/fare-rules.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
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
|
/*
|
|
9
13
|
* Returns an array of all fare rules that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getFareRules(
|
|
12
|
-
|
|
15
|
+
export async function getFareRules(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(fareRules.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/feed-info.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
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
|
/*
|
|
9
13
|
* Returns an array of all feed info that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getFeedInfo(
|
|
12
|
-
|
|
15
|
+
export async function getFeedInfo(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(feedInfo.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/frequencies.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
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
|
/*
|
|
9
13
|
* Returns an array of all frequencies that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getFrequencies(
|
|
12
|
-
|
|
15
|
+
export async function getFrequencies(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(frequencies.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/levels.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
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
|
/*
|
|
9
13
|
* Returns an array of all levels that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getLevels(
|
|
12
|
-
|
|
15
|
+
export async function getLevels(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(levels.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/pathways.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
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
|
/*
|
|
9
13
|
* Returns an array of all pathways that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getPathways(
|
|
12
|
-
|
|
15
|
+
export async function getPathways(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(pathways.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/routes.js
CHANGED
|
@@ -3,7 +3,12 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
3
3
|
|
|
4
4
|
import { getDb } from '../db.js';
|
|
5
5
|
|
|
6
|
-
import {
|
|
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,15 +17,22 @@ 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(
|
|
20
|
+
return `SELECT DISTINCT route_id FROM trips WHERE trip_id IN (${buildStoptimeSubquery(
|
|
21
|
+
query
|
|
22
|
+
)})`;
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
/*
|
|
19
26
|
* Returns an array of routes that match the query parameters. A `stop_id`
|
|
20
27
|
* query parameter may be passed to find all routes that contain that stop.
|
|
21
28
|
*/
|
|
22
|
-
export async function getRoutes(
|
|
23
|
-
|
|
29
|
+
export async function getRoutes(
|
|
30
|
+
query = {},
|
|
31
|
+
fields = [],
|
|
32
|
+
orderBy = [],
|
|
33
|
+
options = {}
|
|
34
|
+
) {
|
|
35
|
+
const db = options.db ?? (await getDb());
|
|
24
36
|
const tableName = sqlString.escapeId(routes.filenameBase);
|
|
25
37
|
const selectClause = formatSelectClause(fields);
|
|
26
38
|
let whereClause = '';
|
|
@@ -29,7 +41,9 @@ export async function getRoutes(query = {}, fields = [], orderBy = []) {
|
|
|
29
41
|
const routeQuery = omit(query, ['stop_id']);
|
|
30
42
|
const stoptimeQuery = pick(query, ['stop_id']);
|
|
31
43
|
|
|
32
|
-
const whereClauses = Object.entries(routeQuery).map(([key, value]) =>
|
|
44
|
+
const whereClauses = Object.entries(routeQuery).map(([key, value]) =>
|
|
45
|
+
formatWhereClause(key, value)
|
|
46
|
+
);
|
|
33
47
|
|
|
34
48
|
if (Object.values(stoptimeQuery).length > 0) {
|
|
35
49
|
whereClauses.push(`route_id IN (${buildTripSubquery(stoptimeQuery)})`);
|
|
@@ -39,5 +53,7 @@ export async function getRoutes(query = {}, fields = [], orderBy = []) {
|
|
|
39
53
|
whereClause = `WHERE ${whereClauses.join(' AND ')}`;
|
|
40
54
|
}
|
|
41
55
|
|
|
42
|
-
return db.all(
|
|
56
|
+
return db.all(
|
|
57
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
58
|
+
);
|
|
43
59
|
}
|
package/lib/gtfs/shapes.js
CHANGED
|
@@ -4,7 +4,12 @@ import { featureCollection } from '@turf/helpers';
|
|
|
4
4
|
|
|
5
5
|
import { getDb } from '../db.js';
|
|
6
6
|
|
|
7
|
-
import {
|
|
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';
|
|
@@ -21,17 +26,34 @@ function buildTripSubquery(query) {
|
|
|
21
26
|
* query parameter may be passed to find all shapes for a trip. A
|
|
22
27
|
* `direction_id` query parameter may be passed to find all shapes for a direction.
|
|
23
28
|
*/
|
|
24
|
-
export async function getShapes(
|
|
25
|
-
|
|
29
|
+
export async function getShapes(
|
|
30
|
+
query = {},
|
|
31
|
+
fields = [],
|
|
32
|
+
orderBy = [],
|
|
33
|
+
options = {}
|
|
34
|
+
) {
|
|
35
|
+
const db = options.db ?? (await getDb());
|
|
26
36
|
const tableName = sqlString.escapeId(shapes.filenameBase);
|
|
27
37
|
const selectClause = formatSelectClause(fields);
|
|
28
38
|
let whereClause = '';
|
|
29
39
|
const orderByClause = formatOrderByClause(orderBy);
|
|
30
40
|
|
|
31
|
-
const shapeQuery = omit(query, [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
const shapeQuery = omit(query, [
|
|
42
|
+
'route_id',
|
|
43
|
+
'trip_id',
|
|
44
|
+
'service_id',
|
|
45
|
+
'direction_id',
|
|
46
|
+
]);
|
|
47
|
+
const tripQuery = pick(query, [
|
|
48
|
+
'route_id',
|
|
49
|
+
'trip_id',
|
|
50
|
+
'service_id',
|
|
51
|
+
'direction_id',
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
const whereClauses = Object.entries(shapeQuery).map(([key, value]) =>
|
|
55
|
+
formatWhereClause(key, value)
|
|
56
|
+
);
|
|
35
57
|
|
|
36
58
|
if (Object.values(tripQuery).length > 0) {
|
|
37
59
|
whereClauses.push(`shape_id IN (${buildTripSubquery(tripQuery)})`);
|
|
@@ -41,15 +63,17 @@ export async function getShapes(query = {}, fields = [], orderBy = []) {
|
|
|
41
63
|
whereClause = `WHERE ${whereClauses.join(' AND ')}`;
|
|
42
64
|
}
|
|
43
65
|
|
|
44
|
-
return db.all(
|
|
66
|
+
return db.all(
|
|
67
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
68
|
+
);
|
|
45
69
|
}
|
|
46
70
|
|
|
47
71
|
/*
|
|
48
72
|
* Returns geoJSON of the shapes that match the query parameters. A `route_id`
|
|
49
73
|
* query parameter may be passed to find all shapes for a route.
|
|
50
74
|
*/
|
|
51
|
-
export async function getShapesAsGeoJSON(query = {}) {
|
|
52
|
-
const agencies = await getAgencies();
|
|
75
|
+
export async function getShapesAsGeoJSON(query = {}, options = {}) {
|
|
76
|
+
const agencies = await getAgencies({}, [], [], options);
|
|
53
77
|
|
|
54
78
|
const routeQuery = {};
|
|
55
79
|
|
|
@@ -57,21 +81,33 @@ export async function getShapesAsGeoJSON(query = {}) {
|
|
|
57
81
|
routeQuery.route_id = query.route_id;
|
|
58
82
|
}
|
|
59
83
|
|
|
60
|
-
const routes = await getRoutes(routeQuery);
|
|
84
|
+
const routes = await getRoutes(routeQuery, [], [], options);
|
|
61
85
|
const features = [];
|
|
62
86
|
|
|
63
|
-
await Promise.all(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
87
|
+
await Promise.all(
|
|
88
|
+
routes.map(async (route) => {
|
|
89
|
+
const shapeQuery = {
|
|
90
|
+
route_id: route.route_id,
|
|
91
|
+
...omit(query, 'route_id'),
|
|
92
|
+
};
|
|
93
|
+
const shapes = await getShapes(
|
|
94
|
+
shapeQuery,
|
|
95
|
+
['shape_id', 'shape_pt_sequence', 'shape_pt_lon', 'shape_pt_lat'],
|
|
96
|
+
[],
|
|
97
|
+
options
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const agency = agencies.find(
|
|
101
|
+
(agency) => agency.agency_id === route.agency_id
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const routeProperties = {
|
|
105
|
+
agency_name: agency ? agency.agency_name : undefined,
|
|
106
|
+
...route,
|
|
107
|
+
};
|
|
108
|
+
features.push(...shapesToGeoJSONFeatures(shapes, routeProperties));
|
|
109
|
+
})
|
|
110
|
+
);
|
|
75
111
|
|
|
76
112
|
return featureCollection(features);
|
|
77
113
|
}
|
package/lib/gtfs/stop-times.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
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
|
/*
|
|
9
13
|
* Returns an array of stoptimes that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getStoptimes(
|
|
12
|
-
|
|
15
|
+
export async function getStoptimes(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(stopTimes.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/stops.js
CHANGED
|
@@ -3,7 +3,12 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
3
3
|
|
|
4
4
|
import { getDb } from '../db.js';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
formatOrderByClause,
|
|
8
|
+
formatSelectClause,
|
|
9
|
+
formatWhereClause,
|
|
10
|
+
formatWhereClauses,
|
|
11
|
+
} from '../utils.js';
|
|
7
12
|
import { stopsToGeoJSON } from '../geojson-utils.js';
|
|
8
13
|
import stops from '../../models/gtfs/stops.js';
|
|
9
14
|
import { getAgencies } from './agencies.js';
|
|
@@ -14,7 +19,9 @@ function buildTripSubquery(query) {
|
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
function buildStoptimeSubquery(query) {
|
|
17
|
-
return `SELECT DISTINCT stop_id FROM stop_times WHERE trip_id IN (${buildTripSubquery(
|
|
22
|
+
return `SELECT DISTINCT stop_id FROM stop_times WHERE trip_id IN (${buildTripSubquery(
|
|
23
|
+
query
|
|
24
|
+
)})`;
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
/*
|
|
@@ -23,17 +30,34 @@ function buildStoptimeSubquery(query) {
|
|
|
23
30
|
* query parameter may be passed to find all shapes for a trip. A
|
|
24
31
|
* `direction_id` query parameter may be passed to find all shapes for a direction.
|
|
25
32
|
*/
|
|
26
|
-
export async function getStops(
|
|
27
|
-
|
|
33
|
+
export async function getStops(
|
|
34
|
+
query = {},
|
|
35
|
+
fields = [],
|
|
36
|
+
orderBy = [],
|
|
37
|
+
options = {}
|
|
38
|
+
) {
|
|
39
|
+
const db = options.db ?? (await getDb());
|
|
28
40
|
const tableName = sqlString.escapeId(stops.filenameBase);
|
|
29
41
|
const selectClause = formatSelectClause(fields);
|
|
30
42
|
let whereClause = '';
|
|
31
43
|
const orderByClause = formatOrderByClause(orderBy);
|
|
32
44
|
|
|
33
|
-
const stopQuery = omit(query, [
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
const stopQuery = omit(query, [
|
|
46
|
+
'route_id',
|
|
47
|
+
'trip_id',
|
|
48
|
+
'service_id',
|
|
49
|
+
'direction_id',
|
|
50
|
+
]);
|
|
51
|
+
const tripQuery = pick(query, [
|
|
52
|
+
'route_id',
|
|
53
|
+
'trip_id',
|
|
54
|
+
'service_id',
|
|
55
|
+
'direction_id',
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
const whereClauses = Object.entries(stopQuery).map(([key, value]) =>
|
|
59
|
+
formatWhereClause(key, value)
|
|
60
|
+
);
|
|
37
61
|
|
|
38
62
|
if (Object.values(tripQuery).length > 0) {
|
|
39
63
|
whereClauses.push(`stop_id IN (${buildStoptimeSubquery(tripQuery)})`);
|
|
@@ -43,29 +67,39 @@ export async function getStops(query = {}, fields = [], orderBy = []) {
|
|
|
43
67
|
whereClause = `WHERE ${whereClauses.join(' AND ')}`;
|
|
44
68
|
}
|
|
45
69
|
|
|
46
|
-
return db.all(
|
|
70
|
+
return db.all(
|
|
71
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
72
|
+
);
|
|
47
73
|
}
|
|
48
74
|
|
|
49
75
|
/*
|
|
50
76
|
* Returns geoJSON with stops for the `agencyKey` specified, optionally limited
|
|
51
77
|
* to the `stopIds` specified
|
|
52
78
|
*/
|
|
53
|
-
export async function getStopsAsGeoJSON(query = {}) {
|
|
54
|
-
const db = await getDb();
|
|
55
|
-
const stops = await getStops(query);
|
|
79
|
+
export async function getStopsAsGeoJSON(query = {}, options = {}) {
|
|
80
|
+
const db = options.db ?? (await getDb());
|
|
81
|
+
const stops = await getStops(query, [], [], options);
|
|
56
82
|
|
|
57
83
|
// Get all agencies for reference
|
|
58
|
-
const agencies = await getAgencies();
|
|
59
|
-
|
|
60
|
-
const preparedStops = await Promise.all(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
84
|
+
const agencies = await getAgencies({}, [], [], options);
|
|
85
|
+
|
|
86
|
+
const preparedStops = await Promise.all(
|
|
87
|
+
stops.map(async (stop) => {
|
|
88
|
+
const routeSubquery =
|
|
89
|
+
'SELECT DISTINCT route_id FROM trips WHERE trip_id IN (SELECT DISTINCT trip_id FROM stop_times WHERE stop_id = ?)';
|
|
90
|
+
const routes = await db.all(
|
|
91
|
+
`SELECT * FROM routes WHERE route_id IN (${routeSubquery})`,
|
|
92
|
+
[stop.stop_id]
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
stop.routes = orderBy(routes, (route) =>
|
|
96
|
+
Number.parseInt(route.route_short_name, 10)
|
|
97
|
+
);
|
|
98
|
+
stop.agency_name = agencies[0].agency_name;
|
|
99
|
+
|
|
100
|
+
return stop;
|
|
101
|
+
})
|
|
102
|
+
);
|
|
69
103
|
|
|
70
104
|
return stopsToGeoJSON(preparedStops);
|
|
71
105
|
}
|
package/lib/gtfs/transfers.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
formatOrderByClause,
|
|
7
|
+
formatSelectClause,
|
|
8
|
+
formatWhereClauses,
|
|
9
|
+
} from '../utils.js';
|
|
6
10
|
import transfers from '../../models/gtfs/transfers.js';
|
|
7
11
|
|
|
8
12
|
/*
|
|
9
13
|
* Returns an array of all transfers that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getTransfers(
|
|
12
|
-
|
|
15
|
+
export async function getTransfers(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(transfers.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/translations.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
formatOrderByClause,
|
|
7
|
+
formatSelectClause,
|
|
8
|
+
formatWhereClauses,
|
|
9
|
+
} from '../utils.js';
|
|
6
10
|
import translations from '../../models/gtfs/translations.js';
|
|
7
11
|
|
|
8
12
|
/*
|
|
9
13
|
* Returns an array of all translations that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getTranslations(
|
|
12
|
-
|
|
15
|
+
export async function getTranslations(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(translations.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|
package/lib/gtfs/trips.js
CHANGED
|
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
|
|
|
2
2
|
|
|
3
3
|
import { getDb } from '../db.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
formatOrderByClause,
|
|
7
|
+
formatSelectClause,
|
|
8
|
+
formatWhereClauses,
|
|
9
|
+
} from '../utils.js';
|
|
6
10
|
import trips from '../../models/gtfs/trips.js';
|
|
7
11
|
|
|
8
12
|
/*
|
|
9
13
|
* Returns an array of all trips that match the query parameters.
|
|
10
14
|
*/
|
|
11
|
-
export async function getTrips(
|
|
12
|
-
|
|
15
|
+
export async function getTrips(
|
|
16
|
+
query = {},
|
|
17
|
+
fields = [],
|
|
18
|
+
orderBy = [],
|
|
19
|
+
options = {}
|
|
20
|
+
) {
|
|
21
|
+
const db = options.db ?? (await getDb());
|
|
13
22
|
const tableName = sqlString.escapeId(trips.filenameBase);
|
|
14
23
|
const selectClause = formatSelectClause(fields);
|
|
15
24
|
const whereClause = formatWhereClauses(query);
|
|
16
25
|
const orderByClause = formatOrderByClause(orderBy);
|
|
17
26
|
|
|
18
|
-
return db.all(
|
|
27
|
+
return db.all(
|
|
28
|
+
`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
|
|
29
|
+
);
|
|
19
30
|
}
|