Skip to content

Commit fe8cc66

Browse files
committed
Issue #1.
1 parent b0339e6 commit fe8cc66

File tree

11 files changed

+465
-0
lines changed

11 files changed

+465
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.project
2+
.settings

core/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.settings
2+
target
3+
.classpath
4+
.project

core/pom.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>org.hisrc.gdrb</groupId>
4+
<artifactId>gdrb-core</artifactId>
5+
<packaging>jar</packaging>
6+
<name>GDRB Core</name>
7+
<parent>
8+
<groupId>org.hisrc.gdrb</groupId>
9+
<artifactId>gdrb-project</artifactId>
10+
<version>1.0.0-SNAPSHOT</version>
11+
</parent>
12+
<dependencies>
13+
<dependency>
14+
<groupId>org.apache.commons</groupId>
15+
<artifactId>commons-lang3</artifactId>
16+
</dependency>
17+
<dependency>
18+
<groupId>commons-io</groupId>
19+
<artifactId>commons-io</artifactId>
20+
</dependency>
21+
<dependency>
22+
<groupId>joda-time</groupId>
23+
<artifactId>joda-time</artifactId>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.onebusaway</groupId>
27+
<artifactId>onebusaway-gtfs</artifactId>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.slf4j</groupId>
31+
<artifactId>slf4j-simple</artifactId>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.jgrapht</groupId>
35+
<artifactId>jgrapht-core</artifactId>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.neo4j</groupId>
39+
<artifactId>neo4j</artifactId>
40+
</dependency>
41+
</dependencies>
42+
<build>
43+
</build>
44+
</project>

