acceptDrtOffer(DrtRequest request, double de
.newBuilder()
.request(request)
.earliestStartTime(request.getEarliestStartTime())
+ .maxRideDuration(request.getMaxRideDuration())
.latestArrivalTime(Math.min(updatedLatestStartTime + request.getMaxRideDuration(), request.getLatestArrivalTime()))
- .latestStartTime(updatedLatestStartTime).build());
+ .latestStartTime(updatedLatestStartTime)
+ .build());
}
}
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java
index 25cc051ece8..306b61d62b3 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java
@@ -19,23 +19,20 @@
package org.matsim.contrib.dvrp.run;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
+import jakarta.validation.constraints.DecimalMax;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.PositiveOrZero;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.TransportMode;
-import org.matsim.contrib.dynagent.run.DynQSimConfigConsistencyChecker;
import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets;
+import org.matsim.contrib.dynagent.run.DynQSimConfigConsistencyChecker;
import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams;
import org.matsim.core.config.Config;
-import jakarta.validation.constraints.DecimalMax;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Positive;
-import jakarta.validation.constraints.PositiveOrZero;
+import javax.annotation.Nullable;
+import java.util.Set;
public class DvrpConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets {
private static final Logger log = LogManager.getLogger(DvrpConfigGroup.class);
@@ -68,13 +65,14 @@ public static DvrpConfigGroup get(Config config) {
@Parameter
@Comment("Used for OFFLINE estimation of travel times for VrpOptimizer"
+ " by means of the exponential moving average."
- + " The weighting decrease, alpha, must be in (0,1]."
+ + " The weighting decrease, alpha, must be in [0,1]."
+ " We suggest small values of alpha, e.g. 0.05."
+ " The averaging starts from the initial travel time estimates. If not provided,"
- + " the free-speed TTs is used as the initial estimates")
- @Positive
+ + " the free-speed TTs is used as the initial estimates. If alpha is set to 0, the initial"
+ + " travel times stay fixed.")
+ @PositiveOrZero
@DecimalMax("1.0")
- public double travelTimeEstimationAlpha = 0.05; // [-], 1 ==> TTs from the last iteration only
+ public double travelTimeEstimationAlpha = 0.05; // [-], 1 ==> TTs from the last iteration only, 0 ==> initial TTs only
@Parameter
@Comment(""
@@ -146,6 +144,12 @@ protected void checkConsistency(Config config) {
if (!config.eventsManager().getSynchronizeOnSimSteps()) {
throw new RuntimeException("Synchronization on sim steps is required");
}
+ if(initialTravelTimesFile == null && travelTimeEstimationAlpha == 0.0) {
+ throw new RuntimeException("Initial travel times file is required if travel times should not be updated.");
+ }
+ if(travelTimeEstimationAlpha == 0.0 && travelTimeEstimationBeta > 0) {
+ throw new RuntimeException("Online estimation beta should be 0 if travel time should not be updated.");
+ }
}
public DvrpTravelTimeMatrixParams getTravelTimeMatrixParams() {
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java
index 5d80e161462..efd03ff8c0a 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimator.java
@@ -90,7 +90,7 @@ public DvrpOfflineTravelTimeEstimator(TravelTime initialTT, TravelTime observedT
this.delimiter = delimiter;
alpha = travelTimeEstimationAlpha;
- checkArgument(alpha > 0 && alpha <= 1, "travelTimeEstimationAlpha must be in (0,1]");
+ checkArgument(alpha >= 0 && alpha <= 1, "travelTimeEstimationAlpha must be in [0,1]");
linkTravelTimes = DvrpOfflineTravelTimes.convertToLinkTravelTimeMatrix(initialTT, network.getLinks().values(),
timeDiscretizer);
@@ -114,7 +114,9 @@ private int getIdx(double time) {
@Override
public void notifyMobsimBeforeCleanup(@SuppressWarnings("rawtypes") MobsimBeforeCleanupEvent e) {
- updateTTs(observedTT, alpha);
+ if(alpha > 0) {
+ updateTTs(observedTT, alpha);
+ }
}
@Override
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java
index c295c70ac6a..2ac35955346 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpTravelTimeModule.java
@@ -64,7 +64,7 @@ public void install() {
addMobsimListenerBinding().to(DvrpOfflineTravelTimeEstimator.class);
addControlerListenerBinding().to(DvrpOfflineTravelTimeEstimator.class);
- if (dvrpCfg.travelTimeEstimationBeta > 0) {// online estimation
+ if (dvrpCfg.travelTimeEstimationBeta > 0 && dvrpCfg.travelTimeEstimationAlpha > 0) {// online estimation
bind(DvrpOnlineTravelTimeEstimator.class).asEagerSingleton();
addMobsimListenerBinding().to(DvrpOnlineTravelTimeEstimator.class);
bind(DvrpTravelTimeEstimator.class).to(DvrpOnlineTravelTimeEstimator.class);
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java
index 77e717cfea7..a12930c5d42 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java
@@ -23,6 +23,7 @@
import jakarta.validation.constraints.PositiveOrZero;
import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets;
import org.matsim.contrib.common.zones.ZoneSystemParams;
+import org.matsim.contrib.common.zones.systems.geom_free_zones.GeometryFreeZoneSystemParams;
import org.matsim.contrib.common.zones.systems.grid.GISFileZoneSystemParams;
import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams;
import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams;
@@ -77,6 +78,10 @@ private void initSingletonParameterSets() {
addDefinition(H3GridZoneSystemParams.SET_NAME, H3GridZoneSystemParams::new,
() -> zoneSystemParams,
params -> zoneSystemParams = (H3GridZoneSystemParams)params);
+
+ addDefinition(GeometryFreeZoneSystemParams.SET_NAME, GeometryFreeZoneSystemParams::new,
+ () -> zoneSystemParams,
+ params -> zoneSystemParams = (GeometryFreeZoneSystemParams)params);
}
@Override
diff --git a/contribs/hybridsim/pom.xml b/contribs/hybridsim/pom.xml
index f58a572c939..ac7da45f5b5 100644
--- a/contribs/hybridsim/pom.xml
+++ b/contribs/hybridsim/pom.xml
@@ -1,77 +1,82 @@
-
- org.matsim
- contrib
- 2025.0-SNAPSHOT
-
- 4.0.0
- org.matsim.contrib
- hybridsim
- hybridsim
+
+ org.matsim
+ contrib
+ 2025.0-SNAPSHOT
+
+ 4.0.0
+ org.matsim.contrib
+ hybridsim
+ hybridsim
-
- 4.27.2
- 1.65.1
-
+
+ 4.28.0
+ 1.66.0
+
-
+
-
- com.google.protobuf
- protobuf-java
- ${protobuf.version}
-
+
+ com.google.protobuf
+ protobuf-java
+ ${protobuf.version}
+
-
- io.grpc
- grpc-all
- ${grpc.version}
-
+
+ io.grpc
+ grpc-all
+ ${grpc.version}
+
-
- javax.annotation
- javax.annotation-api
- 1.3.2
-
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+
+
+ io.opentelemetry
+ opentelemetry-sdk
+ 1.40.0
+
-
+
-
-
-
- kr.motd.maven
- os-maven-plugin
- 1.7.1
-
-
- initialize
-
- detect
-
-
-
-
-
- org.xolstice.maven.plugins
- protobuf-maven-plugin
- 0.6.1
-
- com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
-
- grpc-java
- io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
-
- true
-
-
-
-
- compile
- compile-custom
-
-
-
-
-
-
+
+
+
+ kr.motd.maven
+ os-maven-plugin
+ 1.7.1
+
+
+ initialize
+
+ detect
+
+
+
+
+
+ org.xolstice.maven.plugins
+ protobuf-maven-plugin
+ 0.6.1
+
+ com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
+
+ grpc-java
+ io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
+
+ true
+
+
+
+
+ compile
+ compile-custom
+
+
+
+
+
+
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java
index ee231f716ed..20c0b113bed 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/CarEgressWalkChanger.java
@@ -33,7 +33,7 @@
*
* This class allows to implicitly apply penalties to plans by changing the duration of the egress walk after car interactions.
* By construction this only works for plans involving car trips and can not be used if you want to penalize all plans that
- * fulfill a certain condition.
+ * fulfill a certain condition. Note that if you bind this, you should also bind the return value of {@link #getBackChanger()}!
*
*
* More precisely, the class will...
@@ -49,13 +49,14 @@
* @author tkohl / Senozon
*
*/
-class CarEgressWalkChanger implements BeforeMobsimListener, AfterMobsimListener {
+class CarEgressWalkChanger implements BeforeMobsimListener {
public static final String PENALTY_ATTRIBUTE = "parkingPenalty";
private final CarEgressWalkObserver observer;
private final AccessEgressFinder egressFinder = new AccessEgressFinder(TransportMode.car);
private final Iter0Method iter0Method;
+ private final CarEgressWalkBackChanger backChanger;
/**
* Sets the class up with the specified {@linkplain PenaltyGenerator} and {@linkplain PenaltyFunction}.
@@ -66,6 +67,21 @@ class CarEgressWalkChanger implements BeforeMobsimListener, AfterMobsimListener
public CarEgressWalkChanger(PenaltyGenerator penaltyGenerator, PenaltyFunction penaltyFunction, CarEgressWalkObserver observer, Iter0Method iter0Method) {
this.observer = observer;
this.iter0Method = iter0Method;
+ this.backChanger = new CarEgressWalkBackChanger(this);
+ }
+
+ @Override
+ public double priority() { //we want this to happen very late, because it should only affect the mobsim, not other listeners
+ return -1001;
+ }
+
+ /**
+ * Returns the class that changes the egress walks bag in AfterMobsim. Note that you need to bind this separately!
+ *
+ * @return the {@linkplain CarEgressWalkBackChanger} to this class
+ */
+ public CarEgressWalkBackChanger getBackChanger() {
+ return this.backChanger;
}
/**
@@ -93,33 +109,6 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) {
this.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), false);
}
}
-
- /**
- * resets egress times before scoring / replanning
- */
- @Override
- public void notifyAfterMobsim(AfterMobsimEvent event) {
- // we need to roll back the changes we made before the mobsim, otherwise we can't apply
- // a different penalty next iteration.
- if (event.getIteration() == 0) {
- switch (this.iter0Method) {
- case noPenalty:
- case hourPenalty:
- case estimateFromPlans:
- this.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true);
- break;
- case takeFromAttributes:
- this.changeEgressTimesByAttribute(event.getServices().getScenario().getPopulation().getPersons().values(), true);
- break;
- default:
- throw new RuntimeException("Unknown iter0 mode");
- }
- } else {
- this.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true);
- }
- // yyyy this is something we do not like: to just "fake" something and take it back afterwards. Would be good to find some other design
- // eventually. Not so obvious, though ... kai, mar'20
- }
/**
* Changes the egress times of all agents using cars according to the penalty for the corresponding space-time-gridcell and writes the penalty
@@ -130,12 +119,13 @@ public void notifyAfterMobsim(AfterMobsimEvent event) {
* by that time (calling this method twice, first with {@code false}, then with {@code true} should yield the original plans)
*/
private void changeEgressTimesByGridcell(Collection extends Person> population, boolean reverse) {
- int sign = reverse ? -1 : 1;
for (Person p : population) {
for (LegActPair walkActPair : this.egressFinder.findEgressWalks(p.getSelectedPlan())) {
- double penalty = sign * this.observer.getPenaltyCalculator().getPenalty(walkActPair.leg.getDepartureTime().seconds(), walkActPair.act.getCoord());
- setTimes(walkActPair, penalty);
- if (!reverse) {
+ double penalty = Math.round(this.observer.getPenaltyCalculator().getPenalty(walkActPair.leg.getDepartureTime().seconds(), walkActPair.act.getCoord()));
+ if (reverse) {
+ setTimes(walkActPair, -penalty);
+ } else {
+ setTimes(walkActPair, penalty);
walkActPair.leg.getAttributes().putAttribute(PENALTY_ATTRIBUTE, penalty);
}
}
@@ -171,4 +161,50 @@ private static void setTimes(LegActPair walkActPair, double penalty) {
walkActPair.leg.getRoute().setTravelTime(walkActPair.leg.getRoute().getTravelTime().seconds() + penalty);
walkActPair.act.setStartTime(walkActPair.act.getStartTime().seconds() + penalty);
}
+
+ /**
+ * The reverse to {@linkplain CarEgressWalkChanger}
+ *
+ * @author tkohl
+ *
+ */
+ static class CarEgressWalkBackChanger implements AfterMobsimListener {
+ private final CarEgressWalkChanger forwardChanger;
+
+ CarEgressWalkBackChanger(CarEgressWalkChanger forwardChanger) {
+ this.forwardChanger = forwardChanger;
+ }
+
+ @Override
+ public double priority() { //we want this to happen very early to undo what we did before the mobsim before other listeners can pick it up
+ return 1001;
+ }
+
+ /**
+ * resets egress times before scoring / replanning
+ */
+ @Override
+ public void notifyAfterMobsim(AfterMobsimEvent event) {
+ // we need to roll back the changes we made before the mobsim, otherwise we can't apply
+ // a different penalty next iteration.
+ if (event.getIteration() == 0) {
+ switch (forwardChanger.iter0Method) {
+ case noPenalty:
+ case hourPenalty:
+ case estimateFromPlans:
+ forwardChanger.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true);
+ break;
+ case takeFromAttributes:
+ forwardChanger.changeEgressTimesByAttribute(event.getServices().getScenario().getPopulation().getPersons().values(), true);
+ break;
+ default:
+ throw new RuntimeException("Unknown iter0 mode");
+ }
+ } else {
+ forwardChanger.changeEgressTimesByGridcell(event.getServices().getScenario().getPopulation().getPersons().values(), true);
+ }
+ // yyyy this is something we do not like: to just "fake" something and take it back afterwards. Would be good to find some other design
+ // eventually. Not so obvious, though ... kai, mar'20
+ }
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java
index f356f0911e8..41f179d4977 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingproxy/ParkingProxyModule.java
@@ -92,7 +92,9 @@ public void install() {
if (parkingConfig.getObserveOnly()) {
super.addControlerListenerBinding().toInstance(walkObserver);
} else {
- super.addControlerListenerBinding().toInstance(new CarEgressWalkChanger(parkingHandler, penaltyFunction, walkObserver, parkingConfig.getIter0Method()));
+ CarEgressWalkChanger walkChanger = new CarEgressWalkChanger(parkingHandler, penaltyFunction, walkObserver, parkingConfig.getIter0Method());
+ super.addControlerListenerBinding().toInstance(walkChanger);
+ super.addControlerListenerBinding().toInstance(walkChanger.getBackChanger());
}
}
diff --git a/contribs/protobuf/pom.xml b/contribs/protobuf/pom.xml
index a2c8a4ef62b..a08c2d527c8 100644
--- a/contribs/protobuf/pom.xml
+++ b/contribs/protobuf/pom.xml
@@ -11,7 +11,7 @@
protobuf
- 4.27.2
+ 4.28.0
diff --git a/matsim/pom.xml b/matsim/pom.xml
index 7f768fffe76..e5c689b9261 100644
--- a/matsim/pom.xml
+++ b/matsim/pom.xml
@@ -222,7 +222,7 @@
com.github.luben
zstd-jni
- 1.5.6-3
+ 1.5.6-5
jakarta.validation
diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java
index e2d6ff5078c..906c97396ee 100644
--- a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java
+++ b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java
@@ -41,15 +41,18 @@
import org.matsim.pt.transitSchedule.api.TransitRoute;
import org.matsim.pt.transitSchedule.api.TransitRouteStop;
import org.matsim.pt.transitSchedule.api.TransitSchedule;
+import org.matsim.pt.transitSchedule.api.TransitStopArea;
import org.matsim.pt.transitSchedule.api.TransitStopFacility;
/**
* Builds a network where transit vehicles can drive along and assigns the correct
- * links to the transit stop facilities and routes of transit lines. Each stop facility
- * is assigned to a loop link, located in a node with the same coordinates as the stop.
- * The stop facility ID is used for node and link IDs.
+ * links to the transit stop facilities and routes of transit lines. As each transit
+ * stop facility can only be connected to at most one link, the algorithm is forced
+ * to duplicated transit stop facilities in certain cases to build the network.
*
- * @author mrieser, davibicudo
+ * See {@link CreatePseudoNetworkWithLoopLinks} for a version that uses loop links instead of duplicating stop facilities.
+ *
+ * @author mrieser
*/
public class CreatePseudoNetwork {
@@ -59,8 +62,13 @@ public class CreatePseudoNetwork {
private final double linkFreeSpeed;
private final double linkCapacity;
- private final Map, Link> links = new HashMap<>();
- private final Map nodes = new HashMap<>();
+
+ private final Map, Link> links = new HashMap, Link>();
+ private final Map, TransitStopFacility> stopFacilities = new HashMap, TransitStopFacility>();
+ private final Map nodes = new HashMap();
+ private final Map> facilityCopies = new HashMap>();
+
+ private long linkIdCounter = 0;
private final Set transitModes = Collections.singleton(TransportMode.pt);
@@ -83,27 +91,24 @@ public CreatePseudoNetwork(final TransitSchedule schedule, final Network network
public void createNetwork() {
- createStopNodesAndLoopLinks();
+ List> toBeRemoved = new LinkedList>();
- List> toBeRemoved = new LinkedList<>();
for (TransitLine tLine : this.schedule.getTransitLines().values()) {
for (TransitRoute tRoute : tLine.getRoutes().values()) {
- ArrayList> routeLinks = new ArrayList<>();
+ ArrayList> routeLinks = new ArrayList>();
TransitRouteStop prevStop = null;
for (TransitRouteStop stop : tRoute.getStops()) {
- if (prevStop != null) {
- Link link = getNetworkLink(prevStop, stop);
- routeLinks.add(link.getId());
- }
+ Link link = getNetworkLink(prevStop, stop);
+ routeLinks.add(link.getId());
prevStop = stop;
}
- if (!routeLinks.isEmpty()) {
- NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks);
+ if (routeLinks.size() > 0) {
+ NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks );
tRoute.setRoute(route);
} else {
System.err.println("Line " + tLine.getId() + " route " + tRoute.getId() + " has less than two stops. Removing this route from schedule.");
- toBeRemoved.add(new Tuple<>(tLine, tRoute));
+ toBeRemoved.add(new Tuple(tLine, tRoute));
}
}
}
@@ -113,40 +118,64 @@ public void createNetwork() {
}
}
- private void createStopNodesAndLoopLinks() {
- for (TransitStopFacility stop : this.schedule.getFacilities().values()) {
- Node node = this.network.getFactory().createNode(Id.createNodeId(this.prefix + stop.getId()), stop.getCoord());
- this.network.addNode(node);
- this.nodes.put(stop, node);
-
- Link loopLink = this.network.getFactory().createLink(Id.createLinkId (this.prefix + stop.getId()), node, node);
- stop.setLinkId(loopLink.getId());
- this.network.addLink(loopLink);
- Tuple connection = new Tuple<>(node, node);
- this.links.put(connection, loopLink);
- }
- }
-
private Link getNetworkLink(final TransitRouteStop fromStop, final TransitRouteStop toStop) {
- TransitStopFacility fromFacility = fromStop.getStopFacility();
+ TransitStopFacility fromFacility = (fromStop == null) ? toStop.getStopFacility() : fromStop.getStopFacility();
TransitStopFacility toFacility = toStop.getStopFacility();
Node fromNode = this.nodes.get(fromFacility);
+ if (fromNode == null) {
+ fromNode = this.network.getFactory().createNode(Id.create(this.prefix + toFacility.getId(), Node.class), fromFacility.getCoord());
+ this.network.addNode(fromNode);
+ this.nodes.put(toFacility, fromNode);
+ }
+
Node toNode = this.nodes.get(toFacility);
+ if (toNode == null) {
+ toNode = this.network.getFactory().createNode(Id.create(this.prefix + toFacility.getId(), Node.class), toFacility.getCoord());
+ this.network.addNode(toNode);
+ this.nodes.put(toFacility, toNode);
+ }
- Tuple connection = new Tuple<>(fromNode, toNode);
+ Tuple connection = new Tuple(fromNode, toNode);
Link link = this.links.get(connection);
- return link == null ? createAndAddLink(connection) : link;
+ if (link == null) {
+ link = createAndAddLink(fromNode, toNode, connection);
+
+ if (toFacility.getLinkId() == null) {
+ toFacility.setLinkId(link.getId());
+ this.stopFacilities.put(connection, toFacility);
+ } else {
+ List copies = this.facilityCopies.get(toFacility);
+ if (copies == null) {
+ copies = new ArrayList();
+ this.facilityCopies.put(toFacility, copies);
+ }
+ Id newId = Id.create(toFacility.getId().toString() + "." + Integer.toString(copies.size() + 1), TransitStopFacility.class);
+ TransitStopFacility newFacility = this.schedule.getFactory().createTransitStopFacility(newId, toFacility.getCoord(), toFacility.getIsBlockingLane());
+ newFacility.setStopAreaId(Id.create(toFacility.getId(), TransitStopArea.class));
+ newFacility.setLinkId(link.getId());
+ newFacility.setName(toFacility.getName());
+ copies.add(newFacility);
+ this.nodes.put(newFacility, toNode);
+ this.schedule.addStopFacility(newFacility);
+ toStop.setStopFacility(newFacility);
+ this.stopFacilities.put(connection, newFacility);
+ }
+ } else {
+ toStop.setStopFacility(this.stopFacilities.get(connection));
+ }
+ return link;
}
- private Link createAndAddLink(Tuple connection) {
- Node fromNode = connection.getFirst();
- Node toNode = connection.getSecond();
+ private Link createAndAddLink(Node fromNode, Node toNode,
+ Tuple connection) {
Link link;
- link = this.network.getFactory().createLink(Id.createLinkId(this.prefix + fromNode.getId() + "-" + toNode.getId()), fromNode,
- toNode);
- link.setLength(CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord()));
-
+ link = this.network.getFactory().createLink(Id.create(this.prefix + this.linkIdCounter++, Link.class), fromNode, toNode);
+ if (fromNode == toNode) {
+ link.setLength(50);
+ } else {
+ link.setLength(CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord()));
+ }
link.setFreespeed(linkFreeSpeed);
link.setCapacity(linkCapacity);
link.setNumberOfLanes(1);
@@ -156,4 +185,11 @@ private Link createAndAddLink(Tuple connection) {
return link;
}
+ public Link getLinkBetweenStops(final TransitStopFacility fromStop, final TransitStopFacility toStop) {
+ Node fromNode = this.nodes.get(fromStop);
+ Node toNode = this.nodes.get(toStop);
+ Tuple connection = new Tuple(fromNode, toNode);
+ return this.links.get(connection);
+ }
+
}
diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java
new file mode 100644
index 00000000000..d0532315137
--- /dev/null
+++ b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java
@@ -0,0 +1,153 @@
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * CreatePseudoNetwork
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2009 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.pt.utils;
+
+import com.google.common.annotations.Beta;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.network.Network;
+import org.matsim.api.core.v01.network.Node;
+import org.matsim.core.population.routes.NetworkRoute;
+import org.matsim.core.population.routes.RouteUtils;
+import org.matsim.core.utils.collections.Tuple;
+import org.matsim.core.utils.geometry.CoordUtils;
+import org.matsim.pt.transitSchedule.api.*;
+
+import java.util.*;
+
+/**
+ * Builds a network where transit vehicles can drive along and assigns the correct
+ * links to the transit stop facilities and routes of transit lines. Each stop facility
+ * is assigned to a loop link, located in a node with the same coordinates as the stop.
+ * The stop facility ID is used for node and link IDs.
+ *
+ * @author mrieser, davibicudo
+ *
+ * @implNote THis functionality might be merged with {@link CreatePseudoNetwork}.
+ */
+@Beta
+public class CreatePseudoNetworkWithLoopLinks {
+
+ private final TransitSchedule schedule;
+ private final Network network;
+ private final String prefix;
+ private final double linkFreeSpeed;
+ private final double linkCapacity;
+
+ private final Map, Link> links = new HashMap<>();
+ private final Map nodes = new HashMap<>();
+
+ private final Set transitModes = Collections.singleton(TransportMode.pt);
+
+ public CreatePseudoNetworkWithLoopLinks(final TransitSchedule schedule, final Network network, final String networkIdPrefix) {
+ this.schedule = schedule;
+ this.network = network;
+ this.prefix = networkIdPrefix;
+ this.linkFreeSpeed = 100.0 / 3.6;
+ this.linkCapacity = 100000.0;
+ }
+
+ public CreatePseudoNetworkWithLoopLinks(final TransitSchedule schedule, final Network network, final String networkIdPrefix,
+ final double linkFreeSpeed, final double linkCapacity) {
+ this.schedule = schedule;
+ this.network = network;
+ this.prefix = networkIdPrefix;
+ this.linkFreeSpeed = linkFreeSpeed;
+ this.linkCapacity = linkCapacity;
+ }
+
+ public void createNetwork() {
+
+ createStopNodesAndLoopLinks();
+
+ List> toBeRemoved = new LinkedList<>();
+ for (TransitLine tLine : this.schedule.getTransitLines().values()) {
+ for (TransitRoute tRoute : tLine.getRoutes().values()) {
+ ArrayList> routeLinks = new ArrayList<>();
+ TransitRouteStop prevStop = null;
+ for (TransitRouteStop stop : tRoute.getStops()) {
+ if (prevStop != null) {
+ Link link = getNetworkLink(prevStop, stop);
+ routeLinks.add(link.getId());
+ }
+ prevStop = stop;
+ }
+
+ if (!routeLinks.isEmpty()) {
+ NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks);
+ tRoute.setRoute(route);
+ } else {
+ System.err.println("Line " + tLine.getId() + " route " + tRoute.getId() + " has less than two stops. Removing this route from schedule.");
+ toBeRemoved.add(new Tuple<>(tLine, tRoute));
+ }
+ }
+ }
+
+ for (Tuple remove : toBeRemoved) {
+ remove.getFirst().removeRoute(remove.getSecond());
+ }
+ }
+
+ private void createStopNodesAndLoopLinks() {
+ for (TransitStopFacility stop : this.schedule.getFacilities().values()) {
+ Node node = this.network.getFactory().createNode(Id.createNodeId(this.prefix + stop.getId()), stop.getCoord());
+ this.network.addNode(node);
+ this.nodes.put(stop, node);
+
+ Link loopLink = this.network.getFactory().createLink(Id.createLinkId (this.prefix + stop.getId()), node, node);
+ stop.setLinkId(loopLink.getId());
+ this.network.addLink(loopLink);
+ Tuple connection = new Tuple<>(node, node);
+ this.links.put(connection, loopLink);
+ }
+ }
+
+ private Link getNetworkLink(final TransitRouteStop fromStop, final TransitRouteStop toStop) {
+ TransitStopFacility fromFacility = fromStop.getStopFacility();
+ TransitStopFacility toFacility = toStop.getStopFacility();
+
+ Node fromNode = this.nodes.get(fromFacility);
+ Node toNode = this.nodes.get(toFacility);
+
+ Tuple connection = new Tuple<>(fromNode, toNode);
+ Link link = this.links.get(connection);
+ return link == null ? createAndAddLink(connection) : link;
+ }
+
+ private Link createAndAddLink(Tuple connection) {
+ Node fromNode = connection.getFirst();
+ Node toNode = connection.getSecond();
+ Link link;
+ link = this.network.getFactory().createLink(Id.createLinkId(this.prefix + fromNode.getId() + "-" + toNode.getId()), fromNode,
+ toNode);
+ link.setLength(CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord()));
+
+ link.setFreespeed(linkFreeSpeed);
+ link.setCapacity(linkCapacity);
+ link.setNumberOfLanes(1);
+ this.network.addLink(link);
+ link.setAllowedModes(this.transitModes);
+ this.links.put(connection, link);
+ return link;
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index f7866d67c0a..6dbd5f639cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,10 +30,10 @@
21
- 2.23.1
+ 2.24.0
31.3
0.49.2
- 1.19.0
+ 1.20.0
7.0.0
2.17.2
2.5.0
@@ -103,12 +103,12 @@
com.google.guava
guava
- 33.2.1-jre
+ 33.3.0-jre
org.apache.commons
commons-lang3
- 3.14.0
+ 3.17.0
org.apache.commons
@@ -118,7 +118,7 @@
org.apache.commons
commons-compress
- 1.26.2
+ 1.27.1
commons-logging
@@ -242,7 +242,7 @@
org.slf4j
slf4j-api
- 2.0.13
+ 2.0.16
@@ -425,7 +425,7 @@
org.apache.maven.plugins
maven-failsafe-plugin
- 3.3.1
+ 3.5.0
org.apache.maven.plugins
@@ -445,17 +445,17 @@
org.apache.maven.plugins
maven-install-plugin
- 3.1.2
+ 3.1.3
org.apache.maven.plugins
maven-javadoc-plugin
- 3.7.0
+ 3.10.0
org.codehaus.mojo
buildnumber-maven-plugin
- 3.2.0
+ 3.2.1
validate