Skip to content

Commit 68c107f

Browse files
committed
add capability for netex data, introduce VR_bussit in finland as the first netex data
1 parent 60ba06e commit 68c107f

9 files changed

Lines changed: 135 additions & 10 deletions

File tree

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ data
22
storage
33
node_modules/
44
.DS_Store
5+
.pnp.cjs
6+
.pnp.loader.mjs
7+
.yarn/
8+
yarn.lock
59
router-finland.zip
610
router-hsl.zip
711
router-waltti.zip
812
router-waltti-alt.zip
9-
13+
*~
1014
.tmp

README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,14 @@ the databuilding process can also be called directly from the source tree. The o
1717
required external dependency is Docker. Docker is used for launching external
1818
commands that do, for example, data manipulation.
1919

20-
install gulp cli:
21-
`yarn global add gulp-cli`
22-
23-
install app deps:
24-
`yarn`
20+
install application and development dependecies:
21+
`yarn install`
2522

2623
update osm data:
27-
`ROUTER_NAME=hsl gulp osm:update`
24+
`ROUTER_NAME=hsl yarn gulp osm:update`
2825

2926
download new gtfs data for waltti:
30-
`ROUTER_NAME=waltti gulp gtfs:dl`
27+
`ROUTER_NAME=waltti yarn gulp gtfs:dl`
3128

3229
#### Configuration
3330

finland/config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,13 @@ module.exports = {
127127
false,
128128
),
129129
],
130+
netex: [
131+
{
132+
id: 'VR_bussit',
133+
url: 'https://mobility.mobility-database.fintraffic.fi/static/vr_bussit.zip',
134+
groupFilePattern: '(line)_.*\\.xml',
135+
sharedFilePattern: '_.*\\.xml',
136+
},
137+
],
130138
osm: ['finland', 'estonia'],
131139
};

gulpfile.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const prepareFit = require('./task/PrepareFit');
88
const mapFit = require('./task/MapFit');
99
const { validateBlobSize } = require('./task/BlobValidation');
1010
const { testOTPFile } = require('./task/OTPTest');
11+
const { testNetexFile } = require('./task/NetexTest');
1112
const { runOSMPreprocessing } = require('./task/OSMPreprocessing');
1213
const seed = require('./task/Seed');
1314
const {
@@ -22,6 +23,7 @@ const {
2223
buildOTPStreetOnlyGraphTask,
2324
} = require('./task/BuildOTPGraph');
2425
const { renameGTFSFile } = require('./task/GTFSRename');
26+
const { renameNetexFile } = require('./task/NetexRename');
2527
const { replaceGTFSFilesTask } = require('./task/GTFSReplace');
2628
const { extractFilesTask, addFilesTask } = require('./task/ZipTask');
2729
const { createDir } = require('./util');
@@ -32,10 +34,12 @@ const seedSourceDir = `${config.dataDir}/router-${config.router.id}`; // e.g. da
3234
const osmDlDir = `${config.dataDir}/downloads/osm`;
3335
const demDlDir = `${config.dataDir}/downloads/dem`;
3436
const gtfsDlDir = `${config.dataDir}/downloads/gtfs`;
37+
const netexDlDir = `${config.dataDir}/downloads/netex`;
3538

3639
const osmDir = `${config.dataDir}/ready/osm`;
3740
const demDir = `${config.dataDir}/ready/dem`;
3841
const gtfsDir = `${config.dataDir}/ready/gtfs`;
42+
const netexDir = `${config.dataDir}/ready/netex`;
3943

4044
const gtfsSeedDir = `${config.dataDir}/seed`;
4145
const fitDir = `${config.dataDir}/fit`;
@@ -49,6 +53,34 @@ const renamedDir = `${config.dataDir}/renamed`;
4953

5054
const noBuf = { buffer: false }; // options for gulp src
5155

56+
/**
57+
* Download netex data
58+
*/
59+
gulp.task('netex:download', async cb => {
60+
if (!config.router.netex) {
61+
return Promise.resolve();
62+
}
63+
createDir(netexDlDir);
64+
createDir(netexDir);
65+
await dl(config.router.netex, netexDlDir);
66+
cb();
67+
});
68+
69+
gulp.task('netex:rename', () =>
70+
gulp
71+
.src(`${netexDlDir}/*`, noBuf)
72+
.pipe(renameNetexFile())
73+
.pipe(gulp.dest(netexDir)),
74+
);
75+
76+
gulp.task(
77+
'netex:update',
78+
gulp.series(
79+
'netex:download',
80+
'netex:rename',
81+
),
82+
);
83+
5284
/**
5385
* Download osm data
5486
*/
@@ -231,6 +263,17 @@ gulp.task(
231263
),
232264
);
233265

266+
gulp.task('netex:del', () => del(netexDir));
267+
268+
gulp.task(
269+
'netex:seed',
270+
gulp.series('netex:del', () =>
271+
gulp
272+
.src(`${seedSourceDir}/*-netex.zip`, noBuf)
273+
.pipe(gulp.dest(netexDir)),
274+
),
275+
);
276+
234277
gulp.task('osm:del', () => del(osmDir));
235278

236279
gulp.task(
@@ -271,6 +314,7 @@ gulp.task(
271314
'dem:seed',
272315
'osm:seed',
273316
'gtfs:seed',
317+
'netex:seed',
274318
'seed:cleanup',
275319
),
276320
);

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@eslint/js": "^9.18.0",
3838
"eslint": "^9.18.0",
3939
"globals": "^15.14.0",
40+
"gulp-cli": "^3.1.0",
4041
"prettier": "^3.4.2"
4142
}
4243
}

