From 13b945f4c97d1d83aa529d94cdd8d2b5dd0ae40a Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sat, 13 Oct 2018 11:37:55 +0200 Subject: [PATCH 01/11] Fix #57 --- lib/Connections2JSONLD.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Connections2JSONLD.js b/lib/Connections2JSONLD.js index 677c617..94e37a1 100644 --- a/lib/Connections2JSONLD.js +++ b/lib/Connections2JSONLD.js @@ -22,7 +22,8 @@ var Connections2JSONLD = function (baseUris, context) { "@id": "http://semweb.mmlab.be/ns/linkedconnections#arrivalStop" }, "departureTime": "http://semweb.mmlab.be/ns/linkedconnections#departureTime", - "arrivalTime": "http://semweb.mmlab.be/ns/linkedconnections#arrivalTime" + "arrivalTime": "http://semweb.mmlab.be/ns/linkedconnections#arrivalTime", + "direction": "gtfs:headsign" } }; @@ -47,7 +48,9 @@ Connections2JSONLD.prototype._transform = function (connection, encoding, done) "gtfs:route": this._uris.getRouteId(connection) }; - if(connection.trip.trip_headsign) { + if (connection.departure_stop_headsign) { + lc["direction"] = connection.trip.trip_headsign; + } else if (connection.trip.trip_headsign) { lc["direction"] = connection.trip.trip_headsign; } From 727e8ada667d91f56aab5ece69a97a5d5a84383e Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sat, 13 Oct 2018 11:38:40 +0200 Subject: [PATCH 02/11] Fixes #58 --- lib/Connections2JSONLD.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Connections2JSONLD.js b/lib/Connections2JSONLD.js index 94e37a1..d50ba50 100644 --- a/lib/Connections2JSONLD.js +++ b/lib/Connections2JSONLD.js @@ -63,7 +63,7 @@ Connections2JSONLD.prototype._transform = function (connection, encoding, done) var dropOffType = types[0]; if (connection['drop_off_type'] && connection['drop_off_type'] !== null) { dropOffType = types[connection['drop_off_type']]; - lc["gtfs:dropOffType"] = pickupType; + lc["gtfs:dropOffType"] = dropOffType; } done(null, lc); From 72ad3e2b628c947b2b831a1114894d47bca730b6 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sat, 13 Oct 2018 12:00:35 +0200 Subject: [PATCH 03/11] Fix #34 --- lib/stoptimes/st2c.js | 42 ++++++++++++++-------------------------- test/testResultStream.js | 6 ++++-- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/lib/stoptimes/st2c.js b/lib/stoptimes/st2c.js index 422b9ae..c3b2b66 100644 --- a/lib/stoptimes/st2c.js +++ b/lib/stoptimes/st2c.js @@ -16,35 +16,21 @@ util.inherits(StopTimesToConnections, Transform); * When ordered, we can just take 2 gtfs:StopTimes and bring them together in 1 "connection rule", which is an intermediate data structure we define here */ StopTimesToConnections.prototype._transform = function (stopTime, encoding, done) { - // If both pick_up_type of previousStopTime and drop_off_type of current stoptime are 1, then discard this stoptime and look further, but now for the stoptime that continues from this "via" - if (stopTime['drop_off_type'] !== null && stopTime['drop_off_type'] == 1 && stopTime['pickup_type'] !== null && stopTime['pickup_type'] == 1) { - if (this._previousStopTime && !this._previousStopTime['vias']) { - this._previousStopTime['vias'] = [stopTime['stop_id']]; - } else if (this._previousStopTime) { - this._previousStopTime['vias'].push(stopTime['stop_id']); - } - } else { - if (!this._previousStopTime) { - this._previousStopTime = stopTime; - } else { - if (this._previousStopTime['trip_id'] === stopTime['trip_id']) { - //dfm is "duration from midnight" (see GTFS reference) - this.push({ - trip_id: this._previousStopTime['trip_id'], - arrival_dfm: stopTime['arrival_time'], - departure_dfm: this._previousStopTime['departure_time'], - departure_stop: this._previousStopTime['stop_id'], - arrival_stop : stopTime['stop_id'], - departure_stop_headsign: this._previousStopTime['stop_headsign'], - arrival_stop_headsign: stopTime['stop_headsign'], - pickup_type: this._previousStopTime['pickup_type'], - drop_off_type: stopTime['drop_off_type'], - vias: this._previousStopTime['vias'] - }); - } - } - this._previousStopTime = stopTime; + if (this._previousStopTime && this._previousStopTime['trip_id'] === stopTime['trip_id']) { + //dfm is "duration from midnight" (see GTFS reference) + this.push({ + trip_id: this._previousStopTime['trip_id'], + arrival_dfm: stopTime['arrival_time'], + departure_dfm: this._previousStopTime['departure_time'], + departure_stop: this._previousStopTime['stop_id'], + arrival_stop : stopTime['stop_id'], + departure_stop_headsign: this._previousStopTime['stop_headsign'], + arrival_stop_headsign: stopTime['stop_headsign'], + pickup_type: this._previousStopTime['pickup_type'], + drop_off_type: stopTime['drop_off_type'], + }); } + this._previousStopTime = stopTime; done(); }; diff --git a/test/testResultStream.js b/test/testResultStream.js index 141fe47..ec0dc83 100644 --- a/test/testResultStream.js +++ b/test/testResultStream.js @@ -31,8 +31,10 @@ describe('Testing whether result contains certain objects (regression tests)', f it('Stream should contain certain things', async () => { var connections = await lcstreamToArray(); - assert.equal(connections[0]['arrivalStop'],'NANAA'); - assert.equal(connections[0]['headsign'],'City'); + assert.equal(connections[0]['arrivalStop'],'BEATTY_AIRPORT'); + assert.equal(connections[0]['drop_off_type'], 1); + assert.equal(connections[0]['pickup_type'], 1); + assert.equal(connections[0]['headsign'],'Shuttle'); }); it('JSON-LD Stream should contain Connections', async () => { From 1d35b3dde54f426699ee410ecaab2cf5483113d3 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sat, 13 Oct 2018 12:02:15 +0200 Subject: [PATCH 04/11] Fix #57 bis --- lib/Connections2JSONLD.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Connections2JSONLD.js b/lib/Connections2JSONLD.js index d50ba50..097bee0 100644 --- a/lib/Connections2JSONLD.js +++ b/lib/Connections2JSONLD.js @@ -48,8 +48,8 @@ Connections2JSONLD.prototype._transform = function (connection, encoding, done) "gtfs:route": this._uris.getRouteId(connection) }; - if (connection.departure_stop_headsign) { - lc["direction"] = connection.trip.trip_headsign; + if (connection.headsign) { + lc["direction"] = connection.headsign; } else if (connection.trip.trip_headsign) { lc["direction"] = connection.trip.trip_headsign; } From a1c52a5f70367fcf536cf1db4eb23e5297a85150 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 16 Oct 2018 09:45:58 +0200 Subject: [PATCH 05/11] Fixed Stream Iterator with asynciterator --- lib/StreamIterator.js | 30 +++++++++++++++--------------- package-lock.json | 13 +++++++++++++ package.json | 1 + 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/StreamIterator.js b/lib/StreamIterator.js index e6ad82e..0252fdf 100644 --- a/lib/StreamIterator.js +++ b/lib/StreamIterator.js @@ -1,18 +1,17 @@ -var util = require('util'), - moment = require('moment'), - EventEmitter = require('events').EventEmitter; +const util = require('util'), + moment = require('moment'), + {AsyncIterator} = require('asynciterator'), + EventEmitter = require('events').EventEmitter; var StreamIterator = function (stream, interval) { this._interval = interval; - this._stream = stream; - this._currentObject = null; - this._currentCB = null; - var self = this; + this._iterator = AsyncIterator.wrap(stream); this._streamEnded = false; - this._stream.on("end", function () { - self._streamEnded = true; - if (self._currentCB) { - self._currentCB(); + this._currentCB; + this._iterator.on("end", () => { + this._streamEnded = true; + if (this._currentCB) { + this._currentCB(); } }); }; @@ -24,13 +23,13 @@ StreamIterator.prototype.getCurrentObject = function () { }; StreamIterator.prototype.next = function (callback) { - var self = this; this._currentCB = callback; - var object = this._stream.read(); + var object = this._iterator.read(); if (!object && !this._streamEnded) { - this._stream.once("readable", function () { - self.next(callback); + this._iterator.once("readable", () => { + this.next(callback); }); + //Filter our object on the date property and check whether it’s in our interval. } else if (object && this._interval.inclusiveBetween(moment(object['date'], 'YYYYMMDD'))) { this._currentObject = object; callback(object); @@ -45,3 +44,4 @@ StreamIterator.prototype.next = function (callback) { }; module.exports = StreamIterator; + diff --git a/package-lock.json b/package-lock.json index 8314b62..0a5df11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,6 +83,14 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, + "asynciterator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-2.0.0.tgz", + "integrity": "sha512-sAD0fwT3h5hC8O/tclYGLWy3xPs8G8P20ROAOzDKG7SBkdySRAo/NMftlE37cVRe+RAfzGT5dYG+malp2KfefA==", + "requires": { + "immediate": "^3.2.3" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -549,6 +557,11 @@ "sshpk": "^1.7.0" } }, + "immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", diff --git a/package.json b/package.json index 156e978..4095675 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "url": "https://github.com/LinkedConnections/gtfs2lc/issues" }, "dependencies": { + "asynciterator": "^2.0.0", "commander": "^2.19.0", "fast-csv": "^0.6.0", "jsonld-stream": "^1.0.4", From 8035849cb5ff94dd40967c3f762bc17018d2c8ca Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 16 Oct 2018 09:48:11 +0200 Subject: [PATCH 06/11] Clean-up test, fix headsign logic --- lib/Connections2JSONLD.js | 3 +-- test/testResultStream.js | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/Connections2JSONLD.js b/lib/Connections2JSONLD.js index 097bee0..82b7649 100644 --- a/lib/Connections2JSONLD.js +++ b/lib/Connections2JSONLD.js @@ -48,10 +48,9 @@ Connections2JSONLD.prototype._transform = function (connection, encoding, done) "gtfs:route": this._uris.getRouteId(connection) }; + //the headsign is already the result here of earlier checking whether there’s a trip headsign or a route headsign if connection headsign was not set. It can be used reliably if (connection.headsign) { lc["direction"] = connection.headsign; - } else if (connection.trip.trip_headsign) { - lc["direction"] = connection.trip.trip_headsign; } var pickupType = types[0]; diff --git a/test/testResultStream.js b/test/testResultStream.js index ec0dc83..98839f3 100644 --- a/test/testResultStream.js +++ b/test/testResultStream.js @@ -41,7 +41,6 @@ describe('Testing whether result contains certain objects (regression tests)', f var triples = await lcstreamToArray({ format : 'jsonld' }); - console.log(triples[0]); assert.equal(triples[0]['@type'],'Connection'); }); From 7cd37912f42c243d8e63ba8dfb6b229e4670de8e Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 16 Oct 2018 14:58:07 +0200 Subject: [PATCH 07/11] Through2 to async iterator, instantiate connectionRules stream in finished --- lib/gtfs2connections.js | 152 ++++++++++++++++++++++------------------ package-lock.json | 9 --- package.json | 1 - 3 files changed, 82 insertions(+), 80 deletions(-) diff --git a/lib/gtfs2connections.js b/lib/gtfs2connections.js index e848a0d..6de2048 100644 --- a/lib/gtfs2connections.js +++ b/lib/gtfs2connections.js @@ -1,19 +1,19 @@ -var csv = require('fast-csv'), -ConnectionRules = require('./stoptimes/st2c.js'), -ConnectionsBuilder = require('./ConnectionsBuilder.js'), -Services = require('./services/calendar.js'), -DateInterval = require('./DateInterval.js'), -Store = require('./stores/Store.js'), -through2 = require('through2'), -moment = require('moment'), -fs = require('fs'); +const csv = require('fast-csv'), + ConnectionRules = require('./stoptimes/st2c.js'), + ConnectionsBuilder = require('./ConnectionsBuilder.js'), + Services = require('./services/calendar.js'), + DateInterval = require('./DateInterval.js'), + Store = require('./stores/Store.js'), + {AsyncIterator} = require('asynciterator'), + moment = require('moment'), + fs = require('fs'); var Mapper = function (options) { -this._options = options; -this._options.interval = new DateInterval(options.startDate, options.endDate); -if (!this._options.store) { - this._options.store = 'MemStore'; -} + this._options = options; + this._options.interval = new DateInterval(options.startDate, options.endDate); + if (!this._options.store) { + this._options.store = 'MemStore'; + } }; /** @@ -26,66 +26,78 @@ if (!this._options.store) { * Caveat: coding this with numerous callbacks and streams, makes this code not chronologically ordered. */ Mapper.prototype.resultStream = function (path, done) { -var routes = fs.createReadStream(path + '/routes.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).on('error', function (e) { - console.error(e); -}); - -var trips = fs.createReadStream(path + '/trips.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).on('error', function (e) { - console.error(e); -}); -var calendarDates = fs.createReadStream(path + '/calendar_dates.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).on('error', function (e) { - console.error(e); -}); -var services = fs.createReadStream(path + '/calendar.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).pipe(new Services(calendarDates, this._options)).on('error', function (e) { - console.error(e); -}); -//Preparations for step 4 -var connectionRules = fs.createReadStream(path + '/stop_times.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).pipe(new ConnectionRules()).on('error', function (e) { - console.error(e); -}); - -//Step 2 & 3: store in leveldb in 3 hidden directories, or in memory, depending on the options -var routesdb = Store(path + '/.routes', this._options.store); -var tripsdb = Store(path + '/.trips', this._options.store); -var servicesdb = Store(path + '/.services', this._options.store); -var count = 0; -var self = this; - -var finished = function () { - count++; - //wait for the 3 streams to finish (services and trips) to write to the stores - if (count === 3) { - console.error("Indexing services and trips succesful!"); - //Step 4 and 5: let's create our connections! - done(connectionRules.pipe(new ConnectionsBuilder(tripsdb, servicesdb, routesdb, self._options))); - } -}; + var routes = fs.createReadStream(path + '/routes.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).on('error', function (e) { + console.error(e); + }); -services.pipe(through2.obj(function (service, encoding, doneService) { - if (service['service_id']) { - servicesdb.put(service['service_id'], service['dates'], doneService); - } -})).on('error', function (e) { - console.error(e); -}).on('finish', finished); + var trips = fs.createReadStream(path + '/trips.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).on('error', function (e) { + console.error(e); + }); + var calendarDates = fs.createReadStream(path + '/calendar_dates.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).on('error', function (e) { + console.error(e); + }); + var services = fs.createReadStream(path + '/calendar.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).pipe(new Services(calendarDates, this._options)).on('error', function (e) { + console.error(e); + }); + //Preparations for step 4 + //Step 2 & 3: store in leveldb in 3 hidden directories, or in memory, depending on the options + var routesdb = Store(path + '/.routes', this._options.store); + var tripsdb = Store(path + '/.trips', this._options.store); + var servicesdb = Store(path + '/.services', this._options.store); + var count = 0; + var options = this._options; + var finished = function () { + count++; + //wait for the 3 streams to finish (services, trips and routes) to write to the stores + if (count === 3) { + console.error("Indexing services and trips succesful!"); + //Step 4 and 5: let's create our connections! + var connectionRules = fs.createReadStream(path + '/stop_times.txt', { encoding: 'utf8', objectMode: true }).pipe(csv({ objectMode: true, headers: true })).pipe(new ConnectionRules()).on('error', function (e) { + console.error('Hint: Did you run gtfs2lc-sort?'); + console.error(e); + }); + let connectionsBuilder = new ConnectionsBuilder(tripsdb, servicesdb, routesdb, options); + let connectionsStream = connectionRules.pipe(connectionsBuilder); + done(connectionsStream); + } + }; -trips.pipe(through2.obj(function (trip, encoding, doneTrip) { - if (trip['trip_id']) { - tripsdb.put(trip['trip_id'], trip, doneTrip); - } -})).on('error', function (e) { - console.error(e); -}).on('finish', finished); + var servicesIterator = AsyncIterator.wrap(services); + var tripsIterator = AsyncIterator.wrap(trips); + var routesIterator = AsyncIterator.wrap(routes); + + servicesIterator.transform((service, doneService) =>{ + if (service['service_id']) { + servicesdb.put(service['service_id'], service['dates'], doneService); + } else { + doneService(); + } + }).on('data', () => { + }).on('error', function (e) { + console.error(e); + }).on('end', finished); + tripsIterator.transform((trip, doneTrip) => { + if (trip['trip_id']) { + tripsdb.put(trip['trip_id'], trip, doneTrip); + } else { + doneTrip(); + } + }).on('data', () => { + }).on('error', function (e) { + console.error(e); + }).on('end', finished); -routes.pipe(through2.obj(function (route, encoding, doneRoute) { - if (route['route_id']) { - routesdb.put(route['route_id'], route, doneRoute); - } -})).on('error', function (e) { - console.error(e); -}).on('finish', finished); - + routesIterator.transform((route, doneRoute) => { + if (route['route_id']) { + routesdb.put(route['route_id'], route, doneRoute); + } else { + doneRoute(); + } + }).on('data', () => { + }).on('error', function (e) { + console.error(e); + }).on('end', finished); }; module.exports = Mapper; diff --git a/package-lock.json b/package-lock.json index 0a5df11..f2f8d5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1213,15 +1213,6 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - } - }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", diff --git a/package.json b/package.json index 4095675..03012f6 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "moment": "^2.22.2", "moment-timezone": "^0.5.21", "n3": "^0.4.5", - "through2": "^2.0.0", "uri-templates": "^0.2.0" }, "devDependencies": { From d5a5a3fbf2941b313a1e4e4ec11bbda6abb8a663 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 16 Oct 2018 15:39:16 +0200 Subject: [PATCH 08/11] Better reporting of errors --- lib/ConnectionsBuilder.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/ConnectionsBuilder.js b/lib/ConnectionsBuilder.js index 4a88d01..518e190 100644 --- a/lib/ConnectionsBuilder.js +++ b/lib/ConnectionsBuilder.js @@ -21,12 +21,11 @@ ConnectionsBuilder.prototype._transform = function (connectionRule, encoding, do // * a trip: { route_id: 'AAMV',service_id: 'WE',trip_id: 'AAMV4',trip_headsign: 'to Airport',direction_id: '1', block_id: '', shape_id: '' } var departureDFM = moment.duration(connectionRule['departure_dfm']); var arrivalDFM = moment.duration(connectionRule['arrival_dfm']); - var self = this; - this._tripsdb.get(connectionRule['trip_id'], function (error, trip) { + this._tripsdb.get(connectionRule['trip_id'], (error, trip) => { if (!error) { - self._routesdb.get(trip['route_id'], function (error, route) { + this._routesdb.get(trip['route_id'], (error, route) => { if (!error) { - self._servicesdb.get(trip['service_id'], function (error, service) { + this._servicesdb.get(trip['service_id'], (error, service) => { if (!error) { for (var i in service) { trip["route"] = route; @@ -64,15 +63,21 @@ ConnectionsBuilder.prototype._transform = function (connectionRule, encoding, do connection['pickup_type'] = connectionRule['pickup_type']; } - self.push(connection); + this.push(connection); } + } else { + console.error('Did not find this service id in calendar or calendar dates: ', trip); } done(); }); - + } else { + console.error('Did not find this route id in routes.txt: ', trip, error); + done(); } }); - + } else { + console.error('Did not find this trip id in trips.txt: ', connectionRule); + done(); } }); }; From e9308fbc4967301f5d90c40cfe14499a543402f4 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 16 Oct 2018 15:39:35 +0200 Subject: [PATCH 09/11] Fix #61 --- bin/gtfs2lc-sort.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/gtfs2lc-sort.sh b/bin/gtfs2lc-sort.sh index e9645af..bb3acbe 100755 --- a/bin/gtfs2lc-sort.sh +++ b/bin/gtfs2lc-sort.sh @@ -7,6 +7,8 @@ sed 's/\r//' trips.txt > trips_unix.txt; mv trips_unix.txt trips.txt & sed 's/\r//' calendar.txt > calendar_unix.txt; mv calendar_unix.txt calendar.txt & sed 's/\r//' calendar_dates.txt > calendar_dates_unix.txt; mv calendar_dates_unix.txt calendar_dates.txt ; + sed 's/\r//' routes.txt > routes_unix.txt; mv routes_unix.txt routes.txt ; + } ; echo Removing UTF-8 artifacts in directory $1; { @@ -14,6 +16,7 @@ sed '1s/^\xEF\xBB\xBF//' trips.txt > trips_unix.txt; mv trips_unix.txt trips.txt & sed '1s/^\xEF\xBB\xBF//' calendar.txt > calendar_unix.txt; mv calendar_unix.txt calendar.txt & sed '1s/^\xEF\xBB\xBF//' calendar_dates.txt > calendar_dates_unix.txt; mv calendar_dates_unix.txt calendar_dates.txt ; + sed '1s/^\xEF\xBB\xBF//' routes.txt > routes_unix.txt; mv routes_unix.txt routes.txt ; } ; echo Sorting files in directory $1; { head -n 1 stop_times.txt ; tail -n +2 stop_times.txt | sort -t , -k1,1 -k5,5n ; } > stop_times2.txt ; mv stop_times2.txt stop_times.txt & From fa8434eea4cef53e4b20c496490879209e40ea0b Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 16 Oct 2018 15:50:24 +0200 Subject: [PATCH 10/11] Added better CSV output --- bin/gtfs2lc.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/gtfs2lc.js b/bin/gtfs2lc.js index 661506d..dbb7bc5 100755 --- a/bin/gtfs2lc.js +++ b/bin/gtfs2lc.js @@ -66,10 +66,12 @@ mapper.resultStream(program.path, function (stream) { }); } else if (program.format === 'csv') { //print header - console.log('"id","departureStop","departureTime","arrivalStop","arrivalTime","trip","route"'); + console.error('The CSV output is not using a Linked Data format – jsonld is the preferred format.'); + console.log('"id","departureStop","departureTime","arrivalStop","arrivalTime","trip","route","headsign"'); var count = 0; + stream.on('data', function (connection) { - console.log(count + ',' + connection["departureStop"] + ',' + connection["departureTime"].toISOString() + ',' + connection["arrivalStop"] + ',' + connection["arrivalTime"].toISOString() + ',' + connection["trip"] + ',' + connection["route"]); + console.log(count + ',' + connection["departureStop"] + ',' + connection["departureTime"].toISOString() + ',' + connection["arrivalStop"] + ',' + connection["arrivalTime"].toISOString() + ',' + connection["trip"]["trip_id"] + ',' + connection.trip.route.route_id + ',"' + connection.headsign + '"'); count ++; }); } else if ([,'jsonld','mongold'].indexOf(program.format) > -1) { From 6b44ebf6e1804d01f439d39164245b8bb3908cc1 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 16 Oct 2018 15:52:21 +0200 Subject: [PATCH 11/11] 0.8.2 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03012f6..ebc0813 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gtfs2lc", - "version": "0.8.1", + "version": "0.8.2", "description": "Mapping script from gtfs to (linked) connections", "main": "lib/gtfs2lc.js", "bin": {