Skip to content

Commit

Permalink
#22 #21 add multiple pin types support, change coordinates to [lng, l…
Browse files Browse the repository at this point in the history
…at], fix pin connections
  • Loading branch information
ronhippler committed Jul 29, 2018
1 parent 6a51d25 commit 895cd52
Show file tree
Hide file tree
Showing 11 changed files with 425 additions and 186 deletions.
8 changes: 6 additions & 2 deletions src/coords.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import axios, { AxiosRequestConfig } from "axios";
import * as utils from "./utils";

/** Patch section titled API of README.md file in given directory. */
/**
* Find the coordinates for a given POI id.
* @param id the POI ID
* @returns coordinate as [lng, lat] or undefined
*/
export function coords(id: string): Promise<number[] | undefined> {

const options: AxiosRequestConfig = {
Expand All @@ -20,6 +24,6 @@ export function coords(id: string): Promise<number[] | undefined> {

const coordinates = response.data.split("|");

return utils.gk4toWgs84(coordinates[0], coordinates[1]);
return utils.GK4toWGS84(coordinates[1], coordinates[0]);
});
}
28 changes: 22 additions & 6 deletions src/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig } from "axios";
import { IAddress, IPoint } from "./interfaces";
import * as utils from "./utils";

async function pointFinder(name: string, stopsOnly: boolean, assignedStops: boolean): Promise<IPoint[]> {
function pointFinder(name: string, stopsOnly: boolean, assignedStops: boolean): Promise<IPoint[]> {
if (typeof name !== "string") {
throw utils.constructError("ValidationError", "query has to be a string");
}
Expand Down Expand Up @@ -32,7 +32,7 @@ async function pointFinder(name: string, stopsOnly: boolean, assignedStops: bool

const city = poi[2] === "" ? "Dresden" : poi[2];
const idAndType = utils.parsePoiID(poi[0]);
const coords = utils.gk4toWgs84(poi[4], poi[5]);
const coords = utils.GK4toWGS84(poi[5], poi[4]);

if (coords) {
const point: IPoint = {
Expand All @@ -52,17 +52,33 @@ async function pointFinder(name: string, stopsOnly: boolean, assignedStops: bool
.catch(utils.convertError);
}

export async function findStop(searchString: string) {
/**
* Search for a single stop in the network of the DVB.
* @param searchString the name of the stop
* @returns an array of all possible hits including their GPS coordinates.
*/
export function findStop(searchString: string): Promise<IPoint[]> {
return pointFinder(searchString, true, false);
}

export async function findPOI(searchString: string) {
/**
* Search for POI in the network of the DVB.
* @param searchString the name of the stop
* @returns an array of all possible hits including their GPS coordinates.
*/
export function findPOI(searchString: string): Promise<IPoint[]> {
return pointFinder(searchString, false, false);
}

export async function findAddress(lat: number, lng: number) {
/**
* Lookup address and nearby stops by coordinate.
* @param lng longitude of the coordinate
* @param lat latitude of the coordinate
* @returns the adress and neaby stops
*/
export function findAddress(lng: number, lat: number): Promise<IAddress | undefined> {

const gk4 = utils.wgs84toGk4(lat, lng);
const gk4 = utils.WGS84toGK4(lng, lat);

return pointFinder(`coord:${gk4[0]}:${gk4[1]}`, false, true)
.then((points) => {
Expand Down
18 changes: 14 additions & 4 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,42 @@ export enum PIN_TYPE {
ticketmachine = "ticketmachine",
carsharing = "carsharing",
parkandride = "parkandride",
unknown = "unknown",
}

/**
* WGS84 coordinates [lng, lat]
*/
export type coord = number[];

export interface IDiva {
number: number;
network: string;
network?: string;
}

export interface IPlatform {
name: string;
type: string;
}

/**
* - The id for PIN_TYPE.platform is always an empty string.
* - PIN_TYPE.platform conatins platform_nr.
* - PIN_TYPE.stop contains connections.
* - PIN_TYPE.parkandride contains info.
*/
export interface IPin {
id: string;
type: PIN_TYPE;
name: string;
coords?: coord;
coords: coord;
platform_nr?: string;
connections?: IConnection[];
info?: string;
}

export interface IConnection {
line: string;
type: string;
mode: IMode;
}

export interface IMode {
Expand Down
7 changes: 5 additions & 2 deletions src/lines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ function parseLine(line: any): ILine {
directions: line.Directions.map(parseDirection),
};
}

export async function lines(stopID: string): Promise<ILine[]> {
/**
* get a list of availible tram/bus lines for a stop.
* @param stopID the stop ID
*/
export function lines(stopID: string): Promise<ILine[]> {

const options: AxiosRequestConfig = {
url: "https://webapi.vvo-online.de/stt/lines",
Expand Down
8 changes: 7 additions & 1 deletion src/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import axios, { AxiosRequestConfig } from "axios";
import { IMonitor } from "./interfaces";
import * as utils from "./utils";

export async function monitor(stopID: string, offset = 0, amount = 0): Promise<IMonitor[]> {
/**
* Monitor a single stop to see every bus or tram leaving this stop after the specified time offset.
* @param stopID ID of the stop
* @param offset how many minutes in the future, 0 for now
* @param amount number of results
*/
export function monitor(stopID: string, offset = 0, amount = 0): Promise<IMonitor[]> {

const now = new Date();
const time = new Date(now.getTime() + (offset * 60 * 1000));
Expand Down
28 changes: 18 additions & 10 deletions src/pins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,29 @@ import axios, { AxiosRequestConfig } from "axios";
import { IPin, PIN_TYPE } from "./interfaces";
import * as utils from "./utils";

export async function pins(swlat: number, swlng: number, nelat: number, nelng: number,
pinType: PIN_TYPE): Promise<IPin[]> {
/**
* Search for different kinds of POIs inside a given bounding box.
* @param swlng the longitude of the south west coordinate
* @param swlat the latitude of the south west coordinate
* @param nelng the longitude of the north east coordinate
* @param nelat the latitude of the north east coordinate
* @param pinTypes array of pin types
*/
export function pins(swlng: number, swlat: number, nelng: number, nelat: number,
pinTypes: PIN_TYPE[] = [PIN_TYPE.stop]): Promise<IPin[]> {

const sw = utils.wgs84toGk4(swlat, swlng);
const ne = utils.wgs84toGk4(nelat, nelng);
const sw = utils.WGS84toGK4(swlng, swlat);
const ne = utils.WGS84toGK4(nelng, nelat);

let url = "https://www.dvb.de/apps/map/pins?showLines=true";
pinTypes.forEach((type) => url += `&pintypes=${type}`);
const options: AxiosRequestConfig = {
url: "https://www.dvb.de/apps/map/pins",
url,
params: {
showLines: "true",
swlat: sw[1],
swlng: sw[0],
nelat: ne[1],
swlat: sw[1],
nelng: ne[0],
pintypes: pinType,
nelat: ne[1],
},
responseType: "text",
};
Expand All @@ -25,5 +33,5 @@ export async function pins(swlat: number, swlng: number, nelat: number, nelng: n
.then((response) => {
return response.data || [];
})
.then((elements) => elements.map((elem: string) => utils.parsePin(elem, pinType)));
.then((elements) => elements.map((elem: string) => utils.parsePin(elem)));
}
83 changes: 14 additions & 69 deletions src/route.ts
Original file line number Diff line number Diff line change
@@ -1,74 +1,19 @@
import axios, { AxiosRequestConfig } from "axios";
import { ILocation, INode, IRoute, IStop, IStopLocation, ITrip } from "./interfaces";
import { ILocation, IRoute } from "./interfaces";
import * as utils from "./utils";

function extractStop(stop: any): IStop {
return {
name: stop.Name.trim(),
city: stop.Place,
type: stop.Type,
platform: utils.parsePlatform(stop.Platform),
coords: utils.gk4toWgs84(stop.Latitude, stop.Longitude) || [0, 0],
arrival: utils.parseDate(stop.ArrivalTime),
departure: utils.parseDate(stop.DepartureTime),
};
}

function extractNode(node: any, mapData: any): INode {
const stops: IStop[] = node.RegularStops ? node.RegularStops.map(extractStop) : [];

let departure: IStopLocation | undefined;
let arrival: IStopLocation | undefined;

if (stops && stops.length > 1) {
const firstStop = stops[0];
const lastStop = stops[stops.length - 1];

departure = {
name: firstStop.name,
city: firstStop.city,
platform: firstStop.platform,
time: firstStop.departure,
coords: firstStop.coords,
type: firstStop.type,
};

arrival = {
name: lastStop.name,
city: lastStop.city,
platform: lastStop.platform,
time: lastStop.arrival,
coords: lastStop.coords,
type: lastStop.type,
};
}

return {
stops,
departure,
arrival,
mode: utils.parseMode(node.Mot.Type),
line: node.Mot.Name ? node.Mot.Name : "",
direction: node.Mot.Direction ? node.Mot.Direction.trim() : "",
diva: utils.parseDiva(node.Mot.Diva),
duration: 1,
path: utils.convertCoordinates(mapData[node.MapDataIndex]),
};
}

function extractTrip(trip: any): ITrip {
const nodes: INode[] = trip.PartialRoutes.map((node: any) => extractNode(node, trip.MapData));

return {
nodes,
departure: nodes[0].departure,
arrival: nodes[nodes.length - 1].arrival,
duration: 1,
interchanges: trip.Interchanges,
};
}

export async function route(originID: string, destinationID: string,
/**
* Query the server for possible routes from one stop to another.
* @param originID the id of the origin stop
* @param destinationID the id of the destination stop
* @param time starting at what time
* @param isArrivalTime is time the arrival time
* @returns Returns multiple possible trips, the bus-/tramlines to be taken,
* the single stops, their arrival and departure times and their GPS coordinates.
* The path property of a trip contains an array consisting of all the coordinates
* describing the path of this node. This can be useful to draw the route on a map.
*/
export function route(originID: string, destinationID: string,
time = new Date(), isArrivalTime = true): Promise<IRoute> {

const options: AxiosRequestConfig = {
Expand All @@ -90,7 +35,7 @@ export async function route(originID: string, destinationID: string,
utils.checkStatus(response.data);

if (response.data.Routes) {
const trips = response.data.Routes.map(extractTrip);
const trips = response.data.Routes.map(utils.extractTrip);

let origin: ILocation | undefined;
let destination: ILocation | undefined;
Expand Down
52 changes: 48 additions & 4 deletions src/test/helper.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { assert } from "chai";
import {
coord, IAddress, IDiva, ILocation, IMode,
IPlatform, IPoint, IStop, IStopLocation, POI_TYPE,
coord, IAddress, IConnection, IDiva, ILocation, IMode,
IPin, IPlatform, IPoint, IStop, IStopLocation, PIN_TYPE, POI_TYPE,
} from "../interfaces";

export function assertCoords(coords: coord) {
assert.isArray(coords);
assert.lengthOf(coords, 2);

assert.approximately(coords[0], 51, 1);
assert.approximately(coords[1], 13, 2);
assert.approximately(coords[0], 13, 2);
assert.approximately(coords[1], 51, 1);
}

export function assertPlatform(platform: IPlatform) {
Expand Down Expand Up @@ -98,3 +98,47 @@ export function assertStopLocation(stop: IStopLocation) {

assert.strictEqual(stop.type, POI_TYPE.Stop);
}

export function assertConnection(con: IConnection) {
assert.isObject(con);
assert.isString(con.line);
assert.isNotEmpty(con.line);
assertMode(con.mode);
}

export function assertPin(pin: IPin, type?: PIN_TYPE) {
assert.isObject(pin);
assert.isString(pin.type);

if (type) {
assert.strictEqual(pin.type, type);
}

assert.isString(pin.id);
assert.isString(pin.name);
assertCoords(pin.coords);

if (pin.type === PIN_TYPE.platform) {
assert.isString(pin.platform_nr);
assert.isNotEmpty(pin.platform_nr);
} else {
assert.isUndefined(pin.platform_nr);
}

if (pin.type === PIN_TYPE.stop) {
assert.isArray(pin.connections);
if (pin.name !== "Ebertplatz") {
assert.isNotEmpty(pin.connections);
}
pin.connections!.forEach(assertConnection);
} else {
assert.isUndefined(pin.connections);
}

if (pin.type === PIN_TYPE.parkandride) {
assert.isString(pin.info);
assert.isNotEmpty(pin.info);
} else {
assert.isUndefined(pin.info);
}
}
Loading

0 comments on commit 895cd52

Please sign in to comment.