Skip to content

Commit

Permalink
feat(routing): use graphhopper to provide GTFS based public transport…
Browse files Browse the repository at this point in the history
… routing
  • Loading branch information
kschrab committed Nov 29, 2024
1 parent a5182ce commit 8842528
Show file tree
Hide file tree
Showing 26 changed files with 17,684 additions and 31 deletions.
7 changes: 7 additions & 0 deletions bundle/src/assembly/mosaic-bundle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@
<include>org.locationtech.jts:jts-core</include>
<!-- [END] GraphHopper dependencies -->

<!-- [START] GraphHopper PT routing dependencies -->
<include>com.graphhopper:graphhopper-reader-gtfs</include>
<include>io.mobilitydata.transit:gtfs-realtime-bindings</include>
<include>net.sourceforge.javacsv:javacsv</include>
<include>org.mapdb:mapdb</include>
<!-- [END] GraphHopper PT routing dependencies -->

<include>com.github.mwiede:jsch</include>
<include>com.google.protobuf:protobuf-java</include>
<include>org.xerial:sqlite-jdbc</include>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ public ApplicationAmbassador(AmbassadorParameter ambassadorParameter) {
// set the CNC (central navigation component)
CentralNavigationComponent cnc = new CentralNavigationComponent(
ambassadorParameter,
ambassadorConfig.navigationConfiguration
ambassadorConfig.navigationConfiguration,
ambassadorConfig.publicTransportConfiguration
);
SimulationKernel.SimulationKernel.setCentralNavigationComponent(cnc);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@
import org.eclipse.mosaic.lib.routing.RoutingPosition;
import org.eclipse.mosaic.lib.routing.RoutingRequest;
import org.eclipse.mosaic.lib.routing.RoutingResponse;
import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting;
import org.eclipse.mosaic.lib.routing.database.DatabaseRouting;
import org.eclipse.mosaic.lib.routing.norouting.NoRouting;
import org.eclipse.mosaic.lib.routing.pt.PtRouting;
import org.eclipse.mosaic.lib.routing.pt.PtRoutingRequest;
import org.eclipse.mosaic.lib.routing.pt.PtRoutingResponse;
import org.eclipse.mosaic.rti.api.IllegalValueException;
import org.eclipse.mosaic.rti.api.Interaction;
import org.eclipse.mosaic.rti.api.InternalFederateException;
Expand Down Expand Up @@ -83,11 +87,22 @@ public class CentralNavigationComponent {
*/
private Routing routing;


/**
* Public Transport routing
*/
private PtRouting ptRouting;

/**
* The configuration for routingAPI.
*/
private CApplicationAmbassador.CRoutingByType configuration;

/**
* The configuration for public transport routing.
*/
private CPublicTransportRouting ptConfiguration;

/**
* Constructor for the CentralNavigationComponent.
* Sets the logger and the configuration for navigation.
Expand All @@ -99,10 +114,12 @@ public class CentralNavigationComponent {
*/
public CentralNavigationComponent(
final AmbassadorParameter ambassadorParameter,
CApplicationAmbassador.CRoutingByType navigationConfiguration
CApplicationAmbassador.CRoutingByType navigationConfiguration,
CPublicTransportRouting publicTransportConfiguration
) {
this.applicationAmbassadorParameter = ambassadorParameter;
this.configuration = navigationConfiguration;
this.ptConfiguration = publicTransportConfiguration;
}

/**
Expand All @@ -124,11 +141,14 @@ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateExcep
routing = createFromType(this.configuration != null ? this.configuration.type : null);
routing.initialize(configuration, applicationAmbassadorParameter.configuration.getParentFile());

ptRouting = new PtRouting();
ptRouting.initialize(ptConfiguration, applicationAmbassadorParameter.configuration.getParentFile());

this.log.info("CNC - Navigation-System initialized");

try {
final Map<String, VehicleRoute> routeMap = routing.getRoutesFromDatabaseForMessage();
for (var routeEntry: routeMap.entrySet()) {
for (var routeEntry : routeMap.entrySet()) {
SimulationKernel.SimulationKernel.registerRoute(routeEntry.getKey(), routeEntry.getValue());
}

Expand Down Expand Up @@ -289,6 +309,17 @@ public GeoPoint getSourcePositionOfRoute(String routeId) {
}
}

/**
* Find a public transport route from a provided position to a provided target position at a specific request time.
*
* @param routingRequest A {@link PtRoutingRequest} that contains
* the origin, the end, the request time, and additional
* routing parameters to calculate the public transport route.
*/
PtRoutingResponse findPtRoute(PtRoutingRequest routingRequest) {
return ptRouting.findPtRoute(routingRequest);
}

/**
* Provides the current routing API implementation.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

package org.eclipse.mosaic.fed.application.config;

import org.eclipse.mosaic.lib.routing.config.CRouting;
import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting;
import org.eclipse.mosaic.lib.routing.config.CVehicleRouting;
import org.eclipse.mosaic.lib.util.gson.TimeFieldAdapter;
import org.eclipse.mosaic.lib.util.scheduling.MultiThreadedEventScheduler;
import org.eclipse.mosaic.rti.TIME;
Expand Down Expand Up @@ -53,18 +54,30 @@ public class CApplicationAmbassador implements Serializable {
*/
public int eventSchedulerThreads = 1;

/**
* Configuration options for route calculation via public transport.
* Requires paths to OSM and GTFS files.
*/
public CPublicTransportRouting publicTransportConfiguration = new CPublicTransportRouting();

/**
* Class containing the information for the configuration of the
* Routing/Navigation (CentralNavigationComponent).
*/
public CRoutingByType navigationConfiguration = null;

/**
* Extends the {@link CRouting} configuration with a type parameter
* Configuration for the perception backend used in the ApplicationSimulator
* to determine surrounding vehicles.
*/
public CPerception perceptionConfiguration = new CPerception();

/**
* Extends the {@link CVehicleRouting} configuration with a type parameter
* allowing to define the actual {@link org.eclipse.mosaic.lib.routing.Routing}
* implementation to use.
*/
public static class CRoutingByType extends CRouting implements Serializable {
public static class CRoutingByType extends CVehicleRouting implements Serializable {

/**
* Defines the {@link org.eclipse.mosaic.lib.routing.Routing} implementation
Expand All @@ -74,9 +87,4 @@ public static class CRoutingByType extends CRouting implements Serializable {
public String type = null;
}

/**
* Configuration for the perception backend used in the ApplicationSimulator
* to determine surrounding vehicles.
*/
public CPerception perceptionConfiguration = new CPerception();
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
import org.eclipse.mosaic.lib.routing.RoutingParameters;
import org.eclipse.mosaic.lib.routing.RoutingPosition;
import org.eclipse.mosaic.lib.routing.RoutingRequest;
import org.eclipse.mosaic.lib.routing.config.CRouting;
import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting;
import org.eclipse.mosaic.lib.routing.config.CVehicleRouting;
import org.eclipse.mosaic.lib.routing.norouting.NoRouting;
import org.eclipse.mosaic.rti.TIME;
import org.eclipse.mosaic.rti.api.IllegalValueException;
Expand Down Expand Up @@ -125,7 +126,7 @@ public void initialize_vehicleRoutesInitializationSent() throws InternalFederate
cnc.initialize(rtiAmbassadorMock);

//ASSERT
verify(routingMock).initialize(isNull(CRouting.class), isA(File.class));
verify(routingMock).initialize(isNull(CVehicleRouting.class), isA(File.class));
verify(rtiAmbassadorMock).triggerInteraction(isA(VehicleRoutesInitialization.class));
}

Expand Down Expand Up @@ -246,7 +247,7 @@ public void initializeNoRouting() throws InternalFederateException, IOException
routingConfig.type = "no-routing";

CentralNavigationComponent centralNavigationComponent
= new CentralNavigationComponent(ambassadorParameter,routingConfig );
= new CentralNavigationComponent(ambassadorParameter, routingConfig, new CPublicTransportRouting());
centralNavigationComponent.initialize(rtiAmbassadorMock);

assertNotNull(centralNavigationComponent.getRouting());
Expand All @@ -264,7 +265,7 @@ public void initializeMyTestRouting() throws InternalFederateException, IOExcept
routingConfig.type = MyTestRouting.class.getCanonicalName();

CentralNavigationComponent centralNavigationComponent
= new CentralNavigationComponent(ambassadorParameter,routingConfig );
= new CentralNavigationComponent(ambassadorParameter, routingConfig, new CPublicTransportRouting());
centralNavigationComponent.initialize(rtiAmbassadorMock);

assertNotNull(centralNavigationComponent.getRouting());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ protected void before() throws Throwable {

CApplicationAmbassador applicationConfig = new CApplicationAmbassador();
AmbassadorParameter ambassadorParameters = new AmbassadorParameter("test", configCopy.getParentFile());
centralNavigationComponent = new CentralNavigationComponent(ambassadorParameters, applicationConfig.navigationConfiguration) {
centralNavigationComponent = new CentralNavigationComponent(ambassadorParameters, applicationConfig.navigationConfiguration, applicationConfig.publicTransportConfiguration) {
@Override
Routing createFromType(String type) throws InternalFederateException {
return routingMock;
Expand Down
8 changes: 8 additions & 0 deletions lib/mosaic-routing/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
<groupId>com.graphhopper</groupId>
<artifactId>graphhopper-core</artifactId>
</dependency>
<dependency>
<groupId>com.graphhopper</groupId>
<artifactId>graphhopper-reader-gtfs</artifactId>
</dependency>
<dependency>
<groupId>io.mobilitydata.transit</groupId>
<artifactId>gtfs-realtime-bindings</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.eclipse.mosaic.lib.objects.road.INode;
import org.eclipse.mosaic.lib.objects.road.IRoadPosition;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleRoute;
import org.eclipse.mosaic.lib.routing.config.CRouting;
import org.eclipse.mosaic.lib.routing.config.CVehicleRouting;
import org.eclipse.mosaic.rti.api.InternalFederateException;

import java.io.File;
Expand All @@ -35,7 +35,7 @@ public interface Routing {
/**
* Initializes the connection to the belonging database.
*/
void initialize(CRouting routingConfiguration, File configurationLocation) throws InternalFederateException;
void initialize(CVehicleRouting routingConfiguration, File configurationLocation) throws InternalFederateException;

/**
* Find a route from your actual position to the target position.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Fraunhofer FOKUS and others. All rights reserved.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contact: [email protected]
*/

package org.eclipse.mosaic.lib.routing.config;

public class CPublicTransportRouting {

public boolean enabled = false;

public String osmFile = "map.osm";
public String gtfsFile = "gtfs.zip";
public String scheduleDateTime = "2024-12-03T10:15:30";
public String timeZone = "ECT";
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
/**
* Base Class for the navigation configuration.
*/
public class CRouting implements Serializable {
public class CVehicleRouting implements Serializable {

/**
* The source for the route calculation, e.g. the path to the database containing the road network.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import org.eclipse.mosaic.lib.routing.Routing;
import org.eclipse.mosaic.lib.routing.RoutingRequest;
import org.eclipse.mosaic.lib.routing.RoutingResponse;
import org.eclipse.mosaic.lib.routing.config.CRouting;
import org.eclipse.mosaic.lib.routing.config.CVehicleRouting;
import org.eclipse.mosaic.lib.routing.graphhopper.GraphHopperRouting;
import org.eclipse.mosaic.rti.api.InternalFederateException;

Expand Down Expand Up @@ -65,7 +65,7 @@ public class DatabaseRouting implements Routing {
private GraphHopperRouting routing;

@Override
public void initialize(final CRouting configuration, final File baseDirectory) throws InternalFederateException {
public void initialize(final CVehicleRouting configuration, final File baseDirectory) throws InternalFederateException {

File dbFile;
// try to find the database file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.eclipse.mosaic.lib.routing.Routing;
import org.eclipse.mosaic.lib.routing.RoutingRequest;
import org.eclipse.mosaic.lib.routing.RoutingResponse;
import org.eclipse.mosaic.lib.routing.config.CRouting;
import org.eclipse.mosaic.lib.routing.config.CVehicleRouting;
import org.eclipse.mosaic.rti.api.InternalFederateException;

import com.google.common.collect.Lists;
Expand All @@ -44,7 +44,7 @@
public class NoRouting implements Routing {

@Override
public void initialize(CRouting configuration, File configurationLocation) throws InternalFederateException {
public void initialize(CVehicleRouting configuration, File configurationLocation) throws InternalFederateException {
// nop
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2024 Fraunhofer FOKUS and others. All rights reserved.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contact: [email protected]
*/

package org.eclipse.mosaic.lib.routing.pt;

import org.eclipse.mosaic.lib.objects.vehicle.VehicleDeparture;

public class MultiModalLeg {

public enum Type {
WALKING, VEHICLE_SHARED, VEHICLE_PRIVATE, PUBLIC_TRANSPORT
}

private Type legType;

//For legs where a vehicle needs to be spawned
private VehicleDeparture vehicleLeg = null;

//For PTlegs
private PtLeg publicTransportationLeg = null;

private WalkLeg walkLeg = null;

//For legs where a vehicle already exists
private String carID = null;

public long departureTime;
public long arrivalTime;

public MultiModalLeg(VehicleDeparture vehicleLeg, long departureTime, long arrivalTime) {
this.legType = Type.VEHICLE_PRIVATE;
this.vehicleLeg = vehicleLeg;

this.departureTime = departureTime;
this.arrivalTime = arrivalTime;
}

public MultiModalLeg(PtLeg ptRoute, long departureTime, long arrivalTime) {
this.legType = Type.PUBLIC_TRANSPORT;
this.publicTransportationLeg = ptRoute;

this.departureTime = departureTime;
this.arrivalTime = arrivalTime;
}

public MultiModalLeg(WalkLeg walkLeg, long departureTime, long arrivalTime) {
this.legType = Type.WALKING;
this.walkLeg = walkLeg;

this.departureTime = departureTime;
this.arrivalTime = arrivalTime;
}

public MultiModalLeg(String carID, long departureTime, long arrivalTime) {
this.legType = Type.VEHICLE_PRIVATE;
this.carID = carID;

this.departureTime = departureTime;
this.arrivalTime = arrivalTime;
}

public Object getLeg() {
return switch (legType) {
case VEHICLE_PRIVATE -> vehicleLeg;
case VEHICLE_SHARED -> carID;
case PUBLIC_TRANSPORT -> publicTransportationLeg;
case WALKING -> walkLeg;
};
}

public Type getLegType() {
return legType;
}
}
Loading

0 comments on commit 8842528

Please sign in to comment.