From 2ed219a98944789f925b042bd42e6c1e3f1072e3 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Fri, 29 Nov 2024 17:20:16 +0100 Subject: [PATCH 01/13] feat(routing): use graphhopper to provide GTFS based public transport routing --- bundle/src/assembly/mosaic-bundle.xml | 7 + .../ambassador/ApplicationAmbassador.java | 3 +- .../CentralNavigationComponent.java | 35 +- .../config/CApplicationAmbassador.java | 24 +- .../CentralNavigationComponentTest.java | 9 +- .../CentralNavigationComponentTestRule.java | 2 +- lib/mosaic-routing/pom.xml | 8 + .../eclipse/mosaic/lib/routing/Routing.java | 4 +- .../config/CPublicTransportRouting.java | 26 + .../{CRouting.java => CVehicleRouting.java} | 2 +- .../lib/routing/database/DatabaseRouting.java | 4 +- .../lib/routing/norouting/NoRouting.java | 4 +- .../mosaic/lib/routing/pt/MultiModalLeg.java | 86 + .../lib/routing/pt/MultiModalRoute.java | 53 + .../eclipse/mosaic/lib/routing/pt/PtLeg.java | 37 + .../mosaic/lib/routing/pt/PtRouting.java | 183 + .../lib/routing/pt/PtRoutingParameters.java | 35 + .../lib/routing/pt/PtRoutingRequest.java | 54 + .../lib/routing/pt/PtRoutingResponse.java | 29 + .../lib/routing/pt/PtTimeConversion.java | 70 + .../mosaic/lib/routing/pt/WalkLeg.java | 34 + .../routing/database/DatabaseRoutingTest.java | 6 +- .../mosaic/lib/routing/pt/PtRoutingTest.java | 110 + .../src/test/resources/pt/pt-gtfs.zip | Bin 0 -> 1770 bytes .../src/test/resources/pt/pt.osm | 16852 ++++++++++++++++ pom.xml | 38 +- 26 files changed, 17684 insertions(+), 31 deletions(-) create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java rename lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/{CRouting.java => CVehicleRouting.java} (93%) create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java create mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java create mode 100644 lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java create mode 100644 lib/mosaic-routing/src/test/resources/pt/pt-gtfs.zip create mode 100644 lib/mosaic-routing/src/test/resources/pt/pt.osm diff --git a/bundle/src/assembly/mosaic-bundle.xml b/bundle/src/assembly/mosaic-bundle.xml index 0fb75cf06..c0d73ba4c 100644 --- a/bundle/src/assembly/mosaic-bundle.xml +++ b/bundle/src/assembly/mosaic-bundle.xml @@ -151,6 +151,13 @@ org.locationtech.jts:jts-core + + com.graphhopper:graphhopper-reader-gtfs + io.mobilitydata.transit:gtfs-realtime-bindings + net.sourceforge.javacsv:javacsv + org.mapdb:mapdb + + com.github.mwiede:jsch com.google.protobuf:protobuf-java org.xerial:sqlite-jdbc diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java index cb8e8d787..34be4f3ce 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java @@ -143,7 +143,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); } diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java index 63834b9db..40dc6eeb5 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java @@ -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; @@ -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. @@ -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; } /** @@ -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 routeMap = routing.getRoutesFromDatabaseForMessage(); - for (var routeEntry: routeMap.entrySet()) { + for (var routeEntry : routeMap.entrySet()) { SimulationKernel.SimulationKernel.registerRoute(routeEntry.getKey(), routeEntry.getValue()); } @@ -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. * diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java index c03116e4c..223b45795 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java @@ -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; @@ -53,6 +54,12 @@ 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). @@ -60,11 +67,17 @@ public class CApplicationAmbassador implements Serializable { 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 @@ -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(); } diff --git a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java index 77e905f13..60c4e6dd2 100644 --- a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java +++ b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java @@ -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; @@ -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)); } @@ -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()); @@ -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()); diff --git a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java index fb6d220e1..5aa5232f3 100644 --- a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java +++ b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java @@ -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; diff --git a/lib/mosaic-routing/pom.xml b/lib/mosaic-routing/pom.xml index 40b011110..ceaa0ff01 100644 --- a/lib/mosaic-routing/pom.xml +++ b/lib/mosaic-routing/pom.xml @@ -34,6 +34,14 @@ com.graphhopper graphhopper-core + + com.graphhopper + graphhopper-reader-gtfs + + + io.mobilitydata.transit + gtfs-realtime-bindings + com.google.guava guava diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/Routing.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/Routing.java index d3be8cef5..274583935 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/Routing.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/Routing.java @@ -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; @@ -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. diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java new file mode 100644 index 000000000..d1316d205 --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java @@ -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: mosaic@fokus.fraunhofer.de + */ + +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"; +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CVehicleRouting.java similarity index 93% rename from lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CRouting.java rename to lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CVehicleRouting.java index 5e94530f5..77ae27ebc 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CVehicleRouting.java @@ -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. diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java index 1186b05b2..6a37d0970 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java @@ -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; @@ -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 diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java index 6922e1ef5..58f0fd096 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java @@ -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; @@ -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 } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java new file mode 100644 index 000000000..e62fbaec0 --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java @@ -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: mosaic@fokus.fraunhofer.de + */ + +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; + } +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java new file mode 100644 index 000000000..2dce0b4ab --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java @@ -0,0 +1,53 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +import java.util.ArrayList; +import java.util.List; + +public class MultiModalRoute { + + private final List legs = new ArrayList<>(); + + public MultiModalRoute(List legs) { + this.legs.addAll(legs); + } + + public List getLegs() { + return this.legs; + } + + /** + * can be used to check if the route exists and is valid, + * if allowTeleportation is set to true it ignores arrival/ departure times + * + * @return whether or not a valid route exists and is valid + */ + public boolean checkValidity() { + if (!legs.isEmpty()) { + for (int i = 0; i < legs.size() - 1; i++) { + if (legs.get(i).arrivalTime > legs.get(i + 1).departureTime) { + return false; + } + } + } else { + return false; + } + return true; + } + + +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java new file mode 100644 index 000000000..6351083ec --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java @@ -0,0 +1,37 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +import org.eclipse.mosaic.lib.geo.GeoPoint; + +import java.util.ArrayList; +import java.util.List; + +public class PtLeg { + + public record PtStop(GeoPoint location, Long departureTime, Long arrivalTime) {} + + private final List legs = new ArrayList<>(); + + public PtLeg(List legs) { + this.legs.addAll(legs); + } + + public List getLegs() { + return legs; + } + +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java new file mode 100644 index 000000000..4dad4bc25 --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java @@ -0,0 +1,183 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +import org.eclipse.mosaic.lib.geo.GeoPoint; +import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting; + +import com.google.common.collect.Iterables; +import com.graphhopper.GHResponse; +import com.graphhopper.GraphHopperConfig; +import com.graphhopper.ResponsePath; +import com.graphhopper.Trip; +import com.graphhopper.config.Profile; +import com.graphhopper.gtfs.GraphHopperGtfs; +import com.graphhopper.gtfs.PtRouter; +import com.graphhopper.gtfs.PtRouterImpl; +import com.graphhopper.gtfs.Request; +import com.graphhopper.util.StopWatch; +import com.graphhopper.util.TranslationMap; +import org.apache.commons.lang3.Validate; +import org.locationtech.jts.geom.Coordinate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.nio.file.Path; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class PtRouting { + + private static final Logger LOG = LoggerFactory.getLogger(PtRouting.class); + + private final ExecutorService routingExecution = Executors.newSingleThreadExecutor(); + + private PtRouter ptRouter; + private GraphHopperGtfs graphHopperGtfs; + + private LocalDateTime scheduleDateTime; + private ZoneId timeZone; + + public void initialize(CPublicTransportRouting routingConfiguration, File configurationLocation) { + if (!routingConfiguration.enabled) { + return; + } + + Path baseDirectory = configurationLocation.toPath(); + + GraphHopperConfig ghConfig = new GraphHopperConfig() + .putObject("import.osm.ignored_highways", "motorway,trunk,primary") + .putObject("graph.location", baseDirectory.resolve("ptgraph").toAbsolutePath().toString()) + .putObject("datareader.file", baseDirectory.resolve(routingConfiguration.osmFile).toAbsolutePath().toString()) + .putObject("gtfs.file", baseDirectory.resolve(routingConfiguration.gtfsFile).toAbsolutePath().toString()) + .setProfiles(Collections.singletonList(new Profile("foot").setVehicle("foot"))); + + scheduleDateTime = LocalDateTime.parse(routingConfiguration.scheduleDateTime, DateTimeFormatter.ISO_DATE_TIME); + timeZone = ZoneId.of(ZoneId.SHORT_IDS.get(routingConfiguration.timeZone)); + + final StopWatch sw = new StopWatch(); + sw.start(); + graphHopperGtfs = new GraphHopperGtfs(ghConfig); + graphHopperGtfs.init(ghConfig); + graphHopperGtfs.importOrLoad(); + sw.stop(); + LOG.debug("Took {} ms to load public transport router.", sw.getMillis()); + + LOG.info("setting ptRouter"); + ptRouter = new PtRouterImpl.Factory(ghConfig, + new TranslationMap().doImport(), + graphHopperGtfs.getBaseGraph(), + graphHopperGtfs.getEncodingManager(), + graphHopperGtfs.getLocationIndex(), + graphHopperGtfs.getGtfsStorage() + ).createWithoutRealtimeFeed(); + } + + + + public PtRoutingResponse findPtRoute(PtRoutingRequest request) { + if (ptRouter == null) { + throw new IllegalStateException("PT Routing is not available. Must be enabled in application_config.json."); + } + Validate.isTrue(request.getRoutingParameters().getWalkingSpeedMps() > 0, "Walking speed must be greater than 0."); + + Instant departureTime = toScheduleTime(request.getRequestTime()); + + final Request ghRequest = new Request( + request.getStartingGeoPoint().getLatitude(), + request.getStartingGeoPoint().getLongitude(), + request.getTargetGeoPoint().getLatitude(), + request.getTargetGeoPoint().getLongitude() + ); +// ghRequest.setBlockedRouteTypes(request.getRoutingParameters().excludedPtModes);//FIXME generalize this + ghRequest.setEarliestDepartureTime(departureTime); + ghRequest.setWalkSpeedKmH(request.getRoutingParameters().getWalkingSpeedMps() * 3.6); + + final Future responseFuture = routingExecution.submit(() -> ptRouter.route(ghRequest)); + final GHResponse route; + try { + final StopWatch sw = new StopWatch(); + sw.start(); + route = responseFuture.get(30, TimeUnit.SECONDS); + sw.stop(); + LOG.debug("Took {} ms to calculate public transport route.", sw.getMillis()); + } catch (TimeoutException e) { + responseFuture.cancel(true); + throw new RuntimeException("Could not finish route calculation. Exceeded timeout."); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException("Could not finish route calculation. Exceeded timeout.", e); + } + + final List legs = convertToMultiModalLegs(route.getBest()); + + return new PtRoutingResponse(new MultiModalRoute(legs)); + } + + private List convertToMultiModalLegs(ResponsePath ghBestRoute) { + List legs = new ArrayList<>(); + for (Trip.Leg leg : ghBestRoute.getLegs()) { + if (leg instanceof Trip.PtLeg ptLeg) { + List newStops = new ArrayList<>(); + for (Trip.Stop stop : ptLeg.stops) { + newStops.add(new PtLeg.PtStop(GeoPoint.lonLat(stop.geometry.getX(), stop.geometry.getY()), fromScheduleTime(stop.departureTime), fromScheduleTime(stop.arrivalTime))); + } + legs.add(new MultiModalLeg( + new PtLeg(newStops), newStops.get(0).departureTime(), Iterables.getLast(newStops).arrivalTime()) + ); + } else if (leg instanceof Trip.WalkLeg walkLeg) { + List waypoints = new ArrayList<>(); + for (Coordinate coordinate : walkLeg.geometry.getCoordinates()) { + waypoints.add(GeoPoint.lonLat(coordinate.x, coordinate.y)); + } + legs.add(new MultiModalLeg(new WalkLeg(waypoints), fromScheduleTime(leg.getDepartureTime()), fromScheduleTime(leg.getArrivalTime()))); + } + } + return legs; + } + + private Instant toScheduleTime(long simTime) { + return scheduleDateTime.plusNanos(simTime).atZone(timeZone).toInstant(); + } + + private Long fromScheduleTime(Date date) { + if (date == null) { + return null; + } + return fromScheduleTime(date.toInstant()); + } + + private long fromScheduleTime(Instant instant) { + return scheduleDateTime.until(LocalDateTime.ofInstant(instant, timeZone), ChronoUnit.NANOS); + } + + public void close() { + graphHopperGtfs.close(); + } +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java new file mode 100644 index 000000000..4f92c1790 --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java @@ -0,0 +1,35 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +public class PtRoutingParameters { + + private double walkingSpeedMps = 5 / 3.6; + + public PtRoutingParameters walkingSpeedKmh(double kmh) { + walkingSpeedMps = kmh / 3.6; + return this; + } + + public PtRoutingParameters walkingSpeedMps(double meterPerSecond) { + walkingSpeedMps = meterPerSecond; + return this; + } + + public double getWalkingSpeedMps() { + return walkingSpeedMps; + } +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java new file mode 100644 index 000000000..0682be96b --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java @@ -0,0 +1,54 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +import org.eclipse.mosaic.lib.geo.GeoPoint; + +public class PtRoutingRequest { + + private final long requestTime; + private final GeoPoint startingGeoPoint; + private final GeoPoint targetGeoPoint; + + private final PtRoutingParameters routingParameters; + + public PtRoutingRequest(long requestTime, GeoPoint from, GeoPoint to) { + this(requestTime, from, to, new PtRoutingParameters()); + } + + public PtRoutingRequest(long requestTime, GeoPoint from, GeoPoint to, PtRoutingParameters additionalParameters) { + this.requestTime = requestTime; + this.startingGeoPoint = from; + this.targetGeoPoint = to; + this.routingParameters = additionalParameters; + } + + public long getRequestTime() { + return requestTime; + } + + public GeoPoint getStartingGeoPoint() { + return startingGeoPoint; + } + + public GeoPoint getTargetGeoPoint() { + return targetGeoPoint; + } + + public PtRoutingParameters getRoutingParameters() { + return routingParameters; + } +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java new file mode 100644 index 000000000..8b5e949da --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java @@ -0,0 +1,29 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +public class PtRoutingResponse { + + private final MultiModalRoute bestRoute; + + public PtRoutingResponse(MultiModalRoute bestRoute) { + this.bestRoute = bestRoute; + } + + public MultiModalRoute getBestRoute() { + return bestRoute; + } +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java new file mode 100644 index 000000000..8f1173704 --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java @@ -0,0 +1,70 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +import org.eclipse.mosaic.rti.TIME; + +import java.time.LocalTime; +import java.util.Date; + +/** + * Contains functions to calculate between different time formats, since "time" is usually always referring to + * simulation time, but a real-world time is needed for the calculation of public transportation routes + */ +public final class PtTimeConversion { + + private static final LocalTime realWorldTime = LocalTime.of(0, 0, 0); + private static final long realWorldTimeNanoS = + TIME.HOUR * realWorldTime.getHour() + + TIME.MINUTE * realWorldTime.getMinute() + + TIME.SECOND * realWorldTime.getSecond(); + + private PtTimeConversion() { + //just need functions to calculate bewtween time formats + } + + public static LocalTime toLocalTime(long simTime) { + return LocalTime.ofNanoOfDay(simTime + realWorldTimeNanoS); + } + + public static long toSimTime(LocalTime time) { + int hourDiff = time.getHour() - realWorldTime.getHour(); + int minuteDiff = time.getMinute() - realWorldTime.getMinute(); + int secondDiff = time.getSecond() - realWorldTime.getSecond(); + + long simTime = TIME.HOUR * hourDiff + TIME.MINUTE * minuteDiff + TIME.SECOND * secondDiff; + + if (simTime < 0) { + System.out.println("Warning, calculated simtime is before sim actually starts"); + } + + return simTime; + } + + public static long toSimTime(Date date) { + return toSimTime(dateToLocalTime(date)); + } + + public static LocalTime dateToLocalTime(Date date) { + if (date == null) { + return null; + } + String[] splitString = date.toString().split(" "); + String[] timeStrings = splitString[3].split(":"); + return LocalTime.of(Integer.parseInt(timeStrings[0]), Integer.parseInt(timeStrings[1]), Integer.parseInt(timeStrings[2])); + } + +} diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java new file mode 100644 index 000000000..9e991a051 --- /dev/null +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java @@ -0,0 +1,34 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +import org.eclipse.mosaic.lib.geo.GeoPoint; + +import java.util.ArrayList; +import java.util.List; + +public class WalkLeg { + + private final List waypoints = new ArrayList<>(); + + public WalkLeg(List waypoints) { + this.waypoints.addAll(waypoints); + } + + public List getWaypoints() { + return waypoints; + } +} diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/database/DatabaseRoutingTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/database/DatabaseRoutingTest.java index 66b283cc9..62416a0cf 100644 --- a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/database/DatabaseRoutingTest.java +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/database/DatabaseRoutingTest.java @@ -32,7 +32,7 @@ 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.CRouting; +import org.eclipse.mosaic.lib.routing.config.CVehicleRouting; import org.eclipse.mosaic.rti.api.InternalFederateException; import org.apache.commons.io.FileUtils; @@ -66,7 +66,7 @@ public class DatabaseRoutingTest { private final static String dbFile = "/tiergarten.db"; private DatabaseRouting databaseRouting; - private CRouting configuration; + private CVehicleRouting configuration; private File cfgDir; @@ -80,7 +80,7 @@ public void setup() throws IOException { FileUtils.copyInputStreamToFile(getClass().getResourceAsStream(dbFile), dbFileCopy); - configuration = new CRouting(); + configuration = new CVehicleRouting(); databaseRouting = new DatabaseRouting(); } diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java new file mode 100644 index 000000000..d36be2e1f --- /dev/null +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java @@ -0,0 +1,110 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.lib.routing.pt; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.mosaic.lib.geo.GeoPoint; +import org.eclipse.mosaic.lib.junit.GeoProjectionRule; +import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; +import java.time.LocalTime; + +public class PtRoutingTest { + + @Rule + public GeoProjectionRule transformationRule = new GeoProjectionRule(GeoPoint.latLon(36.9, -116.7)); + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private PtRouting ptRouting; + private CPublicTransportRouting routingConfiguration; + private File configDir; + + @Before + public void setup() throws IOException { + routingConfiguration = new CPublicTransportRouting(); + routingConfiguration.enabled = true; + routingConfiguration.scheduleDateTime = "2010-01-01T00:00:00"; + routingConfiguration.timeZone = "PST"; + routingConfiguration.osmFile = "pt.osm"; + routingConfiguration.gtfsFile = "pt-gtfs.zip"; + + configDir = folder.newFolder("pt"); + final File osmFileCopy = folder.newFile("pt/" + routingConfiguration.osmFile); + final File gtfsFileCopy = folder.newFile("pt/" + routingConfiguration.gtfsFile); + + FileUtils.copyInputStreamToFile(getClass().getResourceAsStream("/pt/pt.osm"), osmFileCopy); + FileUtils.copyInputStreamToFile(getClass().getResourceAsStream("/pt/pt-gtfs.zip"), gtfsFileCopy); + + ptRouting = new PtRouting(); + } + + @Test(expected = IllegalStateException.class) + public void initialize_skipInitialization() { + routingConfiguration.enabled = false; + ptRouting.initialize(routingConfiguration, configDir); + + // ASSERT + ptRouting.findPtRoute(new PtRoutingRequest(0, GeoPoint.ORIGO, GeoPoint.ORIGO)); + } + + @Test + public void findRoute_walkOnlyCauseIAmFast() { + ptRouting.initialize(routingConfiguration, configDir); + + PtRoutingResponse response = ptRouting.findPtRoute(new PtRoutingRequest( + LocalTime.of(8, 50).toNanoOfDay(), + GeoPoint.latLon(36.900760, -116.766464), + GeoPoint.latLon(36.907353, -116.761829), + new PtRoutingParameters().walkingSpeedKmh(5) + )); + + // ASSERT + MultiModalRoute route = response.getBestRoute(); + assertEquals(1, route.getLegs().size()); + assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(0).getLegType()); + } + + @Test + public void findRoute_findPublicTransportRoute() { + ptRouting.initialize(routingConfiguration, configDir); + + PtRoutingResponse response = ptRouting.findPtRoute(new PtRoutingRequest( + LocalTime.of(8, 57).toNanoOfDay(), + GeoPoint.latLon(36.900760, -116.766464), + GeoPoint.latLon(36.907353, -116.761829), + new PtRoutingParameters().walkingSpeedKmh(3) + )); + + // ASSERT + MultiModalRoute route = response.getBestRoute(); + assertEquals(3, route.getLegs().size()); + assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(0).getLegType()); + assertEquals(MultiModalLeg.Type.PUBLIC_TRANSPORT, route.getLegs().get(1).getLegType()); + assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(2).getLegType()); + } + +} diff --git a/lib/mosaic-routing/src/test/resources/pt/pt-gtfs.zip b/lib/mosaic-routing/src/test/resources/pt/pt-gtfs.zip new file mode 100644 index 0000000000000000000000000000000000000000..2c8238e87c30325318d7939a7c3d5c788eec8734 GIT binary patch literal 1770 zcmWIWW@Zs#-~dA2^4drSD5wF_Tnq{fiRr0%$(4E~6(yk|ybSEzCp^v|`-0E6i-8*i5%<_2@Pu1F6*0*L&bxtxl zC17vWr@|`TXCL6r&av)VRBZ~-QjiM+u)4hgD8mDEdvan~1w{Cdy(Ts(R9ytn6?E1H_Vx@;GpuGFj)2=jEy6r3?JYzpV1E@5x4?gKqR8~Pqi zIqLmQBiv z1v(7mIPA{e3X}l_c~O38Nop~MqyGf2i$x1^-&2lUhYSQ-AJ#4`Kf&mB;f_PIw4%nX zHQpZWQ6AQ+GZ~AkCoX&Nu3lb$qQSSz40T6Tr^M$@xj$t`{GT3CCEdsWqhmlBKA@+HOY#fiOEPnjJSGK<2@u8-8=>6?xta|G zT;4a;Pjc4zav|=hGj~uxG2g*8r7N$NY!>|Wo%do87qjv1&uyG@-L!cG*QH(R@fQ%A zqsYf{`(>r4PZ9rmhT{G8?grN$*NXA|b}yK9U+w{{6zl0_}IN{gXyCQ>GB|7N*6B*=mPo!!)}|G%I<02UjAeIW2?=_w%ql-x_8%XclPitF6)v>la}=Agcb5_OgA%u_B(K7>s(F51 zX@OZqo@sS*9$K2}_LkCXbd@(UEa{wn`lh{!#*q`|CO1s4gdYcICH6yxS2RzCf6&$S z(>;6D@Pgr$hfkS+?quh%-+e435$H0I>jJzPnM9ZoB^Yw~0Lo45XRk;rC)Qa*CZ y0i}Ex*w(1W3^5xswP48y=*A*PEUK{_z)FVbL>S=B$_8=~8xV>B{dxdgLjeF)+#Wsv literal 0 HcmV?d00001 diff --git a/lib/mosaic-routing/src/test/resources/pt/pt.osm b/lib/mosaic-routing/src/test/resources/pt/pt.osm new file mode 100644 index 000000000..c2252f48e --- /dev/null +++ b/lib/mosaic-routing/src/test/resources/pt/pt.osm @@ -0,0 +1,16852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 710d30706..5f972d1c8 100644 --- a/pom.xml +++ b/pom.xml @@ -96,11 +96,12 @@ 1.3.9-1 8.0 2.10.1 + 0.0.5 32.1.1-jre 0.8.1 2.16.1 1.3.9 - 2.7.5 + 2.0 1.1.13 0.1.51 1.3.1 @@ -112,6 +113,7 @@ 0.2.16 1.5.0 5.6.0 + 1.0.8 3.23.2 2.0.12 3.42.0.0 @@ -334,10 +336,6 @@ de.westnordost osm-legal-default-speeds-jvm - - org.codehaus.janino - janino - org.apache.xmlgraphics xmlgraphics-commons @@ -352,6 +350,36 @@ + + + com.graphhopper + graphhopper-reader-gtfs + ${version.graphhopper} + + + javax.inject + javax.inject + + + + + + net.sourceforge.javacsv + javacsv + ${version.javacsv} + + + + org.mapdb + mapdb + ${version.mapdb} + + + + io.mobilitydata.transit + gtfs-realtime-bindings + ${version.gtfs-bindings} + com.carrotsearch From 25541ae7cd1717956adcfca4efe021a154fc59b2 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Mon, 2 Dec 2024 17:16:15 +0100 Subject: [PATCH 02/13] docs(routing): documentation for pt routing config --- .../config/CPublicTransportRouting.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java index d1316d205..e63c59cb6 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java @@ -17,10 +17,29 @@ public class CPublicTransportRouting { + /** + * Declares if PT routing is enabled (default=false). + */ public boolean enabled = false; + /** + * The path to the OSM file which is used to calculate walking between PT legs. + */ public String osmFile = "map.osm"; + + /** + * The path to the GTFS file (ZIP archive) which contains the whole PT schedule. + */ public String gtfsFile = "gtfs.zip"; + + /** + * The time in ISO format at which the simulation should start. + * Example format: 2024-11-27T10:15:30 + */ public String scheduleDateTime = "2024-12-03T10:15:30"; + + /** + * The time zone of the location where the PT system is implemented. + */ public String timeZone = "ECT"; } From 85ece70f1d83aea7aa394bc2376a77327396eac9 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Wed, 4 Dec 2024 16:09:26 +0100 Subject: [PATCH 03/13] refactor(routing): use opencsv instead of javacsv for CSV parsing from GTFS --- bundle/src/assembly/mosaic-bundle.xml | 1 + lib/mosaic-routing/pom.xml | 5 +- .../main/java/com/csvreader/CsvReader.java | 108 ++++++++++++++++++ .../mosaic/lib/routing/pt/PtRoutingTest.java | 22 ++-- pom.xml | 14 ++- 5 files changed, 133 insertions(+), 17 deletions(-) create mode 100644 lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java diff --git a/bundle/src/assembly/mosaic-bundle.xml b/bundle/src/assembly/mosaic-bundle.xml index c0d73ba4c..55aee075d 100644 --- a/bundle/src/assembly/mosaic-bundle.xml +++ b/bundle/src/assembly/mosaic-bundle.xml @@ -156,6 +156,7 @@ io.mobilitydata.transit:gtfs-realtime-bindings net.sourceforge.javacsv:javacsv org.mapdb:mapdb + com.opencsv:opencsv com.github.mwiede:jsch diff --git a/lib/mosaic-routing/pom.xml b/lib/mosaic-routing/pom.xml index ceaa0ff01..a01a4edaf 100644 --- a/lib/mosaic-routing/pom.xml +++ b/lib/mosaic-routing/pom.xml @@ -38,6 +38,10 @@ com.graphhopper graphhopper-reader-gtfs + + com.opencsv + opencsv + io.mobilitydata.transit gtfs-realtime-bindings @@ -47,7 +51,6 @@ guava - org.eclipse.mosaic mosaic-geomath diff --git a/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java new file mode 100644 index 000000000..c38a86585 --- /dev/null +++ b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java @@ -0,0 +1,108 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ +package com.csvreader; + +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvValidationException; +import com.opencsv.validators.LineValidator; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +/** + * Replaces com.csvreader.CsvReader from javacsv with an implementation which uses CSVReader from opencsv. + *

