Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
ffa8af2d5d | |||
eb400b52ca | |||
0e21c0d64c | |||
7e3af36e22 | |||
93acfad184 | |||
daa84f61c5 | |||
0304f6e0f4 | |||
56d482b723 | |||
afffaa4a6f | |||
e12775b6ae | |||
6b0481a5e1 | |||
ca9578a4d3 | |||
9ecb3763af | |||
a8fc93fb41 | |||
1f4bd9f411 | |||
ee1d8bd2c8 | |||
4b3a255e18 | |||
6fab3ab6fe | |||
35728fa9b1 | |||
5a93a54c64 | |||
d7f6c34fc0 | |||
746696405c | |||
b208a732c7 | |||
03e6fc0338 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
target/
|
||||
.idea/
|
||||
*.iml
|
14
.travis.yml
14
.travis.yml
@ -1,3 +1,15 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk8
|
||||
install: true
|
||||
addons:
|
||||
sonarcloud:
|
||||
organization: "stklcode-github"
|
||||
token:
|
||||
secure: "FkEe/+MKpF4pSX3ZYOgu7oeIKf0460Q3XVLUhIX9bk2dyY8hoab74oCo4FtD7jim0+ZC13JVHGDX7iOQMUtS5EZ+x+pA0qpppzCK5zV8afN/l46HJ07kJldvr+EH0klbDVMFZQ5dT7r/w6CoDzjtENHzKQAJLcheUVDNpkcuBdaplTqIAVf3lQpKtOuVjQJ5qZDwwS5wsHNqPcYbcEGrPmcKDVnp3mD3bfI6dT1bbRt845QcD73rPYkQKxen8eIwJxFf5MZStgvbj7yphPxPGwoLAsoLP6LpThTDYcrg+vgUnSs+l9GckL3IbhPAmecixLbKVnphBZzRTvpdMTt5KeOoAJ2nM6RLs5cRCqiEgLEioWkVaSH5WxoBj38Z1h4fTsDV3dTcCuQWX8GFxdeeTelu+XbatdRWMnUgiF7oax+uNvR62fasTbAc7dWPJbARiD7ZbkWH4nHEY07xKKx87xzUz36ZeEHGoBXgqnLmv/FCwqMrEpOoIT41fc0WYtdIA4wjRoAyG0u+wNBMbVlf4PK72seM4b/bmU+TtmaaVla/SvNOiz+A3DHxtJEUScPcL3QGjviddglMf+wyD6VXVViq9VuYRKZFyjpuoNpb5lwEbwmRnmLabBx8jBgyPinjpmqHYlIntcPAwuyLRaqTHFcmCrbeeZEf7KaPRYKx+Cs="
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.m2/repository'
|
||||
- '$HOME/.sonar/cache'
|
||||
script:
|
||||
- mvn -P jacoco clean package sonar:sonar
|
||||
|
15
CHANGELOG.md
Normal file
15
CHANGELOG.md
Normal file
@ -0,0 +1,15 @@
|
||||
## 1.1.2 [2018-03-24]
|
||||
* [improvement] Added automatic module name for JPMS compatibility
|
||||
|
||||
## 1.1.1 [2018-02-20]
|
||||
* [improvement] On connection or parsing errors, the `IOException` is no longer ignored, but encapsulated in `RuntimeException` (no StackTraces printed)
|
||||
* [internal] Code cleanup and minor improvements
|
||||
* [dependeny] Minor dependency updates
|
||||
|
||||
## 1.1.0 [2017-01-07]
|
||||
* [feature] Filter stops by coordinates and radius
|
||||
* [feature] Filter trips by destination and and towards fields
|
||||
* [test] Test coverage 100% (line); tested against ASEAG and TFL APIs
|
||||
|
||||
## 1.0.0 [2017-01-02]
|
||||
* Initial release
|
65
README.md
65
README.md
@ -1,46 +1,69 @@
|
||||
jURAclient [](https://travis-ci.org/stklcode/juraclient)
|
||||
==========
|
||||
|
||||
# jURAclient
|
||||
[](https://travis-ci.org/stklcode/juraclient)
|
||||
[](https://sonarcloud.io/dashboard?id=de.stklcode.pubtrans%3Ajuraclient)
|
||||
[](https://www.javadoc.io/doc/de.stklcode.pubtrans/juraclient)
|
||||
[](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22de.stklcode.pubtrans%22%20AND%20a%3A%22juraclient%22)
|
||||
[](https://github.com/stklcode/juraclient/blob/master/LICENSE.txt)
|
||||
|
||||
Java client for URA based public transport APIs.
|
||||
|
||||
This client allows to simply connect any Java application to the public transport API to implement a monitor for the
|
||||
local bus station or any other custom queries.
|
||||
local bus station or any other custom queries. API versions 1.x and 2.x are supported.
|
||||
|
||||
**Usage Example**
|
||||
## Usage Examples
|
||||
|
||||
### Initialization
|
||||
```java
|
||||
// Instantiate the client (e.g. using the ASEAG API)
|
||||
UraClient ura = new UraClient("http://ivu.aseag.de");
|
||||
// Instantiate the client (e.g. using the TFL API)
|
||||
UraClient ura = new UraClient("http://countdown.api.tfl.gov.uk");
|
||||
|
||||
// Initiailize with non-standard endpoints
|
||||
// Initiailize the API with non-standard endpoints (e.g. ASEAG with API V2)
|
||||
UraClient ura = new UraClient("http://ivu.aseag.de",
|
||||
"interfaces/ura/instant_V2",
|
||||
"interfaces/ura/stream_V2");
|
||||
|
||||
// List available stops
|
||||
List<Stop> stops = ura.listStops();
|
||||
|
||||
// Get next 10 trips for given stops and lines (all filters optional)
|
||||
List<Trip> trips = ura.forStop("100000")
|
||||
.forLines("25", "35")
|
||||
.getTrips(10);
|
||||
```
|
||||
|
||||
**Maven Artifact**
|
||||
### List Stops
|
||||
|
||||
```java
|
||||
// List ALL available stops
|
||||
List<Stop> stops = ura.getStops();
|
||||
|
||||
// List available stops in a 200m radius around given coordinates
|
||||
List<Stop> stops = ura.forPosition(51.51009, -0.1345734, 200)
|
||||
.getStops();
|
||||
|
||||
```
|
||||
|
||||
### Get Trips
|
||||
|
||||
```java
|
||||
// Get next 10 trips for given stops and lines in a single direction (all filters optional)
|
||||
List<Trip> trips = ura.forStop("100000")
|
||||
.forLines("25", "35")
|
||||
.forDirection(1)
|
||||
.getTrips(10);
|
||||
|
||||
// Get trips from given stop towards your destination
|
||||
List<Trip> trips = ura.forStopByName("Piccadilly Circus")
|
||||
.towards("Marble Arch")
|
||||
.getTrips();
|
||||
```
|
||||
|
||||
## Maven Artifact
|
||||
```
|
||||
<dependency>
|
||||
<groupId>de.stklcode.pubtrans</groupId>
|
||||
<artifactId>juraclient</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
**Planned features:**
|
||||
## Planned Features
|
||||
|
||||
* More refined query parameters
|
||||
* Stream API with asynchronous consumer
|
||||
|
||||
**License**
|
||||
## License
|
||||
|
||||
The project is licensed under [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
|
||||
The project is licensed under [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
167
pom.xml
167
pom.xml
@ -5,23 +5,57 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.stklcode.pubtrans</groupId>
|
||||
<artifactId>juraclien</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<artifactId>juraclient</artifactId>
|
||||
<version>1.1.2</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>jURAclient</name>
|
||||
<description>Java client for URA based public transport API</description>
|
||||
<url>https://github.com/stklcode/juraclient</url>
|
||||
<inceptionYear>2016</inceptionYear>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Stefan Kalscheuer</name>
|
||||
<email>stefan@stklcode.de</email>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/stklcode/juraclient.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:stklcode/juraclient.git</developerConnection>
|
||||
<url>https://github.com/stklcode/juraclient</url>
|
||||
</scm>
|
||||
|
||||
<issueManagement>
|
||||
<system>github</system>
|
||||
<url>https://github.com/stklcode/juraclient/issues</url>
|
||||
</issueManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.8.5</version>
|
||||
<version>2.9.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.8.5</version>
|
||||
<version>2.9.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
@ -38,13 +72,13 @@
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<version>2.0.0-beta.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<version>2.0.0-beta.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@ -54,12 +88,129 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Automatic-Module-Name>de.stklcode.pubtrans.juraclient</Automatic-Module-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jacoco</id>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>org.jacoco.agent</artifactId>
|
||||
<version>0.8.0</version>
|
||||
<classifier>runtime</classifier>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-instrument</id>
|
||||
<goals>
|
||||
<goal>instrument</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>default-restore-instrumented-classes</id>
|
||||
<goals>
|
||||
<goal>restore-instrumented-classes</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<dataFile>${project.build.directory}/coverage.exec</dataFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.20.1</version>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<jacoco-agent.destfile>${project.build.directory}/jacoco.exec</jacoco-agent.destfile>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>sources</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>javadoc</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
</profiles>
|
||||
</project>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 Stefan Kalscheuer
|
||||
* Copyright 2016-2018 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -31,11 +31,11 @@ import java.util.List;
|
||||
/**
|
||||
* Client for URA based public transport API.
|
||||
*
|
||||
* @author Stefan Kalscheuer <stefan@stklcode.de>
|
||||
* @author Stefan Kalscheuer
|
||||
*/
|
||||
public class UraClient {
|
||||
private static final String DEFAULT_INSTANT_URL = "/interfaces/ura/instant_V2";
|
||||
private static final String DEFAULT_STREAM_URL = "/interfaces/ura/stream_V2";
|
||||
private static final String DEFAULT_INSTANT_URL = "/interfaces/ura/instant_V1";
|
||||
private static final String DEFAULT_STREAM_URL = "/interfaces/ura/stream_V1";
|
||||
|
||||
private static final String PAR_STOP_ID = "StopID";
|
||||
private static final String PAR_STOP_NAME = "StopPointName";
|
||||
@ -51,10 +51,12 @@ public class UraClient {
|
||||
private static final String PAR_VEHICLE_ID = "VehicleID";
|
||||
private static final String PAR_TRIP_ID = "TripID";
|
||||
private static final String PAR_ESTTIME = "EstimatedTime";
|
||||
private static final String PAR_TOWARDS = "Towards";
|
||||
private static final String PAR_CIRCLE = "Circle";
|
||||
|
||||
private static final Integer RES_TYPE_STOP = 0;
|
||||
private static final Integer RES_TYPE_PREDICTION = 1;
|
||||
|
||||
private static final Integer RES_TYPE_URA_VERSION = 4;
|
||||
|
||||
private static final String[] REQUEST_STOP = {PAR_STOP_NAME, PAR_STOP_ID, PAR_STOP_INDICATOR, PAR_STOP_STATE, PAR_GEOLOCATION};
|
||||
private static final String[] REQUEST_TRIP = {PAR_STOP_NAME, PAR_STOP_ID, PAR_STOP_INDICATOR, PAR_STOP_STATE, PAR_GEOLOCATION,
|
||||
@ -68,20 +70,20 @@ public class UraClient {
|
||||
/**
|
||||
* Constructor with base URL and default API paths.
|
||||
*
|
||||
* @param baseURL the base URL (with protocol, without trailing slash)
|
||||
* @param baseURL The base URL (with protocol, without trailing slash).
|
||||
*/
|
||||
public UraClient(String baseURL) {
|
||||
public UraClient(final String baseURL) {
|
||||
this(baseURL, DEFAULT_INSTANT_URL, DEFAULT_STREAM_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with base URL and custom API paths
|
||||
* Constructor with base URL and custom API paths.
|
||||
*
|
||||
* @param baseURL the base URL (including protocol)
|
||||
* @param instantURL the path for instant requests
|
||||
* @param streamURL the path for stream requests
|
||||
* @param baseURL The base URL (including protocol).
|
||||
* @param instantURL The path for instant requests.
|
||||
* @param streamURL The path for stream requests.
|
||||
*/
|
||||
public UraClient(String baseURL, String instantURL, String streamURL) {
|
||||
public UraClient(final String baseURL, final String instantURL, final String streamURL) {
|
||||
this.baseURL = baseURL;
|
||||
this.instantURL = instantURL;
|
||||
this.streamURL = streamURL;
|
||||
@ -94,7 +96,7 @@ public class UraClient {
|
||||
* @param stops Stop IDs
|
||||
* @return the request
|
||||
*/
|
||||
public Query forStops(final String...stops) {
|
||||
public final Query forStops(final String... stops) {
|
||||
return new Query().forStops(stops);
|
||||
}
|
||||
|
||||
@ -104,45 +106,80 @@ public class UraClient {
|
||||
* @param stopNames Stop Point Names
|
||||
* @return the request
|
||||
*/
|
||||
public Query forStopsByName(final String...stopNames) {
|
||||
public final Query forStopsByName(final String... stopNames) {
|
||||
return new Query().forStopsByName(stopNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given line IDs.
|
||||
*
|
||||
* @param lines line IDs
|
||||
* @return the request
|
||||
* @param lines Line IDs.
|
||||
* @return The request.
|
||||
*/
|
||||
public Query forLines(final String...lines) {
|
||||
public final Query forLines(final String... lines) {
|
||||
return new Query().forLines(lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given line names.
|
||||
*
|
||||
* @param lineNames line names
|
||||
* @return the request
|
||||
* @param lineNames Line names.
|
||||
* @return The request.
|
||||
*/
|
||||
public Query forLinesByName(final String...lineNames) {
|
||||
public final Query forLinesByName(final String... lineNames) {
|
||||
return new Query().forLinesByName(lineNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given direction.
|
||||
*
|
||||
* @param direction the direction ID
|
||||
* @return the request
|
||||
* @param direction The direction ID.
|
||||
* @return The request.
|
||||
*/
|
||||
public Query forDirection(final Integer direction) {
|
||||
public final Query forDirection(final Integer direction) {
|
||||
return new Query().forDirection(direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given destination names.
|
||||
*
|
||||
* @param destinationNames Destination names.
|
||||
* @return The request.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final Query forDestinationNames(final String... destinationNames) {
|
||||
return new Query().forDestinationNames(destinationNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given direction defined by stop point name.
|
||||
*
|
||||
* @param towards Towards stop point names.
|
||||
* @return The request.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final Query towards(final String... towards) {
|
||||
return new Query().towards(towards);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given destination names.
|
||||
*
|
||||
* @param latitude Latitude (WGS84).
|
||||
* @param longitude Longitude (WGS84).
|
||||
* @param radius Search radius (meters).
|
||||
* @return The request.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final Query forPosition(final Double latitude, final Double longitude, final Integer radius) {
|
||||
return new Query().forPosition(latitude, longitude, radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of trips.
|
||||
* If forStops() and/or forLines() has been called, those will be used as filter.
|
||||
*
|
||||
* @return list of trips
|
||||
* @return List of trips.
|
||||
*/
|
||||
public List<Trip> getTrips() {
|
||||
return getTrips(new Query(), null);
|
||||
@ -152,7 +189,8 @@ public class UraClient {
|
||||
* Get list of trips with limit.
|
||||
* If forStops() and/or forLines() has been called, those will be used as filter.
|
||||
*
|
||||
* @return list of trips
|
||||
* @param limit Maximum number of results.
|
||||
* @return List of trips.
|
||||
*/
|
||||
public List<Trip> getTrips(final Integer limit) {
|
||||
return getTrips(new Query(), limit);
|
||||
@ -162,32 +200,40 @@ public class UraClient {
|
||||
* Get list of trips.
|
||||
* If forStops() and/or forLines() has been called, those will be used as filter.
|
||||
*
|
||||
* @return list of trips
|
||||
* @param query The query.
|
||||
* @return List of trips.
|
||||
*/
|
||||
public List<Trip> getTrips(Query query) {
|
||||
public List<Trip> getTrips(final Query query) {
|
||||
return getTrips(query, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of trips for given stopIDs and lineIDs with result limit.
|
||||
*
|
||||
* @param query the request
|
||||
* @param limit maximum number of results
|
||||
* @return list of trips
|
||||
* @param query The query.
|
||||
* @param limit Maximum number of results.
|
||||
* @return List of trips.
|
||||
*/
|
||||
public List<Trip> getTrips(final Query query, final Integer limit) {
|
||||
List<Trip> trips = new ArrayList<>();
|
||||
try (InputStream is = requestInstant(REQUEST_TRIP, query.stopIDs, query.stopNames, query.lineIDs, query.lineNames, query.direction);
|
||||
try (InputStream is = requestInstant(REQUEST_TRIP, query);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null && (limit == null || trips.size() < limit)) {
|
||||
String version = null;
|
||||
String line = br.readLine();
|
||||
while (line != null && (limit == null || trips.size() < limit)) {
|
||||
List l = mapper.readValue(line, List.class);
|
||||
/* Check if result exists and has correct response type */
|
||||
if (l != null && l.size() > 0 && l.get(0).equals(RES_TYPE_PREDICTION))
|
||||
trips.add(new Trip(l));
|
||||
if (l != null && !l.isEmpty()) {
|
||||
if (l.get(0).equals(RES_TYPE_URA_VERSION)) {
|
||||
version = l.get(1).toString();
|
||||
} else if (l.get(0).equals(RES_TYPE_PREDICTION)) {
|
||||
trips.add(new Trip(l, version));
|
||||
}
|
||||
}
|
||||
line = br.readLine();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalStateException("Failed to read from API", e);
|
||||
}
|
||||
return trips;
|
||||
}
|
||||
@ -195,7 +241,7 @@ public class UraClient {
|
||||
/**
|
||||
* Get list of stops without filters.
|
||||
*
|
||||
* @return the list
|
||||
* @return Lhe list.
|
||||
*/
|
||||
public List<Stop> getStops() {
|
||||
return getStops(new Query());
|
||||
@ -205,21 +251,23 @@ public class UraClient {
|
||||
* List available stopIDs.
|
||||
* If forStops() and/or forLines() has been called, those will be used as filter.
|
||||
*
|
||||
* @return the list
|
||||
* @param query The query.
|
||||
* @return The list.
|
||||
*/
|
||||
public List<Stop> getStops(Query query) {
|
||||
public List<Stop> getStops(final Query query) {
|
||||
List<Stop> stops = new ArrayList<>();
|
||||
try (InputStream is = requestInstant(REQUEST_STOP, query.stopIDs, query.stopNames, query.lineIDs, query.lineNames, query.direction);
|
||||
try (InputStream is = requestInstant(REQUEST_STOP, query);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
List l = mapper.readValue(line, List.class);
|
||||
/* Check if result exists and has correct response type */
|
||||
if (l != null && l.size() > 0 && l.get(0).equals(RES_TYPE_STOP))
|
||||
if (l != null && !l.isEmpty() && l.get(0).equals(RES_TYPE_STOP)) {
|
||||
stops.add(new Stop(l));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalStateException("Failed to read from API", e);
|
||||
}
|
||||
return stops;
|
||||
}
|
||||
@ -227,43 +275,64 @@ public class UraClient {
|
||||
/**
|
||||
* Issue request to instant endpoint and return input stream.
|
||||
*
|
||||
* @param returnList fields to fetch
|
||||
* @param returnList Fields to fetch.
|
||||
* @param query The query.
|
||||
* @return Input stream of the URL
|
||||
* @throws IOException on errors
|
||||
*/
|
||||
private InputStream requestInstant(String[] returnList, String[] stopIDs, String[] stopNames, String[] lineIDs, String[] lineNames, Integer direction) throws IOException {
|
||||
private InputStream requestInstant(final String[] returnList, final Query query) throws IOException {
|
||||
String urlStr = baseURL + instantURL + "?ReturnList=" + String.join(",", returnList);
|
||||
if (stopIDs != null && stopIDs.length > 0)
|
||||
urlStr += "&" + PAR_STOP_ID + "=" + String.join(",", stopIDs);
|
||||
if (stopNames != null && stopNames.length > 0)
|
||||
urlStr += "&" + PAR_STOP_NAME + "=" + String.join(",", stopNames);
|
||||
if (lineIDs != null && lineIDs.length > 0)
|
||||
urlStr += "&" + PAR_LINE_ID + "=" + String.join(",", lineIDs);
|
||||
if (lineNames != null && lineNames.length > 0)
|
||||
urlStr += "&" + PAR_LINE_NAME + "=" + String.join(",", lineNames);
|
||||
if (direction != null)
|
||||
urlStr += "&" + PAR_DIR_ID + "=" + direction;
|
||||
|
||||
if (query.stopIDs != null && query.stopIDs.length > 0) {
|
||||
urlStr += "&" + PAR_STOP_ID + "=" + String.join(",", query.stopIDs);
|
||||
}
|
||||
if (query.stopNames != null && query.stopNames.length > 0) {
|
||||
urlStr += "&" + PAR_STOP_NAME + "=" + String.join(",", query.stopNames);
|
||||
}
|
||||
if (query.lineIDs != null && query.lineIDs.length > 0) {
|
||||
urlStr += "&" + PAR_LINE_ID + "=" + String.join(",", query.lineIDs);
|
||||
}
|
||||
if (query.lineNames != null && query.lineNames.length > 0) {
|
||||
urlStr += "&" + PAR_LINE_NAME + "=" + String.join(",", query.lineNames);
|
||||
}
|
||||
if (query.direction != null) {
|
||||
urlStr += "&" + PAR_DIR_ID + "=" + query.direction;
|
||||
}
|
||||
if (query.destinationNames != null) {
|
||||
urlStr += "&" + PAR_DEST_NAME + "=" + String.join(",", query.destinationNames);
|
||||
}
|
||||
if (query.towards != null) {
|
||||
urlStr += "&" + PAR_TOWARDS + "=" + String.join(",", query.towards);
|
||||
}
|
||||
if (query.circle != null) {
|
||||
urlStr += "&" + PAR_CIRCLE + "=" + String.join(",", query.circle);
|
||||
}
|
||||
|
||||
URL url = new URL(urlStr);
|
||||
|
||||
return url.openStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request meta object.
|
||||
*/
|
||||
public class Query {
|
||||
public final class Query {
|
||||
private String[] stopIDs;
|
||||
private String[] stopNames;
|
||||
private String[] lineIDs;
|
||||
private String[] lineNames;
|
||||
private Integer direction;
|
||||
private String[] destinationNames;
|
||||
private String[] towards;
|
||||
private String circle;
|
||||
|
||||
/**
|
||||
* Builder pattern to request given line IDs.
|
||||
*
|
||||
* @param lineIDs line IDs
|
||||
* @return the query
|
||||
* @param lineIDs Line IDs.
|
||||
* @return The query.
|
||||
*/
|
||||
public Query forLines(final String...lineIDs) {
|
||||
public Query forLines(final String... lineIDs) {
|
||||
this.lineIDs = lineIDs;
|
||||
return this;
|
||||
}
|
||||
@ -271,10 +340,10 @@ public class UraClient {
|
||||
/**
|
||||
* Builder pattern to request given line names.
|
||||
*
|
||||
* @param lineNames line names
|
||||
* @return the query
|
||||
* @param lineNames Line names.
|
||||
* @return The query.
|
||||
*/
|
||||
public Query forLinesByName(final String...lineNames) {
|
||||
public Query forLinesByName(final String... lineNames) {
|
||||
this.lineNames = lineNames;
|
||||
return this;
|
||||
}
|
||||
@ -282,10 +351,10 @@ public class UraClient {
|
||||
/**
|
||||
* Builder pattern to request given stop IDs.
|
||||
*
|
||||
* @param stopIDs stop IDs
|
||||
* @return the query
|
||||
* @param stopIDs Stop IDs.
|
||||
* @return The query.
|
||||
*/
|
||||
public Query forStops(final String...stopIDs) {
|
||||
public Query forStops(final String... stopIDs) {
|
||||
this.stopIDs = stopIDs;
|
||||
return this;
|
||||
}
|
||||
@ -293,10 +362,10 @@ public class UraClient {
|
||||
/**
|
||||
* Builder pattern to request given stop names.
|
||||
*
|
||||
* @param stopNames line names
|
||||
* @return the query
|
||||
* @param stopNames Line names.
|
||||
* @return The query.
|
||||
*/
|
||||
public Query forStopsByName(final String...stopNames) {
|
||||
public Query forStopsByName(final String... stopNames) {
|
||||
this.stopNames = stopNames;
|
||||
return this;
|
||||
}
|
||||
@ -304,18 +373,56 @@ public class UraClient {
|
||||
/**
|
||||
* Builder pattern to request given direction.
|
||||
*
|
||||
* @param direction the direction
|
||||
* @return the query
|
||||
* @param direction The direction.
|
||||
* @return The query.
|
||||
*/
|
||||
public Query forDirection(final Integer direction) {
|
||||
this.direction = direction;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given destination names.
|
||||
*
|
||||
* @param destinationNames Names of destinations.
|
||||
* @return The query.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public Query forDestinationNames(final String... destinationNames) {
|
||||
this.destinationNames = destinationNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given direction defined by stop point name.
|
||||
*
|
||||
* @param towards Towards stop point names.
|
||||
* @return The request.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public Query towards(final String... towards) {
|
||||
this.towards = towards;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder pattern to request given position and radius.
|
||||
*
|
||||
* @param latitude Latitude (WGS84).
|
||||
* @param longitude Longitude (WGS84).
|
||||
* @param radius Search radius (meters).
|
||||
* @return The query.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public Query forPosition(final Double latitude, final Double longitude, final Integer radius) {
|
||||
this.circle = latitude.toString() + "," + longitude.toString() + "," + radius.toString();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stops for set filters.
|
||||
*
|
||||
* @return List of matching trips
|
||||
* @return List of matching trips.
|
||||
*/
|
||||
public List<Stop> getStops() {
|
||||
return UraClient.this.getStops(this);
|
||||
@ -324,7 +431,7 @@ public class UraClient {
|
||||
/**
|
||||
* Get trips for set filters.
|
||||
*
|
||||
* @return List of matching trips
|
||||
* @return List of matching trips.
|
||||
*/
|
||||
public List<Trip> getTrips() {
|
||||
return UraClient.this.getTrips(this);
|
||||
|
49
src/main/java/de/stklcode/pubtrans/ura/model/Model.java
Normal file
49
src/main/java/de/stklcode/pubtrans/ura/model/Model.java
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2016-2018 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package de.stklcode.pubtrans.ura.model;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 1.1.1
|
||||
*/
|
||||
interface Model {
|
||||
/**
|
||||
* Generate exception for unmatched type when String is expected.
|
||||
*
|
||||
* @param field Field number.
|
||||
* @param actual Actual class.
|
||||
* @return The Exception.
|
||||
*/
|
||||
static IOException typeErrorString(int field, Class actual) {
|
||||
return typeError(field, actual, "String");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate exception for unmatched type.
|
||||
*
|
||||
* @param field Field number.
|
||||
* @param actual Actual class.
|
||||
* @param expected Expected type.
|
||||
* @return The Exception.
|
||||
*/
|
||||
static IOException typeError(int field, Class actual, String expected) {
|
||||
return new IOException(String.format("Field %d not of expected type %s, found %s",
|
||||
field, expected, actual.getSimpleName()));
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 Stefan Kalscheuer
|
||||
* Copyright 2016-2018 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -22,9 +22,17 @@ import java.util.List;
|
||||
/**
|
||||
* Entity for a single stop.
|
||||
*
|
||||
* @author Stefan Kalscheuer <stefan@stklcode.de>
|
||||
* @author Stefan Kalscheuer
|
||||
*/
|
||||
public class Stop {
|
||||
public final class Stop implements Model {
|
||||
private static final int F_STOP_NAME = 1;
|
||||
private static final int F_STOP_ID = 2;
|
||||
private static final int F_INDICATOR = 3;
|
||||
private static final int F_STATE = 4;
|
||||
private static final int F_LATITUDE = 5;
|
||||
private static final int F_LONGITUDE = 6;
|
||||
private static final int F_NUM_OF_FIELDS = 7;
|
||||
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final String indicator;
|
||||
@ -32,7 +40,22 @@ public class Stop {
|
||||
private final Double latitude;
|
||||
private final Double longitude;
|
||||
|
||||
public Stop(String id, String name, String indicator, Integer state, Double latitude, Double longitude) {
|
||||
/**
|
||||
* Construct Stop object.
|
||||
*
|
||||
* @param id Stop ID.
|
||||
* @param name Stop name.
|
||||
* @param indicator Stop indicator.
|
||||
* @param state Stop state.
|
||||
* @param latitude Stop geolocation latitude.
|
||||
* @param longitude Stop geolocation longitude.
|
||||
*/
|
||||
public Stop(final String id,
|
||||
final String name,
|
||||
final String indicator,
|
||||
final Integer state,
|
||||
final Double latitude,
|
||||
final Double longitude) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.indicator = indicator;
|
||||
@ -41,56 +64,94 @@ public class Stop {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public Stop(List raw) throws IOException {
|
||||
if (raw == null || raw.size() < 7)
|
||||
/**
|
||||
* Construct Stop object from raw list of attributes parsed from JSON.
|
||||
*
|
||||
* @param raw List of attributes from JSON line
|
||||
* @throws IOException Thrown on invalid line format.
|
||||
*/
|
||||
public Stop(final List raw) throws IOException {
|
||||
if (raw == null || raw.size() < F_NUM_OF_FIELDS) {
|
||||
throw new IOException("Invalid number of fields");
|
||||
}
|
||||
|
||||
if (raw.get(1) instanceof String)
|
||||
name = (String)raw.get(1);
|
||||
else
|
||||
throw new IOException("Field 1 not of expected type String, found " + raw.get(1).getClass().getSimpleName());
|
||||
if (raw.get(2) instanceof String)
|
||||
id = (String)raw.get(2);
|
||||
else
|
||||
throw new IOException("Field 2 not of expected type String, found " + raw.get(2).getClass().getSimpleName());
|
||||
if (raw.get(3) instanceof String)
|
||||
indicator = (String)raw.get(3);
|
||||
else
|
||||
throw new IOException("Field 3 not of expected type String, found " + raw.get(3).getClass().getSimpleName());
|
||||
if (raw.get(4) instanceof Integer)
|
||||
state = (Integer)raw.get(4);
|
||||
else
|
||||
throw new IOException("Field 4 not of expected type Integer, found " + raw.get(4).getClass().getSimpleName());
|
||||
if (raw.get(5) instanceof Double)
|
||||
latitude = (Double)raw.get(5);
|
||||
else
|
||||
throw new IOException("Field 5 not of expected type Double, found " + raw.get(5).getClass().getSimpleName());
|
||||
if (raw.get(6) instanceof Double)
|
||||
longitude = (Double)raw.get(6);
|
||||
else
|
||||
throw new IOException("Field 6 not of expected type Double, found " + raw.get(6).getClass().getSimpleName());
|
||||
if (raw.get(1) instanceof String) {
|
||||
name = (String) raw.get(F_STOP_NAME);
|
||||
} else {
|
||||
throw Model.typeErrorString(F_STOP_NAME, raw.get(F_STOP_NAME).getClass());
|
||||
}
|
||||
|
||||
if (raw.get(F_STOP_ID) instanceof String) {
|
||||
id = (String) raw.get(F_STOP_ID);
|
||||
} else {
|
||||
throw Model.typeErrorString(F_STOP_ID, raw.get(F_STOP_ID).getClass());
|
||||
}
|
||||
|
||||
if (raw.get(F_INDICATOR) instanceof String) {
|
||||
indicator = (String) raw.get(F_INDICATOR);
|
||||
} else if (raw.get(F_INDICATOR) == null) {
|
||||
indicator = null;
|
||||
} else {
|
||||
throw Model.typeErrorString(F_INDICATOR, raw.get(F_INDICATOR).getClass());
|
||||
}
|
||||
|
||||
if (raw.get(F_STATE) instanceof Integer) {
|
||||
state = (Integer) raw.get(F_STATE);
|
||||
} else {
|
||||
throw Model.typeError(F_STATE, raw.get(F_STATE).getClass(), "Integer");
|
||||
}
|
||||
|
||||
if (raw.get(F_LATITUDE) instanceof Double) {
|
||||
latitude = (Double) raw.get(F_LATITUDE);
|
||||
} else {
|
||||
throw Model.typeError(F_LATITUDE, raw.get(F_LATITUDE).getClass(), "Double");
|
||||
}
|
||||
|
||||
if (raw.get(F_LONGITUDE) instanceof Double) {
|
||||
longitude = (Double) raw.get(F_LONGITUDE);
|
||||
} else {
|
||||
throw Model.typeError(F_LONGITUDE, raw.get(F_LONGITUDE).getClass(), "Double");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The stop ID.
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The stop name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The stop indicator.
|
||||
*/
|
||||
public String getIndicator() {
|
||||
return indicator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The stop indicator.
|
||||
*/
|
||||
public Integer getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The stop geoloaction latitude.
|
||||
*/
|
||||
public Double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The stop geolocation longitude.
|
||||
*/
|
||||
public Double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 Stefan Kalscheuer
|
||||
* Copyright 2016-2018 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -22,9 +22,20 @@ import java.util.List;
|
||||
/**
|
||||
* Entity for a single trip.
|
||||
*
|
||||
* @author Stefan Kalscheuer <stefan@stklcode.de>
|
||||
* @author Stefan Kalscheuer
|
||||
*/
|
||||
public class Trip {
|
||||
public final class Trip implements Model {
|
||||
private static final int VISIT_ID = 7;
|
||||
private static final int LINE_ID = 8;
|
||||
private static final int LINE_NAME = 9;
|
||||
private static final int DIRECTION_ID = 10;
|
||||
private static final int DESTINATION_NAME = 11;
|
||||
private static final int DESTINATION_TEXT = 12;
|
||||
private static final int VEHICLE_ID = 13;
|
||||
private static final int TRIP_ID = 14;
|
||||
private static final int ESTIMATED_TIME = 15;
|
||||
private static final int NUM_OF_FIELDS = 16;
|
||||
|
||||
private final Stop stop;
|
||||
private final String id;
|
||||
private final Integer visitID;
|
||||
@ -36,13 +47,81 @@ public class Trip {
|
||||
private final Long estimatedTime;
|
||||
private final String vehicleID;
|
||||
|
||||
public Trip(String stopID, String stopName, String stopIndicator, Integer stopState, Double stopLatitude, Double stopLongitude,
|
||||
Integer visitID, String lineID, String lineName, Integer directionID, String destinationName, String destinationText, String vehicleID, String tripID, Long estimatedTime) {
|
||||
this(new Stop(stopID, stopName, stopIndicator, stopState, stopLatitude, stopLongitude),
|
||||
visitID, lineID, lineName, directionID, destinationName, destinationText, vehicleID, tripID, estimatedTime);
|
||||
/**
|
||||
* Construct Trip object from complete set of data.
|
||||
*
|
||||
* @param stopID Stop ID.
|
||||
* @param stopName Stop name.
|
||||
* @param stopIndicator Stop Indicator.
|
||||
* @param stopState Stop state.
|
||||
* @param stopLatitude Stop geolocation latitude.
|
||||
* @param stopLongitude Stop geolocation latitude.
|
||||
* @param visitID Visit ID.
|
||||
* @param lineID Line ID.
|
||||
* @param lineName Line name.
|
||||
* @param directionID Direction ID.
|
||||
* @param destinationName Destination name.
|
||||
* @param destinationText Destination text.
|
||||
* @param vehicleID Vehicle ID.
|
||||
* @param tripID Trip ID.
|
||||
* @param estimatedTime Estimated time.
|
||||
*/
|
||||
public Trip(final String stopID,
|
||||
final String stopName,
|
||||
final String stopIndicator,
|
||||
final Integer stopState,
|
||||
final Double stopLatitude,
|
||||
final Double stopLongitude,
|
||||
final Integer visitID,
|
||||
final String lineID,
|
||||
final String lineName,
|
||||
final Integer directionID,
|
||||
final String destinationName,
|
||||
final String destinationText,
|
||||
final String vehicleID,
|
||||
final String tripID,
|
||||
final Long estimatedTime) {
|
||||
this(new Stop(stopID,
|
||||
stopName,
|
||||
stopIndicator,
|
||||
stopState,
|
||||
stopLatitude,
|
||||
stopLongitude),
|
||||
visitID,
|
||||
lineID,
|
||||
lineName,
|
||||
directionID,
|
||||
destinationName,
|
||||
destinationText,
|
||||
vehicleID,
|
||||
tripID,
|
||||
estimatedTime);
|
||||
}
|
||||
|
||||
public Trip(Stop stop, Integer visitID, String lineID, String lineName, Integer directionID, String destinationName, String destinationText, String vehicleID, String tripID, Long estimatedTime) {
|
||||
/**
|
||||
* Construct Trip object from Stop model and set of additional data.
|
||||
*
|
||||
* @param stop Stop model
|
||||
* @param visitID Visit ID
|
||||
* @param lineID Line ID
|
||||
* @param lineName Line name
|
||||
* @param directionID Direction ID
|
||||
* @param destinationName Destination name
|
||||
* @param destinationText Destination text
|
||||
* @param vehicleID Vehicle ID
|
||||
* @param tripID Trip ID
|
||||
* @param estimatedTime Estimated time
|
||||
*/
|
||||
public Trip(final Stop stop,
|
||||
final Integer visitID,
|
||||
final String lineID,
|
||||
final String lineName,
|
||||
final Integer directionID,
|
||||
final String destinationName,
|
||||
final String destinationText,
|
||||
final String vehicleID,
|
||||
final String tripID,
|
||||
final Long estimatedTime) {
|
||||
this.stop = stop;
|
||||
this.visitID = visitID;
|
||||
this.lineID = lineID;
|
||||
@ -55,86 +134,159 @@ public class Trip {
|
||||
this.estimatedTime = estimatedTime;
|
||||
}
|
||||
|
||||
public Trip(List raw) throws IOException {
|
||||
if (raw == null || raw.size() < 16)
|
||||
/**
|
||||
* Construct Trip object from raw list of attributes parsed from JSON.
|
||||
*
|
||||
* @param raw List of attributes from JSON line
|
||||
* @throws IOException Thrown on invalid line format.
|
||||
*/
|
||||
public Trip(final List raw) throws IOException {
|
||||
this(raw, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Stop object from raw list of attributes parsed from JSON with explicitly specified version.
|
||||
*
|
||||
* @param raw List of attributes from JSON line
|
||||
* @param version API version
|
||||
* @throws IOException Thrown on invalid line format.
|
||||
*/
|
||||
public Trip(final List raw, final String version) throws IOException {
|
||||
if (raw == null || raw.size() < NUM_OF_FIELDS) {
|
||||
throw new IOException("Invalid number of fields");
|
||||
}
|
||||
|
||||
stop = new Stop(raw);
|
||||
|
||||
if (raw.get(7) instanceof Integer)
|
||||
visitID = (Integer) raw.get(7);
|
||||
else
|
||||
throw new IOException("Field 7 not of expected type Integer, found " + raw.get(7).getClass().getSimpleName());
|
||||
if (raw.get(8) instanceof String)
|
||||
lineID = (String)raw.get(8);
|
||||
else
|
||||
throw new IOException("Field 8 not of expected type String, found " + raw.get(8).getClass().getSimpleName());
|
||||
if (raw.get(9) instanceof String)
|
||||
lineName = (String)raw.get(9);
|
||||
else
|
||||
throw new IOException("Field 9 not of expected type String, found " + raw.get(9).getClass().getSimpleName());
|
||||
if (raw.get(10) instanceof Integer)
|
||||
directionID = (Integer)raw.get(10);
|
||||
else
|
||||
throw new IOException("Field 10 not of expected type Integer, found " + raw.get(10).getClass().getSimpleName());
|
||||
if (raw.get(11) instanceof String)
|
||||
destinationName = (String)raw.get(11);
|
||||
else
|
||||
throw new IOException("Field 11 not of expected type String, found " + raw.get(11).getClass().getSimpleName());
|
||||
if (raw.get(12) instanceof String)
|
||||
destinationText = (String)raw.get(12);
|
||||
else
|
||||
throw new IOException("Field 12 not of expected type String, found " + raw.get(12).getClass().getSimpleName());
|
||||
if (raw.get(13) instanceof String)
|
||||
vehicleID = (String)raw.get(13);
|
||||
else
|
||||
throw new IOException("Field 13 not of expected type String, found " + raw.get(13).getClass().getSimpleName());
|
||||
if (raw.get(14) instanceof String)
|
||||
id = (String)raw.get(14);
|
||||
else
|
||||
throw new IOException("Field 14 not of expected type String, found " + raw.get(14).getClass().getSimpleName());
|
||||
if (raw.get(15) instanceof Long)
|
||||
estimatedTime = (Long)raw.get(15);
|
||||
else
|
||||
throw new IOException("Field 15 not of expected type Long, found " + raw.get(15).getClass().getSimpleName());
|
||||
if (raw.get(VISIT_ID) instanceof Integer) {
|
||||
visitID = (Integer) raw.get(VISIT_ID);
|
||||
} else {
|
||||
throw Model.typeError(VISIT_ID, raw.get(VISIT_ID).getClass(), "Integer");
|
||||
}
|
||||
|
||||
if (raw.get(LINE_ID) instanceof String) {
|
||||
lineID = (String) raw.get(LINE_ID);
|
||||
} else {
|
||||
throw Model.typeErrorString(LINE_ID, raw.get(LINE_ID).getClass());
|
||||
}
|
||||
|
||||
if (raw.get(LINE_NAME) instanceof String) {
|
||||
lineName = (String) raw.get(LINE_NAME);
|
||||
} else {
|
||||
throw Model.typeErrorString(LINE_NAME, raw.get(LINE_NAME).getClass());
|
||||
}
|
||||
|
||||
if (raw.get(DIRECTION_ID) instanceof Integer) {
|
||||
directionID = (Integer) raw.get(DIRECTION_ID);
|
||||
if (directionID < 0 || directionID > 2) {
|
||||
throw new IOException("Direction out of range. Expected 1 or 2, found " + directionID);
|
||||
}
|
||||
} else {
|
||||
throw Model.typeError(DIRECTION_ID, raw.get(DIRECTION_ID).getClass(), "Integer");
|
||||
}
|
||||
|
||||
if (raw.get(DESTINATION_NAME) instanceof String) {
|
||||
destinationName = (String) raw.get(DESTINATION_NAME);
|
||||
} else {
|
||||
throw Model.typeErrorString(DESTINATION_NAME, raw.get(DESTINATION_NAME).getClass());
|
||||
}
|
||||
|
||||
if (raw.get(DESTINATION_TEXT) instanceof String) {
|
||||
destinationText = (String) raw.get(DESTINATION_TEXT);
|
||||
} else {
|
||||
throw Model.typeErrorString(DESTINATION_TEXT, raw.get(DESTINATION_TEXT).getClass());
|
||||
}
|
||||
|
||||
/* TFL and ASEAG deliver different types with the same API version, so this field is a little more tolerant */
|
||||
if (raw.get(VEHICLE_ID) instanceof String
|
||||
|| raw.get(VEHICLE_ID) instanceof Integer
|
||||
|| raw.get(VEHICLE_ID) instanceof Long) {
|
||||
vehicleID = raw.get(VEHICLE_ID).toString();
|
||||
} else {
|
||||
throw Model.typeError(VEHICLE_ID, raw.get(VEHICLE_ID).getClass(), "String/Integer/Long");
|
||||
}
|
||||
|
||||
if (raw.get(TRIP_ID) instanceof String
|
||||
|| raw.get(TRIP_ID) instanceof Integer
|
||||
|| raw.get(TRIP_ID) instanceof Long) {
|
||||
id = raw.get(TRIP_ID).toString();
|
||||
} else {
|
||||
throw Model.typeError(TRIP_ID, raw.get(TRIP_ID).getClass(), "String/Integer/Long");
|
||||
}
|
||||
|
||||
if (raw.get(ESTIMATED_TIME) instanceof Long) {
|
||||
estimatedTime = (Long) raw.get(ESTIMATED_TIME);
|
||||
} else {
|
||||
throw Model.typeError(ESTIMATED_TIME, raw.get(ESTIMATED_TIME).getClass(), "Long");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The (starting) stop.
|
||||
*/
|
||||
public Stop getStop() {
|
||||
return stop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The trip ID.
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The visit ID.
|
||||
*/
|
||||
public Integer getVisitID() {
|
||||
return visitID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The line ID.
|
||||
*/
|
||||
public String getLineID() {
|
||||
return lineID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The line name.
|
||||
*/
|
||||
public String getLineName() {
|
||||
return lineName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The direction ID.
|
||||
*/
|
||||
public Integer getDirectionID() {
|
||||
return directionID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The destination name.
|
||||
*/
|
||||
public String getDestinationName() {
|
||||
return destinationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The destination text.
|
||||
*/
|
||||
public String getDestinationText() {
|
||||
return destinationText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The estimated departure time.
|
||||
*/
|
||||
public Long getEstimatedTime() {
|
||||
return estimatedTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The vehicle ID.
|
||||
*/
|
||||
public String getVehicleID() {
|
||||
return vehicleID;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 Stefan Kalscheuer
|
||||
* Copyright 2016-2018 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -32,12 +32,16 @@ import java.util.Optional;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
/**
|
||||
* Unit test for the URA Client.
|
||||
* Tests run against mocked data collected from hte ASEAG API (http://ivu.aseag.de/)
|
||||
* Tests run against mocked data collected from ASEAG API (http://ivu.aseag.de) and
|
||||
* TFL API (http://http://countdown.api.tfl.gov.uk)
|
||||
*
|
||||
* @author Stefan Kalscheuer
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ UraClient.class, URL.class })
|
||||
@ -47,7 +51,8 @@ public class UraClientTest {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_stops.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V2_stops.txt"));
|
||||
|
||||
/* List stops and verify some values */
|
||||
List<Stop> stops = new UraClient("mocked").getStops();
|
||||
@ -65,9 +70,13 @@ public class UraClientTest {
|
||||
throw new IOException("Provoked exception 1.");
|
||||
}
|
||||
});
|
||||
assertThat(new UraClient("mocked").getStops(), hasSize(0));
|
||||
PowerMockito.when(mockURL.openStream()).thenThrow(new IOException("Provoked exception 2."));
|
||||
assertThat(new UraClient("mocked").getStops(), hasSize(0));
|
||||
try {
|
||||
new UraClient("mocked").getStops();
|
||||
} catch (RuntimeException e) {
|
||||
assertThat(e, is(instanceOf(IllegalStateException.class)));
|
||||
assertThat(e.getCause(), is(instanceOf(IOException.class)));
|
||||
assertThat(e.getCause().getMessage(), is("Provoked exception 1."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -75,7 +84,8 @@ public class UraClientTest {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_stops_line.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V2_stops_line.txt"));
|
||||
|
||||
/* List stops and verify some values */
|
||||
List<Stop> stops = new UraClient("mocked").forLines("33").getStops();
|
||||
@ -88,12 +98,89 @@ public class UraClientTest {
|
||||
assertThat(stops.get(5).getLongitude(), is(6.2314072));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getStopsForPositionTest() throws Exception {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_stops_circle.txt"));
|
||||
|
||||
/* List stops and verify some values */
|
||||
List<Stop> stops = new UraClient("mocked")
|
||||
.forPosition(51.51009, -0.1345734, 200)
|
||||
.getStops();
|
||||
assertThat(stops, hasSize(13));
|
||||
assertThat(stops.get(0).getId(), is("156"));
|
||||
assertThat(stops.get(1).getName(), is("Piccadilly Circus"));
|
||||
assertThat(stops.get(2).getState(), is(0));;
|
||||
assertThat(stops.get(3).getLatitude(), is(51.509154));
|
||||
assertThat(stops.get(4).getLongitude(), is(-0.134172));
|
||||
assertThat(stops.get(5).getIndicator(), is(nullValue()));
|
||||
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_stops_circle_name.txt"));
|
||||
stops = new UraClient("mocked")
|
||||
.forStopsByName("Piccadilly Circus")
|
||||
.forPosition(51.51009, -0.1345734, 200)
|
||||
.getStops();
|
||||
assertThat(stops, hasSize(7));
|
||||
assertThat(stops.stream().filter(t -> !t.getName().equals("Piccadilly Circus")).findAny(), is(Optional.empty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTripsForDestinationNamesTest() throws Exception {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_destination.txt"));
|
||||
|
||||
/* List stops and verify some values */
|
||||
List<Trip> trips = new UraClient("mocked").forDestinationNames("Piccadilly Circus").getTrips();
|
||||
assertThat(trips, hasSize(9));
|
||||
assertThat(trips.stream().filter(t -> !t.getDestinationName().equals("Piccadilly Cir")).findAny(),
|
||||
is(Optional.empty()));
|
||||
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_stop_destination.txt"));
|
||||
trips = new UraClient("mocked")
|
||||
.forStops("156")
|
||||
.forDestinationNames("Marble Arch")
|
||||
.getTrips();
|
||||
assertThat(trips, hasSize(5));
|
||||
assertThat(trips.stream().filter(t -> !t.getStop().getId().equals("156")).findAny(),
|
||||
is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getDestinationName().equals("Marble Arch")).findAny(),
|
||||
is(Optional.empty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTripsTowardsTest() throws Exception {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_towards.txt"));
|
||||
|
||||
/* List stops and verify some values */
|
||||
List<Trip> trips = new UraClient("mocked").towards("Marble Arch").getTrips();
|
||||
assertThat(trips, hasSize(10));
|
||||
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_stop_towards.txt"));
|
||||
trips = new UraClient("mocked").forStops("156").towards("Marble Arch").getTrips();
|
||||
assertThat(trips, hasSize(17));
|
||||
assertThat(trips.stream().filter(t -> !t.getStop().getId().equals("156")).findAny(), is(Optional.empty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTripsTest() throws Exception {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_all.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_all.txt"));
|
||||
|
||||
/* Get trips without filters and verify some values */
|
||||
List<Trip> trips = new UraClient("mocked").getTrips();
|
||||
@ -109,8 +196,26 @@ public class UraClientTest {
|
||||
assertThat(trips.get(8).getVisitID(), is(30));
|
||||
assertThat(trips.get(9).getStop().getId(), is("100002"));
|
||||
|
||||
/* Repeat test for API V2 */
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V2_trips_all.txt"));
|
||||
/* Get trips without filters and verify some values */
|
||||
trips = new UraClient("mocked").getTrips();
|
||||
assertThat(trips, hasSize(10));
|
||||
assertThat(trips.get(0).getId(), is("27000165015001"));
|
||||
assertThat(trips.get(1).getLineID(), is("55"));
|
||||
assertThat(trips.get(2).getLineName(), is("28"));;
|
||||
assertThat(trips.get(3).getDirectionID(), is(1));
|
||||
assertThat(trips.get(4).getDestinationName(), is("Verlautenheide Endstr."));
|
||||
assertThat(trips.get(5).getDestinationText(), is("Aachen Bushof"));
|
||||
assertThat(trips.get(6).getVehicleID(), is("247"));
|
||||
assertThat(trips.get(7).getEstimatedTime(), is(1482854580000L));
|
||||
assertThat(trips.get(8).getVisitID(), is(30));
|
||||
assertThat(trips.get(9).getStop().getId(), is("100002"));
|
||||
|
||||
/* Get limited number of trips */
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_all.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_all.txt"));
|
||||
trips = new UraClient("mocked").getTrips(5);
|
||||
assertThat(trips, hasSize(5));
|
||||
|
||||
@ -121,9 +226,13 @@ public class UraClientTest {
|
||||
throw new IOException("Provoked exception 1.");
|
||||
}
|
||||
});
|
||||
assertThat(new UraClient("mocked").getTrips(), hasSize(0));
|
||||
PowerMockito.when(mockURL.openStream()).thenThrow(new IOException("Provoked exception 2."));
|
||||
assertThat(new UraClient("mocked").getTrips(), hasSize(0));
|
||||
try {
|
||||
new UraClient("mocked").getTrips();
|
||||
} catch (RuntimeException e) {
|
||||
assertThat(e, is(instanceOf(IllegalStateException.class)));
|
||||
assertThat(e.getCause(), is(instanceOf(IOException.class)));
|
||||
assertThat(e.getCause().getMessage(), is("Provoked exception 1."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -131,7 +240,8 @@ public class UraClientTest {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_stop.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_stop.txt"));
|
||||
|
||||
/* Get trips for stop ID 100000 (Aachen Bushof) and verify some values */
|
||||
List<Trip> trips = new UraClient("mocked")
|
||||
@ -145,12 +255,14 @@ public class UraClientTest {
|
||||
assertThat(trips.get(3).getStop().getIndicator(), is("H.15"));
|
||||
|
||||
/* Get trips for stop name "Uniklinik" and verify some values */
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_stop_name.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_stop_name.txt"));
|
||||
trips = new UraClient("mocked")
|
||||
.forStopsByName("Uniklinik")
|
||||
.getTrips();
|
||||
assertThat(trips, hasSize(10));
|
||||
assertThat(trips.stream().filter(t -> !t.getStop().getName().equals("Uniklinik")).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getStop().getName().equals("Uniklinik")).findAny(),
|
||||
is(Optional.empty()));
|
||||
assertThat(trips.get(0).getId(), is("92000043013001"));
|
||||
assertThat(trips.get(1).getLineID(), is("5"));
|
||||
assertThat(trips.get(2).getVehicleID(), is("317"));;
|
||||
@ -162,7 +274,8 @@ public class UraClientTest {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_line.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_line.txt"));
|
||||
|
||||
/* Get trips for line ID 3 and verify some values */
|
||||
List<Trip> trips = new UraClient("mocked")
|
||||
@ -176,7 +289,8 @@ public class UraClientTest {
|
||||
assertThat(trips.get(3).getStop().getIndicator(), is("H.4 (Pontwall)"));
|
||||
|
||||
/* Get trips for line name "3.A" and verify some values */
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_line_name.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_line_name.txt"));
|
||||
trips = new UraClient("mocked")
|
||||
.forLinesByName("3.A")
|
||||
.getTrips();
|
||||
@ -188,24 +302,26 @@ public class UraClientTest {
|
||||
assertThat(trips.get(3).getStop().getName(), is("Aachen Gartenstraße"));
|
||||
|
||||
/* Get trips for line 3 with direction 1 and verify some values */
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_line_direction.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_line_direction.txt"));
|
||||
trips = new UraClient("mocked")
|
||||
.forLines("3")
|
||||
.forDirection(1)
|
||||
.forLines("412")
|
||||
.forDirection(2)
|
||||
.getTrips();
|
||||
assertThat(trips, hasSize(10));
|
||||
assertThat(trips.stream().filter(t -> !t.getLineID().equals("3")).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getDirectionID().equals(1)).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getLineID().equals("412")).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getDirectionID().equals(2)).findAny(), is(Optional.empty()));
|
||||
|
||||
/* Test lineID and direction in different order */
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_line_direction.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_line_direction.txt"));
|
||||
trips = new UraClient("mocked")
|
||||
.forDirection(1)
|
||||
.forLines("3")
|
||||
.forDirection(2)
|
||||
.forLines("412")
|
||||
.getTrips();
|
||||
assertThat(trips, hasSize(10));
|
||||
assertThat(trips.stream().filter(t -> !t.getLineID().equals("3")).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getDirectionID().equals(1)).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getLineID().equals("412")).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getDirectionID().equals(2)).findAny(), is(Optional.empty()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -213,7 +329,8 @@ public class UraClientTest {
|
||||
/* Mock the HTTP call */
|
||||
URL mockURL = PowerMockito.mock(URL.class);
|
||||
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
|
||||
PowerMockito.when(mockURL.openStream()).thenReturn(getClass().getResourceAsStream("instant_trips_stop_line.txt"));
|
||||
PowerMockito.when(mockURL.openStream())
|
||||
.thenReturn(getClass().getResourceAsStream("instant_V1_trips_stop_line.txt"));
|
||||
|
||||
/* Get trips for line ID 25 and 25 at stop 100000 and verify some values */
|
||||
List<Trip> trips = new UraClient("mocked")
|
||||
@ -221,7 +338,8 @@ public class UraClientTest {
|
||||
.forStops("100000")
|
||||
.getTrips();
|
||||
assertThat(trips, hasSize(10));
|
||||
assertThat(trips.stream().filter(t -> !t.getLineID().equals("25") && !t.getLineID().equals("35")).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getLineID().equals("25") && !t.getLineID().equals("35")).findAny(),
|
||||
is(Optional.empty()));
|
||||
assertThat(trips.stream().filter(t -> !t.getStop().getId().equals("100000")).findAny(), is(Optional.empty()));
|
||||
assertThat(trips.get(0).getId(), is("27000078014001"));
|
||||
assertThat(trips.get(1).getLineID(), is("25"));
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2016-2018 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package de.stklcode.pubtrans.ura.model;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -15,7 +31,7 @@ import static org.junit.Assert.fail;
|
||||
/**
|
||||
* Unit test for the Stop metamodel.
|
||||
*
|
||||
* @author Stefan Kalscheuer <stefan@stklcode.de>
|
||||
* @author Stefan Kalscheuer
|
||||
*/
|
||||
public class StopTest {
|
||||
@Test
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2016-2018 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package de.stklcode.pubtrans.ura.model;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -15,13 +31,26 @@ import static org.junit.Assert.fail;
|
||||
/**
|
||||
* Unit test for the Trip metamodel.
|
||||
*
|
||||
* @author Stefan Kalscheuer <stefan@stklcode.de>
|
||||
* @author Stefan Kalscheuer
|
||||
*/
|
||||
public class TripTest {
|
||||
@Test
|
||||
public void basicConstructorTest() {
|
||||
Trip trip = new Trip("sid", "name", "indicator", 1, 2.345, 6.789,
|
||||
123, "lineid", "linename", 0, "destination name", "destination text", "vehicle", "id", 123456789123456789L);
|
||||
Trip trip = new Trip("sid",
|
||||
"name",
|
||||
"indicator",
|
||||
1,
|
||||
2.345,
|
||||
6.789,
|
||||
123,
|
||||
"lineid",
|
||||
"linename",
|
||||
0,
|
||||
"destination name",
|
||||
"destination text",
|
||||
"vehicle",
|
||||
"id",
|
||||
123456789123456789L);
|
||||
assertThat(trip.getStop().getId(), is("sid"));
|
||||
assertThat(trip.getStop().getName(), is("name"));
|
||||
assertThat(trip.getStop().getIndicator(), is("indicator"));
|
||||
@ -57,7 +86,7 @@ public class TripTest {
|
||||
raw.add("destination name");
|
||||
raw.add("destination text");
|
||||
raw.add("vehicle");
|
||||
raw.add("id");
|
||||
raw.add(9876543210L);
|
||||
raw.add(123456789123456789L);
|
||||
|
||||
try {
|
||||
@ -75,12 +104,22 @@ public class TripTest {
|
||||
assertThat(trip.getDestinationName(), is("destination name"));
|
||||
assertThat(trip.getDestinationText(), is("destination text"));
|
||||
assertThat(trip.getVehicleID(), is("vehicle"));
|
||||
assertThat(trip.getId(), is("id"));
|
||||
assertThat(trip.getId(), is("9876543210"));
|
||||
assertThat(trip.getEstimatedTime(), is(123456789123456789L));
|
||||
} catch (IOException e) {
|
||||
fail("Creation of Trip from valid list failed: " + e.getMessage());
|
||||
}
|
||||
|
||||
/* Test with V2 style list */
|
||||
raw.set(14, "id");
|
||||
try {
|
||||
Trip trip = new Trip(raw, "2.0");
|
||||
assertThat(trip.getId(), is("id"));
|
||||
} catch (IOException e) {
|
||||
fail("Creation of Trip from valid list failed: " + e.getMessage());
|
||||
}
|
||||
raw.set(14, 9876543210L);
|
||||
|
||||
/* Excess elements should be ignored */
|
||||
raw.add("foo");
|
||||
try {
|
||||
@ -164,7 +203,7 @@ public class TripTest {
|
||||
|
||||
invalid = new ArrayList<>(raw);
|
||||
invalid.remove(14);
|
||||
invalid.add(14, 123);
|
||||
invalid.add(14, 1.2);
|
||||
try {
|
||||
new Trip(invalid);
|
||||
fail("Creation of Trip with invalid id field successfull");
|
||||
@ -190,5 +229,14 @@ public class TripTest {
|
||||
} catch (Exception e) {
|
||||
assertThat(e, is(instanceOf(IOException.class)));
|
||||
}
|
||||
|
||||
invalid = new ArrayList<>(raw);
|
||||
invalid.set(10, 3);
|
||||
try {
|
||||
new Trip(invalid);
|
||||
fail("Creation of Trip with direction ID 3 successfull");
|
||||
} catch (Exception e) {
|
||||
assertThat(e, is(instanceOf(IOException.class)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
[4,"1.0",1483808583971]
|
||||
[0,"Piccadilly Circus","156","D",0,51.509822,-0.136967]
|
||||
[0,"Piccadilly Circus","149","G",0,51.51006,-0.135545]
|
||||
[0,"Piccadilly Circus","155","C",0,51.50986,-0.135971]
|
||||
[0,"Piccadilly Circus","34716","S",0,51.509154,-0.136245]
|
||||
[0,"Trocadero / Haymarket","161","H",0,51.510515,-0.134172]
|
||||
[0,"Piccadilly Circus, Haymarket","PCIRHM S",null,0,51.509709,-0.13272]
|
||||
[0,"Regent Street / St James's","17683","Z",0,51.508732,-0.134043]
|
||||
[0,"Regent Street / St James's","154","Y",0,51.508942,-0.134207]
|
||||
[0,"Piccadilly Circus","BP5840","E",0,51.509882,-0.137325]
|
||||
[0,"Piccadilly Circus","150","F",0,51.509894,-0.136402]
|
||||
[0,"Trocadero / Haymarket","37229","K",0,51.511194,-0.133366]
|
||||
[0,"Piccadilly Circus","37122","B",0,51.509306,-0.13621]
|
||||
[0,"Haymarket / Jermyn Street","29867","R",0,51.509691,-0.132706]
|
@ -0,0 +1,8 @@
|
||||
[4,"1.0",1483808692732]
|
||||
[0,"Piccadilly Circus","156","D",0,51.509822,-0.136967]
|
||||
[0,"Piccadilly Circus","149","G",0,51.51006,-0.135545]
|
||||
[0,"Piccadilly Circus","155","C",0,51.50986,-0.135971]
|
||||
[0,"Piccadilly Circus","34716","S",0,51.509154,-0.136245]
|
||||
[0,"Piccadilly Circus","BP5840","E",0,51.509882,-0.137325]
|
||||
[0,"Piccadilly Circus","150","F",0,51.509894,-0.136402]
|
||||
[0,"Piccadilly Circus","37122","B",0,51.509306,-0.13621]
|
@ -0,0 +1,10 @@
|
||||
[4,"1.0",1483809193233]
|
||||
[1,"New Bond Street","829","OE",0,51.514814,-0.146117,1,"94","94",1,"Piccadilly Cir","Piccadilly Circus",15925,443778,1483810113000]
|
||||
[1,"New Bond Street","829","OE",0,51.514814,-0.146117,1,"94","94",1,"Piccadilly Cir","Piccadilly Circus",15209,443756,1483810614000]
|
||||
[1,"Hobury Street / Worlds End","11296","QH",0,51.482463,-0.179129,1,"22","22",1,"Piccadilly Cir","Piccadilly Circus",8923,390782,1483810037000]
|
||||
[1,"Abinger Road","11333",null,0,51.496971,-0.24965,1,"94","94",1,"Piccadilly Cir","Piccadilly Circus",15554,444015,1483809664000]
|
||||
[1,"Knightsbridge Station","210","KJ",0,51.500899,-0.160183,1,"22","22",1,"Piccadilly Cir","Piccadilly Circus",7988,392720,1483810456000]
|
||||
[1,"Piccadilly Circus","37122","B",0,51.509306,-0.13621,1,"22","22",1,"Piccadilly Cir","Piccadilly Circus",8027,502319,1483809941000]
|
||||
[1,"Edith Grove / Worlds End","37444",null,0,51.481603,-0.182217,1,"22","22",1,"Piccadilly Cir","Piccadilly Circus",8015,392809,1483810291000]
|
||||
[1,"Selfridges","153","BB",0,51.514067,-0.152921,1,"94","94",1,"Piccadilly Cir","Piccadilly Circus",15105,444021,1483809200000]
|
||||
[1,"Edith Grove / Worlds End","37444",null,0,51.481603,-0.182217,1,"22","22",1,"Piccadilly Cir","Piccadilly Circus",7988,392720,1483809409000]
|
@ -1,11 +1,11 @@
|
||||
[4,"2.0",1482854839773]
|
||||
[1,"Seffenter Weg","100643","",0,50.7820069,6.0644119,19,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","317","27000154004001",1482855824000]
|
||||
[1,"Normaluhr","100009","H.5 (Wilhelmstr.)",0,50.7680616,6.094883,9,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","226","27000134003001",1482855960000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,5,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","226","27000134002001",1482854820000]
|
||||
[1,"Ponttor","100005","H.4 (Pontwall)",0,50.7808611,6.0779722,15,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","226","27000134003001",1482856500000]
|
||||
[1,"Stiewistraße","100630","",0,50.78029,6.05058,25,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","226","27000134004001",1482859800000]
|
||||
[1,"Misereor","100010","",0,50.7685583,6.0833027,7,"3","3.A",1,"Hbf.-Ponttor-Uniklinik","Hbf.-Ponttor-Uniklinik","0","27000134005001",1482861060000]
|
||||
[1,"Wendlingweg","100646","",0,50.7773216,6.0504405,26,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","338","27000128004001",1482858060000]
|
||||
[1,"Hörn Brücke","100627","",0,50.7871194,6.051875,22,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0","27000141015001",1482861420000]
|
||||
[1,"Forckenbeckstraße","100628","",0,50.78534,6.05054,23,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","338","27000128003001",1482855127000]
|
||||
[1,"Hörn Brücke","100627","",0,50.7871194,6.051875,22,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","338","27000128003001",1482855067000]
|
||||
[1,"Seffenter Weg","100643","",0,50.7820069,6.0644119,19,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","317",27000154004001,1482855824000]
|
||||
[1,"Normaluhr","100009","H.5 (Wilhelmstr.)",0,50.7680616,6.094883,9,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","226",27000134003001,1482855960000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,5,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","226",27000134002001,1482854820000]
|
||||
[1,"Ponttor","100005","H.4 (Pontwall)",0,50.7808611,6.0779722,15,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","226",27000134003001,1482856500000]
|
||||
[1,"Stiewistraße","100630","",0,50.78029,6.05058,25,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","226",27000134004001,1482859800000]
|
||||
[1,"Misereor","100010","",0,50.7685583,6.0833027,7,"3","3.A",1,"Hbf.-Ponttor-Uniklinik","Hbf.-Ponttor-Uniklinik","0",27000134005001,1482861060000]
|
||||
[1,"Wendlingweg","100646","",0,50.7773216,6.0504405,26,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","338",27000128004001,1482858060000]
|
||||
[1,"Hörn Brücke","100627","",0,50.7871194,6.051875,22,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0",27000141015001,1482861420000]
|
||||
[1,"Forckenbeckstraße","100628","",0,50.78534,6.05054,23,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","338",27000128003001,1482855127000]
|
||||
[1,"Hörn Brücke","100627","",0,50.7871194,6.051875,22,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","338",27000128003001,1482855067000]
|
@ -0,0 +1,11 @@
|
||||
[4,"1.0",1483806258560]
|
||||
[1,"Lower Barn Road","16637",null,0,51.330106,-0.093099,1,"412","412",2,"Purley","Purley",3469,653171,1483807114000]
|
||||
[1,"Sanderstead Plantation","23493",null,0,51.339851,-0.069809,1,"412","412",2,"Purley","Purley",2161,653155,1483807649000]
|
||||
[1,"Christchurch Road / Purley Hospital","10825","E",0,51.340668,-0.113337,1,"412","412",2,"Purley","Purley",3146,653175,1483806540000]
|
||||
[1,"Ridge Langley","20396",null,0,51.346848,-0.072013,1,"412","412",2,"Purley","Purley",2161,653155,1483807260000]
|
||||
[1,"Purley / Downlands Precinct","4396","D",0,51.339165,-0.116083,1,"412","412",2,"Purley","Purley",3469,653171,1483807453000]
|
||||
[1,"Coombe Road","10829","W",0,51.368209,-0.099175,1,"412","412",2,"Purley","Purley",2161,653155,1483806733000]
|
||||
[1,"Ruskin Parade / South Croydon Station","4415","F",0,51.363068,-0.097132,1,"412","412",2,"Purley","Purley",1554,653151,1483807590000]
|
||||
[1,"Sussex Road","18810","GP",0,51.359344,-0.093811,1,"412","412",2,"Purley","Purley",1554,653151,1483807686000]
|
||||
[1,"Farley Road","26185","Z",0,51.342569,-0.063937,1,"412","412",2,"Purley","Purley",1554,653151,1483808161000]
|
||||
[1,"Sanderstead Plantation","23493",null,0,51.339851,-0.069809,1,"412","412",2,"Purley","Purley",3469,653171,1483806820000]
|
@ -0,0 +1,11 @@
|
||||
[4,"2.0",1483362794677]
|
||||
[1,"Westbahnhof","100641","H.2",0,50.7805372,6.0719672,17,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0",92000288014001,1483367880000]
|
||||
[1,"Aachen Gartenstraße","100601","",0,50.7704169,6.0695841,4,"3","3.A",1,"Schanz-Hbf.-Ponttor","Schanz-Hbf.-Ponttor","0",92000058014001,1483368360000]
|
||||
[1,"Schanz","100012","H.2 (Boxgraben)",0,50.76891,6.074498,5,"3","3.A",1,"Hbf.-Ponttor-Uniklinik","Hbf.-Ponttor-Uniklinik","0",92000288015001,1483369380000]
|
||||
[1,"Aachen Gartenstraße","100601","",0,50.7704169,6.0695841,4,"3","3.A",1,"Schanz-Hbf.-Ponttor","Schanz-Hbf.-Ponttor","327",92000289012001,1483363045000]
|
||||
[1,"Kastanienweg","100631","",0,50.7854908,6.0547602,21,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0",92000058014001,1483369860000]
|
||||
[1,"Eurogress","100007","",0,50.7807852,6.0900738,13,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","327",92000289012001,1483363994000]
|
||||
[1,"Augustastraße","100008","",0,50.7731333,6.0959027,10,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","0",92000288014001,1483367280000]
|
||||
[1,"Hörn Brücke","100627","",0,50.7871194,6.051875,22,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0",92000279013001,1483369020000]
|
||||
[1,"Audimax","100029","",0,50.7802655,6.0752138,16,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0",92000058014001,1483369560000]
|
||||
[1,"Aachen Hauptbahnhof","100004","H.1",0,50.7687027,6.0906277,8,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","0",92000288014001,1483367040000]
|
@ -0,0 +1,11 @@
|
||||
[4,"2.0",1482854457011]
|
||||
[1,"Aachen Bushof","100000","H.13",0,50.7775936,6.0908191,20,"1","1",1,"Schevenhütte","Schevenhütte","565",27000158010001,1482854446000]
|
||||
[1,"Aachen Bushof","100000","H.2",0,50.7775936,6.0908191,8,"7","7",1,"Aachen Bushof","Aachen Bushof","514",27000210017001,1482854400000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","0",27000171010001,1482854460000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,17,"47","47",1,"Aachen Bushof","Aachen Bushof","258",27000139003001,1482854460000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,1,"7","7",1,"Aachen Diepenbenden","Aachen Diepenbenden","257",27000089026001,1482854454000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,17,"2","2",1,"Eilendorf Schubertstr.","Eilendorf Schubertstr.","221",27000039021001,1482854445000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,28,"12","12",1,"Campus Melaten","Campus Melaten","298",27000062010001,1482854451000]
|
||||
[1,"Aachen Bushof","100000","H.1",0,50.7775936,6.0908191,27,"51","51",1,"Aachen Bushof","Aachen Bushof","603",27000230015001,1482854801000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,1,"43","43",1,"Hüls Schulz+Elleter F.","Hüls Schulz+Elleter F.","258",27000139004001,1482854520000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,25,"33","33",1,"Aachen Fuchserde","Aachen Fuchserde","286",27000033017001,1482854459000]
|
@ -0,0 +1,6 @@
|
||||
[4,"1.0",1483809267076]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16588,309783,1483809502000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16589,239190,1483809796000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16211,310616,1483810325000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16549,238574,1483810733000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16213,216852,1483810840000]
|
@ -1,11 +1,11 @@
|
||||
[4,"2.0",1482855134910]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,32,"35","35",1,"Vaals Grenze","Vaals Grenze","346","27000078014001",1482855350000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,15,"25","25",1,"Stolberg Mühlener Bf.","Stolberg Mühlener Bf.","334","27000268014001",1482856194000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","242","27000270010001",1482856248000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,14,"35","35",1,"Breinig Entengasse","Breinig Entengasse","248","27000074012001",1482856740000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,32,"35","35",1,"Vaals Grenze","Vaals Grenze","294","27000076010001",1482857507000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,15,"25","25",1,"Stolberg Mühlener Bf.","Stolberg Mühlener Bf.","0","27000171011001",1482857640000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","191","27000032012001",1482858057000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,14,"35","35",1,"Breinig Entengasse","Breinig Entengasse","346","27000078015001",1482858540000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,15,"25","25",1,"Stolberg Mühlener Bf.","Stolberg Mühlener Bf.","242","27000270011001",1482859440000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","187","27000060013001",1482859860000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,32,"35","35",1,"Vaals Grenze","Vaals Grenze","346",27000078014001,1482855350000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,15,"25","25",1,"Stolberg Mühlener Bf.","Stolberg Mühlener Bf.","334",27000268014001,1482856194000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","242",27000270010001,1482856248000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,14,"35","35",1,"Breinig Entengasse","Breinig Entengasse","248",27000074012001,1482856740000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,32,"35","35",1,"Vaals Grenze","Vaals Grenze","294",27000076010001,1482857507000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,15,"25","25",1,"Stolberg Mühlener Bf.","Stolberg Mühlener Bf.","0",27000171011001,1482857640000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","191",27000032012001,1482858057000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,14,"35","35",1,"Breinig Entengasse","Breinig Entengasse","346",27000078015001,1482858540000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,15,"25","25",1,"Stolberg Mühlener Bf.","Stolberg Mühlener Bf.","242",27000270011001,1482859440000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","187",27000060013001,1482859860000]
|
@ -0,0 +1,11 @@
|
||||
[4,"2.0",1483362959788]
|
||||
[1,"Uniklinik","100600","H.2",0,50.7756388,6.04425,11,"33","33",1,"Aachen Fuchserde","Aachen Fuchserde","318",92000043013001,1483362935000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,1,"5","5",1,"Driescher Hof-Brand","Driescher Hof-Brand","312",92000282009001,1483362936000]
|
||||
[1,"Uniklinik","100600","H.4",0,50.7756388,6.04425,33,"45","45",1,"Uniklinik","Uniklinik","317",92000285009001,1483363294000]
|
||||
[1,"Uniklinik","100600","H.3",0,50.7756388,6.04425,28,"10","3.B",1,"Uniklinik-Ponttor-Hbf.","Uniklinik-Ponttor-Hbf.","347",92000053015001,1483363039000]
|
||||
[1,"Uniklinik","100600","H.3",0,50.7756388,6.04425,29,"33","33",1,"Uniklinik","Uniklinik","529",92000209014001,1483363288000]
|
||||
[1,"Uniklinik","100600","H.2",0,50.7756388,6.04425,1,"73","73",1,"Aachen Bf.Rothe Erde","Aachen Bf.Rothe Erde","315",92000291016001,1483363080000]
|
||||
[1,"Uniklinik","100600","H.3",0,50.7756388,6.04425,29,"10","3.B",1,"Uniklinik-Ponttor-Hbf.","Uniklinik-Ponttor-Hbf.","347",92000053015001,1483363099000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,28,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","325",92000288012001,1483363080000]
|
||||
[1,"Uniklinik","100600","H.2",0,50.7756388,6.04425,6,"70","70",1,"Aachen Adenauerallee","Aachen Adenauerallee","588",92000225009001,1483363346000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,1,"3","3.A",1,"Schanz-Hbf.-Ponttor","Schanz-Hbf.-Ponttor","325",92000288013001,1483363380000]
|
@ -0,0 +1,18 @@
|
||||
[4,"1.0",1483809773487]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"94","94",2,"Acton Green","Acton Green",15294,445809,1483809898000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16589,239190,1483809806000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"6","6",2,"Willesden Gar","Willesden, Bus Garage",10600,216033,1483810030000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"23","23",2,"Westbourne Park","Westbourne Park",20276,685207,1483810231000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"94","94",2,"Acton Green","Acton Green",15296,445944,1483810322000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"6","6",2,"Willesden Gar","Willesden, Bus Garage",10603,216027,1483810421000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16211,310616,1483810135000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"94","94",2,"Acton Green","Acton Green",15105,445989,1483810449000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"23","23",2,"Westbourne Park","Westbourne Park",20322,690792,1483810642000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"94","94",2,"Acton Green","Acton Green",15575,445855,1483810750000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16213,216852,1483810840000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"6","6",2,"Willesden Gar","Willesden, Bus Garage",10602,216822,1483810854000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"23","23",2,"Westbourne Park","Westbourne Park",20337,689508,1483811038000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16549,238574,1483810791000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"94","94",2,"Acton Green","Acton Green",15925,445840,1483811317000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"6","6",2,"Willesden Gar","Willesden, Bus Garage",10596,216025,1483811331000]
|
||||
[1,"Piccadilly Circus","156","D",0,51.509822,-0.136967,1,"159","159",1,"Marble Arch","Marble Arch",16713,310640,1483811409000]
|
@ -0,0 +1,11 @@
|
||||
[4,"1.0",1483810124081]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"36","36",1,"New Cross Gate","New Cross Gate",8864,595212,1483810191000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"7","7",1,"Oxford Circus","Oxford Circus",9932,109224,1483810173000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"36","36",1,"New Cross Gate","New Cross Gate",8862,597163,1483810551000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"23","23",1,"Liverpool St","Liverpool Street",20333,690728,1483810367000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"7","7",1,"Oxford Circus","Oxford Circus",9861,106419,1483810702000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"36","36",1,"New Cross Gate","New Cross Gate",9407,599527,1483810830000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"23","23",1,"Liverpool St","Liverpool Street",20335,683419,1483810677000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"36","36",1,"New Cross Gate","New Cross Gate",9379,599540,1483811196000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"7","7",1,"Oxford Circus","Oxford Circus",10262,109245,1483811093000]
|
||||
[1,"Porchester Terrace North","16972","L",0,51.516451,-0.186379,1,"23","23",1,"Liverpool St","Liverpool Street",20099,684947,1483811250000]
|
@ -0,0 +1,11 @@
|
||||
[4,"2.0",1482850556146]
|
||||
[1,"Fischbachstraße","215812","",0,50.73893,6.2666311,6,"8","8",1,"Eschweiler Bushof","Eschweiler Bushof","0",27000165015001,1482856620000]
|
||||
[1,"Wolferskaul","100322","",0,50.7439086,6.1594241,19,"55","55",1,"Aachen Elisenbrunnen","Aachen Elisenbrunnen","619",27000229015001,1482852180000]
|
||||
[1,"Lindenallee","213227","",0,50.8271524,6.3194636,8,"28","28",1,"Alsdorf Annapark","Alsdorf Annapark","519",27000190012001,1482853140000]
|
||||
[1,"Karlsgraben","100024","",0,50.7728605,6.0766513,6,"5","5",1,"Driescher Hof-Brand","Driescher Hof-Brand","0",27000283012001,1482855960000]
|
||||
[1,"Eilendorf Bahnhof","100246","",0,50.7855477,6.1521783,61,"57","57",1,"Verlautenheide Endstr.","Verlautenheide Endstr.","528",27000200015001,1482855908000]
|
||||
[1,"Elisenbrunnen","100001","H.1",0,50.7747372,6.0879925,24,"34","34",1,"Aachen Bushof","Aachen Bushof","670",27000237013001,1482854520000]
|
||||
[1,"Schneidmühle","215602","",0,50.7847038,6.2190627,42,"22","22",1,"Stolberg Mühlener Bf.","Stolberg Mühlener Bf.","247",27000118005001,1482855180000]
|
||||
[1,"Dechant-Brock-Str.","215824","",0,50.7592927,6.2735355,22,"1","1",1,"Lintert Friedhof","Lintert Friedhof","268",27000102007001,1482854580000]
|
||||
[1,"Am Tiergarten","100382","",0,50.755833,6.1689597,30,"34","34",1,"Brand","Brand","0",27000224012001,1482854040000]
|
||||
[1,"Hansemannplatz","100002","H.1",0,50.7784794,6.0959816,26,"51","51",1,"Aachen Bushof","Aachen Bushof","603",27000230015001,1482854400000]
|
@ -1,11 +0,0 @@
|
||||
[4,"2.0",1483363349461]
|
||||
[1,"Westbahnhof","100641","H.2",0,50.7805372,6.0719672,17,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","325","92000288014001",1483367880000]
|
||||
[1,"Aachen Gartenstraße","100601","",0,50.7704169,6.0695841,4,"3","3.A",1,"Schanz-Hbf.-Ponttor","Schanz-Hbf.-Ponttor","229","92000058014001",1483368360000]
|
||||
[1,"Schanz","100012","H.2 (Boxgraben)",0,50.76891,6.074498,5,"3","3.A",1,"Hbf.-Ponttor-Uniklinik","Hbf.-Ponttor-Uniklinik","0","92000288015001",1483369380000]
|
||||
[1,"Kastanienweg","100631","",0,50.7854908,6.0547602,21,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","229","92000058014001",1483369860000]
|
||||
[1,"Eurogress","100007","",0,50.7807852,6.0900738,13,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","327","92000289012001",1483363996000]
|
||||
[1,"Augustastraße","100008","",0,50.7731333,6.0959027,10,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","325","92000288014001",1483367280000]
|
||||
[1,"Hörn Brücke","100627","",0,50.7871194,6.051875,22,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0","92000279013001",1483369020000]
|
||||
[1,"Audimax","100029","",0,50.7802655,6.0752138,16,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0","92000288015001",1483370460000]
|
||||
[1,"Misereor","100010","",0,50.7685583,6.0833027,7,"3","3.A",1,"Hbf.-Ponttor-Uniklinik","Hbf.-Ponttor-Uniklinik","0","92000154003001",1483370460000]
|
||||
[1,"Audimax","100029","",0,50.7802655,6.0752138,16,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","229","92000058014001",1483369560000]
|
@ -1,11 +0,0 @@
|
||||
[4,"2.0",1483362794677]
|
||||
[1,"Westbahnhof","100641","H.2",0,50.7805372,6.0719672,17,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0","92000288014001",1483367880000]
|
||||
[1,"Aachen Gartenstraße","100601","",0,50.7704169,6.0695841,4,"3","3.A",1,"Schanz-Hbf.-Ponttor","Schanz-Hbf.-Ponttor","0","92000058014001",1483368360000]
|
||||
[1,"Schanz","100012","H.2 (Boxgraben)",0,50.76891,6.074498,5,"3","3.A",1,"Hbf.-Ponttor-Uniklinik","Hbf.-Ponttor-Uniklinik","0","92000288015001",1483369380000]
|
||||
[1,"Aachen Gartenstraße","100601","",0,50.7704169,6.0695841,4,"3","3.A",1,"Schanz-Hbf.-Ponttor","Schanz-Hbf.-Ponttor","327","92000289012001",1483363045000]
|
||||
[1,"Kastanienweg","100631","",0,50.7854908,6.0547602,21,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0","92000058014001",1483369860000]
|
||||
[1,"Eurogress","100007","",0,50.7807852,6.0900738,13,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","327","92000289012001",1483363994000]
|
||||
[1,"Augustastraße","100008","",0,50.7731333,6.0959027,10,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","0","92000288014001",1483367280000]
|
||||
[1,"Hörn Brücke","100627","",0,50.7871194,6.051875,22,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0","92000279013001",1483369020000]
|
||||
[1,"Audimax","100029","",0,50.7802655,6.0752138,16,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","0","92000058014001",1483369560000]
|
||||
[1,"Aachen Hauptbahnhof","100004","H.1",0,50.7687027,6.0906277,8,"3","3.A",1,"Ponttor-Unikl.-Schanz","Ponttor-Unikl.-Schanz","0","92000288014001",1483367040000]
|
@ -1,11 +0,0 @@
|
||||
[4,"2.0",1482854457011]
|
||||
[1,"Aachen Bushof","100000","H.13",0,50.7775936,6.0908191,20,"1","1",1,"Schevenhütte","Schevenhütte","565","27000158010001",1482854446000]
|
||||
[1,"Aachen Bushof","100000","H.2",0,50.7775936,6.0908191,8,"7","7",1,"Aachen Bushof","Aachen Bushof","514","27000210017001",1482854400000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,30,"25","25",1,"Vaals Busstation","Vaals Busstation","0","27000171010001",1482854460000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,17,"47","47",1,"Aachen Bushof","Aachen Bushof","258","27000139003001",1482854460000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,1,"7","7",1,"Aachen Diepenbenden","Aachen Diepenbenden","257","27000089026001",1482854454000]
|
||||
[1,"Aachen Bushof","100000","H.12",0,50.7775936,6.0908191,17,"2","2",1,"Eilendorf Schubertstr.","Eilendorf Schubertstr.","221","27000039021001",1482854445000]
|
||||
[1,"Aachen Bushof","100000","H.11",0,50.7775936,6.0908191,28,"12","12",1,"Campus Melaten","Campus Melaten","298","27000062010001",1482854451000]
|
||||
[1,"Aachen Bushof","100000","H.1",0,50.7775936,6.0908191,27,"51","51",1,"Aachen Bushof","Aachen Bushof","603","27000230015001",1482854801000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,1,"43","43",1,"Hüls Schulz+Elleter F.","Hüls Schulz+Elleter F.","258","27000139004001",1482854520000]
|
||||
[1,"Aachen Bushof","100000","H.15",0,50.7775936,6.0908191,25,"33","33",1,"Aachen Fuchserde","Aachen Fuchserde","286","27000033017001",1482854459000]
|
@ -1,11 +0,0 @@
|
||||
[4,"2.0",1483362959788]
|
||||
[1,"Uniklinik","100600","H.2",0,50.7756388,6.04425,11,"33","33",1,"Aachen Fuchserde","Aachen Fuchserde","318","92000043013001",1483362935000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,1,"5","5",1,"Driescher Hof-Brand","Driescher Hof-Brand","312","92000282009001",1483362936000]
|
||||
[1,"Uniklinik","100600","H.4",0,50.7756388,6.04425,33,"45","45",1,"Uniklinik","Uniklinik","317","92000285009001",1483363294000]
|
||||
[1,"Uniklinik","100600","H.3",0,50.7756388,6.04425,28,"10","3.B",1,"Uniklinik-Ponttor-Hbf.","Uniklinik-Ponttor-Hbf.","347","92000053015001",1483363039000]
|
||||
[1,"Uniklinik","100600","H.3",0,50.7756388,6.04425,29,"33","33",1,"Uniklinik","Uniklinik","529","92000209014001",1483363288000]
|
||||
[1,"Uniklinik","100600","H.2",0,50.7756388,6.04425,1,"73","73",1,"Aachen Bf.Rothe Erde","Aachen Bf.Rothe Erde","315","92000291016001",1483363080000]
|
||||
[1,"Uniklinik","100600","H.3",0,50.7756388,6.04425,29,"10","3.B",1,"Uniklinik-Ponttor-Hbf.","Uniklinik-Ponttor-Hbf.","347","92000053015001",1483363099000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,28,"3","3.A",1,"Uniklinik-Schanz-Hbf.","Uniklinik-Schanz-Hbf.","325","92000288012001",1483363080000]
|
||||
[1,"Uniklinik","100600","H.2",0,50.7756388,6.04425,6,"70","70",1,"Aachen Adenauerallee","Aachen Adenauerallee","588","92000225009001",1483363346000]
|
||||
[1,"Uniklinik","100600","H.1",0,50.7756388,6.04425,1,"3","3.A",1,"Schanz-Hbf.-Ponttor","Schanz-Hbf.-Ponttor","325","92000288013001",1483363380000]
|
Reference in New Issue
Block a user