task/NetexRename.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const through = require('through2');
2+
3+
module.exports = {
4+
renameNetexFile: () => {
5+
return through.obj(function (file, encoding, callback) {
6+
if (!file.stem.includes('-netex')) {
7+
file.stem = file.stem + '-netex';
8+
}
9+
if (file.extname !== '.zip') {
10+
file.extname = '.zip';
11+
}
12+
callback(null, file);
13+
});
14+
},
15+
};

task/NetexTest.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const through = require('through2');
2+
3+
module.exports = {
4+
testNetexFile: () => {
5+
return through.obj(function (file, encoding, callback) {
6+
const otpFile = file.history[file.history.length - 1];
7+
if (process.env.SKIP_OTP_TESTS) {
8+
process.stdout.write(
9+
'OTP test skipped because the SKIP_OTP_TESTS environment variable is set\n',
10+
);
11+
return callback(null, file);
12+
}
13+
// TODO add test
14+
return callback(null, file);
15+
});
16+
},
17+
};

task/PrepareRouterData.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,31 @@ const extraUpdaters =
2222
? JSON.parse(process.env.EXTRA_UPDATERS)
2323
: {};
2424

25+
function createAndProcessBuildConfig(router) {
26+
process.stdout.write('copying build-config.json...\n');
27+
const configName = `${router.id}/build-config.json`;
28+
const buildConfig = JSON.parse(fs.readFileSync(configName, 'utf8'));
29+
const transitFeeds = buildConfig.transitFeeds || [];
30+
if (router.netex) {
31+
router.netex.forEach(src => {
32+
const feed = {
33+
type: 'netex',
34+
feedId: src.id,
35+
source: 'file:///var/opentripplanner/' + src.id + '-netex.zip',
36+
groupFilePattern: src.groupFilePattern,
37+
sharedFilePattern: src.sharedFilePattern,
38+
};
39+
transitFeeds.push(feed);
40+
});
41+
buildConfig.transitFeeds = transitFeeds;
42+
}
43+
const file = new Vinyl({
44+
path: 'build-config.json',
45+
contents: Buffer.from(JSON.stringify(buildConfig, null, 2)),
46+
});
47+
return file;
48+
}
49+
2550
// Prepares router-config.json data for opentripplanner and applies edits/additions made in EXTRA_UPDATERS env var
2651
function createAndProcessRouterConfig(router) {
2752
process.stdout.write('copying router-config.json...\n');
@@ -68,8 +93,8 @@ function prepareRouterData(router) {
6893
'Collecting data and configuration files for graph build\n',
6994
);
7095

71-
stream.push(createFile(router, 'build-config.json', router.id));
7296
stream.push(createFile(router, 'otp-config.json', router.id));
97+
stream.push(createAndProcessBuildConfig(router));
7398
stream.push(createAndProcessRouterConfig(router));
7499
router.osm.forEach(osmId => {
75100
const name = osmId + '.pbf';
@@ -83,6 +108,12 @@ function prepareRouterData(router) {
83108
const name = src.id + '-gtfs.zip';
84109
stream.push(createFile(router, name, `${dataDir}/ready/gtfs`));
85110
});
111+
if (router.netex) {
112+
router.netex.forEach(src => {
113+
const name = src.id + '-netex.zip';
114+
stream.push(createFile(router, name, `${dataDir}/ready/netex`));
115+
});
116+
}
86117
stream.end();
87118

88119
return stream;
@@ -99,8 +130,8 @@ function prepareRouterDataForStreetOnlyGraphBuild(router) {
99130
'Collecting data and configuration files for street only graph build\n',
100131
);
101132

102-
stream.push(createFile(router, 'build-config.json', router.id));
103133
stream.push(createFile(router, 'otp-config.json', router.id));
134+
stream.push(createAndProcessBuildConfig(router));
104135
stream.push(createAndProcessRouterConfig(router));
105136
router.osm.forEach(osmId => {
106137
const name = osmId + '.pbf';
@@ -145,6 +176,12 @@ function prepareRouterDataForPrebuiltStreetGraphBuild(router) {
145176
const name = src.id + '-gtfs.zip';
146177
stream.push(createFile(router, name, `${dataDir}/ready/gtfs`));
147178
});
179+
if (router.netex) {
180+
router.netex.forEach(src => {
181+
const name = src.id + '-netex.zip';
182+
stream.push(createFile(router, name, `${dataDir}/ready/netex`));
183+
});
184+
}
148185

149186
const osmDirectories = getDirectories(
150187
`${storageDir}/osm-builds/${process.env.DOCKER_TAG}`,

task/Update.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ async function buildGraph(name) {
183183
await handleOsmAndDemUpdate();
184184

185185
await start('gtfs:update');
186+
await start('netex:update');
186187

187188
process.stdout.write('Build routing graph\n');
188189
await start('router:buildGraph');
@@ -223,6 +224,7 @@ async function buildWithPrebuiltStreetGraph(name) {
223224
await handleSeeding();
224225

225226
await start('gtfs:update');
227+
await start('netex:update');
226228

227229
process.stdout.write('Build routing graph from prebuilt street only graph\n');
228230
await start('router:buildWithPrebuiltStreetGraph');

0 commit comments

Comments
 (0)