Skip to content

Commit

Permalink
Merge pull request #56 from openplannerteam/dev
Browse files Browse the repository at this point in the history
Release 0.0.2-alpha
  • Loading branch information
SimonVanneste authored Dec 21, 2018
2 parents 783a200 + 1037f11 commit abd917d
Show file tree
Hide file tree
Showing 41 changed files with 1,143 additions and 488 deletions.
14 changes: 14 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ <h1>Planner.js</h1>
</p>
<section>
<h2 id="demo">Demo</h2>
<h3>Table</h3>
<p
data-height="398"
data-theme-id="light"
Expand All @@ -39,6 +40,19 @@ <h2 id="demo">Demo</h2>
See the Pen <a href="https://codepen.io/maximtmartin/pen/bQZMoj">Using the new JavaScript route
planner</a> on <a href="https://codepen.io">CodePen</a>.
</p>
<h3>Map</h3>
<p
data-height="700"
data-theme-id="light"
data-slug-hash="yGMzLM"
data-default-tab="result"
data-user="maximtmartin"
data-pen-title="Using the new JavaScript route planner (work in progress)"
class="codepen"
>
See the Pen <a href="https://codepen.io/maximtmartin/pen/yGMzLM">Using the new JavaScript route
planner</a> on <a href="https://codepen.io">CodePen</a>.
</p>
</section>
<!--<section>
<h2 id="philosophy">Principles</h2>
Expand Down
16 changes: 14 additions & 2 deletions src/Catalog.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import TravelMode from "./TravelMode";