+ * By excluding javacsv jar and providing this class with the same full qualified name and same API as a supplement + * we are able to use opencsv instead without touching the code of graphhopper-reader-gtfs. + * Therefore, even though the IDE thinks this class is unused, it is actually used by graphhopper-reader-gtfs. + */ +public class CsvReader { + + private final CSVReader openCsvReader; + private final Map headerIndex = new HashMap<>(); + + private String[] currenRecord; + + public CsvReader(InputStream inputStream, char delimiter, Charset charset) { + this(new InputStreamReader(inputStream, charset), delimiter); + } + + public CsvReader(Reader openCsvReader) { + this(openCsvReader, ','); + } + + public CsvReader(Reader openCsvReader, char delimiter) { + this.openCsvReader = new CSVReaderBuilder(openCsvReader) + .withCSVParser(new CSVParserBuilder().withSeparator(delimiter).build()) + .withLineValidator(new IgnoreEmptyLines()) + .build(); + } + + public boolean readRecord() { + try { + currenRecord = this.openCsvReader.readNext(); + return currenRecord != null; + } catch (Exception e) { + return false; + } + } + + public boolean readHeaders() { + Validate.isTrue(currenRecord == null, "Reader has already been used."); + if (readRecord()) { + setHeaders(currenRecord); + return true; + } + return false; + } + + public void setHeaders(String[] strings) { + int index = 0; + for (String entry : strings) { + headerIndex.put(entry, index++); + } + } + + public String get(String column) { + Validate.isTrue(!headerIndex.isEmpty(), "No header defined."); + final Integer index = headerIndex.get(column); + return index != null && index < currenRecord.length + ? currenRecord[index] + : ""; + } + + private static class IgnoreEmptyLines implements LineValidator { + + @Override + public boolean isValid(String s) { + return StringUtils.isNotEmpty(s); + } + + @Override + public void validate(String s) throws CsvValidationException { + if (!isValid(s)) { + throw new CsvValidationException(); + } + } + } +} diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java index d36be2e1f..e7c67e388 100644 --- a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java @@ -32,7 +32,7 @@ import java.time.LocalTime; public class PtRoutingTest { - + @Rule public GeoProjectionRule transformationRule = new GeoProjectionRule(GeoPoint.latLon(36.9, -116.7)); @@ -72,39 +72,39 @@ public void initialize_skipInitialization() { } @Test - public void findRoute_walkOnlyCauseIAmFast() { + public void findRoute_findPublicTransportRoute() { ptRouting.initialize(routingConfiguration, configDir); PtRoutingResponse response = ptRouting.findPtRoute(new PtRoutingRequest( - LocalTime.of(8, 50).toNanoOfDay(), + LocalTime.of(8, 57).toNanoOfDay(), GeoPoint.latLon(36.900760, -116.766464), GeoPoint.latLon(36.907353, -116.761829), - new PtRoutingParameters().walkingSpeedKmh(5) + new PtRoutingParameters().walkingSpeedKmh(3) )); // ASSERT MultiModalRoute route = response.getBestRoute(); - assertEquals(1, route.getLegs().size()); + assertEquals(3, route.getLegs().size()); assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(0).getLegType()); + assertEquals(MultiModalLeg.Type.PUBLIC_TRANSPORT, route.getLegs().get(1).getLegType()); + assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(2).getLegType()); } @Test - public void findRoute_findPublicTransportRoute() { + public void findRoute_IWalkFasterThanTheBus() { ptRouting.initialize(routingConfiguration, configDir); PtRoutingResponse response = ptRouting.findPtRoute(new PtRoutingRequest( - LocalTime.of(8, 57).toNanoOfDay(), + LocalTime.of(8, 50).toNanoOfDay(), GeoPoint.latLon(36.900760, -116.766464), GeoPoint.latLon(36.907353, -116.761829), - new PtRoutingParameters().walkingSpeedKmh(3) + new PtRoutingParameters().walkingSpeedKmh(5) )); // ASSERT MultiModalRoute route = response.getBestRoute(); - assertEquals(3, route.getLegs().size()); + assertEquals(1, route.getLegs().size()); assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(0).getLegType()); - assertEquals(MultiModalLeg.Type.PUBLIC_TRANSPORT, route.getLegs().get(1).getLegType()); - assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(2).getLegType()); } } diff --git a/pom.xml b/pom.xml index 5f972d1c8..1fefa6cba 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,6 @@ 0.8.1 2.16.1 1.3.9 - 2.0 1.1.13 0.1.51 1.3.1 @@ -113,7 +112,8 @@ 0.2.16 1.5.0 5.6.0 - 1.0.8 + 1.0.8 + 5.9 3.23.2 2.0.12 3.42.0.0 @@ -360,13 +360,17 @@ javax.inject javax.inject + + net.sourceforge.javacsv + javacsv +
- net.sourceforge.javacsv - javacsv - ${version.javacsv} + com.opencsv + opencsv + ${version.opencsv} From 7abcd473cf661f27781cb683a3be0ce75b468de8 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Wed, 4 Dec 2024 18:22:59 +0100 Subject: [PATCH 04/13] clean(routing): exclude unused transient libraries --- NOTICE-THIRD-PARTY.md | 32 +++++++++++++++++++++++++++ bundle/src/assembly/mosaic-bundle.xml | 1 - pom.xml | 14 ++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/NOTICE-THIRD-PARTY.md b/NOTICE-THIRD-PARTY.md index de248d952..ef75a8aac 100644 --- a/NOTICE-THIRD-PARTY.md +++ b/NOTICE-THIRD-PARTY.md @@ -101,6 +101,14 @@ GraphHopper Core (8.0) * Source: https://github.com/graphhopper/graphhopper/graphhopper-core +GraphHopper Reader for Gtfs Data (8.0) + + * License: Apache-2.0 + * Maven artifact: `com.graphhopper:graphhopper-reader-gtfs:8.0` + * Project: https://www.graphhopper.com/graphhopper-reader-gtfs + * Source: https://github.com/graphhopper/graphhopper/graphhopper-reader-gtfs + + GraphHopper Web API (8.0) * License: Apache-2.0 @@ -117,6 +125,14 @@ Gson (2.10.1) * Source: https://github.com/google/gson/gson/ +gtfs-realtime-bindings (0.0.5) + + * License: Apache-2.0 + * Maven artifact: `io.mobilitydata.transit:gtfs-realtime-bindings:0.0.5` + * Project: https://github.com/MobilityData/gtfs-realtime-bindings + * Source: https://github.com/MobilityData/gtfs-realtime-bindings + + Guava: Google Core Libraries for Java (32.1.1-jre) * License: Apache-2.0 @@ -221,6 +237,22 @@ Logback Core Module (1.5.0) * Source: https://github.com/qos-ch/logback/logback-core +mapdb (1.0.8) + + * License: Apache-2.0 + * Maven artifact: `org.mapdb:mapdb:1.0.8` + * Project: http://www.mapdb.org + * Source: https://github.com/jankotek/MapDB + + +opencsv (5.9) + + * License: Apache-2.0 + * Maven artifact: `com.opencsv:opencsv:5.9` + * Project: http://opencsv.sf.net + * Source: https://sourceforge.net/p/opencsv/source/ci/master/tree/ + + org.locationtech.jts:jts-core (1.19.0) * License: BSD-3-Clause (Eclipse Distribution License), Eclipse Public License, Version 2.0 diff --git a/bundle/src/assembly/mosaic-bundle.xml b/bundle/src/assembly/mosaic-bundle.xml index 55aee075d..234d2a378 100644 --- a/bundle/src/assembly/mosaic-bundle.xml +++ b/bundle/src/assembly/mosaic-bundle.xml @@ -154,7 +154,6 @@ com.graphhopper:graphhopper-reader-gtfs io.mobilitydata.transit:gtfs-realtime-bindings - net.sourceforge.javacsv:javacsv org.mapdb:mapdb com.opencsv:opencsv diff --git a/pom.xml b/pom.xml index 1fefa6cba..6b7b7c17f 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,7 @@ 1.3.9-1 8.0 2.10.1 - 0.0.5 + 0.0.5 32.1.1-jre 0.8.1 2.16.1 @@ -113,7 +113,7 @@ 1.5.0 5.6.0 1.0.8 - 5.9 + 5.9 3.23.2 2.0.12 3.42.0.0 @@ -371,6 +371,16 @@ com.opencsv opencsv ${version.opencsv} + + + commons-beanutils + commons-beanutils + + + org.apache.commons + commons-collections4 + + From 789f5bc47ca91700612cbfd2050fda19fb85c059 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Wed, 4 Dec 2024 18:41:49 +0100 Subject: [PATCH 05/13] clean(routing): resolve several checkstyle problems --- .../main/java/com/csvreader/CsvReader.java | 1 + .../mosaic/lib/routing/pt/MultiModalLeg.java | 27 +++++-- .../lib/routing/pt/MultiModalRoute.java | 20 ------ .../mosaic/lib/routing/pt/PtRouting.java | 42 ++++++++--- .../lib/routing/pt/PtTimeConversion.java | 70 ------------------- 5 files changed, 52 insertions(+), 108 deletions(-) delete mode 100644 lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java diff --git a/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java index c38a86585..b79991740 100644 --- a/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java +++ b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java @@ -12,6 +12,7 @@ * * Contact: mosaic@fokus.fraunhofer.de */ + package com.csvreader; import com.opencsv.CSVParserBuilder; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java index e62fbaec0..8f7e22738 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java @@ -25,20 +25,24 @@ public enum Type { private Type legType; - //For legs where a vehicle needs to be spawned + // For legs where a vehicle needs to be spawned private VehicleDeparture vehicleLeg = null; - //For PTlegs + // For PTlegs private PtLeg publicTransportationLeg = null; + // For walk legs private WalkLeg walkLeg = null; - //For legs where a vehicle already exists - private String carID = null; + // For legs where a vehicle already exists + private String sharedVehicleId = null; public long departureTime; public long arrivalTime; + /** + * Creates a new leg in which a new vehicle must be spawned. + */ public MultiModalLeg(VehicleDeparture vehicleLeg, long departureTime, long arrivalTime) { this.legType = Type.VEHICLE_PRIVATE; this.vehicleLeg = vehicleLeg; @@ -47,6 +51,9 @@ public MultiModalLeg(VehicleDeparture vehicleLeg, long departureTime, long arriv this.arrivalTime = arrivalTime; } + /** + * Creates a new leg which uses public transport. + */ public MultiModalLeg(PtLeg ptRoute, long departureTime, long arrivalTime) { this.legType = Type.PUBLIC_TRANSPORT; this.publicTransportationLeg = ptRoute; @@ -55,6 +62,9 @@ public MultiModalLeg(PtLeg ptRoute, long departureTime, long arrivalTime) { this.arrivalTime = arrivalTime; } + /** + * Creates a new leg which uses walking mode. + */ public MultiModalLeg(WalkLeg walkLeg, long departureTime, long arrivalTime) { this.legType = Type.WALKING; this.walkLeg = walkLeg; @@ -63,9 +73,12 @@ public MultiModalLeg(WalkLeg walkLeg, long departureTime, long arrivalTime) { this.arrivalTime = arrivalTime; } - public MultiModalLeg(String carID, long departureTime, long arrivalTime) { + /** + * Creates a new leg which uses a shared vehicle by a given vehicle ID. + */ + public MultiModalLeg(String vehicleId, long departureTime, long arrivalTime) { this.legType = Type.VEHICLE_PRIVATE; - this.carID = carID; + this.sharedVehicleId = vehicleId; this.departureTime = departureTime; this.arrivalTime = arrivalTime; @@ -74,7 +87,7 @@ public MultiModalLeg(String carID, long departureTime, long arrivalTime) { public Object getLeg() { return switch (legType) { case VEHICLE_PRIVATE -> vehicleLeg; - case VEHICLE_SHARED -> carID; + case VEHICLE_SHARED -> sharedVehicleId; case PUBLIC_TRANSPORT -> publicTransportationLeg; case WALKING -> walkLeg; }; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java index 2dce0b4ab..2df5a4624 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java @@ -30,24 +30,4 @@ public List getLegs() { return this.legs; } - /** - * can be used to check if the route exists and is valid, - * if allowTeleportation is set to true it ignores arrival/ departure times - * - * @return whether or not a valid route exists and is valid - */ - public boolean checkValidity() { - if (!legs.isEmpty()) { - for (int i = 0; i < legs.size() - 1; i++) { - if (legs.get(i).arrivalTime > legs.get(i + 1).departureTime) { - return false; - } - } - } else { - return false; - } - return true; - } - - } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java index 4dad4bc25..fe59f2f14 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java @@ -65,12 +65,20 @@ public class PtRouting { private LocalDateTime scheduleDateTime; private ZoneId timeZone; + /** + * Initializes the pt routing if it is enabled in the provided {@link CPublicTransportRouting}. + * All paths defined in the provided config are expcted to be relative to the provided configuration + * location. + */ public void initialize(CPublicTransportRouting routingConfiguration, File configurationLocation) { if (!routingConfiguration.enabled) { return; } - Path baseDirectory = configurationLocation.toPath(); + scheduleDateTime = LocalDateTime.parse(routingConfiguration.scheduleDateTime, DateTimeFormatter.ISO_DATE_TIME); + timeZone = ZoneId.of(ZoneId.SHORT_IDS.get(routingConfiguration.timeZone)); + + final Path baseDirectory = configurationLocation.toPath(); GraphHopperConfig ghConfig = new GraphHopperConfig() .putObject("import.osm.ignored_highways", "motorway,trunk,primary") @@ -79,9 +87,6 @@ public void initialize(CPublicTransportRouting routingConfiguration, File config .putObject("gtfs.file", baseDirectory.resolve(routingConfiguration.gtfsFile).toAbsolutePath().toString()) .setProfiles(Collections.singletonList(new Profile("foot").setVehicle("foot"))); - scheduleDateTime = LocalDateTime.parse(routingConfiguration.scheduleDateTime, DateTimeFormatter.ISO_DATE_TIME); - timeZone = ZoneId.of(ZoneId.SHORT_IDS.get(routingConfiguration.timeZone)); - final StopWatch sw = new StopWatch(); sw.start(); graphHopperGtfs = new GraphHopperGtfs(ghConfig); @@ -100,12 +105,17 @@ public void initialize(CPublicTransportRouting routingConfiguration, File config ).createWithoutRealtimeFeed(); } - - + /** + * Calculates a public transport route according to the given request. + * The request must contain a valid start and target position, as well as valid request time. + */ public PtRoutingResponse findPtRoute(PtRoutingRequest request) { if (ptRouter == null) { throw new IllegalStateException("PT Routing is not available. Must be enabled in application_config.json."); } + Validate.notNull(request.getStartingGeoPoint(), "Starting point must not be null."); + Validate.notNull(request.getTargetGeoPoint(), "Target point must not be null."); + Validate.isTrue(request.getRequestTime() >= 0, "Invalid request time."); Validate.isTrue(request.getRoutingParameters().getWalkingSpeedMps() > 0, "Walking speed must be greater than 0."); Instant departureTime = toScheduleTime(request.getRequestTime()); @@ -116,7 +126,7 @@ public PtRoutingResponse findPtRoute(PtRoutingRequest request) { request.getTargetGeoPoint().getLatitude(), request.getTargetGeoPoint().getLongitude() ); -// ghRequest.setBlockedRouteTypes(request.getRoutingParameters().excludedPtModes);//FIXME generalize this + // ghRequest.setBlockedRouteTypes(request.getRoutingParameters().excludedPtModes);//FIXME generalize this ghRequest.setEarliestDepartureTime(departureTime); ghRequest.setWalkSpeedKmH(request.getRoutingParameters().getWalkingSpeedMps() * 3.6); @@ -146,17 +156,27 @@ private List convertToMultiModalLegs(ResponsePath ghBestRoute) { if (leg instanceof Trip.PtLeg ptLeg) { List newStops = new ArrayList<>(); for (Trip.Stop stop : ptLeg.stops) { - newStops.add(new PtLeg.PtStop(GeoPoint.lonLat(stop.geometry.getX(), stop.geometry.getY()), fromScheduleTime(stop.departureTime), fromScheduleTime(stop.arrivalTime))); + newStops.add(new PtLeg.PtStop( + GeoPoint.lonLat(stop.geometry.getX(), stop.geometry.getY()), + fromScheduleTime(stop.departureTime), + fromScheduleTime(stop.arrivalTime) + )); } legs.add(new MultiModalLeg( - new PtLeg(newStops), newStops.get(0).departureTime(), Iterables.getLast(newStops).arrivalTime()) - ); + new PtLeg(newStops), + newStops.get(0).departureTime(), + Iterables.getLast(newStops).arrivalTime() + )); } else if (leg instanceof Trip.WalkLeg walkLeg) { List waypoints = new ArrayList<>(); for (Coordinate coordinate : walkLeg.geometry.getCoordinates()) { waypoints.add(GeoPoint.lonLat(coordinate.x, coordinate.y)); } - legs.add(new MultiModalLeg(new WalkLeg(waypoints), fromScheduleTime(leg.getDepartureTime()), fromScheduleTime(leg.getArrivalTime()))); + legs.add(new MultiModalLeg( + new WalkLeg(waypoints), + fromScheduleTime(leg.getDepartureTime()), + fromScheduleTime(leg.getArrivalTime()) + )); } } return legs; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java deleted file mode 100644 index 8f1173704..000000000 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtTimeConversion.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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: mosaic@fokus.fraunhofer.de - */ - -package org.eclipse.mosaic.lib.routing.pt; - -import org.eclipse.mosaic.rti.TIME; - -import java.time.LocalTime; -import java.util.Date; - -/** - * Contains functions to calculate between different time formats, since "time" is usually always referring to - * simulation time, but a real-world time is needed for the calculation of public transportation routes - */ -public final class PtTimeConversion { - - private static final LocalTime realWorldTime = LocalTime.of(0, 0, 0); - private static final long realWorldTimeNanoS = - TIME.HOUR * realWorldTime.getHour() + - TIME.MINUTE * realWorldTime.getMinute() + - TIME.SECOND * realWorldTime.getSecond(); - - private PtTimeConversion() { - //just need functions to calculate bewtween time formats - } - - public static LocalTime toLocalTime(long simTime) { - return LocalTime.ofNanoOfDay(simTime + realWorldTimeNanoS); - } - - public static long toSimTime(LocalTime time) { - int hourDiff = time.getHour() - realWorldTime.getHour(); - int minuteDiff = time.getMinute() - realWorldTime.getMinute(); - int secondDiff = time.getSecond() - realWorldTime.getSecond(); - - long simTime = TIME.HOUR * hourDiff + TIME.MINUTE * minuteDiff + TIME.SECOND * secondDiff; - - if (simTime < 0) { - System.out.println("Warning, calculated simtime is before sim actually starts"); - } - - return simTime; - } - - public static long toSimTime(Date date) { - return toSimTime(dateToLocalTime(date)); - } - - public static LocalTime dateToLocalTime(Date date) { - if (date == null) { - return null; - } - String[] splitString = date.toString().split(" "); - String[] timeStrings = splitString[3].split(":"); - return LocalTime.of(Integer.parseInt(timeStrings[0]), Integer.parseInt(timeStrings[1]), Integer.parseInt(timeStrings[2])); - } - -} From 1ab6f222f1bb7d08b5693e2b1f195a91d09ee624 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Thu, 5 Dec 2024 10:24:30 +0100 Subject: [PATCH 06/13] clean(routing): define default navigationConfiguration --- .../ambassador/ApplicationAmbassador.java | 5 +-- .../CentralNavigationComponent.java | 13 +++++-- .../config/CApplicationAmbassador.java | 4 +-- .../CApplicationAmbassadorScheme.json | 36 +++++++++++++++++++ .../CentralNavigationComponentTest.java | 3 +- .../config/CApplicationAmbassadorTest.java | 5 ++- .../config/CPublicTransportRouting.java | 6 ++-- .../lib/routing/config/CVehicleRouting.java | 2 +- .../mosaic/lib/routing/pt/MultiModalLeg.java | 4 +-- .../eclipse/mosaic/lib/routing/pt/PtLeg.java | 10 +++--- .../mosaic/lib/routing/pt/PtRouting.java | 10 ++++-- 11 files changed, 73 insertions(+), 25 deletions(-) diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java index 34be4f3ce..03597df11 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java @@ -143,8 +143,8 @@ public ApplicationAmbassador(AmbassadorParameter ambassadorParameter) { // set the CNC (central navigation component) CentralNavigationComponent cnc = new CentralNavigationComponent( ambassadorParameter, - ambassadorConfig.navigationConfiguration, - ambassadorConfig.publicTransportConfiguration + Validate.notNull(ambassadorConfig.navigationConfiguration, "Field navigationConfiguration must not be null."), + Validate.notNull(ambassadorConfig.publicTransportConfiguration, "Field publicTransportConfiguration must not be null.") ); SimulationKernel.SimulationKernel.setCentralNavigationComponent(cnc); } @@ -229,6 +229,7 @@ public void initialize(final long startTime, final long endTime) throws Internal private void shutdownSimulationUnits(Event event) { SimulationKernel.SimulationKernel.setCurrentSimulationTime(event.getTime()); + SimulationKernel.SimulationKernel.getCentralNavigationComponent().close(); log.debug("remaining events: {}", eventScheduler.getAllEvents()); UnitSimulator.UnitSimulator.removeAllSimulationUnits(); diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java index 40dc6eeb5..aad4948b3 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java @@ -59,6 +59,7 @@ import java.util.List; import java.util.Map; import java.util.function.Predicate; +import javax.annotation.Nonnull; /** * The {@link CentralNavigationComponent} unites functionality concerned with @@ -114,8 +115,8 @@ public class CentralNavigationComponent { */ public CentralNavigationComponent( final AmbassadorParameter ambassadorParameter, - CApplicationAmbassador.CRoutingByType navigationConfiguration, - CPublicTransportRouting publicTransportConfiguration + @Nonnull CApplicationAmbassador.CRoutingByType navigationConfiguration, + @Nonnull CPublicTransportRouting publicTransportConfiguration ) { this.applicationAmbassadorParameter = ambassadorParameter; this.configuration = navigationConfiguration; @@ -138,7 +139,7 @@ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateExcep try { this.log.info("Initializing CNC-Navigation"); - routing = createFromType(this.configuration != null ? this.configuration.type : null); + routing = createFromType(configuration.type); routing.initialize(configuration, applicationAmbassadorParameter.configuration.getParentFile()); ptRouting = new PtRouting(); @@ -167,6 +168,12 @@ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateExcep } } + public void close() { + if (ptRouting != null) { + ptRouting.close(); + } + } + /** * Returns an unmodifiable view of all routes known to the {@link SimulationKernel}. * diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java index 223b45795..c879aceb9 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java @@ -64,7 +64,7 @@ public class CApplicationAmbassador implements Serializable { * Class containing the information for the configuration of the * Routing/Navigation (CentralNavigationComponent). */ - public CRoutingByType navigationConfiguration = null; + public CRoutingByType navigationConfiguration = new CRoutingByType(); /** * Configuration for the perception backend used in the ApplicationSimulator @@ -84,7 +84,7 @@ public static class CRoutingByType extends CVehicleRouting implements Serializab * to use for navigation. Possible values are {@code "database" or "no-routing"}, * or any full-qualified java class name. */ - public String type = null; + public String type = "database"; } } diff --git a/fed/mosaic-application/src/main/resources/CApplicationAmbassadorScheme.json b/fed/mosaic-application/src/main/resources/CApplicationAmbassadorScheme.json index 8cabada77..d8ea6ba43 100644 --- a/fed/mosaic-application/src/main/resources/CApplicationAmbassadorScheme.json +++ b/fed/mosaic-application/src/main/resources/CApplicationAmbassadorScheme.json @@ -27,6 +27,10 @@ "description": "Configuration options for the route calculation.", "$ref": "#/definitions/routingByType" }, + "publicTransportConfiguration": { + "description": "Configuration options for the public transport route calculation.", + "$ref": "#/definitions/ptRouting" + }, "perceptionConfiguration": { "description": "Configuration options for perception backend", "$ref": "#/definitions/perceptionConfiguration" @@ -48,6 +52,38 @@ } } }, + "ptRouting": { + "title": "ptRouting", + "description": "Object to define the configuration for the public transport route calculation.", + "type": "object", + "properties": { + "enabled": { + "description": "Defines, if public transport routing is enabled.", + "default": false, + "type": "boolean" + }, + "osmFile": { + "description": "The relative path to the OSM file to load with the GTFS feed.", + "default": "map.osm", + "type": "string" + }, + "gtfsFile": { + "description": "The relative path to the GTFS feed (ZIP archive).", + "default": "gtfs.zip", + "type": "string" + }, + "scheduleDateTime": { + "description": "The real time in ISO format at which the beginning of the simulation should point at. Example format: 2024-11-27T10:15:30", + "default": "2024-12-03T10:15:30", + "type": "string" + }, + "timeZone": { + "description": " The time zone of the location where the PT system is implemented, e.g., \"ECT\".", + "default": "ECT", + "type": "string" + } + } + }, "perceptionConfiguration": { "title": "perceptionConfiguration", "description": "Configuration options for perception backend", diff --git a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java index 60c4e6dd2..c5742bcea 100644 --- a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java +++ b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java @@ -24,7 +24,6 @@ import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -126,7 +125,7 @@ public void initialize_vehicleRoutesInitializationSent() throws InternalFederate cnc.initialize(rtiAmbassadorMock); //ASSERT - verify(routingMock).initialize(isNull(CVehicleRouting.class), isA(File.class)); + verify(routingMock).initialize(isA(CVehicleRouting.class), isA(File.class)); verify(rtiAmbassadorMock).triggerInteraction(isA(VehicleRoutesInitialization.class)); } diff --git a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassadorTest.java b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassadorTest.java index 3fc41ab5d..729538880 100644 --- a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassadorTest.java +++ b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassadorTest.java @@ -18,7 +18,6 @@ import static org.hamcrest.CoreMatchers.startsWith; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -58,8 +57,8 @@ public void readValidConfig_assertProperties() throws InstantiationException { assertNotNull(applicationAmbassadorConfiguration); // assert that configuration is created assertEquals(40 * TIME.SECOND, applicationAmbassadorConfiguration.messageCacheTime); assertTrue(applicationAmbassadorConfiguration.encodePayloads); - assertNull(applicationAmbassadorConfiguration.navigationConfiguration); - + assertNotNull(applicationAmbassadorConfiguration.navigationConfiguration); + assertEquals("database", applicationAmbassadorConfiguration.navigationConfiguration.type); } /** diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java index e63c59cb6..773308ee7 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java @@ -15,7 +15,9 @@ package org.eclipse.mosaic.lib.routing.config; -public class CPublicTransportRouting { +import java.io.Serializable; + +public class CPublicTransportRouting implements Serializable { /** * Declares if PT routing is enabled (default=false). @@ -33,7 +35,7 @@ public class CPublicTransportRouting { public String gtfsFile = "gtfs.zip"; /** - * The time in ISO format at which the simulation should start. + * The real time in ISO format at which the beginning of the simulation should point at. * Example format: 2024-11-27T10:15:30 */ public String scheduleDateTime = "2024-12-03T10:15:30"; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CVehicleRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CVehicleRouting.java index 77ae27ebc..a44779975 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CVehicleRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CVehicleRouting.java @@ -23,7 +23,7 @@ public class CVehicleRouting implements Serializable { /** - * The source for the route calculation, e.g. the path to the database containing the road network. + * The source for the route calculation, e.g., the path to the database containing the road network. */ public String source = null; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java index 8f7e22738..ca41183f6 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java @@ -23,12 +23,12 @@ public enum Type { WALKING, VEHICLE_SHARED, VEHICLE_PRIVATE, PUBLIC_TRANSPORT } - private Type legType; + private final Type legType; // For legs where a vehicle needs to be spawned private VehicleDeparture vehicleLeg = null; - // For PTlegs + // For public transport legs private PtLeg publicTransportationLeg = null; // For walk legs diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java index 6351083ec..98c426878 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java @@ -24,14 +24,14 @@ public class PtLeg { public record PtStop(GeoPoint location, Long departureTime, Long arrivalTime) {} - private final List legs = new ArrayList<>(); + private final List stops = new ArrayList<>(); - public PtLeg(List legs) { - this.legs.addAll(legs); + public PtLeg(List stops) { + this.stops.addAll(stops); } - public List getLegs() { - return legs; + public List getStops() { + return stops; } } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java index fe59f2f14..033679c74 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java @@ -52,6 +52,8 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class PtRouting { @@ -186,18 +188,20 @@ private Instant toScheduleTime(long simTime) { return scheduleDateTime.plusNanos(simTime).atZone(timeZone).toInstant(); } - private Long fromScheduleTime(Date date) { + private Long fromScheduleTime(@Nullable Date date) { if (date == null) { return null; } return fromScheduleTime(date.toInstant()); } - private long fromScheduleTime(Instant instant) { + private long fromScheduleTime(@Nonnull Instant instant) { return scheduleDateTime.until(LocalDateTime.ofInstant(instant, timeZone), ChronoUnit.NANOS); } public void close() { - graphHopperGtfs.close(); + if (graphHopperGtfs != null) { + graphHopperGtfs.close(); + } } } From af26c87d26d90738508087b3c71e3e2f120d3bec Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Thu, 5 Dec 2024 17:15:36 +0100 Subject: [PATCH 07/13] fix(routing): fix handling of empty lines --- .../main/java/com/csvreader/CsvReader.java | 31 ++++++------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java index b79991740..bc4854e67 100644 --- a/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java +++ b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java @@ -18,11 +18,10 @@ import com.opencsv.CSVParserBuilder; import com.opencsv.CSVReader; import com.opencsv.CSVReaderBuilder; -import com.opencsv.exceptions.CsvValidationException; -import com.opencsv.validators.LineValidator; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; @@ -55,15 +54,20 @@ public CsvReader(Reader openCsvReader) { public CsvReader(Reader openCsvReader, char delimiter) { this.openCsvReader = new CSVReaderBuilder(openCsvReader) .withCSVParser(new CSVParserBuilder().withSeparator(delimiter).build()) - .withLineValidator(new IgnoreEmptyLines()) .build(); } public boolean readRecord() { try { - currenRecord = this.openCsvReader.readNext(); - return currenRecord != null; - } catch (Exception e) { + do { + currenRecord = this.openCsvReader.readNextSilently(); + if (currenRecord == null) { + return false; + } + } while (currenRecord.length == 1 && StringUtils.isEmpty(currenRecord[0])); + return true; + } catch (IOException e) { + currenRecord = null; return false; } } @@ -91,19 +95,4 @@ public String get(String column) { ? currenRecord[index] : ""; } - - private static class IgnoreEmptyLines implements LineValidator { - - @Override - public boolean isValid(String s) { - return StringUtils.isNotEmpty(s); - } - - @Override - public void validate(String s) throws CsvValidationException { - if (!isValid(s)) { - throw new CsvValidationException(); - } - } - } } From 20dbb2019aad61bf75bca9bdd484128693239747 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Wed, 11 Dec 2024 14:08:03 +0100 Subject: [PATCH 08/13] feat(routing): new UNITS class for km/h conversion --- .../GraphHopperEdgeProperties.java | 5 +- .../graphhopper/GraphHopperWeighting.java | 3 +- .../graphhopper/util/TurnCostAnalyzer.java | 7 ++- .../graphhopper/GraphHopperWeightingTest.java | 7 ++- .../util/DatabaseGraphLoaderTest.java | 3 +- .../lib/util/gson/UnitFieldAdapter.java | 4 +- .../java/org/eclipse/mosaic/rti/TIME.java | 7 +-- .../java/org/eclipse/mosaic/rti/UNITS.java | 63 +++++++++++++++++++ .../org/eclipse/mosaic/rti/UNITSTest.java | 37 +++++++++++ 9 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java create mode 100644 rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java index 048030d1e..dad44f279 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java @@ -22,6 +22,7 @@ import org.eclipse.mosaic.lib.routing.graphhopper.util.GraphhopperToDatabaseMapper; import org.eclipse.mosaic.lib.routing.graphhopper.util.VehicleEncoding; import org.eclipse.mosaic.lib.routing.graphhopper.util.WayTypeEncoder; +import org.eclipse.mosaic.rti.UNITS; import com.google.common.collect.Iterables; import com.graphhopper.util.EdgeIteratorState; @@ -59,8 +60,8 @@ void setCurrentEdgeIterator(EdgeIteratorState currentEdgeIterator, boolean rever public double getSpeed() { Validate.notNull(currentEdgeIterator, "Edge iterator is null"); return reverseRequests - ? currentEdgeIterator.getReverse(encoding.speed()) / 3.6 - : currentEdgeIterator.get(encoding.speed()) / 3.6; + ? currentEdgeIterator.getReverse(encoding.speed()) * UNITS.KMH + : currentEdgeIterator.get(encoding.speed()) * UNITS.KMH; } @Override diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java index 778ae9753..011435ff0 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java @@ -19,6 +19,7 @@ import org.eclipse.mosaic.lib.routing.graphhopper.util.GraphhopperToDatabaseMapper; import org.eclipse.mosaic.lib.routing.graphhopper.util.VehicleEncoding; import org.eclipse.mosaic.lib.routing.graphhopper.util.WayTypeEncoder; +import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.weighting.AbstractWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; @@ -40,7 +41,7 @@ public class GraphHopperWeighting extends AbstractWeighting { public GraphHopperWeighting(VehicleEncoding vehicleEncoding, WayTypeEncoder wayTypeEncoder, TurnCostProvider turnCostProvider, GraphhopperToDatabaseMapper graphMapper) { super(vehicleEncoding.access(), vehicleEncoding.speed(), turnCostProvider); this.edgePropertiesState = new GraphHopperEdgeProperties(vehicleEncoding, wayTypeEncoder, graphMapper); - this.maxSpeed = speedEnc.getMaxOrMaxStorableDecimal() / 3.6; // getMaxOrMaxStorableDecimal returns the speed in km/h + this.maxSpeed = speedEnc.getMaxOrMaxStorableDecimal() * UNITS.KILOMETER_PER_HOUR; // getMaxOrMaxStorableDecimal returns the speed in km/h } public GraphHopperWeighting setRoutingCostFunction(RoutingCostFunction routingCostFunction) { diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java index 976ed287a..0f273a973 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java @@ -17,6 +17,7 @@ import org.eclipse.mosaic.lib.geo.GeoPoint; import org.eclipse.mosaic.lib.geo.GeoUtils; +import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.util.AccessFilter; import com.graphhopper.storage.BaseGraph; @@ -140,8 +141,8 @@ private double calculateTurnCosts(VehicleEncoding encoding, EdgeIterator incomin double alpha = (bearingViaTo - (bearingFromVia) + 360) % 360; //get length and max speed of edges - double v1 = incomingEdge.get(encoding.speed()) / 3.6; - double v2 = outgoingEdge.get(encoding.speed()) / 3.6; + double v1 = incomingEdge.get(encoding.speed()) * UNITS.KMH; + double v2 = outgoingEdge.get(encoding.speed()) * UNITS.KMH; double l1 = incomingEdge.getDistance(); double l2 = outgoingEdge.getDistance(); @@ -176,7 +177,7 @@ private double calculateTurnCosts(VehicleEncoding encoding, EdgeIterator incomin if (WayTypeEncoder.isResidential(incomingWayType) && WayTypeEncoder.isResidential( outgoingWayType)) { //decrease max turn speed to 10 km/h, if it is on a junction within a residential area - turnVelocity = Math.min(turnVelocity, 10.0 / 3.6); + turnVelocity = Math.min(turnVelocity, 10.0 * UNITS.KMH); } // drivers usually do not max out their turn velocity diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java index 374203e5f..5f03bc089 100644 --- a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java @@ -21,6 +21,7 @@ import org.eclipse.mosaic.lib.routing.graphhopper.junit.TestGraphRule; import org.eclipse.mosaic.lib.routing.graphhopper.util.OptionalTurnCostProvider; import org.eclipse.mosaic.lib.routing.graphhopper.util.VehicleEncoding; +import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.util.EdgeExplorer; @@ -48,7 +49,7 @@ public void fastest_noTurnCosts() { double weight = w.calcEdgeWeight(it, false); double turnWeight = w.calcTurnWeight(1, 0, 0); - assertEquals(distance / enc.speed().getMaxStorableDecimal() * 3.6, weight, 0.1d); + assertEquals(distance / enc.speed().getMaxStorableDecimal() / UNITS.KMH, weight, 0.1d); assertEquals(0, turnWeight, 0.1d); } @@ -110,7 +111,7 @@ public void fastest_turnCosts() { double weight = w.calcEdgeWeight(it, false); double turnWeight = w.calcTurnWeight(1, 0, 0); - assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() * 3.6, weight, 0.1d); + assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() / UNITS.KMH, weight, 0.1d); assertEquals(10, turnWeight, 0.1d); } @@ -152,7 +153,7 @@ public void fastest_turnRestriction() { double weight = w.calcEdgeWeight(it, false); double turnWeight = w.calcTurnWeight(1, 0, 0); - assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() * 3.6, weight, 0.1d); + assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() / UNITS.KMH, weight, 0.1d); assertEquals(Double.POSITIVE_INFINITY, turnWeight, 0.1d); } diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java index a67db7f0a..2b7eccba3 100644 --- a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java @@ -22,6 +22,7 @@ import org.eclipse.mosaic.lib.database.Database; import org.eclipse.mosaic.lib.routing.graphhopper.junit.TestGraphRule; +import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.AccessFilter; @@ -131,7 +132,7 @@ public void correctImport() throws Exception { //assert outgoing edges of node 4 it = expl.setBaseNode(n4); - assertionMap.put(n2, edgeAssertion(n2, con2_4_2, 50, 30 * 3.6 * 0.9, true)); + assertionMap.put(n2, edgeAssertion(n2, con2_4_2, 50, 30 / UNITS.KMH * 0.9, true)); assertNextEdge(vehicleEncoding.speed(), wayTypeEnc, it, assertionMap); assertTrue(assertionMap.isEmpty()); assertFalse(it.next()); diff --git a/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java b/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java index 9f7b09c85..eef83422b 100644 --- a/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java +++ b/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java @@ -15,6 +15,8 @@ package org.eclipse.mosaic.lib.util.gson; +import org.eclipse.mosaic.rti.UNITS; + import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.TypeAdapter; @@ -133,7 +135,7 @@ private double determineSpeedDivisor(String timeUnit) { double determineUnitMultiplier(String prefix, String unit) { if (unit.startsWith("mile")) { //special case - return 1609.344; + return UNITS.MILE; } else if (StringUtils.isNotEmpty(prefix)) { return UNIT_MULTIPLIERS.getOrDefault(prefix, 1d); } diff --git a/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java b/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java index cf192a73c..d1b1f6701 100644 --- a/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java +++ b/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java @@ -27,17 +27,17 @@ private TIME() { } /** - * One nano-second in simulation time. + * One nanosecond in simulation time. */ public static final long NANO_SECOND = 1; /** - * One micro-second in simulation time. + * One microsecond in simulation time. */ public static final long MICRO_SECOND = 1000 * NANO_SECOND; /** - * One milli-second in simulation time . + * One millisecond in simulation time . */ public static final long MILLI_SECOND = 1000 * MICRO_SECOND; @@ -78,7 +78,6 @@ public static String format(long nanosecond) { sb.append(" s"); return sb.toString(); - } } diff --git a/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java b/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java new file mode 100644 index 000000000..007b0acae --- /dev/null +++ b/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java @@ -0,0 +1,63 @@ +/* + * 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.rti; + +public final class UNITS { + + private UNITS() { + // access to constants only + } + + /** + * Distance of one meter. + */ + public static final double METER = 1; + + /** + * Distance of one kilometer. + */ + public static final double KILOMETER = 1000 * METER; + + /** + * Distance of one mile in meters. + */ + public static final double MILE = 1609.344 * METER; + + /** + * Speed of one meter per second. + */ + public static final double METER_PER_SECOND = 1; + + /** + * Speed of one kilometer per hour in meter per second. + */ + public static final double KILOMETER_PER_HOUR = 1 / 3.6; + + /** + * Speed of one mile per hour in meter per second. + */ + public static final double MILES_PER_HOUR = 1.609344 * KILOMETER_PER_HOUR; + + /** + * Speed of one kilometer per hour in meter per second. + */ + public static final double KMH = KILOMETER_PER_HOUR; + + /** + * Speed of one mile per hour in meter per second. + */ + public static final double MPH = MILES_PER_HOUR; +} diff --git a/rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java b/rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java new file mode 100644 index 000000000..a9e7b6e4c --- /dev/null +++ b/rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 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: mosaic@fokus.fraunhofer.de + */ + +package org.eclipse.mosaic.rti; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class UNITSTest { + + @Test + public void testUnitsConstants() { + double delta = 1e-10; + + assertEquals(1, UNITS.METER, delta); + assertEquals(1000, UNITS.KILOMETER, delta); + assertEquals(1609.344, UNITS.MILE, delta); + + assertEquals(13.88, 50 * UNITS.KMH, 0.01); // Kilometers per hour -> Meters per second + assertEquals(15.65, 35 * UNITS.MPH, 0.01); // Miles per hour -> Meters per second + assertEquals(48.28, 30 * UNITS.MPH / UNITS.KMH, 0.01); // Miles per hour -> Kilometers per hour + } + +} From 3e0229a979b407c7bbf0dc2936134faf14941f78 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Wed, 11 Dec 2024 14:10:01 +0100 Subject: [PATCH 09/13] docs(routing): javadoc --- .../CentralNavigationComponent.java | 2 +- .../mosaic/lib/routing/pt/MultiModalLeg.java | 62 ++++++++++++++----- .../lib/routing/pt/MultiModalRoute.java | 6 ++ .../eclipse/mosaic/lib/routing/pt/PtLeg.java | 15 ++++- .../mosaic/lib/routing/pt/PtRouting.java | 7 ++- .../lib/routing/pt/PtRoutingParameters.java | 6 +- .../lib/routing/pt/PtRoutingRequest.java | 15 +++++ .../lib/routing/pt/PtRoutingResponse.java | 9 ++- .../mosaic/lib/routing/pt/WalkLeg.java | 8 ++- 9 files changed, 107 insertions(+), 23 deletions(-) diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java index aad4948b3..aa898528d 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java @@ -90,7 +90,7 @@ public class CentralNavigationComponent { /** - * Public Transport routing + * Access to Public Transport routing. */ private PtRouting ptRouting; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java index ca41183f6..bbbde3ce3 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java @@ -17,28 +17,54 @@ import org.eclipse.mosaic.lib.objects.vehicle.VehicleDeparture; +/** + * A leg of a multi-modal-journey consists of a planned departure and planned arrival time, and + * details about the transport mode, such as the walking path or the public transport route. + */ public class MultiModalLeg { public enum Type { - WALKING, VEHICLE_SHARED, VEHICLE_PRIVATE, PUBLIC_TRANSPORT + /** + * For legs which uses public transport. + */ + PUBLIC_TRANSPORT, + /** + * For legs which will require foot work. + */ + WALKING, + /** + * For legs which require to spawn a new vehicle. + */ + VEHICLE_PRIVATE, + /** + * For legs which uses a shared vehicle which already exists in the simulation. + */ + VEHICLE_SHARED } private final Type legType; + private final long departureTime; + private final long arrivalTime; - // For legs where a vehicle needs to be spawned - private VehicleDeparture vehicleLeg = null; - - // For public transport legs + /** + * For legs which uses public transport. + */ private PtLeg publicTransportationLeg = null; - // For walk legs + /** + * For legs which will require foot work. + */ private WalkLeg walkLeg = null; - // For legs where a vehicle already exists - private String sharedVehicleId = null; + /** + * For legs which require to spawn a new vehicle. + */ + private VehicleDeparture vehicleLeg = null; - public long departureTime; - public long arrivalTime; + /** + * For legs which uses a shared vehicle which already exists in the simulation. + */ + private String sharedVehicleId = null; /** * Creates a new leg in which a new vehicle must be spawned. @@ -84,6 +110,18 @@ public MultiModalLeg(String vehicleId, long departureTime, long arrivalTime) { this.arrivalTime = arrivalTime; } + public long getArrivalTime() { + return arrivalTime; + } + + public long getDepartureTime() { + return departureTime; + } + + public Type getLegType() { + return legType; + } + public Object getLeg() { return switch (legType) { case VEHICLE_PRIVATE -> vehicleLeg; @@ -92,8 +130,4 @@ public Object getLeg() { case WALKING -> walkLeg; }; } - - public Type getLegType() { - return legType; - } } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java index 2df5a4624..9d77c6a16 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java @@ -18,6 +18,9 @@ import java.util.ArrayList; import java.util.List; +/** + * A multi-modal route which consists of multiple legs. + */ public class MultiModalRoute { private final List legs = new ArrayList<>(); @@ -26,6 +29,9 @@ public MultiModalRoute(List legs) { this.legs.addAll(legs); } + /** + * Returns the individual legs of this multi-modal route. + */ public List getLegs() { return this.legs; } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java index 98c426878..903beaa6c 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtLeg.java @@ -20,9 +20,19 @@ import java.util.ArrayList; import java.util.List; +/** + * A public transport leg contains all pt stops of the route. + */ public class PtLeg { - public record PtStop(GeoPoint location, Long departureTime, Long arrivalTime) {} + /** + * Each public transport stop consists of its geo-location and the planned arrival and departure time at this stop. + * + * @param location The geographic location of the stop. + * @param arrivalTime The time when arriving at this stop. {@code null} for the first stop of the leg. + * @param departureTime The time when leaving this stop. {@code null} for the last stop of the leg. + */ + public record PtStop(GeoPoint location, Long arrivalTime, Long departureTime) {} private final List stops = new ArrayList<>(); @@ -30,6 +40,9 @@ public PtLeg(List stops) { this.stops.addAll(stops); } + /** + * Returns the list of stops along the public transport route. + */ public List getStops() { return stops; } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java index 033679c74..d21d55fb7 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java @@ -17,6 +17,7 @@ import org.eclipse.mosaic.lib.geo.GeoPoint; import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting; +import org.eclipse.mosaic.rti.UNITS; import com.google.common.collect.Iterables; import com.graphhopper.GHResponse; @@ -130,7 +131,7 @@ public PtRoutingResponse findPtRoute(PtRoutingRequest request) { ); // ghRequest.setBlockedRouteTypes(request.getRoutingParameters().excludedPtModes);//FIXME generalize this ghRequest.setEarliestDepartureTime(departureTime); - ghRequest.setWalkSpeedKmH(request.getRoutingParameters().getWalkingSpeedMps() * 3.6); + ghRequest.setWalkSpeedKmH(request.getRoutingParameters().getWalkingSpeedMps() / UNITS.KMH); final Future responseFuture = routingExecution.submit(() -> ptRouter.route(ghRequest)); final GHResponse route; @@ -160,8 +161,8 @@ private List convertToMultiModalLegs(ResponsePath ghBestRoute) { for (Trip.Stop stop : ptLeg.stops) { newStops.add(new PtLeg.PtStop( GeoPoint.lonLat(stop.geometry.getX(), stop.geometry.getY()), - fromScheduleTime(stop.departureTime), - fromScheduleTime(stop.arrivalTime) + fromScheduleTime(stop.arrivalTime), + fromScheduleTime(stop.departureTime) )); } legs.add(new MultiModalLeg( diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java index 4f92c1790..0bae4afe2 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java @@ -15,12 +15,14 @@ package org.eclipse.mosaic.lib.routing.pt; +import org.eclipse.mosaic.rti.UNITS; + public class PtRoutingParameters { - private double walkingSpeedMps = 5 / 3.6; + private double walkingSpeedMps = 5 * UNITS.KILOMETER_PER_HOUR; public PtRoutingParameters walkingSpeedKmh(double kmh) { - walkingSpeedMps = kmh / 3.6; + walkingSpeedMps = kmh * UNITS.KILOMETER_PER_HOUR; return this; } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java index 0682be96b..41d30374f 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java @@ -25,10 +25,25 @@ public class PtRoutingRequest { private final PtRoutingParameters routingParameters; + /** + * Constructs a request for calculating a public transport route. + * + * @param requestTime The earliest time to start the journey. + * @param from The geographic location to start the journey. + * @param to The geographic location to end the journey. + */ public PtRoutingRequest(long requestTime, GeoPoint from, GeoPoint to) { this(requestTime, from, to, new PtRoutingParameters()); } + /** + * Constructs a request for calculating a public transport route. + * + * @param requestTime The earliest time to start the journey. + * @param from The geographic location to start the journey. + * @param to The geographic location to end the journey. + * @param additionalParameters Additional parameters, such as walking speed. + */ public PtRoutingRequest(long requestTime, GeoPoint from, GeoPoint to, PtRoutingParameters additionalParameters) { this.requestTime = requestTime; this.startingGeoPoint = from; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java index 8b5e949da..54cbb70bc 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java @@ -15,6 +15,10 @@ package org.eclipse.mosaic.lib.routing.pt; +/** + * The result of the routing request. Contains the multi-modal route which + * matches the routing request at best. + */ public class PtRoutingResponse { private final MultiModalRoute bestRoute; @@ -23,7 +27,10 @@ public PtRoutingResponse(MultiModalRoute bestRoute) { this.bestRoute = bestRoute; } - public MultiModalRoute getBestRoute() { + /** + * Returns the best multi-modal route of the route calculation. + */ + public final MultiModalRoute getBestRoute() { return bestRoute; } } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java index 9e991a051..ff7d98931 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/WalkLeg.java @@ -20,6 +20,9 @@ import java.util.ArrayList; import java.util.List; +/** + * A walking leg contains a linestring of geographical points which form the walking route. + */ public class WalkLeg { private final List waypoints = new ArrayList<>(); @@ -28,7 +31,10 @@ public WalkLeg(List waypoints) { this.waypoints.addAll(waypoints); } - public List getWaypoints() { + /** + * Returns the list of geographical positions which form the walking route. + */ + public final List getWaypoints() { return waypoints; } } From 875b11baa31e67b75b201da037f71f91f45fd222 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Thu, 12 Dec 2024 10:08:04 +0100 Subject: [PATCH 10/13] Revert "feat(routing): new UNITS class for km/h conversion" This reverts commit 20dbb2019aad61bf75bca9bdd484128693239747. --- .../GraphHopperEdgeProperties.java | 5 +- .../graphhopper/GraphHopperWeighting.java | 3 +- .../graphhopper/util/TurnCostAnalyzer.java | 7 +-- .../graphhopper/GraphHopperWeightingTest.java | 7 +-- .../util/DatabaseGraphLoaderTest.java | 3 +- .../lib/util/gson/UnitFieldAdapter.java | 4 +- .../java/org/eclipse/mosaic/rti/TIME.java | 7 ++- .../java/org/eclipse/mosaic/rti/UNITS.java | 63 ------------------- .../org/eclipse/mosaic/rti/UNITSTest.java | 37 ----------- 9 files changed, 15 insertions(+), 121 deletions(-) delete mode 100644 rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java delete mode 100644 rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java index dad44f279..048030d1e 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperEdgeProperties.java @@ -22,7 +22,6 @@ import org.eclipse.mosaic.lib.routing.graphhopper.util.GraphhopperToDatabaseMapper; import org.eclipse.mosaic.lib.routing.graphhopper.util.VehicleEncoding; import org.eclipse.mosaic.lib.routing.graphhopper.util.WayTypeEncoder; -import org.eclipse.mosaic.rti.UNITS; import com.google.common.collect.Iterables; import com.graphhopper.util.EdgeIteratorState; @@ -60,8 +59,8 @@ void setCurrentEdgeIterator(EdgeIteratorState currentEdgeIterator, boolean rever public double getSpeed() { Validate.notNull(currentEdgeIterator, "Edge iterator is null"); return reverseRequests - ? currentEdgeIterator.getReverse(encoding.speed()) * UNITS.KMH - : currentEdgeIterator.get(encoding.speed()) * UNITS.KMH; + ? currentEdgeIterator.getReverse(encoding.speed()) / 3.6 + : currentEdgeIterator.get(encoding.speed()) / 3.6; } @Override diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java index 011435ff0..778ae9753 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeighting.java @@ -19,7 +19,6 @@ import org.eclipse.mosaic.lib.routing.graphhopper.util.GraphhopperToDatabaseMapper; import org.eclipse.mosaic.lib.routing.graphhopper.util.VehicleEncoding; import org.eclipse.mosaic.lib.routing.graphhopper.util.WayTypeEncoder; -import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.weighting.AbstractWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; @@ -41,7 +40,7 @@ public class GraphHopperWeighting extends AbstractWeighting { public GraphHopperWeighting(VehicleEncoding vehicleEncoding, WayTypeEncoder wayTypeEncoder, TurnCostProvider turnCostProvider, GraphhopperToDatabaseMapper graphMapper) { super(vehicleEncoding.access(), vehicleEncoding.speed(), turnCostProvider); this.edgePropertiesState = new GraphHopperEdgeProperties(vehicleEncoding, wayTypeEncoder, graphMapper); - this.maxSpeed = speedEnc.getMaxOrMaxStorableDecimal() * UNITS.KILOMETER_PER_HOUR; // getMaxOrMaxStorableDecimal returns the speed in km/h + this.maxSpeed = speedEnc.getMaxOrMaxStorableDecimal() / 3.6; // getMaxOrMaxStorableDecimal returns the speed in km/h } public GraphHopperWeighting setRoutingCostFunction(RoutingCostFunction routingCostFunction) { diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java index 0f273a973..976ed287a 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/graphhopper/util/TurnCostAnalyzer.java @@ -17,7 +17,6 @@ import org.eclipse.mosaic.lib.geo.GeoPoint; import org.eclipse.mosaic.lib.geo.GeoUtils; -import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.util.AccessFilter; import com.graphhopper.storage.BaseGraph; @@ -141,8 +140,8 @@ private double calculateTurnCosts(VehicleEncoding encoding, EdgeIterator incomin double alpha = (bearingViaTo - (bearingFromVia) + 360) % 360; //get length and max speed of edges - double v1 = incomingEdge.get(encoding.speed()) * UNITS.KMH; - double v2 = outgoingEdge.get(encoding.speed()) * UNITS.KMH; + double v1 = incomingEdge.get(encoding.speed()) / 3.6; + double v2 = outgoingEdge.get(encoding.speed()) / 3.6; double l1 = incomingEdge.getDistance(); double l2 = outgoingEdge.getDistance(); @@ -177,7 +176,7 @@ private double calculateTurnCosts(VehicleEncoding encoding, EdgeIterator incomin if (WayTypeEncoder.isResidential(incomingWayType) && WayTypeEncoder.isResidential( outgoingWayType)) { //decrease max turn speed to 10 km/h, if it is on a junction within a residential area - turnVelocity = Math.min(turnVelocity, 10.0 * UNITS.KMH); + turnVelocity = Math.min(turnVelocity, 10.0 / 3.6); } // drivers usually do not max out their turn velocity diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java index 5f03bc089..374203e5f 100644 --- a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/GraphHopperWeightingTest.java @@ -21,7 +21,6 @@ import org.eclipse.mosaic.lib.routing.graphhopper.junit.TestGraphRule; import org.eclipse.mosaic.lib.routing.graphhopper.util.OptionalTurnCostProvider; import org.eclipse.mosaic.lib.routing.graphhopper.util.VehicleEncoding; -import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.util.EdgeExplorer; @@ -49,7 +48,7 @@ public void fastest_noTurnCosts() { double weight = w.calcEdgeWeight(it, false); double turnWeight = w.calcTurnWeight(1, 0, 0); - assertEquals(distance / enc.speed().getMaxStorableDecimal() / UNITS.KMH, weight, 0.1d); + assertEquals(distance / enc.speed().getMaxStorableDecimal() * 3.6, weight, 0.1d); assertEquals(0, turnWeight, 0.1d); } @@ -111,7 +110,7 @@ public void fastest_turnCosts() { double weight = w.calcEdgeWeight(it, false); double turnWeight = w.calcTurnWeight(1, 0, 0); - assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() / UNITS.KMH, weight, 0.1d); + assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() * 3.6, weight, 0.1d); assertEquals(10, turnWeight, 0.1d); } @@ -153,7 +152,7 @@ public void fastest_turnRestriction() { double weight = w.calcEdgeWeight(it, false); double turnWeight = w.calcTurnWeight(1, 0, 0); - assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() / UNITS.KMH, weight, 0.1d); + assertEquals(distance / enc.speed().getMaxOrMaxStorableDecimal() * 3.6, weight, 0.1d); assertEquals(Double.POSITIVE_INFINITY, turnWeight, 0.1d); } diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java index 2b7eccba3..a67db7f0a 100644 --- a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/graphhopper/util/DatabaseGraphLoaderTest.java @@ -22,7 +22,6 @@ import org.eclipse.mosaic.lib.database.Database; import org.eclipse.mosaic.lib.routing.graphhopper.junit.TestGraphRule; -import org.eclipse.mosaic.rti.UNITS; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.AccessFilter; @@ -132,7 +131,7 @@ public void correctImport() throws Exception { //assert outgoing edges of node 4 it = expl.setBaseNode(n4); - assertionMap.put(n2, edgeAssertion(n2, con2_4_2, 50, 30 / UNITS.KMH * 0.9, true)); + assertionMap.put(n2, edgeAssertion(n2, con2_4_2, 50, 30 * 3.6 * 0.9, true)); assertNextEdge(vehicleEncoding.speed(), wayTypeEnc, it, assertionMap); assertTrue(assertionMap.isEmpty()); assertFalse(it.next()); diff --git a/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java b/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java index eef83422b..9f7b09c85 100644 --- a/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java +++ b/lib/mosaic-utils/src/main/java/org/eclipse/mosaic/lib/util/gson/UnitFieldAdapter.java @@ -15,8 +15,6 @@ package org.eclipse.mosaic.lib.util.gson; -import org.eclipse.mosaic.rti.UNITS; - import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.TypeAdapter; @@ -135,7 +133,7 @@ private double determineSpeedDivisor(String timeUnit) { double determineUnitMultiplier(String prefix, String unit) { if (unit.startsWith("mile")) { //special case - return UNITS.MILE; + return 1609.344; } else if (StringUtils.isNotEmpty(prefix)) { return UNIT_MULTIPLIERS.getOrDefault(prefix, 1d); } diff --git a/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java b/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java index d1b1f6701..cf192a73c 100644 --- a/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java +++ b/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/TIME.java @@ -27,17 +27,17 @@ private TIME() { } /** - * One nanosecond in simulation time. + * One nano-second in simulation time. */ public static final long NANO_SECOND = 1; /** - * One microsecond in simulation time. + * One micro-second in simulation time. */ public static final long MICRO_SECOND = 1000 * NANO_SECOND; /** - * One millisecond in simulation time . + * One milli-second in simulation time . */ public static final long MILLI_SECOND = 1000 * MICRO_SECOND; @@ -78,6 +78,7 @@ public static String format(long nanosecond) { sb.append(" s"); return sb.toString(); + } } diff --git a/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java b/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java deleted file mode 100644 index 007b0acae..000000000 --- a/rti/mosaic-rti-api/src/main/java/org/eclipse/mosaic/rti/UNITS.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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: mosaic@fokus.fraunhofer.de - */ - -package org.eclipse.mosaic.rti; - -public final class UNITS { - - private UNITS() { - // access to constants only - } - - /** - * Distance of one meter. - */ - public static final double METER = 1; - - /** - * Distance of one kilometer. - */ - public static final double KILOMETER = 1000 * METER; - - /** - * Distance of one mile in meters. - */ - public static final double MILE = 1609.344 * METER; - - /** - * Speed of one meter per second. - */ - public static final double METER_PER_SECOND = 1; - - /** - * Speed of one kilometer per hour in meter per second. - */ - public static final double KILOMETER_PER_HOUR = 1 / 3.6; - - /** - * Speed of one mile per hour in meter per second. - */ - public static final double MILES_PER_HOUR = 1.609344 * KILOMETER_PER_HOUR; - - /** - * Speed of one kilometer per hour in meter per second. - */ - public static final double KMH = KILOMETER_PER_HOUR; - - /** - * Speed of one mile per hour in meter per second. - */ - public static final double MPH = MILES_PER_HOUR; -} diff --git a/rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java b/rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java deleted file mode 100644 index a9e7b6e4c..000000000 --- a/rti/mosaic-rti-api/src/test/java/org/eclipse/mosaic/rti/UNITSTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2020 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: mosaic@fokus.fraunhofer.de - */ - -package org.eclipse.mosaic.rti; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class UNITSTest { - - @Test - public void testUnitsConstants() { - double delta = 1e-10; - - assertEquals(1, UNITS.METER, delta); - assertEquals(1000, UNITS.KILOMETER, delta); - assertEquals(1609.344, UNITS.MILE, delta); - - assertEquals(13.88, 50 * UNITS.KMH, 0.01); // Kilometers per hour -> Meters per second - assertEquals(15.65, 35 * UNITS.MPH, 0.01); // Miles per hour -> Meters per second - assertEquals(48.28, 30 * UNITS.MPH / UNITS.KMH, 0.01); // Miles per hour -> Kilometers per hour - } - -} From f7e0aa986b751ddd226f95c06fe502a4a3e3ec15 Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Thu, 12 Dec 2024 10:10:39 +0100 Subject: [PATCH 11/13] clean(routing): use SpeedUtils for kmh conversion --- .../java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java | 4 ++-- .../eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java index d21d55fb7..e550c0176 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java @@ -16,8 +16,8 @@ package org.eclipse.mosaic.lib.routing.pt; import org.eclipse.mosaic.lib.geo.GeoPoint; +import org.eclipse.mosaic.lib.math.SpeedUtils; import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting; -import org.eclipse.mosaic.rti.UNITS; import com.google.common.collect.Iterables; import com.graphhopper.GHResponse; @@ -131,7 +131,7 @@ public PtRoutingResponse findPtRoute(PtRoutingRequest request) { ); // ghRequest.setBlockedRouteTypes(request.getRoutingParameters().excludedPtModes);//FIXME generalize this ghRequest.setEarliestDepartureTime(departureTime); - ghRequest.setWalkSpeedKmH(request.getRoutingParameters().getWalkingSpeedMps() / UNITS.KMH); + ghRequest.setWalkSpeedKmH(SpeedUtils.ms2kmh(request.getRoutingParameters().getWalkingSpeedMps())); final Future responseFuture = routingExecution.submit(() -> ptRouter.route(ghRequest)); final GHResponse route; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java index 0bae4afe2..08358b365 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingParameters.java @@ -15,14 +15,14 @@ package org.eclipse.mosaic.lib.routing.pt; -import org.eclipse.mosaic.rti.UNITS; +import org.eclipse.mosaic.lib.math.SpeedUtils; public class PtRoutingParameters { - private double walkingSpeedMps = 5 * UNITS.KILOMETER_PER_HOUR; + private double walkingSpeedMps = SpeedUtils.kmh2ms(5); public PtRoutingParameters walkingSpeedKmh(double kmh) { - walkingSpeedMps = kmh * UNITS.KILOMETER_PER_HOUR; + walkingSpeedMps = SpeedUtils.kmh2ms(kmh); return this; } From e63a3c46fc3625bac5da48a28e617cb95dc5dfcd Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Tue, 7 Jan 2025 15:19:16 +0100 Subject: [PATCH 12/13] clean(routing): work after review * rename Routing to VehicleRouting * improved documentation --- .../CentralNavigationComponent.java | 48 +++++++++---------- .../CentralPerceptionComponent.java | 4 +- .../config/CApplicationAmbassador.java | 4 +- .../CentralNavigationComponentTest.java | 4 +- .../CentralNavigationComponentTestRule.java | 8 ++-- .../main/java/com/csvreader/CsvReader.java | 2 +- .../{Routing.java => VehicleRouting.java} | 4 +- .../config/CPublicTransportRouting.java | 2 + .../lib/routing/database/DatabaseRouting.java | 6 +-- .../lib/routing/norouting/NoRouting.java | 6 +-- .../lib/routing/pt/MultiModalRoute.java | 2 +- .../mosaic/lib/routing/pt/PtRouting.java | 33 ++++++++----- .../lib/routing/pt/PtRoutingRequest.java | 30 ++++++------ .../lib/routing/pt/PtRoutingResponse.java | 16 +------ .../mosaic/lib/routing/pt/PtRoutingTest.java | 4 +- 15 files changed, 86 insertions(+), 87 deletions(-) rename lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/{Routing.java => VehicleRouting.java} (98%) diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java index aa898528d..cdf472db5 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponent.java @@ -32,12 +32,12 @@ import org.eclipse.mosaic.lib.objects.vehicle.VehicleRoute; import org.eclipse.mosaic.lib.routing.CandidateRoute; import org.eclipse.mosaic.lib.routing.IllegalRouteException; -import org.eclipse.mosaic.lib.routing.Routing; import org.eclipse.mosaic.lib.routing.RoutingCostFunction; 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.RoutingResponse; +import org.eclipse.mosaic.lib.routing.VehicleRouting; import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting; import org.eclipse.mosaic.lib.routing.database.DatabaseRouting; import org.eclipse.mosaic.lib.routing.norouting.NoRouting; @@ -86,7 +86,7 @@ public class CentralNavigationComponent { /** * The IRoutingApi. */ - private Routing routing; + private VehicleRouting vehicleRouting; /** @@ -126,11 +126,11 @@ public CentralNavigationComponent( /** * This method initializes the {@link CentralNavigationComponent}. It is called * by the {@link ApplicationAmbassador}. - * The {@link #routing} will be created and initialized and other simulators will be informed + * The {@link #vehicleRouting} will be created and initialized and other simulators will be informed * using a {@link VehicleRoutesInitialization} interaction. * * @param rtiAmbassador the ambassador of the run time infrastructure - * @throws InternalFederateException if the {@link #routing} couldn't be initialized or the + * @throws InternalFederateException if the {@link #vehicleRouting} couldn't be initialized or the * {@link VehicleRoutesInitialization} interaction couldn't be send to the rti */ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateException { @@ -139,8 +139,8 @@ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateExcep try { this.log.info("Initializing CNC-Navigation"); - routing = createFromType(configuration.type); - routing.initialize(configuration, applicationAmbassadorParameter.configuration.getParentFile()); + vehicleRouting = createFromType(configuration.type); + vehicleRouting.initialize(configuration, applicationAmbassadorParameter.configuration.getParentFile()); ptRouting = new PtRouting(); ptRouting.initialize(ptConfiguration, applicationAmbassadorParameter.configuration.getParentFile()); @@ -148,7 +148,7 @@ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateExcep this.log.info("CNC - Navigation-System initialized"); try { - final Map routeMap = routing.getRoutesFromDatabaseForMessage(); + final Map routeMap = vehicleRouting.getRoutesFromDatabaseForMessage(); for (var routeEntry : routeMap.entrySet()) { SimulationKernel.SimulationKernel.registerRoute(routeEntry.getKey(), routeEntry.getValue()); } @@ -183,7 +183,7 @@ public Map getAllRoutes() { return SimulationKernel.SimulationKernel.getRoutes(); } - Routing createFromType(String type) throws InternalFederateException { + VehicleRouting createFromType(String type) throws InternalFederateException { if (type == null || "database".equalsIgnoreCase(type) || "graphhopper".equalsIgnoreCase(type)) { return new DatabaseRouting(); } else if ("no-routing".equalsIgnoreCase(type)) { @@ -191,7 +191,7 @@ Routing createFromType(String type) throws InternalFederateException { } else { try { Class routingImplClass = Class.forName(type); - return (Routing) routingImplClass.getConstructor().newInstance(); + return (VehicleRouting) routingImplClass.getConstructor().newInstance(); } catch (Exception e) { String msg = "Could not create Routing instance from type '" + type + "'."; InternalFederateException ex = new InternalFederateException(msg, e); @@ -210,7 +210,7 @@ Routing createFromType(String type) throws InternalFederateException { * for. */ RoutingResponse findRoutes(RoutingRequest routingRequest) { - return routing.findRoutes(routingRequest); + return vehicleRouting.findRoutes(routingRequest); } /** @@ -247,7 +247,7 @@ public VehicleRoute switchRoute(VehicleData vehicleData, CandidateRoute rawRoute return requestStaticRouteChange(vehicleData, knownRoute, currentRoute, time); } else { // generate a new route - VehicleRoute route = routing.createRouteForRTI(rawRoute); + VehicleRoute route = vehicleRouting.createRouteForRTI(rawRoute); // propagate the new route try { @@ -295,7 +295,7 @@ private VehicleRoute requestStaticRouteChange(VehicleData vehicleData, VehicleRo GeoPoint getTargetPositionOfRoute(String routeId) { if (getAllRoutes().containsKey(routeId)) { String lastConnectionId = Iterables.getLast(getAllRoutes().get(routeId).getConnectionIds(), null); - return routing.getConnection(lastConnectionId).getEndNode().getPosition(); + return vehicleRouting.getConnection(lastConnectionId).getEndNode().getPosition(); } else { return null; } @@ -310,7 +310,7 @@ GeoPoint getTargetPositionOfRoute(String routeId) { public GeoPoint getSourcePositionOfRoute(String routeId) { if (getAllRoutes().containsKey(routeId)) { String firstConnectionId = Iterables.getFirst(getAllRoutes().get(routeId).getConnectionIds(), null); - return routing.getConnection(firstConnectionId).getStartNode().getPosition(); + return vehicleRouting.getConnection(firstConnectionId).getStartNode().getPosition(); } else { return null; } @@ -330,10 +330,10 @@ PtRoutingResponse findPtRoute(PtRoutingRequest routingRequest) { /** * Provides the current routing API implementation. * - * @return The {@link Routing}. + * @return The {@link VehicleRouting}. */ - public Routing getRouting() { - return routing; + public VehicleRouting getRouting() { + return vehicleRouting; } /** @@ -343,7 +343,7 @@ public Routing getRouting() { * @return A {@link GeoPoint} representing the position of the node. */ private GeoPoint getPositionOfNode(String nodeId) { - return routing.getNode(nodeId).getPosition(); + return vehicleRouting.getNode(nodeId).getPosition(); } /** @@ -353,7 +353,7 @@ private GeoPoint getPositionOfNode(String nodeId) { * @return the length of the connection in [m] */ double getLengthOfConnection(String connectionId) { - return routing.getConnection(connectionId).getLength(); + return vehicleRouting.getConnection(connectionId).getLength(); } /** @@ -424,7 +424,7 @@ public VehicleDeparture createRouteForOdInfo(long time, OriginDestinationPair od final RoutingRequest request = new RoutingRequest(new RoutingPosition(sourcePoint), new RoutingPosition(targetPoint), params); // find route - final RoutingResponse response = routing.findRoutes(request); + final RoutingResponse response = vehicleRouting.findRoutes(request); // check if best route, matches one of the existing routes and if so choose that existing route if (response.getBestRoute() != null) { VehicleRoute route = null; @@ -436,7 +436,7 @@ public VehicleDeparture createRouteForOdInfo(long time, OriginDestinationPair od } if (route == null) { try { - route = routing.createRouteForRTI(response.getBestRoute()); + route = vehicleRouting.createRouteForRTI(response.getBestRoute()); propagateRoute(route, time); } catch (IllegalRouteException e) { log.error("[CNC.createRouteForODInfo]: Could not create route.", e); @@ -466,7 +466,7 @@ private GeoPoint chooseGeoPointInCircle(GeoCircle origin) { /** * This method refines the road position depending on the - * implementation of the {@link Routing} interface this can have + * implementation of the {@link VehicleRouting} interface this can have * different levels of complexity. * * @param roadPosition the {@link IRoadPosition} to be refined @@ -476,7 +476,7 @@ public IRoadPosition refineRoadPosition(IRoadPosition roadPosition) { if (roadPosition == null) { return null; } - return routing.refineRoadPosition(roadPosition); + return vehicleRouting.refineRoadPosition(roadPosition); } /** @@ -538,7 +538,7 @@ INode getNextNodeOnRoute(String routeId, IRoadPosition roadPosition, Predicate nodeList = currentRoute.getNodeIds().subList(indexOfUpcomingNode, currentRoute.getNodeIds().size()); for (String nodeId : nodeList) { - INode node = routing.getNode(nodeId); + INode node = vehicleRouting.getNode(nodeId); if (nodeCondition.test(node)) { return node; } @@ -558,7 +558,7 @@ INode getNextNodeOnRoute(String routeId, IRoadPosition roadPosition, Predicate approximateCosts(Collection candidateRoutes, String lastNodeId) { List routesWithCosts = new ArrayList<>(); for (CandidateRoute candidateRoute : candidateRoutes) { - routesWithCosts.add(routing.approximateCostsForCandidateRoute(candidateRoute, lastNodeId)); + routesWithCosts.add(vehicleRouting.approximateCostsForCandidateRoute(candidateRoute, lastNodeId)); } return routesWithCosts; } diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/perception/CentralPerceptionComponent.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/perception/CentralPerceptionComponent.java index 1ae5cc2a2..3b91ba6f1 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/perception/CentralPerceptionComponent.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/perception/CentralPerceptionComponent.java @@ -24,7 +24,7 @@ import org.eclipse.mosaic.lib.geo.CartesianRectangle; import org.eclipse.mosaic.lib.objects.trafficlight.TrafficLightGroup; import org.eclipse.mosaic.lib.objects.vehicle.VehicleType; -import org.eclipse.mosaic.lib.routing.Routing; +import org.eclipse.mosaic.lib.routing.VehicleRouting; import org.eclipse.mosaic.lib.routing.database.DatabaseRouting; import org.eclipse.mosaic.rti.api.InternalFederateException; @@ -83,7 +83,7 @@ public CentralPerceptionComponent(CPerception perceptionConfiguration) { */ public void initialize() throws InternalFederateException { try { - Routing routing = SimulationKernel.SimulationKernel.getCentralNavigationComponent().getRouting(); + VehicleRouting routing = SimulationKernel.SimulationKernel.getCentralNavigationComponent().getRouting(); // evaluate bounding box for perception scenarioBounds = configuration.perceptionArea == null ? routing.getScenarioBounds() : configuration.perceptionArea.toCartesian(); diff --git a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java index c879aceb9..660278841 100644 --- a/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java +++ b/fed/mosaic-application/src/main/java/org/eclipse/mosaic/fed/application/config/CApplicationAmbassador.java @@ -74,13 +74,13 @@ public class CApplicationAmbassador implements Serializable { /** * Extends the {@link CVehicleRouting} configuration with a type parameter - * allowing to define the actual {@link org.eclipse.mosaic.lib.routing.Routing} + * allowing to define the actual {@link org.eclipse.mosaic.lib.routing.VehicleRouting} * implementation to use. */ public static class CRoutingByType extends CVehicleRouting implements Serializable { /** - * Defines the {@link org.eclipse.mosaic.lib.routing.Routing} implementation + * Defines the {@link org.eclipse.mosaic.lib.routing.VehicleRouting} implementation * to use for navigation. Possible values are {@code "database" or "no-routing"}, * or any full-qualified java class name. */ diff --git a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java index c5742bcea..334cacc49 100644 --- a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java +++ b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTest.java @@ -43,10 +43,10 @@ import org.eclipse.mosaic.lib.objects.vehicle.VehicleRoute; import org.eclipse.mosaic.lib.routing.CandidateRoute; import org.eclipse.mosaic.lib.routing.IllegalRouteException; -import org.eclipse.mosaic.lib.routing.Routing; 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.VehicleRouting; import org.eclipse.mosaic.lib.routing.config.CPublicTransportRouting; import org.eclipse.mosaic.lib.routing.config.CVehicleRouting; import org.eclipse.mosaic.lib.routing.norouting.NoRouting; @@ -79,7 +79,7 @@ public class CentralNavigationComponentTest { private CentralNavigationComponent cnc; - private Routing routingMock; + private VehicleRouting routingMock; private RtiAmbassador rtiAmbassadorMock; private static VehicleRoute createExampleRoute0() { diff --git a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java index 5aa5232f3..a0d30127d 100644 --- a/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java +++ b/fed/mosaic-application/src/test/java/org/eclipse/mosaic/fed/application/ambassador/simulation/navigation/CentralNavigationComponentTestRule.java @@ -19,7 +19,7 @@ import org.eclipse.mosaic.fed.application.ambassador.SimulationKernel; import org.eclipse.mosaic.fed.application.config.CApplicationAmbassador; -import org.eclipse.mosaic.lib.routing.Routing; +import org.eclipse.mosaic.lib.routing.VehicleRouting; import org.eclipse.mosaic.lib.util.junit.TestUtils; import org.eclipse.mosaic.rti.api.InternalFederateException; import org.eclipse.mosaic.rti.api.RtiAmbassador; @@ -36,7 +36,7 @@ public class CentralNavigationComponentTestRule extends ExternalResource { private final static String configFile = "/application_config.json"; private TemporaryFolder folderRule; - private Routing routingMock = mock(Routing.class); + private VehicleRouting routingMock = mock(VehicleRouting.class); private CentralNavigationComponent centralNavigationComponent; private RtiAmbassador rtiAmbassadorMock; @@ -52,7 +52,7 @@ RtiAmbassador getRtiAmbassadorMock() { return rtiAmbassadorMock; } - public Routing getRoutingMock() { + public VehicleRouting getRoutingMock() { return routingMock; } @@ -65,7 +65,7 @@ protected void before() throws Throwable { AmbassadorParameter ambassadorParameters = new AmbassadorParameter("test", configCopy.getParentFile()); centralNavigationComponent = new CentralNavigationComponent(ambassadorParameters, applicationConfig.navigationConfiguration, applicationConfig.publicTransportConfiguration) { @Override - Routing createFromType(String type) throws InternalFederateException { + VehicleRouting createFromType(String type) throws InternalFederateException { return routingMock; } }; diff --git a/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java index bc4854e67..df66c555a 100644 --- a/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java +++ b/lib/mosaic-routing/src/main/java/com/csvreader/CsvReader.java @@ -35,7 +35,7 @@ * By excluding javacsv jar and providing this class with the same full qualified name and same API as a supplement * we are able to use opencsv instead without touching the code of graphhopper-reader-gtfs. * Therefore, even though the IDE thinks this class is unused, it is actually used by graphhopper-reader-gtfs. - */ + */ //TODO: remove this once the PR https://github.com/graphhopper/graphhopper/pull/3084 got accepted and we upgrade graphhopper public class CsvReader { private final CSVReader openCsvReader; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/Routing.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/VehicleRouting.java similarity index 98% rename from lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/Routing.java rename to lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/VehicleRouting.java index 274583935..1b06b47a1 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/Routing.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/VehicleRouting.java @@ -28,9 +28,9 @@ import java.util.Map; /** - * Interface providing a routing API for applications. + * Interface providing a vehicle routing API for applications. */ -public interface Routing { +public interface VehicleRouting { /** * Initializes the connection to the belonging database. diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java index 773308ee7..6c534b24b 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/config/CPublicTransportRouting.java @@ -26,11 +26,13 @@ public class CPublicTransportRouting implements Serializable { /** * The path to the OSM file which is used to calculate walking between PT legs. + * The provided path is expected to be relative to the application directory of the scenario. */ public String osmFile = "map.osm"; /** * The path to the GTFS file (ZIP archive) which contains the whole PT schedule. + * The provided path is expected to be relative to the application directory of the scenario. */ public String gtfsFile = "gtfs.zip"; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java index 6a37d0970..8aff3812f 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/database/DatabaseRouting.java @@ -33,9 +33,9 @@ import org.eclipse.mosaic.lib.objects.vehicle.VehicleRoute; import org.eclipse.mosaic.lib.routing.CandidateRoute; import org.eclipse.mosaic.lib.routing.IllegalRouteException; -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.VehicleRouting; import org.eclipse.mosaic.lib.routing.config.CVehicleRouting; import org.eclipse.mosaic.lib.routing.graphhopper.GraphHopperRouting; import org.eclipse.mosaic.rti.api.InternalFederateException; @@ -50,10 +50,10 @@ import java.util.Map; /** - * An implementation of the {@link Routing} interface which provides access to routing functions + * An implementation of the {@link VehicleRouting} interface which provides access to routing functions * based on data of the scenario-database. */ -public class DatabaseRouting implements Routing { +public class DatabaseRouting implements VehicleRouting { private final static Logger log = LoggerFactory.getLogger(DatabaseRouting.class); diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java index 58f0fd096..b4447c071 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/norouting/NoRouting.java @@ -24,9 +24,9 @@ import org.eclipse.mosaic.lib.objects.vehicle.VehicleRoute; import org.eclipse.mosaic.lib.routing.CandidateRoute; import org.eclipse.mosaic.lib.routing.IllegalRouteException; -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.VehicleRouting; import org.eclipse.mosaic.lib.routing.config.CVehicleRouting; import org.eclipse.mosaic.rti.api.InternalFederateException; @@ -37,11 +37,11 @@ import java.util.Map; /** - * Implementation of {@link Routing} if no scenario database + * Implementation of {@link VehicleRouting} if no scenario database * or any other road traffic map is present. In that case, online-routing * during the simulation is disabled. */ -public class NoRouting implements Routing { +public class NoRouting implements VehicleRouting { @Override public void initialize(CVehicleRouting configuration, File configurationLocation) throws InternalFederateException { diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java index 9d77c6a16..a696586a5 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalRoute.java @@ -33,7 +33,7 @@ public MultiModalRoute(List legs) { * Returns the individual legs of this multi-modal route. */ public List getLegs() { - return this.legs; + return legs; } } diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java index e550c0176..fb86da19c 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRouting.java @@ -56,6 +56,11 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +/** + * Implementation of Public Transport Routing based on GraphHopper GTFS. + * Uses a GTFS file for public transport schedule and an OSM file for walking paths to get access to public transport stations. + * + */ public class PtRouting { private static final Logger LOG = LoggerFactory.getLogger(PtRouting.class); @@ -70,7 +75,7 @@ public class PtRouting { /** * Initializes the pt routing if it is enabled in the provided {@link CPublicTransportRouting}. - * All paths defined in the provided config are expcted to be relative to the provided configuration + * All paths defined in the provided config are expected to be relative to the provided configuration * location. */ public void initialize(CPublicTransportRouting routingConfiguration, File configurationLocation) { @@ -84,8 +89,8 @@ public void initialize(CPublicTransportRouting routingConfiguration, File config final Path baseDirectory = configurationLocation.toPath(); GraphHopperConfig ghConfig = new GraphHopperConfig() - .putObject("import.osm.ignored_highways", "motorway,trunk,primary") - .putObject("graph.location", baseDirectory.resolve("ptgraph").toAbsolutePath().toString()) + .putObject("import.osm.ignored_highways", "motorway,trunk,primary") // don't use those roads for walking paths + .putObject("graph.location", baseDirectory.resolve("ptgraph").toAbsolutePath().toString()) // .putObject("datareader.file", baseDirectory.resolve(routingConfiguration.osmFile).toAbsolutePath().toString()) .putObject("gtfs.file", baseDirectory.resolve(routingConfiguration.gtfsFile).toAbsolutePath().toString()) .setProfiles(Collections.singletonList(new Profile("foot").setVehicle("foot"))); @@ -96,9 +101,7 @@ public void initialize(CPublicTransportRouting routingConfiguration, File config graphHopperGtfs.init(ghConfig); graphHopperGtfs.importOrLoad(); sw.stop(); - LOG.debug("Took {} ms to load public transport router.", sw.getMillis()); - LOG.info("setting ptRouter"); ptRouter = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getBaseGraph(), @@ -106,6 +109,8 @@ public void initialize(CPublicTransportRouting routingConfiguration, File config graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage() ).createWithoutRealtimeFeed(); + + LOG.info("Initialized Public Transport Router. Took {} ms.", sw.getMillis()); } /** @@ -116,18 +121,18 @@ public PtRoutingResponse findPtRoute(PtRoutingRequest request) { if (ptRouter == null) { throw new IllegalStateException("PT Routing is not available. Must be enabled in application_config.json."); } - Validate.notNull(request.getStartingGeoPoint(), "Starting point must not be null."); - Validate.notNull(request.getTargetGeoPoint(), "Target point must not be null."); + Validate.notNull(request.getOrigin(), "Starting point must not be null."); + Validate.notNull(request.getDestination(), "Target point must not be null."); Validate.isTrue(request.getRequestTime() >= 0, "Invalid request time."); Validate.isTrue(request.getRoutingParameters().getWalkingSpeedMps() > 0, "Walking speed must be greater than 0."); Instant departureTime = toScheduleTime(request.getRequestTime()); final Request ghRequest = new Request( - request.getStartingGeoPoint().getLatitude(), - request.getStartingGeoPoint().getLongitude(), - request.getTargetGeoPoint().getLatitude(), - request.getTargetGeoPoint().getLongitude() + request.getOrigin().getLatitude(), + request.getOrigin().getLongitude(), + request.getDestination().getLatitude(), + request.getDestination().getLongitude() ); // ghRequest.setBlockedRouteTypes(request.getRoutingParameters().excludedPtModes);//FIXME generalize this ghRequest.setEarliestDepartureTime(departureTime); @@ -185,10 +190,16 @@ private List convertToMultiModalLegs(ResponsePath ghBestRoute) { return legs; } + /** + * Returns a {@link Instant} time object depicting a real timestamp used for requesting the PT schedule. + */ private Instant toScheduleTime(long simTime) { return scheduleDateTime.plusNanos(simTime).atZone(timeZone).toInstant(); } + /** + * Converts the provided {@link Date} object depicting a real timestamp back to the simulation time. + */ private Long fromScheduleTime(@Nullable Date date) { if (date == null) { return null; diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java index 41d30374f..8621bc9c9 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingRequest.java @@ -20,8 +20,8 @@ public class PtRoutingRequest { private final long requestTime; - private final GeoPoint startingGeoPoint; - private final GeoPoint targetGeoPoint; + private final GeoPoint origin; + private final GeoPoint destination; private final PtRoutingParameters routingParameters; @@ -29,25 +29,25 @@ public class PtRoutingRequest { * Constructs a request for calculating a public transport route. * * @param requestTime The earliest time to start the journey. - * @param from The geographic location to start the journey. - * @param to The geographic location to end the journey. + * @param origin The geographic location to start the journey. + * @param destination The geographic location to end the journey. */ - public PtRoutingRequest(long requestTime, GeoPoint from, GeoPoint to) { - this(requestTime, from, to, new PtRoutingParameters()); + public PtRoutingRequest(long requestTime, GeoPoint origin, GeoPoint destination) { + this(requestTime, origin, destination, new PtRoutingParameters()); } /** * Constructs a request for calculating a public transport route. * * @param requestTime The earliest time to start the journey. - * @param from The geographic location to start the journey. - * @param to The geographic location to end the journey. + * @param origin The geographic location to start the journey. + * @param destination The geographic location to end the journey. * @param additionalParameters Additional parameters, such as walking speed. */ - public PtRoutingRequest(long requestTime, GeoPoint from, GeoPoint to, PtRoutingParameters additionalParameters) { + public PtRoutingRequest(long requestTime, GeoPoint origin, GeoPoint destination, PtRoutingParameters additionalParameters) { this.requestTime = requestTime; - this.startingGeoPoint = from; - this.targetGeoPoint = to; + this.origin = origin; + this.destination = destination; this.routingParameters = additionalParameters; } @@ -55,12 +55,12 @@ public long getRequestTime() { return requestTime; } - public GeoPoint getStartingGeoPoint() { - return startingGeoPoint; + public GeoPoint getOrigin() { + return origin; } - public GeoPoint getTargetGeoPoint() { - return targetGeoPoint; + public GeoPoint getDestination() { + return destination; } public PtRoutingParameters getRoutingParameters() { diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java index 54cbb70bc..b60e57708 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingResponse.java @@ -19,18 +19,4 @@ * The result of the routing request. Contains the multi-modal route which * matches the routing request at best. */ -public class PtRoutingResponse { - - private final MultiModalRoute bestRoute; - - public PtRoutingResponse(MultiModalRoute bestRoute) { - this.bestRoute = bestRoute; - } - - /** - * Returns the best multi-modal route of the route calculation. - */ - public final MultiModalRoute getBestRoute() { - return bestRoute; - } -} +public record PtRoutingResponse(MultiModalRoute bestRoute) { } diff --git a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java index e7c67e388..3098d23c4 100644 --- a/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java +++ b/lib/mosaic-routing/src/test/java/org/eclipse/mosaic/lib/routing/pt/PtRoutingTest.java @@ -83,7 +83,7 @@ public void findRoute_findPublicTransportRoute() { )); // ASSERT - MultiModalRoute route = response.getBestRoute(); + MultiModalRoute route = response.bestRoute(); assertEquals(3, route.getLegs().size()); assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(0).getLegType()); assertEquals(MultiModalLeg.Type.PUBLIC_TRANSPORT, route.getLegs().get(1).getLegType()); @@ -102,7 +102,7 @@ public void findRoute_IWalkFasterThanTheBus() { )); // ASSERT - MultiModalRoute route = response.getBestRoute(); + MultiModalRoute route = response.bestRoute(); assertEquals(1, route.getLegs().size()); assertEquals(MultiModalLeg.Type.WALKING, route.getLegs().get(0).getLegType()); } From 0c516918c23d4fc3c06751e10c96fa32b771963a Mon Sep 17 00:00:00 2001 From: Karl Schrab Date: Thu, 9 Jan 2025 16:51:23 +0100 Subject: [PATCH 13/13] clean(routing): added note to not forget redesigning MultiModalLeg --- .../java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java index bbbde3ce3..81c4b75a5 100644 --- a/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java +++ b/lib/mosaic-routing/src/main/java/org/eclipse/mosaic/lib/routing/pt/MultiModalLeg.java @@ -122,6 +122,9 @@ public Type getLegType() { return legType; } + /** + * TODO: we should redesign this class somehow that we don't have to return Object here. + */ public Object getLeg() { return switch (legType) { case VEHICLE_PRIVATE -> vehicleLeg;