diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java index 3b2152eec90..0d35c029215 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java @@ -50,9 +50,9 @@ public static boolean isSwitchingFromStopToStay(DvrpVehicle vehicle) { if (!STAY.isBaseTypeOf(currentTask)) { return false; } - + // only if stay task is last task: with prebooking we may also idle during the day, but - // currently all the downstream relocation/charging logic assumes that we only stay at + // currently all the downstream relocation/charging logic assumes that we only stay at // the end of the schedule if (currentTask.getTaskIdx() < schedule.getTaskCount() - 1) { return false; @@ -64,13 +64,15 @@ public static boolean isSwitchingFromStopToStay(DvrpVehicle vehicle) { } public static Link findStraightLineNearestDepot(DvrpVehicle vehicle, Set links) { - Link currentLink = ((DrtStayTask)vehicle.getSchedule().getCurrentTask()).getLink(); + Link currentLink = ((DrtStayTask) vehicle.getSchedule().getCurrentTask()).getLink(); return links.contains(currentLink) ? - null /* already at a depot*/ : - links.stream() - .min(Comparator.comparing( - l -> DistanceUtils.calculateSquaredDistance(currentLink.getToNode().getCoord(), - l.getFromNode().getCoord()))) - .get(); + null /* already at a depot*/ : + links.stream().map(l -> new DepotCandidates(l, DistanceUtils.calculateSquaredDistance(currentLink.getToNode().getCoord(), + l.getFromNode().getCoord()))) + .min(Comparator.comparing(DepotCandidates::distance) + .thenComparing(h -> h.link.getId())) + .get().link(); } + + record DepotCandidates(Link link, double distance) {} } diff --git a/matsim/src/main/java/org/matsim/core/config/ReflectiveConfigGroup.java b/matsim/src/main/java/org/matsim/core/config/ReflectiveConfigGroup.java index 0cf673c78e4..3a00441d761 100644 --- a/matsim/src/main/java/org/matsim/core/config/ReflectiveConfigGroup.java +++ b/matsim/src/main/java/org/matsim/core/config/ReflectiveConfigGroup.java @@ -285,14 +285,29 @@ public final void addParam(final String param_name, final String value) { return; } - Preconditions.checkArgument(storeUnknownParameters, "Module %s of type %s doesn't accept unknown parameters." - + " Parameter %s is not part of the valid parameters: %s", getName(), getClass().getName(), param_name, - setters.keySet()); + this.handleAddUnknownParam(param_name, value); + } + + /** + * This method is designed to be overwritten if a config group wants to provide + * custom handling for unknown parameters, e.g. for improved backwards compatibility. + * For example: It allows to convert (old-named) parameter values to different units and + * store them with the new name (old parameter could be km/h, new parameter could be m/s). + * + * The default implementation in {@link ReflectiveConfigGroup} will either store the + * unknown parameter or throw an exception, depending on the value of {@link #storeUnknownParameters}. + * + * If the method is overwritten, it might make sense to also overwrite {@link #handleGetUnknownValue(String)}. + */ + public void handleAddUnknownParam(final String paramName, final String value) { + Preconditions.checkArgument(this.storeUnknownParameters, "Module %s of type %s doesn't accept unknown parameters." + + " Parameter %s is not part of the valid parameters: %s", getName(), getClass().getName(), paramName, + this.setters.keySet()); log.warn( - "Unknown parameter {} for group {}. Here are the valid parameter names: {}. Only the string value will be remembered.", - param_name, getName(), registeredParams); - super.addParam(param_name, value); + "Unknown parameter {} for group {}. Here are the valid parameter names: {}. Only the string value will be remembered.", + paramName, getName(), this.registeredParams); + super.addParam(paramName, value); } private void invokeSetter(final Method setter, final String value) { @@ -438,13 +453,22 @@ public final String getValue(final String param_name) { if (field != null) { return getParamField(field); } + return this.handleGetUnknownValue(param_name); + } - Preconditions.checkArgument(storeUnknownParameters, "Module %s of type %s doesn't store unknown parameters." - + " Parameter %s is not part of the valid parameters: %s", getName(), getClass().getName(), param_name, - registeredParams); + /** + * This method is designed to be overwritten if a config group wants to provide + * custom handling for unknown parameters, e.g. for improved backwards compatibility. + * + * Also see {@link #handleAddUnknownParam(String, String)} + */ + public String handleGetUnknownValue(final String paramName) { + Preconditions.checkArgument(this.storeUnknownParameters, "Module %s of type %s doesn't store unknown parameters." + + " Parameter %s is not part of the valid parameters: %s", getName(), getClass().getName(), paramName, + this.registeredParams); - log.warn("no getter found for param {}: trying parent method", param_name); - return super.getValue(param_name); + log.warn("no getter found for param {}: trying parent method", paramName); + return super.getValue(paramName); } private String invokeGetter(Method getter) {