core/src/main/etc/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/*.zip

core/src/main/etc/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Example GTFS data
2+
3+
Download and put GTFS ZIP files in this directory:
4+
5+
* [`openvbb.zip`](http://www.gtfs-data-exchange.com/agency/berliner-verkehrsbetriebe/)
6+
* [`swu.zip`](http://www.swu.de/privatkunden/swu-nahverkehr/gtfs-daten.html)
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package org.hisrc.gtfs.graph.builder.jgrapht;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
import org.hisrc.gtfs.graph.model.TemporalStopNode;
7+
import org.hisrc.gtfs.graph.model.TransitionEdge;
8+
import org.hisrc.gtfs.graph.model.TransitionType;
9+
import org.jgrapht.DirectedGraph;
10+
import org.jgrapht.EdgeFactory;
11+
import org.jgrapht.graph.DirectedMultigraph;
12+
import org.joda.time.LocalDate;
13+
import org.onebusaway.gtfs.impl.GtfsDaoImpl;
14+
import org.onebusaway.gtfs.model.AgencyAndId;
15+
import org.onebusaway.gtfs.model.ServiceCalendar;
16+
import org.onebusaway.gtfs.model.ServiceCalendarDate;
17+
import org.onebusaway.gtfs.model.Stop;
18+
import org.onebusaway.gtfs.model.StopTime;
19+
import org.onebusaway.gtfs.model.Trip;
20+
import org.onebusaway.gtfs.model.calendar.ServiceDate;
21+
import org.onebusaway.gtfs.services.GtfsMutableDao;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
25+
public class GtfsDirectedGraphBuilder {
26+
27+
private final ServiceDate serviceDate;
28+
private final int dayOfWeek;
29+
private final Set<AgencyAndId> availableServiceIds = new HashSet<AgencyAndId>();
30+
31+
public GtfsDirectedGraphBuilder(int year, int month, int day) {
32+
this.serviceDate = new ServiceDate(year, month, day);
33+
final LocalDate localDate = new LocalDate(year, month, day);
34+
this.dayOfWeek = localDate.getDayOfWeek();
35+
}
36+
37+
private DirectedGraph<TemporalStopNode, TransitionEdge> graph = new DirectedMultigraph<TemporalStopNode, TransitionEdge>(
38+
new EdgeFactory<TemporalStopNode, TransitionEdge>() {
39+
@Override
40+
public TransitionEdge createEdge(TemporalStopNode start,
41+
TemporalStopNode stop) {
42+
throw new UnsupportedOperationException();
43+
}
44+
});
45+
46+
private Logger logger = LoggerFactory
47+
.getLogger(GtfsDirectedGraphBuilder.class);
48+
49+
private final GtfsMutableDao gtfsDao = new GtfsDaoImpl() {
50+
public void saveEntity(Object entity) {
51+
super.saveEntity(entity);
52+
if (entity instanceof ServiceCalendarDate) {
53+
addServiceCalendarDate((ServiceCalendarDate) entity);
54+
}
55+
if (entity instanceof ServiceCalendar) {
56+
addServiceCalendar((ServiceCalendar) entity);
57+
}
58+
if (entity instanceof StopTime) {
59+
addStopTime((StopTime) entity);
60+
}
61+
}
62+
63+
};
64+
65+
private Set<Trip> processedTrips = new HashSet<Trip>();
66+
private Trip lastTrip = null;
67+
private TemporalStopNode lastNode = null;
68+
private int lastStopSequence = -1;
69+
70+
int count = 0;
71+
72+
public void addStopTime(StopTime stopTime) {
73+
74+
final Trip trip = stopTime.getTrip();
75+
if (!availableServiceIds.contains(trip.getServiceId())) {
76+
return;
77+
}
78+
79+
final int stopSequence = stopTime.getStopSequence();
80+
// logger.info("Stop sequence [" + stopSequence + "].");
81+
final TemporalStopNode previousDepartureNode;
82+
if (trip == lastTrip) {
83+
if (stopSequence <= lastStopSequence) {
84+
throw new IllegalStateException(
85+
"Stop sequence must be greater than the last stop sequence.");
86+
} else {
87+
previousDepartureNode = lastNode;
88+
}
89+
} else {
90+
if (processedTrips.contains(trip)) {
91+
throw new IllegalStateException(
92+
"Trip was already processed and now appears again.");
93+
} else {
94+
processedTrips.add(lastTrip);
95+
previousDepartureNode = null;
96+
}
97+
}
98+
99+
final Stop stop = stopTime.getStop();
100+
final int arrivalTime = stopTime.getArrivalTime();
101+
final int departureTime = stopTime.getDepartureTime();
102+
103+
final TemporalStopNode arrivalNode = new TemporalStopNode(stop,
104+
arrivalTime, false);
105+
final TemporalStopNode departureNode = new TemporalStopNode(stop,
106+
departureTime, true);
107+
graph.addVertex(arrivalNode);
108+
graph.addVertex(departureNode);
109+
110+
if (previousDepartureNode != null) {
111+
final int previousDepartureTime = previousDepartureNode.getTime();
112+
final TransitionEdge departureArrivalTransitionEdge = new TransitionEdge(
113+
TransitionType.DEPARTURE_ARRIVAL, arrivalTime
114+
- previousDepartureTime);
115+
116+
// logger.info("Adding [" + previousDepartureNode + "--->"
117+
// + arrivalNode + "]");
118+
graph.addEdge(previousDepartureNode, arrivalNode,
119+
departureArrivalTransitionEdge);
120+
}
121+
// logger.info("Adding [" + arrivalNode + "-" + departureNode + "]");
122+
final TransitionEdge arrivalDepartureTransitionEdge = new TransitionEdge(
123+
TransitionType.ARRIVAL_DEPARTURE, departureTime - arrivalTime);
124+
graph.addEdge(arrivalNode, departureNode,
125+
arrivalDepartureTransitionEdge);
126+
127+
lastTrip = trip;
128+
lastNode = departureNode;
129+
lastStopSequence = stopTime.getStopSequence();
130+
if (count % 10000 == 0) {
131+
logger.info("" + count);
132+
}
133+
count++;
134+
}
135+
136+
private void addServiceCalendar(ServiceCalendar serviceCalendar) {
137+
if (serviceCalendar.getStartDate().compareTo(this.serviceDate) <= 0
138+
&& serviceCalendar.getEndDate().compareTo(this.serviceDate) >= 0
139+
&& (this.dayOfWeek == 1 && serviceCalendar.getMonday() == 1)
140+
|| (this.dayOfWeek == 2 && serviceCalendar.getTuesday() == 1)
141+
|| (this.dayOfWeek == 3 && serviceCalendar.getWednesday() == 1)
142+
|| (this.dayOfWeek == 4 && serviceCalendar.getThursday() == 1)
143+
|| (this.dayOfWeek == 5 && serviceCalendar.getFriday() == 1)
144+
|| (this.dayOfWeek == 6 && serviceCalendar.getSaturday() == 1)
145+
|| (this.dayOfWeek == 7 && serviceCalendar.getSunday() == 1)) {
146+
availableServiceIds.add(serviceCalendar.getServiceId());
147+
}
148+
}
149+
150+
private void addServiceCalendarDate(ServiceCalendarDate serviceCalendarDate) {
151+
if (serviceCalendarDate.getExceptionType() == 1
152+
&& serviceCalendarDate.getDate().equals(this.serviceDate)) {
153+
availableServiceIds.add(serviceCalendarDate.getServiceId());
154+
}
155+
}
156+
157+
public GtfsMutableDao getGtfsMutableDao() {
158+
return gtfsDao;
159+
}
160+
161+
public DirectedGraph<TemporalStopNode, TransitionEdge> build() {
162+
return graph;
163+
}
164+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.hisrc.gtfs.graph.model;
2+
3+
import org.onebusaway.gtfs.model.Stop;
4+
5+
public class TemporalStopNode {
6+
7+
// Reference to the stop
8+
private final Stop stop;
9+
// Time point
10+
private final int time;
11+
// Whether this is a starting point for the routing
12+
private final boolean departure;
13+
14+
public TemporalStopNode(Stop stop, int time, boolean departure) {
15+
super();
16+
this.stop = stop;
17+
this.time = time;
18+
this.departure = departure;
19+
}
20+
21+
public Stop getStop() {
22+
return stop;
23+
}
24+
25+
public int getTime() {
26+
return time;
27+
}
28+
29+
@Override
30+
public String toString() {
31+
return stop + "@" + time;
32+
}
33+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.hisrc.gtfs.graph.model;
2+
3+
public class TransitionEdge {
4+
5+
private final TransitionType transitionType;
6+
private final int cost;
7+
8+
public TransitionEdge(TransitionType transitionType, int cost) {
9+
this.transitionType = transitionType;
10+
this.cost = cost;
11+
}
12+
13+
14+
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.hisrc.gtfs.graph.model;
2+
3+
public enum TransitionType {
4+
5+
DEPARTURE_ARRIVAL, ARRIVAL_DEPARTURE
6+
7+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.hisrc.gtfs.serialization.onebusaway.test;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.net.URISyntaxException;
6+
import java.util.zip.ZipFile;
7+
8+
import org.hisrc.gtfs.graph.builder.jgrapht.GtfsDirectedGraphBuilder;
9+
import org.hisrc.gtfs.graph.model.TemporalStopNode;
10+
import org.hisrc.gtfs.graph.model.TransitionEdge;
11+
import org.hisrc.gtfs.serialization.onebusaway.GtfsReader;
12+
import org.jgrapht.DirectedGraph;
13+
import org.junit.Assert;
14+
import org.junit.Test;
15+
import org.onebusaway.csv_entities.ZipFileCsvInputSource;
16+
import org.onebusaway.gtfs.model.StopTime;
17+
18+
public class RunGtfsParser {
19+
20+
@Test
21+
public void parsesSWU() throws IOException, URISyntaxException {
22+
final GtfsReader gtfsReader = new GtfsReader();
23+
gtfsReader.getEntityClasses().remove(StopTime.class);
24+
gtfsReader.getEntityClasses().add(StopTime.class);
25+
final ZipFile zipFile = new ZipFile(new File("src/main/etc/swu.zip"));
26+
final ZipFileCsvInputSource csvInputSource = new ZipFileCsvInputSource(
27+
zipFile);
28+
gtfsReader.setInputSource(csvInputSource);
29+
30+
final GtfsDirectedGraphBuilder graphBuilder = new GtfsDirectedGraphBuilder(
31+
2015, 07, 10);
32+
gtfsReader.setEntityStore(graphBuilder.getGtfsMutableDao());
33+
gtfsReader.run();
34+
35+
final DirectedGraph<TemporalStopNode, TransitionEdge> graph = graphBuilder
36+
.build();
37+
38+
Assert.assertFalse(graph.edgeSet().isEmpty());
39+
}
40+
41+
}

0 commit comments

Comments
 (0)