export default class Catalog {

public static combine(...catalogs: Catalog[]): Catalog {
const combinedCatalog = new Catalog();

for (const sourceCatalog of catalogs) {
combinedCatalog.stopsFetcherConfigs.push(...sourceCatalog.stopsFetcherConfigs);
combinedCatalog.connectionsFetcherConfigs.push(...sourceCatalog.connectionsFetcherConfigs);
}

return combinedCatalog;
}

public stopsFetcherConfigs = [];
public connectionsFetcherConfigs = [];

public addStopsFetcher(prefix: string, accessUrl: string) {
this.stopsFetcherConfigs.push({prefix, accessUrl});
public addStopsFetcher(accessUrl: string) {
this.stopsFetcherConfigs.push({accessUrl});
}

public addConnectionsFetcher(accessUrl: string, travelMode: TravelMode) {
Expand Down
63 changes: 62 additions & 1 deletion src/Context.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,75 @@
// @ts-ignore
import { EventEmitter, Listener } from "events";
import { Container, injectable } from "inversify";

/**
* The Context serves as event pass through and holder of the inversify container object.
* Proxies an internal EventEmitter because ´decorate(injectable(), EventEmitter)´ causes
* errors when running tests in Jest
*/
@injectable()
export default class Context {
// @ts-ignore
export default class Context implements EventEmitter {
private emitter: EventEmitter;
private container: Container;

constructor() {
this.emitter = new EventEmitter();
}

public setContainer(container: Container) {
this.container = container;
}

public getContainer() {
return this.container;
}

public addListener(type: string | symbol, listener: Listener): this {
this.emitter.addListener(type, listener);

return this;
}

public emit(type: string | symbol, ...args: any[]): boolean {
return this.emitter.emit(type, ...args);
}

public listenerCount(type: string | symbol): number {
return this.emitter.listenerCount(type);
}

public listeners(type: string | symbol): Listener[] {
return this.emitter.listeners(type);
}

public on(type: string | symbol, listener: Listener): this {
this.emitter.on(type, listener);

return this;
}

public once(type: string | symbol, listener: Listener): this {
this.emitter.once(type, listener);

return this;
}

public removeAllListeners(type?: string | symbol): this {
this.emitter.removeAllListeners(type);

return this;
}

public removeListener(type: string | symbol, listener: Listener): this {
this.emitter.removeListener(type, listener);

return this;
}

public setMaxListeners(n: number): this {
this.emitter.setMaxListeners(n);

return this;
}
}
4 changes: 3 additions & 1 deletion src/Defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import Units from "./util/Units";
export default class Defaults {
public static readonly defaultMinimumWalkingSpeed = 3;
public static readonly defaultMaximumWalkingSpeed = 6;
public static readonly defaultWalkingDuration = Units.fromSeconds(10 * 60);
public static readonly defaultMinimumTransferDuration = Units.fromSeconds(60);
public static readonly defaultMaximumTransferDuration = Units.fromHours(.4);
public static readonly defaultMaximumTransfers = 8;
public static readonly defaultMaximumTransfers = 4;
}
12 changes: 12 additions & 0 deletions src/EventType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
enum EventType {
Query = "query",
QueryExponential = "query-exponential",
QueryAbort = "query-abort",
LDFetchGet = "ldfetch-get",
ConnectionScan = "connection-scan",
FinalReachableStops = "final-reachable-stops",
InitialReachableStops = "initial-reachable-stops",
AddedNewTransferProfile = "added-new-transfer-profile",
}

export default EventType;
76 changes: 74 additions & 2 deletions src/Planner.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { AsyncIterator } from "asynciterator";
// @ts-ignore
import { EventEmitter, Listener } from "events";
import Context from "./Context";
import EventType from "./EventType";
import IStop from "./fetcher/stops/IStop";
import IStopsProvider from "./fetcher/stops/IStopsProvider";
import IPath from "./interfaces/IPath";
import IQuery from "./interfaces/IQuery";
import defaultContainer from "./inversify.config";
Expand All @@ -13,7 +18,8 @@ if (!Symbol.asyncIterator) {
/**
* Allows to ask route planning queries over our knowledge graphs
*/
export default class Planner {
// @ts-ignore
export default class Planner implements EventEmitter {
private context: Context;
private queryRunner: IQueryRunner;

Expand All @@ -35,6 +41,72 @@ export default class Planner {
* @returns An AsyncIterator of [[IPath]]s
*/
public async query(query: IQuery): Promise<AsyncIterator<IPath>> {
return this.queryRunner.run(query);
this.emit(EventType.Query, query);

const iterator = await this.queryRunner.run(query);

this.once(EventType.QueryAbort, () => {
iterator.close();
});

return iterator;
}

public addListener(type: string | symbol, listener: Listener): this {
this.context.addListener(type, listener);

return this;
}

public emit(type: string | symbol, ...args: any[]): boolean {
return this.context.emit(type, ...args);
}

public listenerCount(type: string | symbol): number {
return this.context.listenerCount(type);
}

public listeners(type: string | symbol): Listener[] {
return this.context.listeners(type);
}

public on(type: string | symbol, listener: Listener): this {
this.context.on(type, listener);

return this;
}

public once(type: string | symbol, listener: Listener): this {
this.context.once(type, listener);

return this;
}

public removeAllListeners(type?: string | symbol): this {
this.context.removeAllListeners(type);

return this;
}

public removeListener(type: string | symbol, listener: Listener): this {
this.context.removeListener(type, listener);

return this;
}

public setMaxListeners(n: number): this {
this.context.setMaxListeners(n);

return this;
}

public getAllStops(): Promise<IStop[]> {
const provider = this.context.getContainer().get<IStopsProvider>(TYPES.StopsProvider);

if (provider) {
return provider.getAllStops();
}

return Promise.reject();
}
}
18 changes: 18 additions & 0 deletions src/catalog.delijn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Catalog from "./Catalog";
import TravelMode from "./TravelMode";

const catalog = new Catalog();

catalog.addStopsFetcher("http://openplanner.ilabt.imec.be/delijn/Antwerpen/stops");
catalog.addStopsFetcher("http://openplanner.ilabt.imec.be/delijn/Limburg/stops");
catalog.addStopsFetcher("http://openplanner.ilabt.imec.be/delijn/Oost-Vlaanderen/stops");
catalog.addStopsFetcher("http://openplanner.ilabt.imec.be/delijn/Vlaams-Brabant/stops");
catalog.addStopsFetcher("http://openplanner.ilabt.imec.be/delijn/West-Vlaanderen/stops");

catalog.addConnectionsFetcher("http://openplanner.ilabt.imec.be/delijn/Antwerpen/connections", TravelMode.Bus);
catalog.addConnectionsFetcher("http://openplanner.ilabt.imec.be/delijn/Limburg/connections", TravelMode.Bus);
catalog.addConnectionsFetcher("http://openplanner.ilabt.imec.be/delijn/Oost-Vlaanderen/connections", TravelMode.Bus);
catalog.addConnectionsFetcher("http://openplanner.ilabt.imec.be/delijn/Vlaams-Brabant/connections", TravelMode.Bus);
catalog.addConnectionsFetcher("http://openplanner.ilabt.imec.be/delijn/West-Vlaanderen/connections", TravelMode.Bus);

export default catalog;
8 changes: 8 additions & 0 deletions src/catalog.nmbs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Catalog from "./Catalog";
import TravelMode from "./TravelMode";

const catalog = new Catalog();
catalog.addStopsFetcher("https://irail.be/stations/NMBS");
catalog.addConnectionsFetcher("https://graph.irail.be/sncb/connections", TravelMode.Train);

export default catalog;
72 changes: 48 additions & 24 deletions src/demo.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,69 @@
import EventType from "./EventType";
import Planner from "./index";
import IPath from "./interfaces/IPath";
import Units from "./util/Units";

export default async (logResults) => {

const planner = new Planner();

// const roadOnlyResult = await planner.query({
// roadOnly: true,
// from: "http://irail.be/stations/NMBS/008896008", // Kortrijk
// to: "http://irail.be/stations/NMBS/008892007", // Ghent-Sint-Pieters
// });
//
// roadOnlyResult.each((path) => {
// if (logResults) {
// console.log(path);
// }
// });
if (logResults) {
let scannedPages = 0;
let scannedConnections = 0;

console.time("Public transport planner");
planner
.on(EventType.Query, (query) => {
console.log("Query", query);
})
.on(EventType.QueryExponential, (query) => {
const { minimumDepartureTime, maximumArrivalTime } = query;

console.log("Total scanned pages", scannedPages);
console.log("Total scanned connections", scannedConnections);
console.log("[Subquery]", minimumDepartureTime, maximumArrivalTime, maximumArrivalTime - minimumDepartureTime);
})
.on(EventType.LDFetchGet, (url, duration) => {
scannedPages++;
console.log(`[GET] ${url} (${duration}ms)`);
})
.on(EventType.ConnectionScan, (connection) => {
scannedConnections++;
});
}

const publicTransportResult = await planner.query({
publicTransportOnly: true,
// from: "https://data.delijn.be/stops/201657",
// to: "https://data.delijn.be/stops/205910",
// from: "https://data.delijn.be/stops/200455", // Deinze weg op Grammene +456
// to: "https://data.delijn.be/stops/502481", // Tielt Metaalconstructie Goossens
// from: "https://data.delijn.be/stops/509927", // Tield Rameplein perron 1
// to: "https://data.delijn.be/stops/200455", // Deinze weg op Grammene +456
from: "http://irail.be/stations/NMBS/008896925", // Ingelmunster
to: "http://irail.be/stations/NMBS/008892007", // Ghent-Sint-Pieters
minimumDepartureTime: new Date(),
maximumTransferDuration: Units.fromHours(.5),
maximumTransferDuration: Units.fromHours(0.5),
});

console.timeEnd("Public transport planner");

let i = 0;
return new Promise((resolve, reject) => {
let i = 0;

publicTransportResult.on("readable", () => {
let path = publicTransportResult.read();
publicTransportResult.take(3)
.on("data", (path: IPath) => {
++i;

while (path && i < 5) {
console.log(i++, path);
if (logResults) {
console.log(i);
console.log(JSON.stringify(path, null, " "));
console.log("\n");
}

path = publicTransportResult.read();
}
if (i === 3) {
resolve(true);
}
})
.on("end", () => {
resolve(false);
});
});

return true;
};
Loading

0 comments on commit abd917d

Please sign in to comment.