diff --git a/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java b/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java index 5c95006afa8..d644f7d9a92 100644 --- a/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java +++ b/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java @@ -23,6 +23,7 @@ import java.net.URL; import org.matsim.api.core.v01.Scenario; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.run.DrtControlerCreator; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtModule; @@ -33,6 +34,7 @@ import org.matsim.contrib.taxi.run.MultiModeTaxiConfigGroup; import org.matsim.contrib.taxi.run.MultiModeTaxiModule; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; @@ -44,8 +46,13 @@ */ public class RunDrtAndTaxiExample { public static void run(URL configUrl, boolean otfvis) { + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + ConfigGroup zoneParams = dvrpConfigGroup.getTravelTimeMatrixParams().createParameterSet(SquareGridZoneSystemParams.SET_NAME); + dvrpConfigGroup.getTravelTimeMatrixParams().addParameterSet(zoneParams); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new MultiModeTaxiConfigGroup(), - new DvrpConfigGroup(), new OTFVisConfigGroup()); + dvrpConfigGroup, new OTFVisConfigGroup()); Scenario scenario = DrtControlerCreator.createScenarioWithDrtRouteFactory(config); ScenarioUtils.loadScenario(scenario); config.controller() diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java index 68addb0a68a..72144a8d440 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java @@ -29,6 +29,7 @@ import org.matsim.contrib.commercialTrafficApplications.jointDemand.ChangeCommercialJobOperator; import org.matsim.contrib.commercialTrafficApplications.jointDemand.JointDemandConfigGroup; import org.matsim.contrib.commercialTrafficApplications.jointDemand.JointDemandModule; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.DrtConfigs; @@ -36,6 +37,7 @@ import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpQSimComponents; +import org.matsim.core.config.ConfigGroup; import org.matsim.freight.carriers.FreightCarriersConfigGroup; import org.matsim.freight.carriers.CarriersUtils; import org.matsim.core.config.Config; @@ -132,8 +134,11 @@ private static void prepareConfig(Config config) { } private static void loadConfigGroups(Config config) { - ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); - MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); + DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); + ConfigGroup zoneParams = dvrpConfigGroup.getTravelTimeMatrixParams().createParameterSet(SquareGridZoneSystemParams.SET_NAME); + dvrpConfigGroup.getTravelTimeMatrixParams().addParameterSet(zoneParams); + + MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); DrtConfigGroup drtCfg = new DrtConfigGroup(); drtCfg.maxWaitTime = 2 * 3600; diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/util/ReflectiveConfigGroupWithConfigurableParameterSets.java b/contribs/common/src/main/java/org/matsim/contrib/common/util/ReflectiveConfigGroupWithConfigurableParameterSets.java similarity index 99% rename from contribs/dvrp/src/main/java/org/matsim/contrib/util/ReflectiveConfigGroupWithConfigurableParameterSets.java rename to contribs/common/src/main/java/org/matsim/contrib/common/util/ReflectiveConfigGroupWithConfigurableParameterSets.java index f732260b4e6..23a51809991 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/util/ReflectiveConfigGroupWithConfigurableParameterSets.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/util/ReflectiveConfigGroupWithConfigurableParameterSets.java @@ -18,19 +18,18 @@ * *********************************************************************** * */ -package org.matsim.contrib.util; +package org.matsim.contrib.common.util; + +import com.google.common.base.Preconditions; +import com.google.common.base.Verify; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ReflectiveConfigGroup; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; -import org.matsim.core.config.ConfigGroup; -import org.matsim.core.config.ReflectiveConfigGroup; - -import com.google.common.base.Preconditions; -import com.google.common.base.Verify; - /** * Provides additional functionality for handling parameter sets according to definitions. *

diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/GridZoneSystem.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/GridZoneSystem.java new file mode 100644 index 00000000000..65e75baaea9 --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/GridZoneSystem.java @@ -0,0 +1,11 @@ +package org.matsim.contrib.common.zones; + +import org.matsim.api.core.v01.Coord; + +import java.util.Optional; + +public interface GridZoneSystem extends ZoneSystem { + + Optional getZoneForCoord(Coord coord); + +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/Zone.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/Zone.java index dbf0c77caf8..4a820fb6dbf 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/Zone.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/Zone.java @@ -1,6 +1,6 @@ package org.matsim.contrib.common.zones; -import org.locationtech.jts.geom.prep.PreparedGeometry; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.matsim.api.core.v01.BasicLocation; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Identifiable; @@ -11,9 +11,9 @@ public interface Zone extends BasicLocation, Identifiable { @Nullable - PreparedGeometry getPreparedGeometry(); + PreparedPolygon getPreparedGeometry(); Coord getCentroid(); + String getType(); - List getLinks(); } diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneImpl.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneImpl.java index 64b4a009733..9e327306915 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneImpl.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneImpl.java @@ -1,6 +1,6 @@ package org.matsim.contrib.common.zones; -import org.locationtech.jts.geom.prep.PreparedGeometry; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -13,20 +13,20 @@ public class ZoneImpl implements Zone { private final Id id; @Nullable - private final PreparedGeometry preparedGeometry; //null for virtual/dummy zones - private final List links; + private PreparedPolygon preparedGeometry; //null for virtual/dummy zones private final Coord centroid; + private String type; - public ZoneImpl(Id id, PreparedGeometry preparedGeometry, List links) { - this(id, preparedGeometry, links, MGC.point2Coord(preparedGeometry.getGeometry().getCentroid())); + public ZoneImpl(Id id, PreparedPolygon preparedGeometry, @Nullable String type) { + this(id, preparedGeometry, MGC.point2Coord(preparedGeometry.getGeometry().getCentroid()), type); } - private ZoneImpl(Id id, @Nullable PreparedGeometry preparedGeometry, List links, Coord centroid) { + public ZoneImpl(Id id, @Nullable PreparedPolygon preparedGeometry, Coord centroid, @Nullable String type) { this.id = id; this.preparedGeometry = preparedGeometry; - this.links = links; this.centroid = centroid; - } + this.type = type; + } @Override public Id getId() { @@ -40,7 +40,7 @@ public Coord getCoord() { @Override @Nullable - public PreparedGeometry getPreparedGeometry() { + public PreparedPolygon getPreparedGeometry() { return preparedGeometry; } @@ -50,16 +50,21 @@ public Coord getCentroid() { } @Override - public List getLinks() { - return links; + public String getType() { + return type; } boolean isDummy() { return preparedGeometry == null; } - public static ZoneImpl createDummyZone(Id id, List links, Coord centroid) { - return new ZoneImpl(id, null, links, centroid); + public void setGeometry(PreparedPolygon preparedPolygon) { + this.preparedGeometry = preparedPolygon; + } + + + public static ZoneImpl createDummyZone(Id id, Coord centroid) { + return new ZoneImpl(id, null, centroid, null); } } diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystem.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystem.java index 11299b67ad6..9bd5fb6b2b1 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystem.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystem.java @@ -2,13 +2,19 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Node; -import javax.annotation.Nullable; +import java.util.List; import java.util.Map; +import java.util.Optional; public interface ZoneSystem { - @Nullable - Zone getZoneForLinkId(Id linkId); + Optional getZoneForLinkId(Id link); + + Optional getZoneForNodeId(Id nodeId); + + List getLinksForZoneId(Id zone); + Map, Zone> getZones(); } diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemImpl.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemImpl.java index 958575ecf40..31b05b6130c 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemImpl.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemImpl.java @@ -1,36 +1,61 @@ package org.matsim.contrib.common.zones; -import org.apache.commons.lang3.tuple.Pair; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdMap; 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.contrib.common.zones.util.ZoneFinder; -import javax.annotation.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; +import java.util.*; public class ZoneSystemImpl implements ZoneSystem { private final Map, Zone> zones = new IdMap<>(Zone.class); private final IdMap link2zone = new IdMap<>(Link.class); + private final IdMap nodeToZoneMap = new IdMap<>(Node.class); + + private final IdMap> zoneToLinksMap = new IdMap<>(Zone.class); + public ZoneSystemImpl(Collection zones) { zones.forEach(zone -> this.zones.put(zone.getId(), zone)); - zones.stream() - .flatMap(zone -> zone.getLinks().stream().map(link -> Pair.of(link.getId(), zone))) - .forEach(idZonePair -> link2zone.put(idZonePair.getKey(), idZonePair.getValue())); + } + + public ZoneSystemImpl(Collection zones, ZoneFinder zoneFinder, Network network) { + zones.forEach(zone -> this.zones.put(zone.getId(), zone)); + + IdMap nodeToZoneMap = ZoneSystemUtils.createNodeToZoneMap(network, zoneFinder); + IdMap linkToZoneMap = ZoneSystemUtils.createLinkToZoneMap(network, zoneFinder); + this.nodeToZoneMap.putAll(nodeToZoneMap); + this.link2zone.putAll(linkToZoneMap); + + for (Link link : network.getLinks().values()) { + zoneFinder.findZone(link.getToNode().getCoord()).ifPresent(zone -> { + List links = zoneToLinksMap.computeIfAbsent(zone.getId(), zoneId1 -> new ArrayList<>()); + links.add(link); + }); + } } /** - * @param linkId + * @param link * @return the the {@code DrtZone} that contains the {@code linkId}. If the given link's {@code Coord} borders two or more cells, the allocation to a cell is random. * Result may be null in case the given link is outside of the service area. */ @Override - @Nullable - public Zone getZoneForLinkId(Id linkId) { - return link2zone.get(linkId); + public Optional getZoneForLinkId(Id link) { + return Optional.ofNullable(link2zone.get(link)); + } + + @Override + public Optional getZoneForNodeId(Id nodeId) { + return Optional.ofNullable(nodeToZoneMap.get(nodeId)); + } + + @Override + public List getLinksForZoneId(Id zone) { + return zoneToLinksMap.getOrDefault(zone, Collections.emptyList()); } /** diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemParams.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemParams.java new file mode 100644 index 00000000000..c52c39548f3 --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemParams.java @@ -0,0 +1,12 @@ +package org.matsim.contrib.common.zones; + +import org.matsim.core.config.ReflectiveConfigGroup; + +/** + * @author nkuehnel / MOIA + */ +public abstract class ZoneSystemParams extends ReflectiveConfigGroup { + public ZoneSystemParams(String paramSetName) { + super(paramSetName); + } +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java index d1e3e6f2094..91f63ac8be0 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/ZoneSystemUtils.java @@ -1,27 +1,96 @@ package org.matsim.contrib.common.zones; +import com.google.common.base.Preconditions; import one.util.streamex.EntryStream; import one.util.streamex.StreamEx; +import org.apache.commons.lang3.tuple.Pair; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.prep.PreparedGeometry; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdCollectors; +import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.Identifiable; 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.contrib.common.util.DistanceUtils; +import org.matsim.contrib.common.zones.io.ZoneShpReader; +import org.matsim.contrib.common.zones.io.ZoneXmlReader; +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.h3.H3ZoneSystem; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; +import org.matsim.contrib.common.zones.util.ZoneFinder; +import org.matsim.contrib.common.zones.util.ZoneFinderImpl; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.utils.geometry.geotools.MGC; +import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.io.File; +import java.io.UncheckedIOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.*; +import java.util.function.BinaryOperator; +import java.util.function.Predicate; +import java.util.stream.Collectors; -import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.*; +import static org.matsim.utils.gis.shp2matsim.ShpGeometryUtils.loadPreparedPolygons; +/** + * @author nkuehnel / MOIA + */ public final class ZoneSystemUtils { private ZoneSystemUtils() {} - public static ZoneSystem createFromPreparedGeometries(Network network, Map geometries) { + public static ZoneSystem createZoneSystem(Network network, ZoneSystemParams zoneSystemParams) { + return createZoneSystem(null, network, zoneSystemParams, null); + } + + public static ZoneSystem createZoneSystem(URL context, Network network, ZoneSystemParams zoneSystemParams) { + return createZoneSystem(context, network, zoneSystemParams, null); + } + + + public static ZoneSystem createZoneSystem(@Nullable URL context, @Nonnull Network network, + @Nonnull ZoneSystemParams zoneSystemParams, @Nullable String crs) { + + final ZoneSystem zoneSystem = switch (zoneSystemParams.getName()) { + case GISFileZoneSystemParams.SET_NAME -> { + Preconditions.checkNotNull(((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile); + Preconditions.checkNotNull(context); + + final List preparedGeometries = loadPreparedPolygons( + ConfigGroup.getInputFileURL(context, ((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile)); + yield ZoneSystemUtils.createFromPreparedGeometries(network, + EntryStream.of(preparedGeometries).mapKeys(i -> (i + 1) + "").toMap()); + } + case SquareGridZoneSystemParams.SET_NAME -> { + Preconditions.checkNotNull(((SquareGridZoneSystemParams) zoneSystemParams).cellSize); + + Predicate zoneFilter = zone -> true; + SquareGridZoneSystem squareGridZoneSystem = new SquareGridZoneSystem(network, ((SquareGridZoneSystemParams) zoneSystemParams).cellSize, zoneFilter); + yield squareGridZoneSystem; + } + case H3GridZoneSystemParams.SET_NAME -> { + Preconditions.checkNotNull(((H3GridZoneSystemParams) zoneSystemParams).h3Resolution); + Preconditions.checkNotNull(crs); + + Predicate zoneFilter = zone -> true; + yield new H3ZoneSystem(crs, ((H3GridZoneSystemParams) zoneSystemParams).h3Resolution, network, zoneFilter); + } + default -> throw new IllegalStateException("Unexpected value: " + zoneSystemParams.getName()); + }; + return zoneSystem; + } + + public static ZoneSystem createFromPreparedGeometries(Network network, Map geometries) { //geometries without links are skipped Map> linksByGeometryId = StreamEx.of(network.getLinks().values()) @@ -30,11 +99,12 @@ public static ZoneSystem createFromPreparedGeometries(Network network, Map zones = EntryStream.of(linksByGeometryId) - .mapKeyValue((id, links) -> new ZoneImpl(Id.create(id, Zone.class), geometries.get(id), links)) - .collect(toList()); + Map, Zone> zones = EntryStream.of(linksByGeometryId) + .mapKeyValue((id, links) -> new ZoneImpl(Id.create(id, Zone.class), geometries.get(id), null)) + .collect(IdCollectors.toIdMap(Zone.class, Identifiable::getId, zone -> zone)); + - return new ZoneSystemImpl(zones); + return new ZoneSystemImpl(zones.values(), new ZoneFinderImpl(zones), network); } /** @@ -44,7 +114,7 @@ public static ZoneSystem createFromPreparedGeometries(Network network, Map geometries) { + private static String getGeometryIdForLink(Link link, Map geometries) { Point linkCoord = MGC.coord2Point(link.getToNode().getCoord()); return geometries.entrySet() .stream() @@ -61,4 +131,74 @@ public static Id createZoneId(String id) { public static Id createZoneId(long id) { return Id.create(id, Zone.class); } + + public static Map, Zone> readZones(String zonesXmlFile, String zonesShpFile) { + try { + return readZones(new File(zonesXmlFile).toURI().toURL(), new File(zonesShpFile).toURI().toURL()); + } catch (MalformedURLException e) { + throw new UncheckedIOException(e); + } + } + + public static Map, Zone> readZones(URL zonesXmlUrl, URL zonesShpUrl) { + ZoneXmlReader xmlReader = new ZoneXmlReader(); + xmlReader.readURL(zonesXmlUrl); + Map, Zone> zones = xmlReader.getZones(); + + ZoneShpReader shpReader = new ZoneShpReader(zones); + shpReader.readZones(zonesShpUrl); + return zones; + } + + // if CRSs of the network and zones are different, zoneFinder should convert between CRSs + public static IdMap createLinkToZoneMap(Network network, ZoneFinder zoneFinder) { + return EntryStream.of(network.getLinks()) + .mapValues(link -> zoneFinder.findZone(link.getToNode().getCoord())) + .filterValues(Optional::isPresent) + .mapValues(Optional::get) + .collect(IdCollectors.toIdMap(Link.class, Map.Entry::getKey, Map.Entry::getValue)); + } + + public static IdMap createNodeToZoneMap(Network network, ZoneFinder zoneFinder) { + return EntryStream.of(network.getNodes()) + .mapValues(node -> zoneFinder.findZone(node.getCoord())) + .filterValues(Optional::isPresent) + .mapValues(Optional::get) + .collect(IdCollectors.toIdMap(Node.class, Map.Entry::getKey, Map.Entry::getValue)); + + } + + public static Set filterZonesWithNodes(Collection nodes, ZoneSystem zoneSystem) { + return nodes.stream().map(node -> zoneSystem.getZoneForNodeId(node.getId())).filter(Optional::isPresent).map(Optional::get).collect(toSet()); + } + + public static List selectNodesWithinArea(Collection nodes, List areaGeoms) { + return nodes.stream().filter(node -> { + Point point = MGC.coord2Point(node.getCoord()); + return areaGeoms.stream().anyMatch(serviceArea -> serviceArea.intersects(point)); + }).collect(toList()); + } + + public static Map computeMostCentralNodes(Collection nodes, ZoneSystem zoneSystem) { + BinaryOperator chooseMoreCentralNode = (n1, n2) -> { + Zone zone = zoneSystem.getZoneForNodeId(n1.getId()).orElseThrow(); + return DistanceUtils.calculateSquaredDistance(n1, zone) <= DistanceUtils.calculateSquaredDistance(n2, + zone) ? n1 : n2; + }; + return nodes.stream() + .map(n -> Pair.of(n, zoneSystem.getZoneForNodeId(n.getId()).orElseThrow())) + .collect(toMap(Pair::getValue, Pair::getKey, chooseMoreCentralNode)); + } + + public static IdMap> initZonesByDistance(Map, Zone> zones) { + IdMap> zonesByDistance = new IdMap<>(Zone.class); + for (final Zone currentZone : zones.values()) { + List sortedZones = zones.values() + .stream() + .sorted(Comparator.comparing(z -> DistanceUtils.calculateSquaredDistance(currentZone, z))) + .collect(Collectors.toList()); + zonesByDistance.put(currentZone.getId(), sortedZones); + } + return zonesByDistance; + } } diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3GridUtils.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3GridUtils.java deleted file mode 100644 index 9139e56442b..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3GridUtils.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.matsim.contrib.common.zones.h3; - -import com.uber.h3core.AreaUnit; -import com.uber.h3core.H3Core; -import com.uber.h3core.LengthUnit; -import com.uber.h3core.util.LatLng; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.GeometryFactory; -import org.locationtech.jts.geom.Polygon; -import org.locationtech.jts.geom.prep.PreparedGeometry; -import org.locationtech.jts.geom.prep.PreparedGeometryFactory; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.network.Network; -import org.matsim.core.network.NetworkUtils; -import org.matsim.core.utils.geometry.CoordUtils; -import org.matsim.core.utils.geometry.CoordinateTransformation; -import org.matsim.core.utils.geometry.transformations.TransformationFactory; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * @author nkuehnel / MOIA - */ -public class H3GridUtils { - - static final Logger log = LogManager.getLogger(H3GridUtils.class); - - public static Map createH3GridFromNetwork(Network network, int resolution, String crs) { - - H3Core h3 = H3Utils.getInstance(); - - log.info("start creating H3 grid from network at resolution " + resolution); - double hexagonEdgeLengthAvg = h3.getHexagonEdgeLengthAvg(resolution, LengthUnit.m); - log.info("Average edge length: " + hexagonEdgeLengthAvg + " meters."); - log.info("Average centroid distance: " + hexagonEdgeLengthAvg * Math.sqrt(3) + " meters."); - log.info("Average hexagon area: " + h3.getHexagonAreaAvg(resolution, AreaUnit.m2) + " m^2"); - - double[] boundingbox = NetworkUtils.getBoundingBox(network.getNodes().values()); - double minX = boundingbox[0]; - double maxX = boundingbox[2]; - double minY = boundingbox[1]; - double maxY = boundingbox[3]; - - GeometryFactory gf = new GeometryFactory(); - PreparedGeometryFactory preparedGeometryFactory = new PreparedGeometryFactory(); - Map grid = new HashMap<>(); - CoordinateTransformation toLatLong = TransformationFactory.getCoordinateTransformation(crs, TransformationFactory.WGS84); - CoordinateTransformation fromLatLong = TransformationFactory.getCoordinateTransformation(TransformationFactory.WGS84, crs); - - List boundingBoxPoints = new ArrayList<>(); - - Coord bottomLeft = toLatLong.transform(new Coord(minX, minY)); - Coord topLeft = toLatLong.transform(new Coord(minX, maxY)); - Coord topRight = toLatLong.transform(new Coord(maxX, maxY)); - Coord bottomRight = toLatLong.transform(new Coord(maxX, minY)); - - boundingBoxPoints.add(coordToLatLng(bottomLeft)); - boundingBoxPoints.add(coordToLatLng(topLeft)); - boundingBoxPoints.add(coordToLatLng(topRight)); - boundingBoxPoints.add(coordToLatLng(bottomRight)); - boundingBoxPoints.add(coordToLatLng(bottomLeft)); - - long millis = System.currentTimeMillis(); - - //get cells in a finer resolution to catch links at the border - List h3Grid = h3.polygonToCellAddresses(boundingBoxPoints, Collections.emptyList(), Math.min(H3Utils.MAX_RES, resolution)); - h3Grid = h3Grid - .parallelStream() - //also include neighbors with distance 1 - .flatMap(h3Id -> h3.gridDisk(h3Id, 1).stream()) - .distinct() - .toList(); - - if(h3Grid.isEmpty()) { - // bounding box too small to cover even a single H3 cell for a significant part. Use bounding box coords directly. - h3Grid = boundingBoxPoints.stream().map(corner -> h3.latLngToCellAddress(corner.lat, corner.lng, resolution)).distinct().toList(); - } - - log.info("Obtained " + h3Grid.size() + " H3 cells in " + (System.currentTimeMillis() - millis) + " ms."); - - - for (String h3Id : h3Grid) { - List coordinateList = h3.cellToBoundary(h3Id) - .stream() - .map(latLng -> CoordUtils.createGeotoolsCoordinate(fromLatLong.transform(latLngToCoord(latLng)))) - .collect(Collectors.toList()); - - if (!coordinateList.isEmpty()) { - coordinateList.add(coordinateList.get(0)); - } - - Polygon polygon = new Polygon(gf.createLinearRing(coordinateList.toArray(new Coordinate[0])), null, gf); - grid.put(h3Id, preparedGeometryFactory.create(polygon)); - } - - log.info("finished creating H3 grid from network."); - return grid; - } - - public static LatLng coordToLatLng(Coord coord) { - //invert coordinate order - return new LatLng(coord.getY(), coord.getX()); - } - - public static Coord latLngToCoord(LatLng latLng) { - //invert coordinate order - return new Coord(latLng.lng, latLng.lat); - } -} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3Utils.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3Utils.java deleted file mode 100644 index 3bc44478ebf..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3Utils.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.matsim.contrib.common.zones.h3; - -import com.uber.h3core.H3Core; - -import java.io.IOException; - -/** - * @author nkuehnel / MOIA - */ -public final class H3Utils { - - private static H3Core h3; - - public final static int MAX_RES = 16; - - - public static H3Core getInstance() { - if(h3 == null) { - try { - h3 = H3Core.newInstance(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - return h3; - } -} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3ZoneSystemUtils.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3ZoneSystemUtils.java deleted file mode 100644 index f496d62cc5d..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/h3/H3ZoneSystemUtils.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.matsim.contrib.common.zones.h3; - -import com.uber.h3core.H3Core; -import com.uber.h3core.util.LatLng; -import one.util.streamex.EntryStream; -import one.util.streamex.StreamEx; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.locationtech.jts.geom.prep.PreparedGeometry; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Network; -import org.matsim.contrib.common.zones.Zone; -import org.matsim.contrib.common.zones.ZoneImpl; -import org.matsim.contrib.common.zones.ZoneSystem; -import org.matsim.contrib.common.zones.ZoneSystemImpl; -import org.matsim.core.utils.geometry.CoordinateTransformation; -import org.matsim.core.utils.geometry.transformations.TransformationFactory; - -import javax.annotation.Nullable; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static java.util.stream.Collectors.toList; - -/** - * @author nkuehnel / MOIA - */ -public class H3ZoneSystemUtils { - - static final Logger log = LogManager.getLogger(H3ZoneSystemUtils.class); - - - public static ZoneSystem createFromPreparedGeometries(Network network, Map geometries, - String crs, int resolution) { - - //geometries without links are skipped - CoordinateTransformation ct = TransformationFactory.getCoordinateTransformation(crs, TransformationFactory.WGS84); - Map> linksByGeometryId = StreamEx.of(network.getLinks().values()) - .mapToEntry(l -> getGeometryIdForLink(l, geometries, resolution, ct), l -> l) - .filterKeys(Objects::nonNull) - .grouping(toList()); - - log.info("Network filtered zone system contains " + linksByGeometryId.size() + " zones for " - + network.getLinks().size() + " links and " + network.getNodes().size() + " nodes."); - - //the zonal system contains only zones that have at least one link - List zones = EntryStream.of(linksByGeometryId) - .mapKeyValue((id, links) -> new ZoneImpl(Id.create(id, Zone.class), geometries.get(id), links) { - }) - .collect(toList()); - - return new ZoneSystemImpl(zones); - } - - /** - * @param ct - * @param link - * @return the the {@code PreparedGeometry} that contains the {@code linkId}. - * If a given link's {@code Coord} borders two or more cells, the allocation to a cell is random. - * Result may be null in case the given link is outside of the service area. - *

- * Careful: does not work if grid contains different levels of h3 resolutions. - */ - @Nullable - private static String getGeometryIdForLink(Link link, Map geometries, int resolution, CoordinateTransformation ct) { - H3Core h3 = H3Utils.getInstance(); - LatLng latLng = H3GridUtils.coordToLatLng(ct.transform(link.getToNode().getCoord())); - String s = h3.latLngToCellAddress(latLng.lat, latLng.lng, resolution); - if (geometries.containsKey(s)) { - return s; - } else { - return null; - } - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneShpReader.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneShpReader.java similarity index 87% rename from contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneShpReader.java rename to contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneShpReader.java index d47dac4c588..46e6978a184 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneShpReader.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneShpReader.java @@ -17,18 +17,20 @@ * * * *********************************************************************** */ -package org.matsim.contrib.zone.io; - -import java.net.URL; -import java.util.Collection; -import java.util.Map; +package org.matsim.contrib.common.zones.io; import org.locationtech.jts.geom.MultiPolygon; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; import org.matsim.core.utils.gis.GeoFileReader; import org.opengis.feature.simple.SimpleFeature; +import java.net.URL; +import java.util.Collection; +import java.util.Map; + public class ZoneShpReader { private final Map, Zone> zones; @@ -49,7 +51,9 @@ public void readZones(URL url, String idHeader) { for (SimpleFeature ft : features) { String id = ft.getAttribute(idHeader).toString(); Zone z = zones.get(Id.create(id, Zone.class)); - z.setMultiPolygon((MultiPolygon)ft.getDefaultGeometry()); + if(z instanceof ZoneImpl zImpl) { + zImpl.setGeometry(new PreparedPolygon((MultiPolygon) ft.getDefaultGeometry())); + } } } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneShpWriter.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneShpWriter.java similarity index 83% rename from contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneShpWriter.java rename to contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneShpWriter.java index ba5bb104c9d..68ae03a7b6d 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneShpWriter.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneShpWriter.java @@ -17,17 +17,21 @@ * * * *********************************************************************** */ -package org.matsim.contrib.zone.io; - -import java.util.*; +package org.matsim.contrib.common.zones.io; +import org.locationtech.jts.geom.prep.PreparedGeometry; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; import org.matsim.core.utils.geometry.geotools.MGC; -import org.matsim.core.utils.gis.*; +import org.matsim.core.utils.gis.GeoFileWriter; +import org.matsim.core.utils.gis.PolygonFeatureFactory; import org.opengis.feature.simple.SimpleFeature; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + public class ZoneShpWriter { public static final String ID_HEADER = "ID"; @@ -48,7 +52,7 @@ public void write(String shpFile) { List features = new ArrayList<>(); for (Zone z : zones.values()) { String id = z.getId() + ""; - features.add(factory.createPolygon(z.getMultiPolygon(), new Object[] { id }, id)); + features.add(factory.createPolygon(z.getPreparedGeometry().getGeometry().getCoordinates(), new Object[] { id }, id)); } GeoFileWriter.writeGeometries(features, shpFile); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneXmlReader.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneXmlReader.java similarity index 87% rename from contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneXmlReader.java rename to contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneXmlReader.java index 5be277bb3f7..fc3c7ad971b 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneXmlReader.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneXmlReader.java @@ -17,15 +17,19 @@ * * * *********************************************************************** */ -package org.matsim.contrib.zone.io; - -import java.util.*; +package org.matsim.contrib.common.zones.io; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; import org.matsim.core.utils.io.MatsimXmlParser; import org.xml.sax.Attributes; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Stack; + public class ZoneXmlReader extends MatsimXmlParser { private final static String ZONE = "zone"; @@ -53,6 +57,6 @@ public void endTag(String name, String content, Stack context) { private void startZone(Attributes atts) { Id id = Id.create(atts.getValue("id"), Zone.class); String type = atts.getValue("type"); - zones.put(id, new Zone(id, type)); + zones.put(id, new ZoneImpl(id, null, null, type)); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneXmlWriter.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneXmlWriter.java similarity index 90% rename from contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneXmlWriter.java rename to contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneXmlWriter.java index f8f0a5b6180..f38912de946 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/io/ZoneXmlWriter.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/io/ZoneXmlWriter.java @@ -1,15 +1,16 @@ -package org.matsim.contrib.zone.io; +package org.matsim.contrib.common.zones.io; + +import org.matsim.api.core.v01.Id; + +import org.matsim.contrib.common.zones.Zone; +import org.matsim.core.utils.collections.Tuple; +import org.matsim.core.utils.io.MatsimXmlWriter; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; -import org.matsim.core.utils.collections.Tuple; -import org.matsim.core.utils.io.MatsimXmlWriter; - public class ZoneXmlWriter extends MatsimXmlWriter { private final Map, Zone> zones; diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/GISFileZoneSystemParams.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/GISFileZoneSystemParams.java new file mode 100644 index 00000000000..71274cfccf9 --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/GISFileZoneSystemParams.java @@ -0,0 +1,31 @@ +package org.matsim.contrib.common.zones.systems.grid; + +import com.google.common.base.Verify; +import org.matsim.contrib.common.zones.ZoneSystemParams; +import org.matsim.core.config.Config; + +import javax.annotation.Nullable; + +/** + * @author nkuehnel / MOIA + */ +public class GISFileZoneSystemParams extends ZoneSystemParams { + + public static final String SET_NAME = "GISFileZoneSystem"; + + public GISFileZoneSystemParams() { + super(SET_NAME); + } + + @Parameter + @Comment("allows to configure zones. Used with zonesGeneration=ShapeFile") + @Nullable + public String zonesShapeFile = null; + + @Override + protected void checkConsistency(Config config) { + super.checkConsistency(config); + + Verify.verify(zonesShapeFile != null, "GIS zone input file must not be null."); + } +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3GridZoneSystemParams.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3GridZoneSystemParams.java new file mode 100644 index 00000000000..e342419328d --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3GridZoneSystemParams.java @@ -0,0 +1,35 @@ +package org.matsim.contrib.common.zones.systems.grid.h3; + +import com.google.common.base.Verify; +import org.matsim.contrib.common.zones.ZoneSystemParams; +import org.matsim.core.config.Config; + +import javax.annotation.Nullable; + + +/** + * @author nkuehnel / MOIA + */ +public class H3GridZoneSystemParams extends ZoneSystemParams { + + public static final String SET_NAME = "H3GridZoneSystem"; + + public H3GridZoneSystemParams() { + super(SET_NAME); + } + + @Parameter + @Comment("allows to configure H3 hexagonal zones. Used with zonesGeneration=H3. " + + "Range from 0 (122 cells worldwide) to 15 (569 E^12 cells). " + + "Usually meaningful between resolution 6 (3.7 km avg edge length) " + + "and 10 (70 m avg edge length). ") + @Nullable + public Integer h3Resolution = null; + + @Override + protected void checkConsistency(Config config) { + super.checkConsistency(config); + + Verify.verify(h3Resolution != null && h3Resolution >= 0 && h3Resolution < 15, "H3 resolution must be a valid level between 0 and 15."); + } +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3Utils.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3Utils.java new file mode 100644 index 00000000000..ce6d71d86af --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3Utils.java @@ -0,0 +1,106 @@ +package org.matsim.contrib.common.zones.systems.grid.h3; + +import com.google.common.base.Preconditions; +import com.uber.h3core.H3Core; +import com.uber.h3core.util.LatLng; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.geom.prep.PreparedPolygon; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; +import org.matsim.core.utils.geometry.CoordinateTransformation; +import org.matsim.core.utils.geometry.GeometryUtils; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author nkuehnel / MOIA + */ +public final class H3Utils { + + private static H3Core h3; + + static { + try { + h3 = H3Core.newInstance(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public final static int MAX_RES = 16; + + + public static H3Core getInstance() { + if(h3 == null) { + try { + h3 = H3Core.newInstance(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return h3; + } + + private static Polygon getPolygon(String h3Id, CoordinateTransformation fromLatLong) { + Preconditions.checkArgument(h3.isValidCell(h3Id), "Not a valid H3 address: " + h3Id); + List coordinateList = h3.cellToBoundary(h3Id) + .stream() + .map(latLng -> fromLatLong.transform(latLngToCoord(latLng))) + .collect(Collectors.toList()); + + if (!coordinateList.isEmpty()) { + coordinateList.add(coordinateList.get(0)); + } + + return GeometryUtils.createGeotoolsPolygon(coordinateList); + } + + private static Polygon getPolygon(long h3Id, CoordinateTransformation fromLatLong) { + Preconditions.checkArgument(h3.isValidCell(h3Id), "Not a valid H3 address: " + h3Id); + List coordinateList = h3.cellToBoundary(h3Id) + .stream() + .map(latLng -> fromLatLong.transform(latLngToCoord(latLng))) + .collect(Collectors.toList()); + + if (!coordinateList.isEmpty()) { + coordinateList.add(coordinateList.get(0)); + } + + return GeometryUtils.createGeotoolsPolygon(coordinateList); + } + + public static LatLng coordToLatLng(Coord coord) { + //invert coordinate order + return new LatLng(coord.getY(), coord.getX()); + } + + public static Coord latLngToCoord(LatLng latLng) { + //invert coordinate order + return new Coord(latLng.lng, latLng.lat); + } + + public static String getH3Address(Coord latLong, int resolution) { + LatLng latLng = coordToLatLng(latLong); + return h3.latLngToCellAddress(latLng.lat, latLng.lng, resolution); + + } + + public static long getH3Cell(Coord latLong, int resolution) { + LatLng latLng = coordToLatLng(latLong); + return h3.latLngToCell(latLng.lat, latLng.lng, resolution); + + } + + public static Optional createZone(long id, CoordinateTransformation fromLatLong) { + if(h3.isValidCell(id)) { + return Optional.of(new ZoneImpl(Id.create(id, Zone.class), new PreparedPolygon(getPolygon(id, fromLatLong)), "h3")); + } else { + return Optional.empty(); + } + } +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3ZoneSystem.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3ZoneSystem.java new file mode 100644 index 00000000000..e9c84bccc4a --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/h3/H3ZoneSystem.java @@ -0,0 +1,109 @@ +package org.matsim.contrib.common.zones.systems.grid.h3; + +import gnu.trove.map.TObjectLongMap; +import gnu.trove.map.hash.TObjectLongHashMap; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +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.contrib.common.zones.GridZoneSystem; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.core.utils.geometry.CoordinateTransformation; +import org.matsim.core.utils.geometry.transformations.TransformationFactory; + +import java.util.*; +import java.util.function.Predicate; + +/** + * @author nkuehnel / MOIA + */ +public class H3ZoneSystem implements GridZoneSystem { + + private final IdMap zones = new IdMap<>(Zone.class); + private final IdMap> zoneToLinksMap = new IdMap<>(Zone.class); + + private final TObjectLongMap coordH3Cache = new TObjectLongHashMap<>(); + + private final CoordinateTransformation toLatLong; + private final CoordinateTransformation fromLatLong; + + private final int resolution; + private final Network network; + private final Predicate filter; + + public H3ZoneSystem(String crs, int resolution, Network network, Predicate filter) { + this.fromLatLong = TransformationFactory.getCoordinateTransformation(TransformationFactory.WGS84, crs); + this.toLatLong = TransformationFactory.getCoordinateTransformation(crs, TransformationFactory.WGS84); + this.resolution = resolution; + this.network = network; + this.filter = filter; + this.network.getLinks().values().forEach(l -> getZoneForCoord(l.getToNode().getCoord())); + } + + + @Override + public Optional getZoneForCoord(Coord coord) { + + long h3Address = getH3Cell(coord); + Id zoneId = Id.create(h3Address, Zone.class); + + if(zones.containsKey(zoneId)) { + return Optional.of(zones.get(zoneId)); + } else { + Optional zone = H3Utils.createZone(h3Address, fromLatLong); + if(zone.isPresent() && filter.test(zone.get())) { + initZone(zone.get(), h3Address); + return zone; + } else { + return Optional.empty(); + } + } + } + + private void initZone(Zone zone, long h3Address) { + if(filter.test(zone)) { + zones.put(zone.getId(), zone); + for (Link link : network.getLinks().values()) { + long linkH3Address = getH3Cell(link.getToNode().getCoord()); + + if (linkH3Address == h3Address) { + List links = zoneToLinksMap.computeIfAbsent(zone.getId(), id -> new ArrayList<>()); + links.add(link); + } + } + } + } + + private long getH3Cell(Coord coord) { + long h3Address; + if(coordH3Cache.containsKey(coord)) { + h3Address = coordH3Cache.get(coord); + } else { + h3Address = H3Utils.getH3Cell(toLatLong.transform(coord), resolution); + coordH3Cache.put(coord, h3Address); + } + return h3Address; + } + + @Override + public Optional getZoneForLinkId(Id link) { + return getZoneForCoord(network.getLinks().get(link).getToNode().getCoord()); + } + + @Override + public Optional getZoneForNodeId(Id nodeId) { + return getZoneForCoord(network.getNodes().get(nodeId).getCoord()); + } + + @Override + public List getLinksForZoneId(Id zone) { + return zoneToLinksMap.getOrDefault(zone, Collections.emptyList()); + } + + @Override + public Map, Zone> getZones() { + return Collections.unmodifiableMap(zones); + } +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystem.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystem.java new file mode 100644 index 00000000000..f11fa58f614 --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystem.java @@ -0,0 +1,189 @@ +/* *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2015 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.contrib.common.zones.systems.grid.square; + +import com.google.common.base.Preconditions; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.geom.prep.PreparedPolygon; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +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.contrib.common.zones.GridZoneSystem; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.utils.geometry.GeometryUtils; + +import java.util.*; +import java.util.function.Predicate; + +public class SquareGridZoneSystem implements GridZoneSystem { + + private final double cellSize; + private final Predicate zoneFilter; + + private double minX; + private double minY; + private double maxX; + private double maxY; + + private final int cols; + private final int rows; + + private final Zone[] internalZones; + + private final IdMap zones = new IdMap<>(Zone.class); + + private final IdMap> zoneToLinksMap = new IdMap<>(Zone.class); + private final Network network; + + + public SquareGridZoneSystem(Network network, double cellSize) { + this(network, cellSize, true, z -> true); + } + public SquareGridZoneSystem(Network network, double cellSize, Predicate zoneFilter) { + this(network, cellSize, true, zoneFilter); + } + public SquareGridZoneSystem(Network network, double cellSize, boolean filterByNetwork, Predicate zoneFilter) { + this.zoneFilter = zoneFilter; + Preconditions.checkArgument(!network.getNodes().isEmpty(), "Cannot create SquareGrid if no nodes"); + + this.network = network; + this.cellSize = cellSize; + + initBounds(); + + this.rows = Math.max(1, (int) Math.ceil((maxY - minY) / cellSize)); + this.cols = Math.max(1, (int)Math.ceil((maxX - minX) / cellSize)); + this.internalZones = new Zone[rows * cols +1]; + + if(filterByNetwork) { + network.getLinks().values().forEach(l -> getOrCreateZone(l.getToNode().getCoord())); + } else { + for (double lx = minX; lx < maxX; lx += cellSize) { + for (double by = minY; by < maxY; by += cellSize) { + Coord coord = new Coord(lx, by); + getOrCreateZone(coord); + } + } + } + } + + @Override + public Map, Zone> getZones() { + return Collections.unmodifiableMap(zones); + } + + @Override + public Optional getZoneForLinkId(Id linkId) { + return getZoneForNodeId(network.getLinks().get(linkId).getToNode().getId()); + } + + @Override + public Optional getZoneForNodeId(Id nodeId) { + return getOrCreateZone(network.getNodes().get(nodeId).getCoord()); + } + + @Override + public Optional getZoneForCoord(Coord coord) { + return getOrCreateZone(coord); + } + + @Override + public List getLinksForZoneId(Id zone) { + return zoneToLinksMap.get(zone); + } + + private Optional getOrCreateZone(Coord coord) { + int index = getIndex(coord); + Zone zone = internalZones[index]; + if (zone == null) { + int r = bin(coord.getY(), minY); + int c = bin(coord.getX(), minX); + PreparedPolygon geometry = getGeometry(r, c); + zone = new ZoneImpl(Id.create(index, Zone.class), geometry, "square"); + + if(zoneFilter.test(zone)) { + internalZones[index] = zone; + zones.put(zone.getId(), zone); + + for (Link link : network.getLinks().values()) { + if (getIndex(link.getToNode().getCoord()) == index) { + List links = zoneToLinksMap.computeIfAbsent(zone.getId(), zoneId -> new ArrayList<>()); + links.add(link); + } + } + } else { + return Optional.empty(); + } + } + return Optional.of(zone); + } + + private PreparedPolygon getGeometry(int r, int c) { + List coords = new ArrayList<>(); + coords.add(new Coord(minX + c * cellSize, minY + r * cellSize)); + coords.add(new Coord(minX + (c + 1) * cellSize, minY + r * cellSize)); + coords.add(new Coord(minX + (c + 1 ) * cellSize, minY + (r + 1) * cellSize)); + coords.add(new Coord(minX + c * cellSize, minY + (r + 1) * cellSize)); + Polygon polygon = GeometryUtils.createGeotoolsPolygon(coords); + return new PreparedPolygon(polygon); + } + + + // This method's content has been copied from NetworkImpl + private void initBounds() { + double[] boundingBox = NetworkUtils.getBoundingBox(network.getNodes().values()); + minX = boundingBox[0]; + minY = boundingBox[1]; + maxX = boundingBox[2]; + maxY = boundingBox[3]; + // yy the above four lines are problematic if the coordinate values are much smaller than one. kai, oct'15 + } + + + private int getIndex(Coord coord) { + Preconditions.checkArgument(coord.getX() >= minX, "Coord.x less than minX"); + Preconditions.checkArgument(coord.getX() <= maxX, "Coord.x greater than maxX"); + Preconditions.checkArgument(coord.getY() >= minY, "Coord.y less than minY"); + Preconditions.checkArgument(coord.getY() <= maxY, "Coord.y greater than maxY"); + int r; + int c; + if(coord.getY() == maxY) { + r = Math.max(0, rows - 1); + } else { + r = bin(coord.getY(), minY); + } + + if(coord.getX() == maxX) { + c = Math.max(0, cols - 1); + } else { + c = bin(coord.getX(), minX); + } + return r * cols + c; + } + + private int bin(double coord, double minCoord) { + return (int)((coord - minCoord) / cellSize); + } +} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystemParams.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystemParams.java new file mode 100644 index 00000000000..3fe1fbe1b5b --- /dev/null +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystemParams.java @@ -0,0 +1,31 @@ +package org.matsim.contrib.common.zones.systems.grid.square; + +import com.google.common.base.Verify; +import jakarta.validation.constraints.Positive; +import org.matsim.contrib.common.zones.ZoneSystemParams; +import org.matsim.core.config.Config; + +/** + * @author nkuehnel / MOIA + */ +public class SquareGridZoneSystemParams extends ZoneSystemParams { + + public static final String SET_NAME = "SquareGridZoneSystem"; + + public SquareGridZoneSystemParams() { + super(SET_NAME); + } + + @Parameter + @Comment("size of square cells used for demand aggregation." + + " Depends on demand, supply and network. Often used with values in the range of 500 - 2000 m") + @Positive + public double cellSize = 200.;// [m] + + @Override + protected void checkConsistency(Config config) { + super.checkConsistency(config); + Verify.verify(cellSize > 0 && Double.isFinite(cellSize), "cell size must be finite and positive."); + } + +} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/SubzoneUtils.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/util/SubzoneUtils.java similarity index 88% rename from contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/SubzoneUtils.java rename to contribs/common/src/main/java/org/matsim/contrib/common/zones/util/SubzoneUtils.java index a224e470ec6..01b9a80c6ee 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/SubzoneUtils.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/util/SubzoneUtils.java @@ -17,38 +17,38 @@ * * * *********************************************************************** */ -package org.matsim.contrib.zone.util; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +package org.matsim.contrib.common.zones.util; import org.geotools.geometry.jts.GeometryCollector; import org.locationtech.jts.geom.Geometry; -import org.locationtech.jts.geom.MultiPolygon; import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.geom.TopologyException; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.locationtech.jts.geom.util.PolygonExtracter; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; import org.opengis.feature.simple.SimpleFeature; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class SubzoneUtils { public static Map, List> extractSubzonePolygons(Map, Zone> zones, - Collection subzonePattern) { + Collection subzonePattern) { Map, List> polygonsByZone = new HashMap<>(); int topologyExceptionCount = 0; for (Zone z : zones.values()) { - MultiPolygon zoneMultiPoly = z.getMultiPolygon(); + PreparedPolygon zonePoly = z.getPreparedGeometry(); GeometryCollector geometryCollector = new GeometryCollector(); for (SimpleFeature f : subzonePattern) { Geometry featureGeometry = (Geometry)f.getDefaultGeometry(); try { - geometryCollector.add(zoneMultiPoly.intersection(featureGeometry)); + geometryCollector.add(zonePoly.getGeometry().intersection(featureGeometry)); } catch (TopologyException e) { topologyExceptionCount++; } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/ZoneFinder.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/util/ZoneFinder.java similarity index 89% rename from contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/ZoneFinder.java rename to contribs/common/src/main/java/org/matsim/contrib/common/zones/util/ZoneFinder.java index ac14584bd9c..95f0a9ce53c 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/ZoneFinder.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/util/ZoneFinder.java @@ -17,11 +17,13 @@ * * * *********************************************************************** */ -package org.matsim.contrib.zone.util; +package org.matsim.contrib.common.zones.util; import org.matsim.api.core.v01.Coord; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; + +import java.util.Optional; public interface ZoneFinder { - Zone findZone(Coord coord); + Optional findZone(Coord coord); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/ZoneFinderImpl.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/util/ZoneFinderImpl.java similarity index 80% rename from contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/ZoneFinderImpl.java rename to contribs/common/src/main/java/org/matsim/contrib/common/zones/util/ZoneFinderImpl.java index 17f0c8d0716..fbe32f45ac5 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/ZoneFinderImpl.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/util/ZoneFinderImpl.java @@ -17,10 +17,11 @@ * * * *********************************************************************** */ -package org.matsim.contrib.zone.util; +package org.matsim.contrib.common.zones.util; import java.util.List; import java.util.Map; +import java.util.Optional; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Point; @@ -28,7 +29,7 @@ import org.locationtech.jts.index.quadtree.Quadtree; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; import org.matsim.core.utils.geometry.geotools.MGC; public class ZoneFinderImpl implements ZoneFinder { @@ -39,19 +40,26 @@ public ZoneFinderImpl(Map, Zone> zones, double expansionDistance) { this.expansionDistance = expansionDistance; for (Zone z : zones.values()) { - quadTree.insert(z.getMultiPolygon().getEnvelopeInternal(), z); + quadTree.insert(z.getPreparedGeometry().getGeometry().getEnvelopeInternal(), z); + } + } + public ZoneFinderImpl(Map, Zone> zones) { + this.expansionDistance = Double.MIN_VALUE; + + for (Zone z : zones.values()) { + quadTree.insert(z.getPreparedGeometry().getGeometry().getEnvelopeInternal(), z); } } @Override @SuppressWarnings("unchecked") - public Zone findZone(Coord coord) { + public Optional findZone(Coord coord) { Point point = MGC.coord2Point(coord); Envelope env = point.getEnvelopeInternal(); Zone zone = getSmallestZoneContainingPoint(quadTree.query(env), point); if (zone != null) { - return zone; + return Optional.of(zone); } if (expansionDistance > 0) { @@ -59,7 +67,7 @@ public Zone findZone(Coord coord) { zone = getNearestZone(quadTree.query(env), point); } - return zone; + return Optional.ofNullable(zone); } private Zone getSmallestZoneContainingPoint(List zones, Point point) { @@ -71,8 +79,8 @@ private Zone getSmallestZoneContainingPoint(List zones, Point point) { Zone smallestZone = null; for (Zone z : zones) { - if (z.getMultiPolygon().contains(point)) { - double area = z.getMultiPolygon().getArea(); + if (z.getPreparedGeometry().contains(point)) { + double area = z.getPreparedGeometry().getGeometry().getArea(); if (area < minArea) { minArea = area; smallestZone = z; @@ -92,7 +100,7 @@ private Zone getNearestZone(List zones, Point point) { Zone nearestZone = null; for (Zone z : zones) { - double distance = z.getMultiPolygon().distance(point); + double distance = z.getPreparedGeometry().getGeometry().distance(point); if (distance <= expansionDistance) { if (distance < minDistance) { minDistance = distance; diff --git a/contribs/common/src/test/java/org/matsim/contrib/common/zones/systems/grid/SquareGridTest.java b/contribs/common/src/test/java/org/matsim/contrib/common/zones/systems/grid/SquareGridTest.java new file mode 100644 index 00000000000..b22d2500b57 --- /dev/null +++ b/contribs/common/src/test/java/org/matsim/contrib/common/zones/systems/grid/SquareGridTest.java @@ -0,0 +1,112 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2020 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.contrib.common.zones.systems.grid; + +import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.CoordinateSequence; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.impl.CoordinateArraySequence; +import org.locationtech.jts.geom.prep.PreparedPolygon; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; +import org.matsim.core.network.NetworkUtils; + +import static org.assertj.core.api.Assertions.*; + +/** + * @author Michal Maciejewski (michalm) + */ +public class SquareGridTest { + @Test + void emptyNodes_fail() { + assertThatThrownBy(() -> new SquareGridZoneSystem(NetworkUtils.createNetwork(), 100, zone -> true)).isExactlyInstanceOf(IllegalArgumentException.class) + .hasMessage("Cannot create SquareGrid if no nodes"); + } + + @Test + void outsideBoundaries_withinEpsilon_success() { + Node node_0_0 = node(0, 0); + Network network = NetworkUtils.createNetwork(); + network.addNode(node_0_0); + SquareGridZoneSystem grid = new SquareGridZoneSystem(network, 100, zone -> true); + assertThatCode(() -> grid.getZoneForCoord(new Coord(-0, 0))).doesNotThrowAnyException(); + } + + @Test + void outsideBoundaries_outsideEpsilon_fail() { + Node node_0_0 = node(0, 0); + Network network = NetworkUtils.createNetwork(); + network.addNode(node_0_0); + SquareGridZoneSystem grid = new SquareGridZoneSystem(network, 100, zone -> true); + + assertThatThrownBy(() -> grid.getZoneForCoord(new Coord(-2, 0))).isExactlyInstanceOf( + IllegalArgumentException.class); + } + + @Test + void testGrid() { + Node node_0_0 = node(0, 0); + Node node_150_150 = node(150, 150); + + Network network = NetworkUtils.createNetwork(); + network.addNode(node_0_0); + network.addNode(node_150_150); + SquareGridZoneSystem grid = new SquareGridZoneSystem(network, 100, zone -> true); + + Coord coord0 = new Coord(100, 100); + CoordinateSequence coordinateSequence = getCoordinateSequence(); + + PreparedPolygon polygon = new PreparedPolygon(new GeometryFactory().createPolygon(coordinateSequence)); + Zone zone0 = new ZoneImpl(Id.create(3, Zone.class), polygon, new Coord(150, 150), "square"); + assertThat(grid.getZoneForCoord(coord0).orElseThrow()).isEqualToComparingFieldByFieldRecursively(zone0); + + + } + + private static CoordinateSequence getCoordinateSequence() { + CoordinateSequence coordinateSequence = new CoordinateArraySequence(5); + + coordinateSequence.setOrdinate(0,0, 100); + coordinateSequence.setOrdinate(0,1, 100); + + coordinateSequence.setOrdinate(1,0, 200); + coordinateSequence.setOrdinate(1,1, 100); + + coordinateSequence.setOrdinate(2,0, 200); + coordinateSequence.setOrdinate(2,1, 200); + + coordinateSequence.setOrdinate(3,0, 100); + coordinateSequence.setOrdinate(3,1, 200); + + coordinateSequence.setOrdinate(4,0, 100); + coordinateSequence.setOrdinate(4,1, 100); + return coordinateSequence; + } + + private Node node(double x, double y) { + return NetworkUtils.createNode(Id.createNodeId(x + "," + y), new Coord(x, y)); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java index f3947244027..05bf57a35a1 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java @@ -19,7 +19,7 @@ package org.matsim.contrib.drt.extension.companions; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.Config; import java.util.Arrays; import java.util.List; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java index 985435bcfc3..26a4e754538 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java @@ -6,7 +6,7 @@ import jakarta.validation.constraints.PositiveOrZero; import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.dvrp.run.Modal; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; public class DrtEstimatorConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets implements Modal { diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsParams.java index 43dbc38503e..32f1ac22b2b 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsParams.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsParams.java @@ -10,7 +10,7 @@ import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesParams; import org.matsim.contrib.drt.extension.operations.shifts.config.ShiftsParams; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import javax.annotation.Nullable; import java.util.Optional; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesParams.java index 7f90b17861a..1d6454e2668 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesParams.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesParams.java @@ -1,6 +1,6 @@ package org.matsim.contrib.drt.extension.operations.operationFacilities; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.ConfigGroup; import java.net.URL; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java index 2f7944d5b9d..4d76cbddfc0 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java @@ -9,7 +9,7 @@ package org.matsim.contrib.drt.extension.operations.shifts.config; import org.matsim.contrib.ev.infrastructure.ChargerSpecification; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.ConfigGroup; import java.net.URL; diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java index 8a6b6e4098c..b0fa3afd2db 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java @@ -24,10 +24,13 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; @@ -57,7 +60,8 @@ void testRunDrtWithCompanions() { MatsimRandom.reset(); Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new OTFVisConfigGroup(), new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new), new DvrpConfigGroup()); + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + Config config = ConfigUtils.loadConfig(configUrl, new OTFVisConfigGroup(), new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new), dvrpConfigGroup); // Add DrtCompanionParams with some default values into existing Drt configurations MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); @@ -68,6 +72,10 @@ void testRunDrtWithCompanions() { drtWithExtensionsConfigGroup.addParameterSet(crtCompanionParams); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + ConfigGroup zoneSystemParams = matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + matrixParams.addParameterSet(zoneSystemParams); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); config.controller().setOutputDirectory(utils.getOutputDirectory()); @@ -84,7 +92,8 @@ void testRunDrtWithCompanionsMultiThreaded() { MatsimRandom.reset(); Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new OTFVisConfigGroup(), new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new), new DvrpConfigGroup()); + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + Config config = ConfigUtils.loadConfig(configUrl, new OTFVisConfigGroup(), new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new), dvrpConfigGroup); // Add DrtCompanionParams with some default values into existing Drt configurations MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); @@ -95,6 +104,10 @@ void testRunDrtWithCompanionsMultiThreaded() { drtWithExtensionsConfigGroup.addParameterSet(crtCompanionParams); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + ConfigGroup zoneSystemParams = matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + matrixParams.addParameterSet(zoneSystemParams); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); config.controller().setOutputDirectory(utils.getOutputDirectory()); config.qsim().setNumberOfThreads(2); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java index 2ced56d6edf..1d23eb2a1c4 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java @@ -28,6 +28,7 @@ import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.Plan; import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory; import org.matsim.contrib.drt.prebooking.PrebookingParams; import org.matsim.contrib.drt.prebooking.logic.ProbabilityBasedPrebookingLogic; @@ -48,7 +49,9 @@ import org.matsim.contrib.evrp.EvDvrpFleetQSimModule; import org.matsim.contrib.evrp.OperatingVehicleProvider; import org.matsim.contrib.otfvis.OTFVisLiveModule; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; @@ -75,10 +78,10 @@ void test() { void testMultiModeDrtDeterminism() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_multiModeEdrt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfigGroup, new OTFVisConfigGroup(), new EvConfigGroup()); - Controler controller = RunEDrtScenario.createControler(config, false); config.controller().setLastIteration(2); @@ -87,7 +90,7 @@ void testMultiModeDrtDeterminism() { controller.run(); - assertEquals(2011, tracker.passengerPickupEvents); + assertEquals(1926, tracker.passengerPickupEvents); } @@ -95,7 +98,8 @@ void testMultiModeDrtDeterminism() { void testWithPrebooking() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_edrt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfigGroup, new OTFVisConfigGroup(), new EvConfigGroup()); DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(config); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java index 6034419d22e..d9eda86cc8b 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java @@ -5,7 +5,8 @@ import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.events.LinkLeaveEvent; import org.matsim.api.core.v01.events.handler.LinkLeaveEventHandler; -import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; +import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsControlerCreator; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; import org.matsim.contrib.drt.extension.operations.DrtWithOperationsConfigGroup; @@ -17,6 +18,7 @@ import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; @@ -75,16 +77,18 @@ void test() { drtConfigGroup.getRebalancingParams().get().addParameterSet(strategyParams); - DrtZonalSystemParams drtZonalSystemParams = new DrtZonalSystemParams(); - drtZonalSystemParams.zonesGeneration = DrtZonalSystemParams.ZoneGeneration.GridFromNetwork; - drtZonalSystemParams.cellSize = 500.; - drtZonalSystemParams.targetLinkSelection = DrtZonalSystemParams.TargetLinkSelection.mostCentral; - drtConfigGroup.addParameterSet(drtZonalSystemParams); + DrtZoneSystemParams drtZoneSystemParams = new DrtZoneSystemParams(); + SquareGridZoneSystemParams zoneSystemParams = (SquareGridZoneSystemParams) drtZoneSystemParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + zoneSystemParams.cellSize = 500.; + drtZoneSystemParams.addParameterSet(zoneSystemParams); + drtZoneSystemParams.targetLinkSelection = DrtZoneSystemParams.TargetLinkSelection.mostCentral; + drtConfigGroup.addParameterSet(drtZoneSystemParams); multiModeDrtConfigGroup.addParameterSet(drtWithShiftsConfigGroup); + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); final Config config = ConfigUtils.createConfig(multiModeDrtConfigGroup, - new DvrpConfigGroup()); + dvrpConfigGroup); config.setContext(ExamplesUtils.getTestScenarioURL("holzkirchen")); Set modes = new HashSet<>(); @@ -99,6 +103,9 @@ void test() { config.plans().setInputFile(plansFile); config.network().setInputFile(networkFile); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.minOfEndtimeAndMobsimFinished); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/RunDrtWithH3ZonalSystemIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/RunDrtWithH3ZonalSystemIT.java index 86595942ed2..d1ef4e2fea7 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/RunDrtWithH3ZonalSystemIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/RunDrtWithH3ZonalSystemIT.java @@ -5,14 +5,16 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.application.MATSimApplication; import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; -import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; +import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams; import org.matsim.contrib.drt.analysis.zonal.DrtZonalWaitTimesAnalyzer; import org.matsim.contrib.drt.extension.DrtTestScenario; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; @@ -45,8 +47,12 @@ private static void prepare(Controler controler, Config config) { MultiModeDrtConfigGroup drtConfigs = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); for (DrtConfigGroup drtConfig : drtConfigs.getModalElements()) { - drtConfig.getZonalSystemParams().get().h3Resolution = 9; - drtConfig.getZonalSystemParams().get().zonesGeneration = DrtZonalSystemParams.ZoneGeneration.H3; + + DrtZoneSystemParams drtZoneSystemParams = drtConfig.getZonalSystemParams().get(); + drtZoneSystemParams.removeParameterSet(drtZoneSystemParams.getZoneSystemParams()); + ConfigGroup zoneSystemParams = drtZoneSystemParams.createParameterSet(H3GridZoneSystemParams.SET_NAME); + ((H3GridZoneSystemParams) zoneSystemParams).h3Resolution = 9; + drtZoneSystemParams.addParameterSet(zoneSystemParams); controler.addOverridingModule(new AbstractModule() { @Override public void install() { @@ -67,11 +73,6 @@ public void install() { private static void prepare(Config config) { MultiModeDrtConfigGroup drtConfigs = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); - for (DrtConfigGroup drtConfig : drtConfigs.getModalElements()) { - DrtZonalSystemParams params = drtConfig.getZonalSystemParams().orElseThrow(); - params.cellSize = 1.; - params.zonesGeneration = DrtZonalSystemParams.ZoneGeneration.GridFromNetwork; - } } @Test diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone/H3DrtZonalSystemTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone/H3DrtZonalSystemTest.java index 293fa254280..3724d5d8eac 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone/H3DrtZonalSystemTest.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone/H3DrtZonalSystemTest.java @@ -25,8 +25,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.common.zones.ZoneSystem; -import org.matsim.contrib.common.zones.h3.H3GridUtils; -import org.matsim.contrib.common.zones.h3.H3ZoneSystemUtils; +import org.matsim.contrib.common.zones.systems.grid.h3.H3ZoneSystem; import org.matsim.core.config.ConfigGroup; import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.io.MatsimNetworkReader; @@ -49,17 +48,16 @@ void test_Holzkirchen_Resolution3() { Network network = getNetwork(); String crs = TransformationFactory.DHDN_GK4; int resolution = 3; - ZoneSystem drtZonalSystem = H3ZoneSystemUtils.createFromPreparedGeometries(network, - H3GridUtils.createH3GridFromNetwork(network, resolution, crs), crs, resolution); + ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("831f8dfffffffff"))).isTrue(); + assertThat(drtZonalSystem.getZones().containsKey(createZoneId("590526392240701439"))).isTrue(); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).getId()).isEqualTo(createZoneId("831f8dfffffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("590526667118608383")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).getId()).isEqualTo(createZoneId("831f8dfffffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("590526667118608383")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).getId()).isEqualTo(createZoneId("831f89fffffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("590526392240701439")); //check all links are mapped for (Link link : network.getLinks().values()) { @@ -72,20 +70,20 @@ void test_Holzkirchen_Resolution5() { Network network = getNetwork(); String crs = TransformationFactory.DHDN_GK4; int resolution = 5; - ZoneSystem drtZonalSystem = H3ZoneSystemUtils.createFromPreparedGeometries(network, - H3GridUtils.createH3GridFromNetwork(network, resolution, crs), crs, resolution); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("851f88b7fffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("851f8d6bfffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("851f88a7fffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("851f89d3fffffff"))).isTrue(); + ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); + + assertThat(drtZonalSystem.getZones().containsKey(createZoneId("599533579684282367"))).isTrue(); + assertThat(drtZonalSystem.getZones().containsKey(createZoneId("599533826644901887"))).isTrue(); + assertThat(drtZonalSystem.getZones().containsKey(createZoneId("599533499153645567"))).isTrue(); + assertThat(drtZonalSystem.getZones().containsKey(createZoneId("599533503448612863"))).isTrue(); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).getId()).isEqualTo(createZoneId("851f8d6bfffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("599533826644901887")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).getId()).isEqualTo(createZoneId("851f88b7fffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("599533503448612863")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).getId()).isEqualTo(createZoneId("851f89d3fffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("599533579684282367")); //check all links are mapped for (Link link : network.getLinks().values()) { @@ -98,22 +96,15 @@ void test_Holzkirchen_Resolution6() { Network network = getNetwork(); String crs = TransformationFactory.DHDN_GK4; int resolution = 6; - ZoneSystem drtZonalSystem = H3ZoneSystemUtils.createFromPreparedGeometries(network, - H3GridUtils.createH3GridFromNetwork(network, resolution, crs), crs, resolution); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("861f8d697ffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("861f8d687ffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("861f8d69fffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("861f88a6fffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("861f88a6fffffff"))).isTrue(); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("861f89d37ffffff"))).isTrue(); + ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).getId()).isEqualTo(createZoneId("861f8d697ffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("604037425601183743")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).getId()).isEqualTo(createZoneId("861f88b47ffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("604037102136459263")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).getId()).isEqualTo(createZoneId("861f89d07ffffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("604037178372128767")); //check all links are mapped for (Link link : network.getLinks().values()) { @@ -126,15 +117,14 @@ void test_Holzkirchen_Resolution10() { Network network = getNetwork(); String crs = TransformationFactory.DHDN_GK4; int resolution = 10; - ZoneSystem drtZonalSystem = H3ZoneSystemUtils.createFromPreparedGeometries(network, - H3GridUtils.createH3GridFromNetwork(network, resolution, crs), crs, resolution); + ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).getId()).isEqualTo(createZoneId("8a1f8d6930b7fff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("622051824027533311")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).getId()).isEqualTo(createZoneId("8a1f88b4025ffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("622051500514213887")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).getId()).isEqualTo(createZoneId("8a1f89d06d5ffff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("622051576862081023")); //check all links are mapped for (Link link : network.getLinks().values()) { @@ -147,15 +137,16 @@ void test_Holzkirchen_Resolution12() { Network network = getNetwork(); String crs = TransformationFactory.DHDN_GK4; int resolution = 12; - ZoneSystem drtZonalSystem = H3ZoneSystemUtils.createFromPreparedGeometries(network, - H3GridUtils.createH3GridFromNetwork(network, resolution, crs), crs, resolution); + + ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); + // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).getId()).isEqualTo(createZoneId("8c1f8d6930b63ff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("631059023282267135")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).getId()).isEqualTo(createZoneId("8c1f88b4025d1ff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("631058699768943103")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).getId()).isEqualTo(createZoneId("8c1f89d06d581ff")); + assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("631058776116789759")); //check all links are mapped for (Link link : network.getLinks().values()) { diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionExtensionIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionExtensionIT.java index be42758f698..15ef8a6548b 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionExtensionIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionExtensionIT.java @@ -18,6 +18,7 @@ import org.matsim.api.core.v01.events.handler.LinkEnterEventHandler; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.extension.insertion.distances.DistanceApproximator; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.DrtControlerCreator; @@ -39,7 +40,9 @@ import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.vrpagent.TaskEndedEvent; import org.matsim.contrib.dvrp.vrpagent.TaskEndedEventHandler; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; @@ -58,9 +61,14 @@ public class DrtInsertionExtensionIT { private Controler createController() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfigGroup, new OTFVisConfigGroup()); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + ConfigGroup zoneSystemParams = matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + matrixParams.addParameterSet(zoneSystemParams); + config.controller().setOutputDirectory(utils.getOutputDirectory()); config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); @@ -283,7 +291,7 @@ void testRangeConstraintWithCustomInstances() { } assertEquals(1470, distanceCalculator.calculatedDistances); - assertEquals(5280, distanceApproximator.calculatedDistances); + assertEquals(5286, distanceApproximator.calculatedDistances); } @Test @@ -319,7 +327,7 @@ protected void configureQSim() { } assertEquals(1470, distanceCalculator.calculatedDistances); - assertEquals(5280, distanceApproximator.calculatedDistances); + assertEquals(5286, distanceApproximator.calculatedDistances); } static class CustomDistanceCalculator extends CustomCalculator { @@ -421,10 +429,10 @@ void testDefaults() { controller.run(); - assertEquals(16, handler.rejectedRequests); - assertEquals(2112862.0, handler.fleetDistance, 1e-3); - assertEquals(698710.0, handler.activeTime(), 1e-3); - assertEquals(280.19623, handler.meanWaitTime(), 1e-3); + assertEquals(18, handler.rejectedRequests); + assertEquals(2097060.0, handler.fleetDistance, 1e-3); + assertEquals(700441.0, handler.activeTime(), 1e-3); + assertEquals(278.5162162162162, handler.meanWaitTime(), 1e-3); } @Test @@ -442,10 +450,10 @@ void testVehicleActiveTimeObjective() { controller.run(); - assertEquals(16, handler.rejectedRequests); - assertEquals(2112862.0, handler.fleetDistance, 1e-3); - assertEquals(698710.0, handler.activeTime(), 1e-3); - assertEquals(280.19623, handler.meanWaitTime(), 1e-3); + assertEquals(18, handler.rejectedRequests); + assertEquals(2097060, handler.fleetDistance, 1e-3); + assertEquals(700441.0, handler.activeTime(), 1e-3); + assertEquals(278.5162162162162, handler.meanWaitTime(), 1e-3); } @Test diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java index 05e08557722..2bd5fdffc27 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java @@ -2,7 +2,8 @@ import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.TransportMode; -import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; +import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; import org.matsim.contrib.drt.extension.operations.DrtWithOperationsConfigGroup; import org.matsim.contrib.drt.extension.operations.EDrtOperationsControlerCreator; @@ -17,6 +18,7 @@ import org.matsim.contrib.ev.EvConfigGroup; import org.matsim.contrib.ev.charging.*; import org.matsim.contrib.ev.temperature.TemperatureService; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; @@ -78,16 +80,21 @@ void test() { drtConfigGroup.getRebalancingParams().get().addParameterSet(strategyParams); - DrtZonalSystemParams drtZonalSystemParams = new DrtZonalSystemParams(); - drtZonalSystemParams.zonesGeneration = DrtZonalSystemParams.ZoneGeneration.GridFromNetwork; - drtZonalSystemParams.cellSize = 500.; - drtZonalSystemParams.targetLinkSelection = DrtZonalSystemParams.TargetLinkSelection.mostCentral; - drtConfigGroup.addParameterSet(drtZonalSystemParams); + DrtZoneSystemParams drtZoneSystemParams = new DrtZoneSystemParams(); + ConfigGroup parameterSet = drtZoneSystemParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + ((SquareGridZoneSystemParams) parameterSet).cellSize = 500.; + drtZoneSystemParams.addParameterSet(parameterSet); + drtZoneSystemParams.targetLinkSelection = DrtZoneSystemParams.TargetLinkSelection.mostCentral; + drtConfigGroup.addParameterSet(drtZoneSystemParams); multiModeDrtConfigGroup.addParameterSet(drtWithShiftsConfigGroup); + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + final Config config = ConfigUtils.createConfig(multiModeDrtConfigGroup, - new DvrpConfigGroup()); + dvrpConfigGroup); config.setContext(ExamplesUtils.getTestScenarioURL("holzkirchen")); Set modes = new HashSet<>(); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java index 5b3f79ea7dd..b0b5089b81e 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java @@ -2,7 +2,8 @@ import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.TransportMode; -import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; +import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsControlerCreator; import org.matsim.contrib.drt.extension.operations.DrtWithOperationsConfigGroup; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; @@ -14,6 +15,7 @@ import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; @@ -67,16 +69,21 @@ void test() { drtConfigGroup.getRebalancingParams().get().addParameterSet(strategyParams); - DrtZonalSystemParams drtZonalSystemParams = new DrtZonalSystemParams(); - drtZonalSystemParams.zonesGeneration = DrtZonalSystemParams.ZoneGeneration.GridFromNetwork; - drtZonalSystemParams.cellSize = 500.; - drtZonalSystemParams.targetLinkSelection = DrtZonalSystemParams.TargetLinkSelection.mostCentral; - drtConfigGroup.addParameterSet(drtZonalSystemParams); + DrtZoneSystemParams drtZoneSystemParams = new DrtZoneSystemParams(); + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) drtZoneSystemParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + zoneParams.cellSize = 500.; + drtZoneSystemParams.addParameterSet(zoneParams); + drtZoneSystemParams.targetLinkSelection = DrtZoneSystemParams.TargetLinkSelection.mostCentral; + drtConfigGroup.addParameterSet(drtZoneSystemParams); multiModeDrtConfigGroup.addParameterSet(drtWithShiftsConfigGroup); + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + final Config config = ConfigUtils.createConfig(multiModeDrtConfigGroup, - new DvrpConfigGroup()); + dvrpConfigGroup); config.setContext(ExamplesUtils.getTestScenarioURL("holzkirchen")); Set modes = new HashSet<>(); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java index 28034b937c6..1d85910ebec 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java @@ -2,7 +2,8 @@ import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.TransportMode; -import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; +import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsControlerCreator; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; import org.matsim.contrib.drt.extension.operations.DrtWithOperationsConfigGroup; @@ -14,6 +15,7 @@ import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; @@ -68,16 +70,21 @@ void test() { drtConfigGroup.getRebalancingParams().get().addParameterSet(strategyParams); - DrtZonalSystemParams drtZonalSystemParams = new DrtZonalSystemParams(); - drtZonalSystemParams.zonesGeneration = DrtZonalSystemParams.ZoneGeneration.GridFromNetwork; - drtZonalSystemParams.cellSize = 500.; - drtZonalSystemParams.targetLinkSelection = DrtZonalSystemParams.TargetLinkSelection.mostCentral; - drtConfigGroup.addParameterSet(drtZonalSystemParams); + DrtZoneSystemParams drtZoneSystemParams = new DrtZoneSystemParams(); + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) drtZoneSystemParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + zoneParams.cellSize = 500.; + drtZoneSystemParams.addParameterSet(zoneParams); + drtZoneSystemParams.targetLinkSelection = DrtZoneSystemParams.TargetLinkSelection.mostCentral; + drtConfigGroup.addParameterSet(drtZoneSystemParams); multiModeDrtConfigGroup.addParameterSet(drtWithShiftsConfigGroup); + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + final Config config = ConfigUtils.createConfig(multiModeDrtConfigGroup, - new DvrpConfigGroup()); + dvrpConfigGroup); config.setContext(ExamplesUtils.getTestScenarioURL("holzkirchen")); Set modes = new HashSet<>(); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtils.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtils.java deleted file mode 100644 index 75101e4bc6c..00000000000 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtils.java +++ /dev/null @@ -1,98 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2017 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.contrib.drt.analysis.zonal; - -import one.util.streamex.EntryStream; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.GeometryFactory; -import org.locationtech.jts.geom.Polygon; -import org.locationtech.jts.geom.prep.PreparedGeometry; -import org.locationtech.jts.geom.prep.PreparedGeometryFactory; -import org.matsim.api.core.v01.network.Network; -import org.matsim.core.network.NetworkUtils; -import org.matsim.core.utils.misc.Counter; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author jbischoff - */ -public class DrtGridUtils { - - static final Logger log = LogManager.getLogger(DrtGridUtils.class); - - public static Map createGridFromNetwork(Network network, double cellsize) { - log.info("start creating grid from network"); - double[] boundingbox = NetworkUtils.getBoundingBox(network.getNodes().values()); - double minX = (Math.floor(boundingbox[0] / cellsize) * cellsize); - double maxX = (Math.ceil(boundingbox[2] / cellsize) * cellsize); - double minY = (Math.floor(boundingbox[1] / cellsize) * cellsize); - double maxY = (Math.ceil(boundingbox[3] / cellsize) * cellsize); - GeometryFactory gf = new GeometryFactory(); - PreparedGeometryFactory preparedGeometryFactory = new PreparedGeometryFactory(); - Map grid = new HashMap<>(); - int cell = 0; - for (double lx = minX; lx < maxX; lx += cellsize) { - for (double by = minY; by < maxY; by += cellsize) { - cell++; - Coordinate p1 = new Coordinate(lx, by); - Coordinate p2 = new Coordinate(lx + cellsize, by); - Coordinate p3 = new Coordinate(lx + cellsize, by + cellsize); - Coordinate p4 = new Coordinate(lx, by + cellsize); - Coordinate[] ca = { p1, p2, p3, p4, p1 }; - Polygon polygon = new Polygon(gf.createLinearRing(ca), null, gf); - grid.put(cell + "", preparedGeometryFactory.create(polygon)); - } - } - log.info("finished creating grid from network"); - return grid; - } - - /** - * Takes an existing grid and removes all zones that do not intersect the service area. - * Result may contain zones that are barely included in the service area. But as passengers may walk into the service area, - * it seems appropriate that the DrtZonalSystem, which is used for demand estimation, is larger than the service area. - * The {@code cellsize} indirectly determines, how much larger the DrtZonalSystem may get. - * - * @param grid a pre-computed grid of zones - * @param serviceAreaGeoms geometries that define the service area - * @return - */ - public static Map filterGridWithinServiceArea(Map grid, List serviceAreaGeoms) { - log.info("total number of initial grid zones = " + grid.size()); - log.info("searching for grid zones within the drt service area..."); - Counter counter = new Counter("dealt with zone "); - Map zonesWithinServiceArea = EntryStream.of(grid) - .peekKeys(id -> counter.incCounter()) - .filterValues(cell -> serviceAreaGeoms.stream() - .anyMatch(serviceArea -> serviceArea.intersects(cell.getGeometry()))) - .toMap(); - - log.info("number of remaining grid zones = " + zonesWithinServiceArea.size()); - return zonesWithinServiceArea; - } -} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtModeZonalSystemModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtModeZonalSystemModule.java index bd3e6b7ddc6..52f76e5b8db 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtModeZonalSystemModule.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtModeZonalSystemModule.java @@ -23,11 +23,17 @@ import com.google.common.base.Preconditions; import one.util.streamex.EntryStream; import org.locationtech.jts.geom.prep.PreparedGeometry; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.Zone; import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemParams; import org.matsim.contrib.common.zones.ZoneSystemUtils; -import org.matsim.contrib.common.zones.h3.H3GridUtils; -import org.matsim.contrib.common.zones.h3.H3ZoneSystemUtils; +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.h3.H3ZoneSystem; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; @@ -35,11 +41,10 @@ import org.matsim.core.controler.MatsimServices; import java.util.List; -import java.util.Map; +import java.util.function.Predicate; -import static org.matsim.contrib.drt.analysis.zonal.DrtGridUtils.createGridFromNetwork; -import static org.matsim.contrib.drt.analysis.zonal.DrtGridUtils.filterGridWithinServiceArea; import static org.matsim.utils.gis.shp2matsim.ShpGeometryUtils.loadPreparedGeometries; +import static org.matsim.utils.gis.shp2matsim.ShpGeometryUtils.loadPreparedPolygons; /** * @author Michal Maciejewski (michalm) @@ -56,43 +61,51 @@ public DrtModeZonalSystemModule(DrtConfigGroup drtCfg) { @Override public void install() { if (drtCfg.getZonalSystemParams().isPresent()) { - DrtZonalSystemParams params = drtCfg.getZonalSystemParams().get(); + DrtZoneSystemParams params = drtCfg.getZonalSystemParams().get(); + ZoneSystemParams zoneSystemParams = params.getZoneSystemParams(); bindModal(ZoneSystem.class).toProvider(modalProvider(getter -> { Network network = getter.getModal(Network.class); - switch (params.zonesGeneration) { - case ShapeFile: { - final List preparedGeometries = loadPreparedGeometries( - ConfigGroup.getInputFileURL(getConfig().getContext(), params.zonesShapeFile)); + switch (zoneSystemParams.getName()) { + case GISFileZoneSystemParams.SET_NAME: { + Preconditions.checkNotNull(((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile); + final List preparedGeometries = loadPreparedPolygons( + ConfigGroup.getInputFileURL(getConfig().getContext(), ((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile)); return ZoneSystemUtils.createFromPreparedGeometries(network, EntryStream.of(preparedGeometries).mapKeys(i -> (i + 1) + "").toMap()); } - case GridFromNetwork: { - Preconditions.checkNotNull(params.cellSize); - Map gridFromNetwork = createGridFromNetwork(network, params.cellSize); - var gridZones = - switch (drtCfg.operationalScheme) { - case stopbased, door2door -> gridFromNetwork; - case serviceAreaBased -> filterGridWithinServiceArea(gridFromNetwork, - loadPreparedGeometries(ConfigGroup.getInputFileURL(getConfig().getContext(), - drtCfg.drtServiceAreaShapeFile))); - }; - return ZoneSystemUtils.createFromPreparedGeometries(network, gridZones); + case SquareGridZoneSystemParams.SET_NAME: { + Preconditions.checkNotNull(((SquareGridZoneSystemParams) zoneSystemParams).cellSize); + Predicate zoneFilter; + if(drtCfg.operationalScheme == DrtConfigGroup.OperationalScheme.serviceAreaBased) { + List serviceAreas = loadPreparedGeometries(ConfigGroup.getInputFileURL(getConfig().getContext(), + drtCfg.drtServiceAreaShapeFile)); + zoneFilter = zone -> serviceAreas.stream().anyMatch(serviceArea -> serviceArea.intersects(zone.getPreparedGeometry().getGeometry())); + } else { + zoneFilter = zone -> true; + } + + SquareGridZoneSystem squareGridZoneSystem = new SquareGridZoneSystem(network, ((SquareGridZoneSystemParams) zoneSystemParams).cellSize, zoneFilter); + return squareGridZoneSystem; } - case H3: - Preconditions.checkNotNull(params.h3Resolution); + case H3GridZoneSystemParams.SET_NAME: { + + Preconditions.checkNotNull(((H3GridZoneSystemParams) zoneSystemParams).h3Resolution); String crs = getConfig().global().getCoordinateSystem(); - Map gridFromNetwork = H3GridUtils.createH3GridFromNetwork(network, params.h3Resolution, crs); - var gridZones = - switch (drtCfg.operationalScheme) { - case stopbased, door2door -> gridFromNetwork; - case serviceAreaBased -> filterGridWithinServiceArea(gridFromNetwork, - loadPreparedGeometries(ConfigGroup.getInputFileURL(getConfig().getContext(), - drtCfg.drtServiceAreaShapeFile))); - }; - return H3ZoneSystemUtils.createFromPreparedGeometries(network, gridZones, crs, params.h3Resolution); + + Predicate zoneFilter; + if (drtCfg.operationalScheme == DrtConfigGroup.OperationalScheme.serviceAreaBased) { + List serviceAreas = loadPreparedGeometries(ConfigGroup.getInputFileURL(getConfig().getContext(), + drtCfg.drtServiceAreaShapeFile)); + zoneFilter = zone -> serviceAreas.stream().anyMatch(serviceArea -> serviceArea.intersects(zone.getPreparedGeometry().getGeometry())); + } else { + zoneFilter = zone -> true; + } + + return new H3ZoneSystem(crs, ((H3GridZoneSystemParams) zoneSystemParams).h3Resolution, network, zoneFilter); + } default: throw new RuntimeException("Unsupported zone generation"); @@ -104,7 +117,7 @@ public void install() { case mostCentral: return new MostCentralDrtZoneTargetLinkSelector(getter.getModal(ZoneSystem.class)); case random: - return new RandomDrtZoneTargetLinkSelector(); + return new RandomDrtZoneTargetLinkSelector(getter.getModal(ZoneSystem.class)); default: throw new RuntimeException( "Unsupported target link selection = " + params.targetLinkSelection); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemParams.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemParams.java deleted file mode 100644 index 4dd0860b578..00000000000 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemParams.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) 2020 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.contrib.drt.analysis.zonal; - -import javax.annotation.Nullable; - -import org.matsim.contrib.common.zones.h3.H3Utils; -import org.matsim.core.config.Config; -import org.matsim.core.config.ReflectiveConfigGroup; - -import com.google.common.base.Preconditions; - -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Positive; - -/** - * @author Michal Maciejewski (michalm) - */ -public class DrtZonalSystemParams extends ReflectiveConfigGroup { - public static final String SET_NAME = "zonalSystem"; - - public DrtZonalSystemParams() { - super(SET_NAME); - } - - public enum ZoneGeneration {GridFromNetwork, ShapeFile, H3} - - @Parameter - @Comment("Logic for generation of zones for the DRT zonal system. Value can be: [GridFromNetwork, ShapeFile, H3].") - @NotNull - public ZoneGeneration zonesGeneration = null; - - @Parameter - @Comment("size of square cells used for demand aggregation." - + " Depends on demand, supply and network. Often used with values in the range of 500 - 2000 m") - @Nullable - @Positive - public Double cellSize = null;// [m] - - @Parameter - @Comment("allows to configure zones. Used with zonesGeneration=ShapeFile") - @Nullable - public String zonesShapeFile = null; - - @Parameter - @Comment("allows to configure H3 hexagonal zones. Used with zonesGeneration=H3. " + - "Range from 0 (122 cells worldwide) to 15 (569 E^12 cells). " + - "Usually meaningful between resolution 6 (3.7 km avg edge length) " + - "and 10 (70 m avg edge length). ") - @Nullable - public Integer h3Resolution = null; - - public enum TargetLinkSelection {random, mostCentral} - - @Parameter("zoneTargetLinkSelection") - @Comment("Defines how the target link of a zone is determined (e.g. for rebalancing)." - + " Possible values are [random,mostCentral]. Default behavior is mostCentral, where all vehicles are sent to the same link.") - @NotNull - public TargetLinkSelection targetLinkSelection = TargetLinkSelection.mostCentral; - - @Override - protected void checkConsistency(Config config) { - super.checkConsistency(config); - - Preconditions.checkArgument(zonesGeneration != ZoneGeneration.GridFromNetwork || cellSize != null, - "cellSize must not be null when zonesGeneration is " + ZoneGeneration.GridFromNetwork); - Preconditions.checkArgument(zonesGeneration != ZoneGeneration.ShapeFile || zonesShapeFile != null, - "zonesShapeFile must not be null when zonesGeneration is " + ZoneGeneration.ShapeFile); - Preconditions.checkArgument(zonesGeneration != ZoneGeneration.H3 || h3Resolution != null, - "H3 resolution must not be null when zonesGeneration is " + ZoneGeneration.H3); - Preconditions.checkArgument(h3Resolution == null || h3Resolution >= 0 && h3Resolution <= H3Utils.MAX_RES, - "H3 resolution must not be null when zonesGeneration is " + ZoneGeneration.H3); - } -} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java index 4972db0a280..f86d7759e37 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java @@ -29,6 +29,7 @@ import org.locationtech.jts.geom.Polygon; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.common.zones.Zone; import org.matsim.contrib.common.zones.ZoneSystem; @@ -139,10 +140,10 @@ private Map, DescriptiveStatistics> createZonalStats() { for (EventSequence seq : requestAnalyzer.getPerformedRequestSequences().values()) { for (Map.Entry, EventSequence.PersonEvents> entry : seq.getPersonEvents().entrySet()) { if(entry.getValue().getPickedUp().isPresent()) { - Zone zone = zones.getZoneForLinkId(seq.getSubmitted().getFromLinkId()); - final Id zoneStr = zone != null ? zone.getId() : zoneIdForOutsideOfZonalSystem; + Id zone = zones.getZoneForLinkId(seq.getSubmitted().getFromLinkId()) + .map(Identifiable::getId).orElse(zoneIdForOutsideOfZonalSystem); double waitTime = entry.getValue().getPickedUp().get() .getTime() - seq.getSubmitted().getTime(); - zoneStats.get(zoneStr).addValue(waitTime); + zoneStats.get(zone).addValue(waitTime); } } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZoneSystemParams.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZoneSystemParams.java new file mode 100644 index 00000000000..0f9ed49ea1f --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZoneSystemParams.java @@ -0,0 +1,72 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2020 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.contrib.drt.analysis.zonal; + +import jakarta.validation.constraints.NotNull; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.zones.ZoneSystemParams; +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; + +/** + * @author Michal Maciejewski (michalm) + */ +public class DrtZoneSystemParams extends ReflectiveConfigGroupWithConfigurableParameterSets { + public static final String SET_NAME = "zonalSystem"; + + public DrtZoneSystemParams() { + super(SET_NAME); + initSingletonParameterSets(); + } + + public enum TargetLinkSelection {random, mostCentral} + + @Parameter("zoneTargetLinkSelection") + @Comment("Defines how the target link of a zone is determined (e.g. for rebalancing)." + + " Possible values are [random,mostCentral]. Default behavior is mostCentral, where all vehicles are sent to the same link.") + @NotNull + public TargetLinkSelection targetLinkSelection = TargetLinkSelection.mostCentral; + + private ZoneSystemParams zoneSystemParams; + + + private void initSingletonParameterSets() { + + //insertion search params (one of: extensive, selective, repeated selective) + addDefinition(SquareGridZoneSystemParams.SET_NAME, SquareGridZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (SquareGridZoneSystemParams)params); + + addDefinition(GISFileZoneSystemParams.SET_NAME, GISFileZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (GISFileZoneSystemParams)params); + + addDefinition(H3GridZoneSystemParams.SET_NAME, H3GridZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (H3GridZoneSystemParams)params); + } + + public ZoneSystemParams getZoneSystemParams() { + return zoneSystemParams; + } + +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/MostCentralDrtZoneTargetLinkSelector.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/MostCentralDrtZoneTargetLinkSelector.java index 22022631dcc..9b24b56d5d2 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/MostCentralDrtZoneTargetLinkSelector.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/MostCentralDrtZoneTargetLinkSelector.java @@ -37,11 +37,11 @@ public class MostCentralDrtZoneTargetLinkSelector implements DrtZoneTargetLinkSelector { private final Map targetLinks; - public MostCentralDrtZoneTargetLinkSelector(ZoneSystem drtZonalSystem) { - targetLinks = drtZonalSystem.getZones() + public MostCentralDrtZoneTargetLinkSelector(ZoneSystem zoneSystem) { + targetLinks = zoneSystem.getZones() .values() .stream() - .collect(toMap(zone -> zone, zone -> zone.getLinks().stream().min( + .collect(toMap(zone -> zone, zone -> zoneSystem.getLinksForZoneId(zone.getId()).stream().min( //1. choose links with the most central toNode (there may be several "most central" nodes) //2. if there is more than one such link (which is usually the case), // choose one with the most central fromNode diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelector.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelector.java index 7c7f4413e0a..c1edf0e4f0e 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelector.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelector.java @@ -20,10 +20,12 @@ package org.matsim.contrib.drt.analysis.zonal; +import java.util.List; import java.util.function.IntUnaryOperator; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneSystem; import org.matsim.core.gbl.MatsimRandom; /** @@ -31,17 +33,20 @@ */ public class RandomDrtZoneTargetLinkSelector implements DrtZoneTargetLinkSelector { private final IntUnaryOperator random; + private final ZoneSystem zoneSystem; - public RandomDrtZoneTargetLinkSelector() { - this(MatsimRandom.getLocalInstance()::nextInt); + public RandomDrtZoneTargetLinkSelector(ZoneSystem zoneSystem) { + this(zoneSystem, MatsimRandom.getLocalInstance()::nextInt); } - public RandomDrtZoneTargetLinkSelector(IntUnaryOperator random) { + public RandomDrtZoneTargetLinkSelector(ZoneSystem zoneSystem, IntUnaryOperator random) { + this.zoneSystem = zoneSystem; this.random = random; } @Override public Link selectTargetLink(Zone zone) { - return zone.getLinks().get(random.applyAsInt(zone.getLinks().size())); + List linksForZone = zoneSystem.getLinksForZoneId(zone.getId()); + return linksForZone.get(random.applyAsInt(linksForZone.size())); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleCollector.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleCollector.java index 2626e21fc3f..2b965ce7f6b 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleCollector.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleCollector.java @@ -64,10 +64,7 @@ public void handleEvent(TaskEndedEvent event) { private void handleEvent(AbstractTaskEvent event, Consumer handler) { if (event.getDvrpMode().equals(dvrpMode) && event.getTaskType().equals(DrtStayTask.TYPE)) { - Zone zone = zonalSystem.getZoneForLinkId(event.getLinkId()); - if (zone != null) { - handler.accept(zone); - } + zonalSystem.getZoneForLinkId(event.getLinkId()).ifPresent(handler); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleXYVisualiser.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleXYVisualiser.java index 8813f7673ab..4d00795c440 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleXYVisualiser.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/ZonalIdleVehicleXYVisualiser.java @@ -83,10 +83,7 @@ public void handleEvent(TaskEndedEvent event) { private void handleEvent(AbstractTaskEvent event, Consumer handler) { if (event.getDvrpMode().equals(mode) && event.getTaskType().equals(DrtStayTask.TYPE)) { - Zone zone = zonalSystem.getZoneForLinkId(event.getLinkId()); - if (zone != null) { - handler.accept(zone); - } + zonalSystem.getZoneForLinkId(event.getLinkId()).ifPresent(handler); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java index 07b422912d9..0cc73da2bb4 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java @@ -21,7 +21,7 @@ import org.matsim.contrib.drt.optimizer.rebalancing.Feedforward.FeedforwardRebalancingStrategyParams; import org.matsim.contrib.drt.optimizer.rebalancing.mincostflow.MinCostFlowRebalancingStrategyParams; import org.matsim.contrib.drt.optimizer.rebalancing.plusOne.PlusOneRebalancingStrategyParams; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingUtils.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingUtils.java index 8584026e706..bc712ab59f9 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingUtils.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingUtils.java @@ -20,12 +20,6 @@ package org.matsim.contrib.drt.optimizer.rebalancing; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.common.zones.Zone; @@ -38,27 +32,31 @@ import org.matsim.contrib.dvrp.schedule.StayTask; import org.matsim.contrib.dvrp.schedule.Task; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + /** * @author Michal Maciejewski (michalm) */ public class RebalancingUtils { - public static Map> groupRebalancableVehicles(ZoneSystem zonalSystem, + public static Map> groupRebalancableVehicles(ZoneSystem zoneSystem, RebalancingParams params, Stream rebalancableVehicles, double time) { Map> rebalancableVehiclesPerZone = new HashMap<>(); rebalancableVehicles.filter(v -> v.getServiceEndTime() > time + params.minServiceTime).forEach(v -> { Link link = ((StayTask)v.getSchedule().getCurrentTask()).getLink(); - Zone zone = zonalSystem.getZoneForLinkId(link.getId()); - if (zone == null) { - zone = ZoneImpl.createDummyZone(Id.create("single-vehicle-zone-" + v.getId(), Zone.class), List.of(link), - link.getToNode().getCoord()); - } + Zone zone = zoneSystem.getZoneForLinkId(link.getId()) + .orElse(ZoneImpl.createDummyZone(Id.create("single-vehicle-zone-" + v.getId(), Zone.class), + link.getToNode().getCoord())); rebalancableVehiclesPerZone.computeIfAbsent(zone, z -> new ArrayList<>()).add(v); }); return rebalancableVehiclesPerZone; } // also include vehicles being right now relocated or recharged - public static Map> groupSoonIdleVehicles(ZoneSystem zonalSystem, + public static Map> groupSoonIdleVehicles(ZoneSystem zoneSystem, RebalancingParams params, Fleet fleet, double time) { Map> soonIdleVehiclesPerZone = new HashMap<>(); for (DvrpVehicle v : fleet.getVehicles().values()) { @@ -67,10 +65,10 @@ public static Map> groupSoonIdleVehicles(ZoneSystem zona if (stayTask.getStatus() == Task.TaskStatus.PLANNED && stayTask.getBeginTime() < time + params.maxTimeBeforeIdle && v.getServiceEndTime() > time + params.minServiceTime) { - Zone zone = zonalSystem.getZoneForLinkId(stayTask.getLink().getId()); - if (zone != null) { - soonIdleVehiclesPerZone.computeIfAbsent(zone, z -> new ArrayList<>()).add(v); - } + zoneSystem.getZoneForLinkId(stayTask.getLink().getId()) + .ifPresent( + zone -> soonIdleVehiclesPerZone.computeIfAbsent(zone, z -> new ArrayList<>()).add(v) + ); } } return soonIdleVehiclesPerZone; diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java index cc1c0b41dd5..0ebce86e3de 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java @@ -52,8 +52,8 @@ public void handleEvent(DrtRequestSubmittedEvent event) { if (event.getMode().equals(mode)) { // At the submission time, this is only a potential trip. int timeBin = (int)Math.floor(event.getTime() / timeBinSize); - Zone departureZoneId = zonalSystem.getZoneForLinkId(event.getFromLinkId()); - Zone arrivalZoneId = zonalSystem.getZoneForLinkId(event.getToLinkId()); + Zone departureZoneId = zonalSystem.getZoneForLinkId(event.getFromLinkId()).orElseThrow(); + Zone arrivalZoneId = zonalSystem.getZoneForLinkId(event.getToLinkId()).orElseThrow(); potentialDrtTripsMap.put(event.getRequestId(), new Trip(timeBin, departureZoneId, arrivalZoneId)); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimator.java index f6d2f17745d..5c7aa4ca6f4 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimator.java @@ -69,17 +69,16 @@ public void reset(int iteration) { @Override public void handleEvent(PersonDepartureEvent event) { if (event.getLegMode().equals(mode)) { - Zone zone = zonalSystem.getZoneForLinkId(event.getLinkId()); - if (zone == null) { + zonalSystem.getZoneForLinkId(event.getLinkId()).ifPresentOrElse( + zone -> { + int timeBin = getBinForTime(event.getTime()); + currentIterationDepartures.computeIfAbsent(timeBin, v -> new HashMap<>()) + .computeIfAbsent(zone, z -> new MutableInt()) + .increment(); + }, //might be that somebody walks into the service area or that service area is larger/different than DrtZonalSystem... - logger.warn("No zone found for linkId " + event.getLinkId().toString()); - return; - } - - int timeBin = getBinForTime(event.getTime()); - currentIterationDepartures.computeIfAbsent(timeBin, v -> new HashMap<>()) - .computeIfAbsent(zone, z -> new MutableInt()) - .increment(); + () -> logger.warn("No zone found for linkId " + event.getLinkId().toString()) + ); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculator.java index 7968af6e705..a3e587983b9 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculator.java @@ -35,7 +35,7 @@ import java.util.List; import java.util.Map; -import java.util.Objects; +import java.util.Optional; import java.util.function.ToDoubleFunction; import java.util.stream.Collectors; @@ -73,7 +73,8 @@ private Map countFirstActsPerZone(ZoneSystem zonalSystem, Populat .stream() .map(person -> (Activity)person.getSelectedPlan().getPlanElements().get(0)) .map(activity -> zonalSystem.getZoneForLinkId(activity.getLinkId())) - .filter(Objects::nonNull) + .filter(Optional::isPresent) + .map(Optional::get) .collect(Collectors.groupingBy(zone -> zone, collectingAndThen(counting(), Long::intValue))); } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java index 93597ab6271..7d6f0b9cef4 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java @@ -29,7 +29,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.TransportMode; -import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; +import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams; import org.matsim.contrib.drt.fare.DrtFareParams; import org.matsim.contrib.drt.optimizer.DrtRequestInsertionRetryParams; import org.matsim.contrib.drt.optimizer.insertion.DrtInsertionSearchParams; @@ -42,7 +42,7 @@ import org.matsim.contrib.drt.speedup.DrtSpeedUpParams; import org.matsim.contrib.dvrp.router.DvrpModeRoutingNetworkModule; import org.matsim.contrib.dvrp.run.Modal; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.Config; import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.RoutingConfigGroup; @@ -220,7 +220,7 @@ public enum OperationalScheme { private DrtInsertionSearchParams drtInsertionSearchParams; @Nullable - private DrtZonalSystemParams zonalSystemParams; + private DrtZoneSystemParams zonalSystemParams; @Nullable private RebalancingParams rebalancingParams; @@ -248,8 +248,8 @@ private void initSingletonParameterSets() { params -> rebalancingParams = (RebalancingParams)params); //zonal system (optional) - addDefinition(DrtZonalSystemParams.SET_NAME, DrtZonalSystemParams::new, () -> zonalSystemParams, - params -> zonalSystemParams = (DrtZonalSystemParams)params); + addDefinition(DrtZoneSystemParams.SET_NAME, DrtZoneSystemParams::new, () -> zonalSystemParams, + params -> zonalSystemParams = (DrtZoneSystemParams)params); //insertion search params (one of: extensive, selective, repeated selective) addDefinition(ExtensiveInsertionSearchParams.SET_NAME, ExtensiveInsertionSearchParams::new, @@ -340,7 +340,7 @@ public DrtInsertionSearchParams getDrtInsertionSearchParams() { return drtInsertionSearchParams; } - public Optional getZonalSystemParams() { + public Optional getZonalSystemParams() { return Optional.ofNullable(zonalSystemParams); } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java index 0d73adba5c6..0d5ca129c11 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java @@ -1,44 +1,42 @@ package org.matsim.contrib.drt.analysis.zonal; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Map; - import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.Geometry; -import org.locationtech.jts.geom.prep.PreparedGeometry; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; 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.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; import org.matsim.core.network.NetworkUtils; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + public class DrtGridUtilsTest { @Test void test() { Network network = createNetwork(); - Map grid = DrtGridUtils.createGridFromNetwork(network, 100); + SquareGridZoneSystem squareGridZoneSystem = new SquareGridZoneSystem(network, 100, false, z -> true); - assertThat(grid).hasSize(100); + assertThat(squareGridZoneSystem.getZones()).hasSize(100); - int cell = 1; for (int col = 0; col < 10; col++) { for (int row = 0; row < 10; row++) { - Geometry geometry = grid.get(cell + "").getGeometry(); + Optional zoneForCoord = squareGridZoneSystem.getZoneForCoord(new Coord(col * 100, row * 100)); - assertThat(geometry.getCoordinates()).containsExactly(// + assertThat(zoneForCoord).isPresent(); + assertThat(zoneForCoord.get().getPreparedGeometry().getGeometry().getCoordinates()).containsExactly(// new Coordinate(col * 100, row * 100),// new Coordinate(col * 100 + 100, row * 100),// new Coordinate(col * 100 + 100, row * 100 + 100),// new Coordinate(col * 100, row * 100 + 100),// new Coordinate(col * 100, row * 100)); - assertThat(geometry.getCentroid().getCoordinate()).isEqualTo( + assertThat(zoneForCoord.get().getPreparedGeometry().getGeometry().getCentroid().getCoordinate()).isEqualTo( new Coordinate(col * 100 + 50, row * 100 + 50)); - - cell++; } } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java index e17d38c7901..eb2ca828904 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java @@ -29,14 +29,14 @@ import org.locationtech.jts.geom.prep.PreparedGeometryFactory; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; -import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.function.Predicate; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.matsim.contrib.common.zones.ZoneSystemUtils.createFromPreparedGeometries; import static org.matsim.contrib.drt.analysis.zonal.DrtGridUtilsTest.createNetwork; /** @@ -46,16 +46,14 @@ public class DrtZonalSystemTest { @Test void test_cellSize100() { - ZoneSystem drtZonalSystem = createFromPreparedGeometries(createNetwork(), - DrtGridUtils.createGridFromNetwork(createNetwork(), 100)); - Assertions.assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId("ab")).getId().toString()).isEqualTo("10"); + SquareGridZoneSystem drtZonalSystem = new SquareGridZoneSystem(createNetwork(), 100); + Assertions.assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId("ab")).orElseThrow().getId().toString()).isEqualTo("90"); } @Test void test_cellSize700() { - ZoneSystem drtZonalSystem = createFromPreparedGeometries(createNetwork(), - DrtGridUtils.createGridFromNetwork(createNetwork(), 700)); - Assertions.assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId("ab")).getId().toString()).isEqualTo("2"); + SquareGridZoneSystem drtZonalSystem = new SquareGridZoneSystem(createNetwork(), 700); + Assertions.assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId("ab")).orElseThrow().getId().toString()).isEqualTo("2"); } @Test @@ -63,15 +61,15 @@ void test_gridWithinServiceArea(){ Coordinate min = new Coordinate(-500, 500); Coordinate max = new Coordinate(1500, 1500); List serviceArea = createServiceArea(min,max); - Map grid = DrtGridUtils.filterGridWithinServiceArea(DrtGridUtils.createGridFromNetwork(createNetwork(), 100), serviceArea); - ZoneSystem zonalSystem = createFromPreparedGeometries(createNetwork(), - grid); + + Predicate zoneFilter = zone -> serviceArea.stream().anyMatch(area -> area.intersects(zone.getPreparedGeometry().getGeometry())); + SquareGridZoneSystem zonalSystem = new SquareGridZoneSystem(createNetwork(), 100, zoneFilter); assertEquals(2, zonalSystem.getZones().size()); //link 'da' is outside of the service area Id id = Id.createLinkId("da"); - Assertions.assertThat(zonalSystem.getZoneForLinkId(id)).isNull(); + Assertions.assertThat(zonalSystem.getZoneForLinkId(id)).isNotPresent(); } @Test @@ -79,9 +77,9 @@ void test_noZonesWithoutLinks(){ Coordinate min = new Coordinate(1500, 1500); Coordinate max = new Coordinate(2500, 2500); List serviceArea = createServiceArea(min,max); - Map grid = DrtGridUtils.filterGridWithinServiceArea(DrtGridUtils.createGridFromNetwork(createNetwork(), 100), serviceArea); - ZoneSystem zonalSystem = createFromPreparedGeometries(createNetwork(), - grid); + + Predicate zoneFilter = zone -> serviceArea.stream().anyMatch(area -> area.intersects(zone.getPreparedGeometry().getGeometry())); + SquareGridZoneSystem zonalSystem = new SquareGridZoneSystem(createNetwork(), 100, zoneFilter); //service area is off the network - so we should have 0 zones.. assertEquals(0, zonalSystem.getZones().size()); @@ -100,7 +98,4 @@ public List createServiceArea(Coordinate min, Coordinate max){ ServiceArea.add(preparedGeometryFactory.create(polygon)); return ServiceArea; } - - - } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java index f77e5fa57a3..8a31e2470db 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java @@ -20,34 +20,41 @@ package org.matsim.contrib.drt.analysis.zonal; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.List; -import java.util.function.IntUnaryOperator; - import org.junit.jupiter.api.Test; +import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; 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.contrib.common.zones.Zone; import org.matsim.contrib.common.zones.ZoneImpl; -import org.matsim.testcases.fakes.FakeLink; +import org.matsim.contrib.common.zones.ZoneSystemImpl; +import org.matsim.core.network.NetworkUtils; import org.mockito.ArgumentCaptor; +import java.util.List; +import java.util.Optional; +import java.util.function.IntUnaryOperator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + /** * @author Michal Maciejewski (michalm) */ public class RandomDrtZoneTargetLinkSelectorTest { - private final Link link0 = new FakeLink(Id.createLinkId("0")); - private final Link link1 = new FakeLink(Id.createLinkId("1")); - private final Link link2 = new FakeLink(Id.createLinkId("2")); - private final Link link3 = new FakeLink(Id.createLinkId("3")); + private static final Id LINK_ID_0 = Id.createLinkId("0"); + private static final Id LINK_ID_1 = Id.createLinkId("1"); + private static final Id LINK_ID_2 = Id.createLinkId("2"); + private static final Id LINK_ID_3 = Id.createLinkId("3"); @Test void testSelectTargetLink_fourLinks() { - Zone zone = ZoneImpl.createDummyZone(Id.create("zone", Zone.class), List.of(link0, link1, link2, link3), null); + Zone zone = ZoneImpl.createDummyZone(Id.create("zone", Zone.class), null); + + Network network = createNetwork(); //fake random sequence IntUnaryOperator random = mock(IntUnaryOperator.class); @@ -55,13 +62,35 @@ void testSelectTargetLink_fourLinks() { when(random.applyAsInt(boundCaptor.capture())).thenReturn(0, 3, 1, 2); //test selected target links - RandomDrtZoneTargetLinkSelector selector = new RandomDrtZoneTargetLinkSelector(random); - assertThat(selector.selectTargetLink(zone)).isEqualTo(link0); - assertThat(selector.selectTargetLink(zone)).isEqualTo(link3); - assertThat(selector.selectTargetLink(zone)).isEqualTo(link1); - assertThat(selector.selectTargetLink(zone)).isEqualTo(link2); + RandomDrtZoneTargetLinkSelector selector = new RandomDrtZoneTargetLinkSelector(new ZoneSystemImpl(List.of(zone), coord -> Optional.of(zone), network), random); + assertThat(selector.selectTargetLink(zone)).isEqualTo(network.getLinks().get(LINK_ID_0)); + assertThat(selector.selectTargetLink(zone)).isEqualTo(network.getLinks().get(LINK_ID_3)); + assertThat(selector.selectTargetLink(zone)).isEqualTo(network.getLinks().get(LINK_ID_1)); + assertThat(selector.selectTargetLink(zone)).isEqualTo(network.getLinks().get(LINK_ID_2)); //check if correct values were passed to Random as the nextInt() bounds (== link count) assertThat(boundCaptor.getAllValues()).containsExactly(4, 4, 4, 4); } + + static Network createNetwork() { + Network network = NetworkUtils.createNetwork(); + Node a = network.getFactory().createNode(Id.createNodeId("a"), new Coord(0, 0)); + Node b = network.getFactory().createNode(Id.createNodeId("b"), new Coord(0, 1000)); + Node c = network.getFactory().createNode(Id.createNodeId("c"), new Coord(1000, 1000)); + Node d = network.getFactory().createNode(Id.createNodeId("d"), new Coord(1000, 0)); + network.addNode(a); + network.addNode(b); + network.addNode(c); + network.addNode(d); + + Link ab = network.getFactory().createLink(LINK_ID_0, a, b); + Link bc = network.getFactory().createLink(LINK_ID_1, b, c); + Link cd = network.getFactory().createLink(LINK_ID_2, c, d); + Link da = network.getFactory().createLink(LINK_ID_3, d, a); + network.addLink(ab); + network.addLink(bc); + network.addLink(cd); + network.addLink(da); + return network; + } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/MaxDetourConstraintTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/MaxDetourConstraintTest.java index 83ffce4ddb5..ec0e2a1f030 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/MaxDetourConstraintTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/MaxDetourConstraintTest.java @@ -2,10 +2,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.DrtControlerCreator; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; @@ -24,7 +26,12 @@ public class MaxDetourConstraintTest { @Test public void testMaxDetourConstraint() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + + DvrpConfigGroup dvrpConfig = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfig.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfig, new OTFVisConfigGroup()); DrtConfigGroup drtConfigGroup = DrtConfigGroup.getSingleModeDrtConfig(config); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java index 76b6f176cde..8451f93b1e2 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java @@ -9,12 +9,14 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.*; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.run.DrtControlerCreator; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEvent; import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEventHandler; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; @@ -208,7 +210,12 @@ void testBetaOneVehicleForFourAgents() { private PersonEnterDrtVehicleEventHandler setupAndRunScenario(double maxWaitTime, double maxTravelTimeAlpha, double maxTravelTimeBeta) { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + + DvrpConfigGroup dvrpConfig = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfig.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfig, new OTFVisConfigGroup()); config.plans().setInputFile(null); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java index 0b93d725f48..7f43fd42d8b 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java @@ -20,23 +20,26 @@ package org.matsim.contrib.drt.optimizer.rebalancing.demandestimator; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; - import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.events.PersonDepartureEvent; 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.contrib.common.zones.Zone; import org.matsim.contrib.common.zones.ZoneImpl; import org.matsim.contrib.common.zones.ZoneSystem; import org.matsim.contrib.common.zones.ZoneSystemImpl; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingParams; import org.matsim.contrib.drt.run.DrtConfigGroup; -import org.matsim.testcases.fakes.FakeLink; +import org.matsim.core.network.NetworkUtils; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author michalm (Michal Maciejewski) @@ -45,12 +48,22 @@ public class PreviousIterationDrtDemandEstimatorTest { private static final int ESTIMATION_PERIOD = 1800; - private final Link link1 = new FakeLink(Id.createLinkId("link_1")); - private final Link link2 = new FakeLink(Id.createLinkId("link_2")); + private final Network network = createNetwork(); + + private final Link link1 = network.getLinks().get(Id.createLinkId("link_1")); + private final Link link2 = network.getLinks().get(Id.createLinkId("link_2")); - private final Zone zone1 = ZoneImpl.createDummyZone(Id.create("zone_1", Zone.class), List.of(link1), new Coord()); - private final Zone zone2 = ZoneImpl.createDummyZone(Id.create("zone_2", Zone.class), List.of(link2), new Coord()); - private final ZoneSystem zonalSystem = new ZoneSystemImpl(List.of(zone1, zone2)); + private final Zone zone1 = ZoneImpl.createDummyZone(Id.create("zone_1", Zone.class), new Coord()); + private final Zone zone2 = ZoneImpl.createDummyZone(Id.create("zone_2", Zone.class), new Coord()); + private final ZoneSystem zonalSystem = new ZoneSystemImpl(List.of(zone1, zone2), coord -> { + if(coord == link1.getToNode().getCoord()) { + return Optional.of(zone1); + } else if(coord == link2.getToNode().getCoord()) { + return Optional.of(zone2); + } else { + throw new RuntimeException(); + } + }, network); @Test void noDepartures() { @@ -177,4 +190,18 @@ private void assertDemand(PreviousIterationDrtDemandEstimator estimator, double assertThat(estimator.getExpectedDemand(fromTime, ESTIMATION_PERIOD).applyAsDouble(zone)).isEqualTo( expectedDemand); } + + static Network createNetwork() { + Network network = NetworkUtils.createNetwork(); + Node a = network.getFactory().createNode(Id.createNodeId("a"), new Coord()); + Node b = network.getFactory().createNode(Id.createNodeId("b"), new Coord()); + network.addNode(a); + network.addNode(b); + + Link ab = network.getFactory().createLink(Id.createLinkId("link_1"), a, b); + Link bc = network.getFactory().createLink(Id.createLinkId("link_2"), b, a); + network.addLink(ab); + network.addLink(bc); + return network; + } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java index e1ef42a98d1..7e462166a98 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java @@ -26,8 +26,7 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.common.zones.Zone; import org.matsim.contrib.common.zones.ZoneSystem; -import org.matsim.contrib.common.zones.ZoneSystemUtils; -import org.matsim.contrib.drt.analysis.zonal.DrtGridUtils; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.FleetSpecification; @@ -42,8 +41,6 @@ import java.util.Map; import java.util.function.ToDoubleFunction; -import static org.assertj.core.api.Assertions.assertThat; - /** * @author Michal Maciejewski (michalm) */ @@ -55,8 +52,8 @@ public class EqualVehicleDensityTargetCalculatorTest { private final Network network = NetworkUtils.readNetwork( config.network().getInputFileURL(config.getContext()).toString()); - private final ZoneSystem zonalSystem = ZoneSystemUtils.createFromPreparedGeometries(network, - DrtGridUtils.createGridFromNetwork(network, 500.)); + private final ZoneSystem zonalSystem = new SquareGridZoneSystem(network, 500.); + @Test void calculate_oneVehiclePerZone() { diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java index 7c24bd07c26..fff34e1b7d0 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java @@ -20,11 +20,6 @@ package org.matsim.contrib.drt.optimizer.rebalancing.targetcalculator; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Map; -import java.util.function.ToDoubleFunction; - import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -36,7 +31,7 @@ import org.matsim.contrib.common.zones.Zone; import org.matsim.contrib.common.zones.ZoneSystem; import org.matsim.contrib.common.zones.ZoneSystemUtils; -import org.matsim.contrib.drt.analysis.zonal.DrtGridUtils; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.FleetSpecification; @@ -49,6 +44,11 @@ import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; +import java.util.Map; +import java.util.function.ToDoubleFunction; + +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Michal Maciejewski (michalm) */ @@ -60,44 +60,42 @@ public class EqualVehiclesToPopulationRatioTargetCalculatorTest { private final Network network = NetworkUtils.readNetwork( config.network().getInputFileURL(config.getContext()).toString()); - private final ZoneSystem zonalSystem = ZoneSystemUtils.createFromPreparedGeometries(network, - DrtGridUtils.createGridFromNetwork(network, 500.)); - + private final ZoneSystem zonalSystem = new SquareGridZoneSystem(network, 500.); private final Population population = PopulationUtils.createPopulation(config); private final PopulationFactory factory = population.getFactory(); @Test void testCalculate_oneVehiclePerZone() { - initPopulation(Map.of(ZoneSystemUtils.createZoneId("2"), 1, ZoneSystemUtils.createZoneId("4"), 1, ZoneSystemUtils.createZoneId("8"), 1)); + initPopulation(Map.of(ZoneSystemUtils.createZoneId("1"), 1, ZoneSystemUtils.createZoneId("3"), 1, ZoneSystemUtils.createZoneId("7"), 1)); var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(8)).calculate(0, Map.of()); - assertTarget(targetFunction, zonalSystem, Id.create("1", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("2", Zone.class), 8. * (1. / 3)); - assertTarget(targetFunction, zonalSystem, Id.create("3", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("4", Zone.class), 8. * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("0", Zone.class), 0); + assertTarget(targetFunction, zonalSystem, Id.create("1", Zone.class), 8. * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("2", Zone.class), 0); + assertTarget(targetFunction, zonalSystem, Id.create("3", Zone.class), 8. * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("4", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("5", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("6", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("7", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("8", Zone.class), 8. * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("7", Zone.class), 8. * (1. / 3)); } @Test void testCalculate_twoVehiclesPerZone() { - initPopulation(Map.of(ZoneSystemUtils.createZoneId("2"), 1, ZoneSystemUtils.createZoneId("4"), 1, ZoneSystemUtils.createZoneId("8"), 1)); + initPopulation(Map.of(ZoneSystemUtils.createZoneId("1"), 1, ZoneSystemUtils.createZoneId("3"), 1, ZoneSystemUtils.createZoneId("7"), 1)); var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(16)).calculate(0, Map.of()); - assertTarget(targetFunction, zonalSystem, Id.create("1", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("2", Zone.class), 16 * (1. / 3)); - assertTarget(targetFunction, zonalSystem, Id.create("3", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("4", Zone.class), 16 * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("0", Zone.class), 0); + assertTarget(targetFunction, zonalSystem, Id.create("1", Zone.class), 16 * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("2", Zone.class), 0); + assertTarget(targetFunction, zonalSystem, Id.create("3", Zone.class), 16 * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("4", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("5", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("6", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("7", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("8", Zone.class), 16. * (1. / 3)); + assertTarget(targetFunction, zonalSystem, Id.create("7", Zone.class), 16. * (1. / 3)); } @Test @@ -106,6 +104,7 @@ void testCalculate_noPopulation() { var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(16)).calculate(0, Map.of()); + assertTarget(targetFunction, zonalSystem, Id.create("0", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("1", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("2", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("3", Zone.class), 0); @@ -113,23 +112,22 @@ void testCalculate_noPopulation() { assertTarget(targetFunction, zonalSystem, Id.create("5", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("6", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("7", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("8", Zone.class), 0); } @Test void testCalculate_unevenDistributionOfActivitiesInPopulatedZones() { - initPopulation(Map.of(ZoneSystemUtils.createZoneId("2"), 2, ZoneSystemUtils.createZoneId("4"), 4, ZoneSystemUtils.createZoneId("8"), 8)); + initPopulation(Map.of(ZoneSystemUtils.createZoneId("1"), 2, ZoneSystemUtils.createZoneId("3"), 4, ZoneSystemUtils.createZoneId("7"), 8)); var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(16)).calculate(0, Map.of()); - assertTarget(targetFunction, zonalSystem, Id.create("1", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("2", Zone.class), 16 * (2. / 14)); - assertTarget(targetFunction, zonalSystem, Id.create("3", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("4", Zone.class), 16 * (4. / 14)); + assertTarget(targetFunction, zonalSystem, Id.create("0", Zone.class), 0); + assertTarget(targetFunction, zonalSystem, Id.create("1", Zone.class), 16 * (2. / 14)); + assertTarget(targetFunction, zonalSystem, Id.create("2", Zone.class), 0); + assertTarget(targetFunction, zonalSystem, Id.create("3", Zone.class), 16 * (4. / 14)); + assertTarget(targetFunction, zonalSystem, Id.create("4", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("5", Zone.class), 0); assertTarget(targetFunction, zonalSystem, Id.create("6", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("7", Zone.class), 0); - assertTarget(targetFunction, zonalSystem, Id.create("8", Zone.class), 16 * (8. / 14)); + assertTarget(targetFunction, zonalSystem, Id.create("7", Zone.class), 16 * (8. / 14)); } private FleetSpecification createFleetSpecification(int count) { @@ -161,7 +159,7 @@ private void initPopulation(Map, Integer> populationPerZone) { } private void createAndAddPerson(String id, Id zoneId) { - Id linkId = zonalSystem.getZones().get(zoneId).getLinks().get(0).getId(); + Id linkId = zonalSystem.getLinksForZoneId(zoneId).get(0).getId(); Person person = factory.createPerson(Id.createPersonId(id)); Plan plan = factory.createPlan(); plan.addActivity(factory.createActivityFromLinkId("dummy", linkId)); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java index a80d8a42386..c97f2c34a81 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java @@ -9,6 +9,7 @@ import org.matsim.api.core.v01.network.NetworkFactory; import org.matsim.api.core.v01.network.Node; import org.matsim.api.core.v01.population.*; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.optimizer.insertion.DrtInsertionSearchParams; import org.matsim.contrib.drt.optimizer.insertion.selective.SelectiveInsertionSearchParams; import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEvent; @@ -33,6 +34,7 @@ import org.matsim.contrib.dvrp.vrpagent.TaskEndedEventHandler; import org.matsim.contrib.dvrp.vrpagent.TaskStartedEvent; import org.matsim.contrib.dvrp.vrpagent.TaskStartedEventHandler; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.QSimConfigGroup.EndtimeInterpretation; @@ -214,6 +216,8 @@ private void buildConfig(Config config) { config.scoring().addActivityParams(genericParams); DvrpConfigGroup dvrpConfig = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfig.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); config.addModule(dvrpConfig); MultiModeDrtConfigGroup drtConfig = new MultiModeDrtConfigGroup(); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java index 652d66ecf19..9a75670e909 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java @@ -33,6 +33,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.optimizer.DrtRequestInsertionRetryParams; import org.matsim.contrib.drt.optimizer.insertion.repeatedselective.RepeatedSelectiveInsertionSearchParams; import org.matsim.contrib.drt.optimizer.insertion.selective.SelectiveInsertionSearchParams; @@ -53,6 +54,7 @@ import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEventHandler; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; @@ -77,8 +79,13 @@ public class RunDrtExampleIT { @Test void testRunDrtExampleWithNoRejections_ExtensiveSearch() { Id.resetCaches(); + + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfigGroup, new OTFVisConfigGroup()); for (var drtCfg : MultiModeDrtConfigGroup.get(config).getModalElements()) { @@ -93,8 +100,8 @@ void testRunDrtExampleWithNoRejections_ExtensiveSearch() { var expectedStats = Stats.newBuilder() .rejectionRate(0.0) .rejections(0) - .waitAverage(296.95) - .inVehicleTravelTimeMean(387.02) + .waitAverage(297.19) + .inVehicleTravelTimeMean(386.78) .totalTravelTimeMean(683.97) .build(); @@ -105,7 +112,12 @@ void testRunDrtExampleWithNoRejections_ExtensiveSearch() { void testRunDrtExampleWithNoRejections_SelectiveSearch() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfigGroup, new OTFVisConfigGroup()); for (var drtCfg : MultiModeDrtConfigGroup.get(config).getModalElements()) { @@ -139,7 +151,12 @@ void testRunDrtExampleWithNoRejections_SelectiveSearch() { void testRunDrtExampleWithNoRejections_RepeatedSelectiveSearch() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfigGroup, new OTFVisConfigGroup()); for (var drtCfg : MultiModeDrtConfigGroup.get(config).getModalElements()) { @@ -162,9 +179,9 @@ void testRunDrtExampleWithNoRejections_RepeatedSelectiveSearch() { var expectedStats = Stats.newBuilder() .rejectionRate(0.0) .rejections(0) - .waitAverage(261.57) - .inVehicleTravelTimeMean(382.74) - .totalTravelTimeMean(644.32) + .waitAverage(269.8) + .inVehicleTravelTimeMean(379.69) + .totalTravelTimeMean(649.49) .build(); verifyDrtCustomerStatsCloseToExpectedStats(utils.getOutputDirectory(), expectedStats); @@ -173,8 +190,13 @@ void testRunDrtExampleWithNoRejections_RepeatedSelectiveSearch() { @Test void testRunDrtExampleWithRequestRetry() { Id.resetCaches(); + + DvrpConfigGroup dvrpConfig = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfig.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfig, new OTFVisConfigGroup()); for (var drtCfg : MultiModeDrtConfigGroup.get(config).getModalElements()) { @@ -191,8 +213,8 @@ void testRunDrtExampleWithRequestRetry() { var expectedStats = Stats.newBuilder() .rejectionRate(0.0) .rejections(1) - .waitAverage(305.97) - .inVehicleTravelTimeMean(378.18) + .waitAverage(306.21) + .inVehicleTravelTimeMean(377.94) .totalTravelTimeMean(684.16) .build(); @@ -270,11 +292,11 @@ void testRunServiceAreabasedExampleWithSpeedUp() { RunDrtExample.run(config, false); var expectedStats = Stats.newBuilder() - .rejectionRate(0.03) - .rejections(11) - .waitAverage(223.86) - .inVehicleTravelTimeMean(389.57) - .totalTravelTimeMean(613.44) + .rejectionRate(0.02) + .rejections(9) + .waitAverage(224.56) + .inVehicleTravelTimeMean(392.65) + .totalTravelTimeMean(617.21) .build(); verifyDrtCustomerStatsCloseToExpectedStats(utils.getOutputDirectory(), expectedStats); @@ -283,8 +305,13 @@ void testRunServiceAreabasedExampleWithSpeedUp() { @Test void testRunDrtExampleWithIncrementalStopDuration() { Id.resetCaches(); + + DvrpConfigGroup dvrpConfig = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfig.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfig, new OTFVisConfigGroup()); config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); @@ -305,11 +332,11 @@ public void install() { controller.run(); var expectedStats = Stats.newBuilder() - .rejectionRate(0.04) - .rejections(16) - .waitAverage(278.92) - .inVehicleTravelTimeMean(384.6) - .totalTravelTimeMean(663.52) + .rejectionRate(0.05) + .rejections(18) + .waitAverage(276.95) + .inVehicleTravelTimeMean(384.72) + .totalTravelTimeMean(661.66) .build(); verifyDrtCustomerStatsCloseToExpectedStats(utils.getOutputDirectory(), expectedStats); @@ -318,10 +345,15 @@ public void install() { @Test void testRunDrtWithPrebooking() { Id.resetCaches(); + + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), dvrpConfigGroup, new OTFVisConfigGroup()); config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java index fbca29c75b1..42f9267f7a3 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java @@ -24,8 +24,11 @@ import java.util.Set; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.contrib.zone.skims.FreeSpeedTravelTimeMatrix; import org.matsim.contrib.zone.skims.TravelTimeMatrix; import org.matsim.core.config.Config; @@ -78,9 +81,15 @@ public void install() { //use mode-specific travel time matrix built for this subnetwork //lazily initialised: optimisers may not need it bindModal(TravelTimeMatrix.class).toProvider(modalProvider( - getter -> FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(getter.getModal(Network.class), - dvrpConfigGroup.getTravelTimeMatrixParams(), globalConfigGroup.getNumberOfThreads(), - qSimConfigGroup.getTimeStepSize()))).in(Singleton.class); + getter -> { + Network network = getter.getModal(Network.class); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + ZoneSystem zoneSystem = ZoneSystemUtils.createZoneSystem(getConfig().getContext(), network, + matrixParams.getZoneSystemParams(), getConfig().global().getCoordinateSystem()); + return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem, + matrixParams, globalConfigGroup.getNumberOfThreads(), + qSimConfigGroup.getTimeStepSize()); + })).in(Singleton.class); } else { //use DVRP-routing (dvrp-global) network bindModal(Network.class).to( 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 5724d537d36..25cc051ece8 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 @@ -27,7 +27,7 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.dynagent.run.DynQSimConfigConsistencyChecker; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.Config; diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java index 536f9315c82..44da59b0388 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java @@ -22,12 +22,15 @@ import jakarta.inject.Provider; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.dvrp.fleet.DvrpVehicleLookup; import org.matsim.contrib.dvrp.passenger.PassengerModule; import org.matsim.contrib.dvrp.router.DvrpGlobalRoutingNetworkProvider; import org.matsim.contrib.dvrp.trafficmonitoring.DvrpTravelTimeModule; import org.matsim.contrib.dvrp.vrpagent.VrpAgentQueryHelper; import org.matsim.contrib.dynagent.run.DynActivityEngine; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.contrib.zone.skims.FreeSpeedTravelTimeMatrix; import org.matsim.contrib.zone.skims.TravelTimeMatrix; import org.matsim.core.config.groups.QSimConfigGroup; @@ -84,7 +87,10 @@ public void install() { public TravelTimeMatrix get() { var numberOfThreads = getConfig().global().getNumberOfThreads(); var params = dvrpConfigGroup.getTravelTimeMatrixParams(); - return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, params, numberOfThreads, + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + ZoneSystem zoneSystem = ZoneSystemUtils.createZoneSystem(getConfig().getContext(), network, + matrixParams.getZoneSystemParams(), getConfig().global().getCoordinateSystem()); + return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem, params, numberOfThreads, qSimConfigGroup.getTimeStepSize()); } }).in(Singleton.class); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/SquareGrid.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/SquareGrid.java deleted file mode 100644 index 6ca95e174d0..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/SquareGrid.java +++ /dev/null @@ -1,115 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2016 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.contrib.zone; - -import java.util.Collection; - -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Node; - -import com.google.common.base.Preconditions; - -public class SquareGrid { - public static final double EPSILON = 1; - - private final double cellSize; - - private double minX; - private double minY; - private double maxX; - private double maxY; - - private final int cols; - private final int rows; - - private Zone[] zones; - - public SquareGrid(Collection nodes, double cellSize) { - Preconditions.checkArgument(!nodes.isEmpty(), "Cannot create SquareGrid if no nodes"); - this.cellSize = cellSize; - - initBounds(nodes); - - cols = (int)Math.ceil((maxX - minX) / cellSize); - rows = (int)Math.ceil((maxY - minY) / cellSize); - zones = new Zone[rows * cols]; - } - - // This method's content has been copied from NetworkImpl - private void initBounds(Collection nodes) { - minX = Double.POSITIVE_INFINITY; - minY = Double.POSITIVE_INFINITY; - maxX = Double.NEGATIVE_INFINITY; - maxY = Double.NEGATIVE_INFINITY; - for (Node n : nodes) { - if (n.getCoord().getX() < minX) { - minX = n.getCoord().getX(); - } - if (n.getCoord().getY() < minY) { - minY = n.getCoord().getY(); - } - if (n.getCoord().getX() > maxX) { - maxX = n.getCoord().getX(); - } - if (n.getCoord().getY() > maxY) { - maxY = n.getCoord().getY(); - } - } - minX -= EPSILON; - minY -= EPSILON; - maxX += EPSILON; - maxY += EPSILON; - // yy the above four lines are problematic if the coordinate values are much smaller than one. kai, oct'15 - } - - public Zone getZone(Coord coord) { - return zones[getIndex(coord)]; - } - - public Zone getOrCreateZone(Coord coord) { - int index = getIndex(coord); - Zone zone = zones[index]; - if (zone == null) { - double x0 = minX + cellSize / 2; - double y0 = minY + cellSize / 2; - int r = bin(coord.getY(), minY); - int c = bin(coord.getX(), minX); - Coord centroid = new Coord(c * cellSize + x0, r * cellSize + y0); - zone = new Zone(Id.create(index, Zone.class), "square", centroid); - zones[index] = zone; - } - return zone; - } - - private int getIndex(Coord coord) { - Preconditions.checkArgument(coord.getX() >= minX, "Coord.x less than minX"); - Preconditions.checkArgument(coord.getX() <= maxX, "Coord.x greater than maxX"); - Preconditions.checkArgument(coord.getY() >= minY, "Coord.y less than minY"); - Preconditions.checkArgument(coord.getY() <= maxY, "Coord.y greater than maxY"); - int r = bin(coord.getY(), minY); - int c = bin(coord.getX(), minX); - return r * cols + c; - } - - private int bin(double coord, double minCoord) { - return (int)((coord - minCoord) / cellSize); - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/SquareGridSystem.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/SquareGridSystem.java deleted file mode 100644 index 1a4825a9470..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/SquareGridSystem.java +++ /dev/null @@ -1,51 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2015 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.contrib.zone; - -import static java.util.stream.Collectors.toMap; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Node; - -public class SquareGridSystem implements ZonalSystem { - private final SquareGrid grid; - private final Map, Zone> zones; - - public SquareGridSystem(Collection nodes, double cellSize) { - this.grid = new SquareGrid(nodes, cellSize); - zones = nodes.stream() - .map(n -> grid.getOrCreateZone(n.getCoord())) - .collect(toMap(Zone::getId, z -> z, (z1, z2) -> z1)); - } - - @Override - public Map, Zone> getZones() { - return Collections.unmodifiableMap(zones); - } - - @Override - public Zone getZone(Node node) { - return grid.getZone(node.getCoord()); - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystem.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystem.java deleted file mode 100644 index d94238175c4..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystem.java +++ /dev/null @@ -1,31 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2015 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.contrib.zone; - -import java.util.Map; - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Node; - -public interface ZonalSystem { - Map, Zone> getZones(); - - Zone getZone(Node node); -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystemImpl.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystemImpl.java deleted file mode 100644 index c24d789f197..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystemImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2016 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.contrib.zone; - -import java.util.Map; - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.network.Node; -import org.matsim.contrib.zone.util.NetworkWithZonesUtils; -import org.matsim.contrib.zone.util.ZoneFinder; - -public class ZonalSystemImpl implements ZonalSystem { - private final Map, Zone> zones; - private final Map, Zone> nodeToZoneMap; - - public ZonalSystemImpl(Map, Zone> zones, ZoneFinder zoneFinder, Network network) { - this.zones = zones; - nodeToZoneMap = NetworkWithZonesUtils.createNodeToZoneMap(network, zoneFinder); - } - - @Override - public Map, Zone> getZones() { - return zones; - } - - @Override - public Zone getZone(Node node) { - return nodeToZoneMap.get(node.getId()); - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystems.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystems.java deleted file mode 100644 index 4ec41a37a47..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/ZonalSystems.java +++ /dev/null @@ -1,78 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2015 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.contrib.zone; - -import static java.util.stream.Collectors.*; - -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.BinaryOperator; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.tuple.Pair; -import org.locationtech.jts.geom.Point; -import org.locationtech.jts.geom.prep.PreparedGeometry; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.IdMap; -import org.matsim.api.core.v01.network.Node; -import org.matsim.contrib.common.util.DistanceUtils; -import org.matsim.core.utils.geometry.geotools.MGC; - -import com.google.common.collect.Maps; - -//TODO add zone indexing? -public class ZonalSystems { - public static Set filterZonesWithNodes(Collection nodes, ZonalSystem zonalSystem) { - return nodes.stream().map(zonalSystem::getZone).collect(toSet()); - } - - public static List selectNodesWithinArea(Collection nodes, List areaGeoms) { - return nodes.stream().filter(node -> { - Point point = MGC.coord2Point(node.getCoord()); - return areaGeoms.stream().anyMatch(serviceArea -> serviceArea.intersects(point)); - }).collect(toList()); - } - - public static Map computeMostCentralNodes(Collection nodes, ZonalSystem zonalSystem) { - BinaryOperator chooseMoreCentralNode = (n1, n2) -> { - Zone zone = zonalSystem.getZone(n1); - return DistanceUtils.calculateSquaredDistance(n1, zone) <= DistanceUtils.calculateSquaredDistance(n2, - zone) ? n1 : n2; - }; - return nodes.stream() - .map(n -> Pair.of(n, zonalSystem.getZone(n))) - .collect(toMap(Pair::getValue, Pair::getKey, chooseMoreCentralNode)); - } - - public static IdMap> initZonesByDistance(Map, Zone> zones) { - IdMap> zonesByDistance = new IdMap<>(Zone.class); - for (final Zone currentZone : zones.values()) { - List sortedZones = zones.values() - .stream() - .sorted(Comparator.comparing(z -> DistanceUtils.calculateSquaredDistance(currentZone, z))) - .collect(Collectors.toList()); - zonesByDistance.put(currentZone.getId(), sortedZones); - } - return zonesByDistance; - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zone.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zone.java deleted file mode 100644 index c2e548b1e29..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zone.java +++ /dev/null @@ -1,81 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 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.contrib.zone; - -import org.locationtech.jts.geom.MultiPolygon; -import org.matsim.api.core.v01.BasicLocation; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Identifiable; -import org.matsim.core.utils.geometry.geotools.MGC; - -public class Zone implements BasicLocation, Identifiable { - private final Id id; - private final String type; - - private MultiPolygon multiPolygon; - private Coord centroid; - - public Zone(Id id, String type) { - this.id = id; - this.type = type; - } - - public Zone(Id id, String type, Coord centroid) { - this.id = id; - this.type = type; - this.centroid = centroid; - } - - public Zone(Id id, String type, MultiPolygon multiPolygon) { - this.id = id; - this.type = type; - - this.multiPolygon = multiPolygon; - centroid = MGC.point2Coord(multiPolygon.getCentroid()); - } - - @Override - public Id getId() { - return id; - } - - @Override - public Coord getCoord() { - return centroid; - } - - public void setCoord(Coord coord) { - this.centroid = coord; - } - - public String getType() { - return type; - } - - public MultiPolygon getMultiPolygon() { - return multiPolygon; - } - - public void setMultiPolygon(MultiPolygon multiPolygon) { - this.multiPolygon = multiPolygon; - centroid = MGC.point2Coord(multiPolygon.getCentroid()); - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zones.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zones.java deleted file mode 100644 index 34321d05068..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zones.java +++ /dev/null @@ -1,50 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2014 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.contrib.zone; - -import java.io.File; -import java.io.UncheckedIOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Map; - -import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.io.ZoneShpReader; -import org.matsim.contrib.zone.io.ZoneXmlReader; - -public class Zones { - public static Map, Zone> readZones(String zonesXmlFile, String zonesShpFile) { - try { - return readZones(new File(zonesXmlFile).toURI().toURL(), new File(zonesShpFile).toURI().toURL()); - } catch (MalformedURLException e) { - throw new UncheckedIOException(e); - } - } - - public static Map, Zone> readZones(URL zonesXmlUrl, URL zonesShpUrl) { - ZoneXmlReader xmlReader = new ZoneXmlReader(); - xmlReader.readURL(zonesXmlUrl); - Map, Zone> zones = xmlReader.getZones(); - - ZoneShpReader shpReader = new ZoneShpReader(zones); - shpReader.readZones(zonesShpUrl); - return zones; - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixImpl.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixImpl.java index 987f29ea47a..08f899c9d2a 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixImpl.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixImpl.java @@ -22,9 +22,9 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.Node; import org.matsim.contrib.common.util.DistanceUtils; -import org.matsim.contrib.zone.SquareGridSystem; -import org.matsim.contrib.zone.ZonalSystems; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import java.util.List; import java.util.Map; @@ -38,19 +38,19 @@ public class AdaptiveTravelTimeMatrixImpl implements AdaptiveTravelTimeMatrix { private final double TIME_INTERVAL = 3600.; private final List timeDependentMatrix; - private final SquareGridSystem gridSystem; + private final ZoneSystem gridSystem; private final double alpha; private final Map centralNodes; private final int numberOfBins; private final DvrpTravelTimeMatrixParams params; private final Map sparseTravelTimeCache = new ConcurrentHashMap<>(); - public AdaptiveTravelTimeMatrixImpl(double maxTime, Network dvrpNetwork, DvrpTravelTimeMatrixParams params, + public AdaptiveTravelTimeMatrixImpl(double maxTime, Network dvrpNetwork, ZoneSystem zoneSystem, DvrpTravelTimeMatrixParams params, TravelTimeMatrix freeSpeedMatrix, double alpha) { this.alpha = alpha; this.numberOfBins = numberOfBins(maxTime); - this.gridSystem = new SquareGridSystem(dvrpNetwork.getNodes().values(), params.cellSize); - this.centralNodes = ZonalSystems.computeMostCentralNodes(dvrpNetwork.getNodes().values(), this.gridSystem); + this.gridSystem = zoneSystem; + this.centralNodes = ZoneSystemUtils.computeMostCentralNodes(dvrpNetwork.getNodes().values(), this.gridSystem); this.timeDependentMatrix = IntStream.range(0, numberOfBins).mapToObj(i -> new Matrix(centralNodes.keySet())) .toList(); this.params = params; @@ -113,7 +113,7 @@ public double getTravelTime(Node fromNode, Node toNode, double departureTime) { if (sparseValue != null) { return sparseValue; } - return this.timeDependentMatrix.get(bin).get(this.gridSystem.getZone(fromNode), this.gridSystem.getZone(toNode)); + return this.timeDependentMatrix.get(bin).get(this.gridSystem.getZoneForNodeId(fromNode.getId()).orElseThrow(), this.gridSystem.getZoneForNodeId(toNode.getId()).orElseThrow()); } int getBin(double departureTime) { @@ -135,7 +135,7 @@ public void setTravelTime(Node fromNode, Node toNode, double routeEstimate, doub } else { double currentTravelTimeEstimate = this.getTravelTime(fromNode, toNode, departureTime); double value = getUpdatedValue(currentTravelTimeEstimate, routeEstimate, this.alpha); - this.timeDependentMatrix.get(bin).set(this.gridSystem.getZone(fromNode), this.gridSystem.getZone(toNode), + this.timeDependentMatrix.get(bin).set(this.gridSystem.getZoneForNodeId(fromNode.getId()).orElseThrow(), this.gridSystem.getZoneForNodeId(toNode.getId()).orElseThrow(), value); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixModule.java index a546f83a429..d0bf361fd40 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixModule.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/AdaptiveTravelTimeMatrixModule.java @@ -22,6 +22,8 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; @@ -46,10 +48,17 @@ public AdaptiveTravelTimeMatrixModule(String mode) { @Override public void install() { bindModal(AdaptiveTravelTimeMatrix.class).toProvider(modalProvider( - getter -> new AdaptiveTravelTimeMatrixImpl(qsimConfig.getEndTime().orElse(ALTERNATIVE_ENDTIME), - getter.getModal(Network.class), - dvrpConfigGroup.getTravelTimeMatrixParams(), - getter.getModal(TravelTimeMatrix.class),SMOOTHING_ALPHA))) + getter -> { + Network network = getter.getModal(Network.class); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + ZoneSystem zoneSystem = ZoneSystemUtils.createZoneSystem(getConfig().getContext(), network, + matrixParams.getZoneSystemParams(), getConfig().global().getCoordinateSystem()); + return new AdaptiveTravelTimeMatrixImpl(qsimConfig.getEndTime().orElse(ALTERNATIVE_ENDTIME), + network, + zoneSystem, + matrixParams, + getter.getModal(TravelTimeMatrix.class), SMOOTHING_ALPHA); + })) .in(Singleton.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 49fa4f29eb1..1c95a88432f 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 @@ -20,23 +20,19 @@ package org.matsim.contrib.zone.skims; -import org.matsim.core.config.ConfigGroup; -import org.matsim.core.config.ReflectiveConfigGroup; - -import jakarta.validation.constraints.Positive; 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.grid.GISFileZoneSystemParams; +import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; /** * @author Michal Maciejewski (michalm) */ -public class DvrpTravelTimeMatrixParams extends ReflectiveConfigGroup { +public class DvrpTravelTimeMatrixParams extends ReflectiveConfigGroupWithConfigurableParameterSets { public static final String SET_NAME = "travelTimeMatrix"; - @Parameter - @Comment("size of square cells (meters) used for computing travel time matrix." + " Default value is 200 m") - @Positive - public double cellSize = 200; //[m] - // Satisfying only one criterion (max distance or travel time) is enough to be considered a neighbour. @Parameter @@ -58,13 +54,32 @@ public class DvrpTravelTimeMatrixParams extends ReflectiveConfigGroup { + " The unit is seconds. Default value is 0 s (for backward compatibility).") @PositiveOrZero public double maxNeighborTravelTime = 0; //[s] + private ZoneSystemParams zoneSystemParams; + public DvrpTravelTimeMatrixParams() { super(SET_NAME); + initSingletonParameterSets(); + } + + + private void initSingletonParameterSets() { + + //insertion search params (one of: extensive, selective, repeated selective) + addDefinition(SquareGridZoneSystemParams.SET_NAME, SquareGridZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (SquareGridZoneSystemParams)params); + + addDefinition(GISFileZoneSystemParams.SET_NAME, GISFileZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (GISFileZoneSystemParams)params); + + addDefinition(H3GridZoneSystemParams.SET_NAME, H3GridZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (H3GridZoneSystemParams)params); } - @Override - public ConfigGroup createParameterSet(String type) { - return super.createParameterSet(type); + public ZoneSystemParams getZoneSystemParams() { + return zoneSystemParams; } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java index 0adab8701df..6351dd3bce8 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java @@ -22,28 +22,28 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.dvrp.router.TimeAsTravelDisutility; import org.matsim.contrib.dvrp.trafficmonitoring.QSimFreeSpeedTravelTime; -import org.matsim.contrib.zone.SquareGridSystem; -import org.matsim.contrib.zone.ZonalSystems; import org.matsim.core.router.util.TravelTime; /** * @author Michal Maciejewski (michalm) */ public class FreeSpeedTravelTimeMatrix implements TravelTimeMatrix { - public static FreeSpeedTravelTimeMatrix createFreeSpeedMatrix(Network dvrpNetwork, DvrpTravelTimeMatrixParams params, int numberOfThreads, + public static FreeSpeedTravelTimeMatrix createFreeSpeedMatrix(Network dvrpNetwork, ZoneSystem zoneSystem, DvrpTravelTimeMatrixParams params, int numberOfThreads, double qSimTimeStepSize) { - return new FreeSpeedTravelTimeMatrix(dvrpNetwork, params, numberOfThreads, new QSimFreeSpeedTravelTime(qSimTimeStepSize)); + return new FreeSpeedTravelTimeMatrix(dvrpNetwork, zoneSystem, params, numberOfThreads, new QSimFreeSpeedTravelTime(qSimTimeStepSize)); } - private final SquareGridSystem gridSystem; + private final ZoneSystem zoneSystem; private final Matrix freeSpeedTravelTimeMatrix; private final SparseMatrix freeSpeedTravelTimeSparseMatrix; - public FreeSpeedTravelTimeMatrix(Network dvrpNetwork, DvrpTravelTimeMatrixParams params, int numberOfThreads, TravelTime travelTime) { - gridSystem = new SquareGridSystem(dvrpNetwork.getNodes().values(), params.cellSize); - var centralNodes = ZonalSystems.computeMostCentralNodes(dvrpNetwork.getNodes().values(), gridSystem); + public FreeSpeedTravelTimeMatrix(Network dvrpNetwork, ZoneSystem zoneSystem, DvrpTravelTimeMatrixParams params, int numberOfThreads, TravelTime travelTime) { + this.zoneSystem = zoneSystem; + var centralNodes = ZoneSystemUtils.computeMostCentralNodes(dvrpNetwork.getNodes().values(), zoneSystem); var travelDisutility = new TimeAsTravelDisutility(travelTime); var routingParams = new TravelTimeMatrices.RoutingParams(dvrpNetwork, travelTime, travelDisutility, numberOfThreads); freeSpeedTravelTimeMatrix = TravelTimeMatrices.calculateTravelTimeMatrix(routingParams, centralNodes, 0); @@ -62,10 +62,10 @@ public int getTravelTime(Node fromNode, Node toNode, double departureTime) { return time; } } - return freeSpeedTravelTimeMatrix.get(gridSystem.getZone(fromNode), gridSystem.getZone(toNode)); + return freeSpeedTravelTimeMatrix.get(zoneSystem.getZoneForNodeId(fromNode.getId()).orElseThrow(), zoneSystem.getZoneForNodeId(toNode.getId()).orElseThrow()); } public int getZonalTravelTime(Node fromNode, Node toNode, double departureTime) { - return freeSpeedTravelTimeMatrix.get(gridSystem.getZone(fromNode), gridSystem.getZone(toNode)); + return freeSpeedTravelTimeMatrix.get(zoneSystem.getZoneForNodeId(fromNode.getId()).orElseThrow(), zoneSystem.getZoneForNodeId(toNode.getId()).orElseThrow()); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/Matrix.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/Matrix.java index d497276c3f5..96425c78ef5 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/Matrix.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/Matrix.java @@ -27,7 +27,7 @@ import java.util.Set; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; /** * Based on FloatMatrix from sbb-matsim-extensions diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java index dcea254ac6c..7caf007d369 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java @@ -28,8 +28,8 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.Zone; import org.matsim.contrib.util.ExecutorServiceWithResource; -import org.matsim.contrib.zone.Zone; import org.matsim.contrib.zone.skims.SparseMatrix.NodeAndTime; import org.matsim.contrib.zone.skims.SparseMatrix.SparseRow; import org.matsim.core.router.speedy.LeastCostPathTree; diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/NetworkWithZonesUtils.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/NetworkWithZonesUtils.java deleted file mode 100644 index 0a56d2abffc..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/util/NetworkWithZonesUtils.java +++ /dev/null @@ -1,45 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2015 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.contrib.zone.util; - -import org.matsim.api.core.v01.IdCollectors; -import org.matsim.api.core.v01.IdMap; -import org.matsim.api.core.v01.Identifiable; -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.contrib.zone.Zone; - -public class NetworkWithZonesUtils { - // if CRSs of the network and zones are different, zoneFinder should convert between CRSs - public static IdMap createLinkToZoneMap(Network network, ZoneFinder zoneFinder) { - return network.getLinks() - .values() - .stream() - .collect(IdCollectors.toIdMap(Link.class, Identifiable::getId, l -> zoneFinder.findZone(l.getToNode().getCoord()))); - } - - public static IdMap createNodeToZoneMap(Network network, ZoneFinder zoneFinder) { - return network.getNodes() - .values() - .stream() - .collect(IdCollectors.toIdMap(Node.class, Identifiable::getId, n -> zoneFinder.findZone(n.getCoord()))); - } -} diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/SquareGridTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/SquareGridTest.java deleted file mode 100644 index dc09184888e..00000000000 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/SquareGridTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) 2020 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.contrib.zone; - -import static org.assertj.core.api.Assertions.*; -import static org.matsim.contrib.zone.SquareGrid.EPSILON; - -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Node; -import org.matsim.core.network.NetworkUtils; - -/** - * @author Michal Maciejewski (michalm) - */ -public class SquareGridTest { - @Test - void emptyNodes_fail() { - assertThatThrownBy(() -> new SquareGrid(List.of(), 100)).isExactlyInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot create SquareGrid if no nodes"); - } - - @Test - void outsideBoundaries_withinEpsilon_success() { - Node node_0_0 = node(0, 0); - SquareGrid grid = new SquareGrid(List.of(node_0_0), 100); - assertThatCode(() -> grid.getZone(new Coord(-EPSILON, EPSILON))).doesNotThrowAnyException(); - } - - @Test - void outsideBoundaries_outsideEpsilon_fail() { - Node node_0_0 = node(0, 0); - SquareGrid grid = new SquareGrid(List.of(node_0_0), 100); - assertThatThrownBy(() -> grid.getZone(new Coord(-2 * EPSILON, 0))).isExactlyInstanceOf( - IllegalArgumentException.class); - } - - @Test - void testLazyZoneCreation() { - Node node_0_0 = node(0, 0); - SquareGrid grid = new SquareGrid(List.of(node_0_0), 100); - - Coord coord = new Coord(0, 0); - Zone zone = new Zone(Id.create(0, Zone.class), "square", new Coord(49, 49)); - assertThat(grid.getZone(coord)).isNull(); - assertThat(grid.getOrCreateZone(coord)).isEqualToComparingFieldByField(zone); - assertThat(grid.getZone(coord)).isEqualToComparingFieldByField(zone); - } - - @Test - void testGrid() { - Node node_0_0 = node(0, 0); - Node node_150_150 = node(150, 150); - SquareGrid grid = new SquareGrid(List.of(node_0_0, node_150_150), 100); - - Coord coord0 = new Coord(100 - 2 * EPSILON, 100 - 2 * EPSILON); - Zone zone0 = new Zone(Id.create(0, Zone.class), "square", new Coord(49, 49)); - assertThat(grid.getOrCreateZone(coord0)).isEqualToComparingFieldByField(zone0); - - Coord coord1 = new Coord(100 - EPSILON, 100 - EPSILON); - Zone zone1 = new Zone(Id.create(3, Zone.class), "square", new Coord(149, 149)); - assertThat(grid.getOrCreateZone(coord1)).isEqualToComparingFieldByField(zone1); - } - - private Node node(double x, double y) { - return NetworkUtils.createNode(Id.createNodeId(x + "," + y), new Coord(x, y)); - } -} diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java index c5743ffaafb..8aaf6001258 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java @@ -27,6 +27,8 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; import org.matsim.core.network.NetworkUtils; /** @@ -49,9 +51,9 @@ public FreeSpeedTravelTimeMatrixTest() { @Test void matrix() { DvrpTravelTimeMatrixParams params = new DvrpTravelTimeMatrixParams(); - params.cellSize = 100; params.maxNeighborDistance = 0; - var matrix = FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, params, 1, 1); + ZoneSystem zoneSystem = new SquareGridZoneSystem(network, 100.); + var matrix = FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem, params, 1, 1); // distances between central nodes: A and B assertThat(matrix.getTravelTime(nodeA, nodeA, 0)).isEqualTo(0); @@ -69,9 +71,10 @@ void matrix() { @Test void sparseMatrix() { DvrpTravelTimeMatrixParams params = new DvrpTravelTimeMatrixParams(); - params.cellSize = 100; params.maxNeighborDistance = 9999; - var matrix = FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, params, 1, 1); + + ZoneSystem zoneSystem = new SquareGridZoneSystem(network, 100.); + var matrix = FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem, params, 1, 1); // distances between central nodes: A and B assertThat(matrix.getTravelTime(nodeA, nodeA, 0)).isEqualTo(0); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java index 02e6f9fc5dd..fab91039ecc 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java @@ -28,17 +28,18 @@ import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.zone.Zone; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; /** * @author Michal Maciejewski (michalm) */ public class MatrixTest { - private final Zone unknownZone = new Zone(Id.create("?", Zone.class), null); + private final Zone unknownZone = new ZoneImpl(Id.create("?", Zone.class), null, null, null); - private final Zone zoneA = new Zone(Id.create("A", Zone.class), null); - private final Zone zoneB = new Zone(Id.create("B", Zone.class), null); - private final Zone zoneC = new Zone(Id.create("C", Zone.class), null); + private final Zone zoneA = new ZoneImpl(Id.create("A", Zone.class), null, null, null); + private final Zone zoneB = new ZoneImpl(Id.create("B", Zone.class), null, null, null); + private final Zone zoneC = new ZoneImpl(Id.create("C", Zone.class), null, null, null); private final Set zones = Set.of(zoneA, zoneB, zoneC); private final Matrix matrix = new Matrix(zones); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java index 02d7b7bd241..39a17e954a7 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java @@ -29,8 +29,9 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; import org.matsim.contrib.dvrp.router.TimeAsTravelDisutility; -import org.matsim.contrib.zone.Zone; import org.matsim.core.network.NetworkUtils; import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; @@ -45,8 +46,8 @@ void travelTimeMatrix() { Node nodeB = NetworkUtils.createAndAddNode(network, Id.createNodeId("B"), new Coord(150, 150)); NetworkUtils.createAndAddLink(network, Id.createLinkId("AB"), nodeA, nodeB, 150, 15, 20, 1); NetworkUtils.createAndAddLink(network, Id.createLinkId("BA"), nodeB, nodeA, 300, 15, 40, 1); - Zone zoneA = new Zone(Id.create("Zone_A", Zone.class), null); - Zone zoneB = new Zone(Id.create("Zone_Z", Zone.class), null); + Zone zoneA = new ZoneImpl(Id.create("Zone_A", Zone.class), null, null, null); + Zone zoneB = new ZoneImpl(Id.create("Zone_Z", Zone.class), null, null, null); var centralNodes = Map.of(zoneA, nodeA, zoneB, nodeB); var matrix = TravelTimeMatrices.calculateTravelTimeMatrix(routingParams(network), centralNodes, 0); diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java index 3c42d7111c2..5860bea3890 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java @@ -86,7 +86,7 @@ public TaxiOptimizer get() { var chargingInfrastructure = getModalInstance(ChargingInfrastructure.class); var scheduleTimingUpdater = getModalInstance(ScheduleTimingUpdater.class); return new ETaxiOptimizerProvider(events, taxiCfg, fleet, network, timer, travelTime, - travelDisutility, eTaxiScheduler, scheduleTimingUpdater, chargingInfrastructure).get(); + travelDisutility, eTaxiScheduler, scheduleTimingUpdater, chargingInfrastructure, getConfig()).get(); } }); diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiOptimizerProvider.java b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiOptimizerProvider.java index e3b653a0b86..30458550f44 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiOptimizerProvider.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiOptimizerProvider.java @@ -19,7 +19,10 @@ package org.matsim.contrib.etaxi.optimizer; +import com.google.inject.Provider; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; import org.matsim.contrib.etaxi.ETaxiScheduler; @@ -30,23 +33,16 @@ import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure; import org.matsim.contrib.taxi.optimizer.BestDispatchFinder; import org.matsim.contrib.taxi.optimizer.TaxiOptimizer; -import org.matsim.contrib.taxi.optimizer.rules.IdleTaxiZonalRegistry; -import org.matsim.contrib.taxi.optimizer.rules.RuleBasedRequestInserter; -import org.matsim.contrib.taxi.optimizer.rules.RuleBasedTaxiOptimizerParams; -import org.matsim.contrib.taxi.optimizer.rules.UnplannedRequestZonalRegistry; -import org.matsim.contrib.taxi.optimizer.rules.ZonalRegisters; +import org.matsim.contrib.taxi.optimizer.rules.*; import org.matsim.contrib.taxi.run.TaxiConfigGroup; -import org.matsim.contrib.zone.SquareGridSystem; -import org.matsim.contrib.zone.ZonalSystem; import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.config.Config; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.router.speedy.SpeedyALTFactory; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.core.router.util.TravelDisutility; import org.matsim.core.router.util.TravelTime; -import com.google.inject.Provider; - public class ETaxiOptimizerProvider implements Provider { private final EventsManager eventsManager; private final TaxiConfigGroup taxiCfg; @@ -57,11 +53,12 @@ public class ETaxiOptimizerProvider implements Provider { private final TravelDisutility travelDisutility; private final ETaxiScheduler eScheduler; private final ChargingInfrastructure chargingInfrastructure; + private final Config config; private final ScheduleTimingUpdater scheduleTimingUpdater; public ETaxiOptimizerProvider(EventsManager eventsManager, TaxiConfigGroup taxiCfg, Fleet fleet, Network network, MobsimTimer timer, TravelTime travelTime, TravelDisutility travelDisutility, ETaxiScheduler eScheduler, - ScheduleTimingUpdater scheduleTimingUpdater, ChargingInfrastructure chargingInfrastructure) { + ScheduleTimingUpdater scheduleTimingUpdater, ChargingInfrastructure chargingInfrastructure, Config config) { this.eventsManager = eventsManager; this.taxiCfg = taxiCfg; this.fleet = fleet; @@ -72,6 +69,7 @@ public ETaxiOptimizerProvider(EventsManager eventsManager, TaxiConfigGroup taxiC this.eScheduler = eScheduler; this.scheduleTimingUpdater = scheduleTimingUpdater; this.chargingInfrastructure = chargingInfrastructure; + this.config = config; } @Override @@ -79,7 +77,7 @@ public TaxiOptimizer get() { String type = taxiCfg.getTaxiOptimizerParams().getName(); if (type.equals(RuleBasedETaxiOptimizerParams.SET_NAME)) { ZonalRegisters zonalRegisters = createZonalRegisters( - ((RuleBasedETaxiOptimizerParams)taxiCfg.getTaxiOptimizerParams()).getRuleBasedTaxiOptimizerParams()); + ((RuleBasedETaxiOptimizerParams)taxiCfg.getTaxiOptimizerParams()).getRuleBasedTaxiOptimizerParams(), config); BestDispatchFinder dispatchFinder = new BestDispatchFinder(eScheduler.getScheduleInquiry(), network, timer, travelTime, travelDisutility); RuleBasedRequestInserter requestInserter = new RuleBasedRequestInserter(eScheduler, timer, dispatchFinder, @@ -99,11 +97,12 @@ public TaxiOptimizer get() { } } - private ZonalRegisters createZonalRegisters(RuleBasedTaxiOptimizerParams params) { - ZonalSystem zonalSystem = new SquareGridSystem(network.getNodes().values(), params.cellSize); - IdleTaxiZonalRegistry idleTaxiRegistry = new IdleTaxiZonalRegistry(zonalSystem, + private ZonalRegisters createZonalRegisters(RuleBasedTaxiOptimizerParams params, Config config) { + ZoneSystem zoneSystem = ZoneSystemUtils.createZoneSystem(config.getContext(), network, + params.getZoneSystemParams(), config.global().getCoordinateSystem()); + IdleTaxiZonalRegistry idleTaxiRegistry = new IdleTaxiZonalRegistry(zoneSystem, eScheduler.getScheduleInquiry()); - UnplannedRequestZonalRegistry unplannedRequestRegistry = new UnplannedRequestZonalRegistry(zonalSystem); + UnplannedRequestZonalRegistry unplannedRequestRegistry = new UnplannedRequestZonalRegistry(zoneSystem); return new ZonalRegisters(idleTaxiRegistry, unplannedRequestRegistry); } } diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/assignment/AssignmentETaxiOptimizerParams.java b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/assignment/AssignmentETaxiOptimizerParams.java index 3ca8be96021..eaa42b990e6 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/assignment/AssignmentETaxiOptimizerParams.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/assignment/AssignmentETaxiOptimizerParams.java @@ -21,6 +21,7 @@ import org.matsim.contrib.taxi.optimizer.AbstractTaxiOptimizerParams; import org.matsim.contrib.taxi.optimizer.assignment.AssignmentTaxiOptimizerParams; +import org.matsim.contrib.taxi.optimizer.rules.RuleBasedTaxiOptimizerParams; import org.matsim.core.config.ConfigGroup; import jakarta.validation.constraints.DecimalMax; @@ -52,21 +53,14 @@ public final class AssignmentETaxiOptimizerParams extends AbstractTaxiOptimizerP public AssignmentETaxiOptimizerParams() { super(SET_NAME, true, true); + initSingletonParameterSets(); } - @Override - public ConfigGroup createParameterSet(String type) { - return type.equals(AssignmentTaxiOptimizerParams.SET_NAME) ? - new AssignmentTaxiOptimizerParams() : - super.createParameterSet(type); - } - - @Override - public void addParameterSet(ConfigGroup set) { - if (set.getName().equals(AssignmentTaxiOptimizerParams.SET_NAME)) { - assignmentTaxiOptimizerParams = (AssignmentTaxiOptimizerParams)set; - } - super.addParameterSet(set); + private void initSingletonParameterSets() { + //insertion search params (one of: extensive, selective, repeated selective) + addDefinition(AssignmentTaxiOptimizerParams.SET_NAME, AssignmentTaxiOptimizerParams::new, + () -> assignmentTaxiOptimizerParams, + params -> assignmentTaxiOptimizerParams = (AssignmentTaxiOptimizerParams)params); } AssignmentTaxiOptimizerParams getAssignmentTaxiOptimizerParams() { diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/rules/RuleBasedETaxiOptimizerParams.java b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/rules/RuleBasedETaxiOptimizerParams.java index b1525ddc8f6..f8543567a2e 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/rules/RuleBasedETaxiOptimizerParams.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/rules/RuleBasedETaxiOptimizerParams.java @@ -19,6 +19,9 @@ package org.matsim.contrib.etaxi.optimizer.rules; +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; import org.matsim.contrib.taxi.optimizer.AbstractTaxiOptimizerParams; import org.matsim.contrib.taxi.optimizer.rules.RuleBasedTaxiOptimizerParams; import org.matsim.core.config.ConfigGroup; @@ -52,21 +55,14 @@ public final class RuleBasedETaxiOptimizerParams extends AbstractTaxiOptimizerPa public RuleBasedETaxiOptimizerParams() { super(SET_NAME, false, false); + initSingletonParameterSets(); } - @Override - public ConfigGroup createParameterSet(String type) { - return type.equals(RuleBasedTaxiOptimizerParams.SET_NAME) ? - new RuleBasedTaxiOptimizerParams() : - super.createParameterSet(type); - } - - @Override - public void addParameterSet(ConfigGroup set) { - if (set.getName().equals(RuleBasedTaxiOptimizerParams.SET_NAME)) { - ruleBasedTaxiOptimizerParams = (RuleBasedTaxiOptimizerParams)set; - } - super.addParameterSet(set); + private void initSingletonParameterSets() { + //insertion search params (one of: extensive, selective, repeated selective) + addDefinition(RuleBasedTaxiOptimizerParams.SET_NAME, RuleBasedTaxiOptimizerParams::new, + () -> ruleBasedTaxiOptimizerParams, + params -> ruleBasedTaxiOptimizerParams = (RuleBasedTaxiOptimizerParams)params); } public RuleBasedTaxiOptimizerParams getRuleBasedTaxiOptimizerParams() { diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/AbstractTaxiOptimizerParams.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/AbstractTaxiOptimizerParams.java index 32f6272ce9a..176fdbce2a8 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/AbstractTaxiOptimizerParams.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/AbstractTaxiOptimizerParams.java @@ -23,12 +23,13 @@ import jakarta.validation.constraints.Positive; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.ReflectiveConfigGroup; /** * @author michalm */ -public abstract class AbstractTaxiOptimizerParams extends ReflectiveConfigGroup { +public abstract class AbstractTaxiOptimizerParams extends ReflectiveConfigGroupWithConfigurableParameterSets { public static final String REOPTIMIZATION_TIME_STEP = "reoptimizationTimeStep"; protected static final String REOPTIMIZATION_TIME_STEP_EXP = "Specifies how often the reoptimization algorithm is executed." + " Must be a positive integer value. Smaller values mean lower reaction time." diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/DefaultTaxiOptimizerProvider.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/DefaultTaxiOptimizerProvider.java index ed28f925ae7..a9e706f10ea 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/DefaultTaxiOptimizerProvider.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/DefaultTaxiOptimizerProvider.java @@ -22,6 +22,8 @@ import java.net.URL; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; import org.matsim.contrib.taxi.optimizer.assignment.AssignmentRequestInserter; @@ -38,8 +40,7 @@ import org.matsim.contrib.taxi.optimizer.zonal.ZonalTaxiOptimizerParams; import org.matsim.contrib.taxi.run.TaxiConfigGroup; import org.matsim.contrib.taxi.scheduler.TaxiScheduler; -import org.matsim.contrib.zone.SquareGridSystem; -import org.matsim.contrib.zone.ZonalSystem; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.router.util.TravelDisutility; @@ -116,9 +117,9 @@ yield new RuleBasedTaxiOptimizer(eventsManager, taxiCfg, fleet, scheduler, sched } private ZonalRegisters createZonalRegisters(RuleBasedTaxiOptimizerParams params) { - ZonalSystem zonalSystem = new SquareGridSystem(network.getNodes().values(), params.cellSize); - IdleTaxiZonalRegistry idleTaxiRegistry = new IdleTaxiZonalRegistry(zonalSystem, scheduler.getScheduleInquiry()); - UnplannedRequestZonalRegistry unplannedRequestRegistry = new UnplannedRequestZonalRegistry(zonalSystem); + ZoneSystem zoneSystem = ZoneSystemUtils.createZoneSystem(context, network, params.getZoneSystemParams()); + IdleTaxiZonalRegistry idleTaxiRegistry = new IdleTaxiZonalRegistry(zoneSystem, scheduler.getScheduleInquiry()); + UnplannedRequestZonalRegistry unplannedRequestRegistry = new UnplannedRequestZonalRegistry(zoneSystem); return new ZonalRegisters(idleTaxiRegistry, unplannedRequestRegistry); } } diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/IdleTaxiZonalRegistry.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/IdleTaxiZonalRegistry.java index 670c2f8e283..37243ddb127 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/IdleTaxiZonalRegistry.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/IdleTaxiZonalRegistry.java @@ -28,30 +28,30 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdMap; import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.schedule.ScheduleInquiry; import org.matsim.contrib.dvrp.schedule.Schedules; import org.matsim.contrib.taxi.schedule.TaxiStayTask; -import org.matsim.contrib.zone.ZonalSystem; -import org.matsim.contrib.zone.ZonalSystems; -import org.matsim.contrib.zone.Zone; public class IdleTaxiZonalRegistry { private final ScheduleInquiry scheduleInquiry; - private final ZonalSystem zonalSystem; + private final ZoneSystem zoneSystem; private final IdMap> zonesSortedByDistance; private final IdMap, DvrpVehicle>> vehiclesInZones = new IdMap<>(Zone.class); private final Map, DvrpVehicle> vehicles = new LinkedHashMap<>(); - public IdleTaxiZonalRegistry(ZonalSystem zonalSystem, ScheduleInquiry scheduleInquiry) { + public IdleTaxiZonalRegistry(ZoneSystem zoneSystem, ScheduleInquiry scheduleInquiry) { this.scheduleInquiry = scheduleInquiry; - this.zonalSystem = zonalSystem; - zonesSortedByDistance = ZonalSystems.initZonesByDistance(zonalSystem.getZones()); + this.zoneSystem = zoneSystem; + zonesSortedByDistance = ZoneSystemUtils.initZonesByDistance(zoneSystem.getZones()); - for (Id id : zonalSystem.getZones().keySet()) { + for (Id id : zoneSystem.getZones().keySet()) { vehiclesInZones.put(id, new LinkedHashMap<>());//LinkedHashMap to preserve iteration order } } @@ -91,7 +91,7 @@ public Stream findNearestVehicles(Node node, int minCount, Predicat return minCount >= vehicles.size() ? vehicles.values().stream().filter(idleVehicleFilter) : - zonesSortedByDistance.get(zonalSystem.getZone(node).getId()) + zonesSortedByDistance.get(zoneSystem.getZoneForNodeId(node.getId()).orElseThrow().getId()) .stream() .flatMap(z -> vehiclesInZones.get(z.getId()).values().stream()) .filter(idleVehicleFilter) @@ -99,7 +99,7 @@ public Stream findNearestVehicles(Node node, int minCount, Predicat } private Id getZoneId(TaxiStayTask stayTask) { - return zonalSystem.getZone(stayTask.getLink().getToNode()).getId(); + return zoneSystem.getZoneForLinkId(stayTask.getLink().getId()).orElseThrow().getId(); } public Stream vehicles() { diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerParams.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerParams.java index 627fcacb253..c02e1e5a5e8 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerParams.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerParams.java @@ -19,6 +19,10 @@ package org.matsim.contrib.taxi.optimizer.rules; +import org.matsim.contrib.common.zones.ZoneSystemParams; +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; import org.matsim.contrib.taxi.optimizer.AbstractTaxiOptimizerParams; import org.matsim.contrib.taxi.optimizer.rules.RuleBasedRequestInserter.Goal; @@ -62,14 +66,23 @@ public final class RuleBasedTaxiOptimizerParams extends AbstractTaxiOptimizerPar @Positive public int nearestVehiclesLimit = 30; - @Parameter - @Comment("The side length of square zones used in zonal registers of idle vehicles" - + " and open requests. The default value is 1000 m. This value is good for urban areas. For large areas" - + " with sparsely distributed taxis and low taxi demand, you may consider using a bigger cell size." - + " On the other hand, if 'nearestRequestsLimit' or 'nearestVehiclesLimit' are very low," - + " a smaller cell size may work better.") - @Positive - public double cellSize = 1000; + private ZoneSystemParams zoneSystemParams = new SquareGridZoneSystemParams(); + + private void initSingletonParameterSets() { + + //insertion search params (one of: extensive, selective, repeated selective) + addDefinition(SquareGridZoneSystemParams.SET_NAME, SquareGridZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (SquareGridZoneSystemParams)params); + + addDefinition(GISFileZoneSystemParams.SET_NAME, GISFileZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (GISFileZoneSystemParams)params); + + addDefinition(H3GridZoneSystemParams.SET_NAME, H3GridZoneSystemParams::new, + () -> zoneSystemParams, + params -> zoneSystemParams = (H3GridZoneSystemParams)params); + } /** * {@value #REOPTIMIZATION_TIME_STEP_EXP} @@ -81,9 +94,19 @@ public final class RuleBasedTaxiOptimizerParams extends AbstractTaxiOptimizerPar public RuleBasedTaxiOptimizerParams() { super(SET_NAME, false, false); + initSingletonParameterSets(); + initDefault(); + } + + private void initDefault() { + ((SquareGridZoneSystemParams) zoneSystemParams).cellSize = 1000.; } public int getReoptimizationTimeStep() { return reoptimizationTimeStep; } + + public ZoneSystemParams getZoneSystemParams() { + return zoneSystemParams; + } } diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/UnplannedRequestZonalRegistry.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/UnplannedRequestZonalRegistry.java index a2c061d7f68..233aee0db90 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/UnplannedRequestZonalRegistry.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/rules/UnplannedRequestZonalRegistry.java @@ -27,24 +27,24 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdMap; import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.drt.passenger.DrtRequest; import org.matsim.contrib.dvrp.optimizer.Request; -import org.matsim.contrib.zone.ZonalSystem; -import org.matsim.contrib.zone.ZonalSystems; -import org.matsim.contrib.zone.Zone; public class UnplannedRequestZonalRegistry { - private final ZonalSystem zonalSystem; + private final ZoneSystem zoneSystem; private final IdMap> zonesSortedByDistance; private final IdMap, DrtRequest>> requestsInZones = new IdMap<>(Zone.class); private int requestCount = 0; - public UnplannedRequestZonalRegistry(ZonalSystem zonalSystem) { - this.zonalSystem = zonalSystem; - zonesSortedByDistance = ZonalSystems.initZonesByDistance(zonalSystem.getZones()); + public UnplannedRequestZonalRegistry(ZoneSystem zoneSystem) { + this.zoneSystem = zoneSystem; + zonesSortedByDistance = ZoneSystemUtils.initZonesByDistance(zoneSystem.getZones()); - for (Id id : zonalSystem.getZones().keySet()) { + for (Id id : zoneSystem.getZones().keySet()) { requestsInZones.put(id, new LinkedHashMap<>());//LinkedHashMap to preserve iteration order } } @@ -72,14 +72,14 @@ public void removeRequest(DrtRequest request) { } public Stream findNearestRequests(Node node, int minCount) { - return zonesSortedByDistance.get(zonalSystem.getZone(node).getId()) + return zonesSortedByDistance.get(zoneSystem.getZoneForNodeId(node.getId()).orElseThrow().getId()) .stream() .flatMap(z -> requestsInZones.get(z.getId()).values().stream()) .limit(minCount); } private Id getZoneId(DrtRequest request) { - return zonalSystem.getZone(request.getFromLink().getFromNode()).getId(); + return zoneSystem.getZoneForNodeId(request.getFromLink().getFromNode().getId()).orElseThrow().getId(); } public int getRequestCount() { diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalRequestInserter.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalRequestInserter.java index ad971ec8da0..cdba2fc9b00 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalRequestInserter.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalRequestInserter.java @@ -30,6 +30,8 @@ import org.matsim.api.core.v01.IdMap; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneSystemUtils; import org.matsim.contrib.drt.passenger.DrtRequest; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.Fleet; @@ -40,10 +42,7 @@ import org.matsim.contrib.taxi.optimizer.rules.ZonalRegisters; import org.matsim.contrib.taxi.scheduler.TaxiScheduler; import org.matsim.contrib.zone.ZonalSystemParams; -import org.matsim.contrib.zone.Zone; -import org.matsim.contrib.zone.Zones; -import org.matsim.contrib.zone.util.NetworkWithZonesUtils; -import org.matsim.contrib.zone.util.ZoneFinderImpl; +import org.matsim.contrib.common.zones.util.ZoneFinderImpl; import org.matsim.core.config.ConfigGroup; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.router.util.TravelDisutility; @@ -74,11 +73,11 @@ public ZonalRequestInserter(Fleet fleet, TaxiScheduler scheduler, MobsimTimer ti zonalRegisters); ZonalSystemParams zonalSystemParams = params.getZonalSystemParams(); - zones = Zones.readZones(ConfigGroup.getInputFileURL(context, zonalSystemParams.zonesXmlFile), + zones = ZoneSystemUtils.readZones(ConfigGroup.getInputFileURL(context, zonalSystemParams.zonesXmlFile), ConfigGroup.getInputFileURL(context, zonalSystemParams.zonesShpFile)); // TODO No conversion of SRS is done - this.linkToZone = NetworkWithZonesUtils.createLinkToZoneMap(network, new ZoneFinderImpl(zones, zonalSystemParams.expansionDistance)); + this.linkToZone = ZoneSystemUtils.createLinkToZoneMap(network, new ZoneFinderImpl(zones, zonalSystemParams.expansionDistance)); // FIXME zonal system used in RuleBasedTaxiOptim (for registers) should be equivalent to // the zones used in ZonalTaxiOptim (for dispatching) diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerParams.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerParams.java index 60fa239ef4e..7076e48acbf 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerParams.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerParams.java @@ -20,6 +20,7 @@ package org.matsim.contrib.taxi.optimizer.zonal; import org.matsim.contrib.taxi.optimizer.AbstractTaxiOptimizerParams; +import org.matsim.contrib.taxi.optimizer.assignment.AssignmentTaxiOptimizerParams; import org.matsim.contrib.taxi.optimizer.rules.RuleBasedTaxiOptimizerParams; import org.matsim.contrib.zone.ZonalSystemParams; import org.matsim.core.config.ConfigGroup; @@ -32,26 +33,17 @@ public final class ZonalTaxiOptimizerParams extends AbstractTaxiOptimizerParams public ZonalTaxiOptimizerParams() { super(SET_NAME, false, false); + initSingletonParameterSets(); } - @Override - public ConfigGroup createParameterSet(String type) { - return switch (type) { - case RuleBasedTaxiOptimizerParams.SET_NAME -> new RuleBasedTaxiOptimizerParams(); - case ZonalSystemParams.SET_NAME -> new ZonalSystemParams(); - default -> super.createParameterSet(type); - }; - } - - @Override - public void addParameterSet(ConfigGroup set) { - switch (set.getName()) { - case RuleBasedTaxiOptimizerParams.SET_NAME -> - ruleBasedTaxiOptimizerParams = (RuleBasedTaxiOptimizerParams)set; - case ZonalSystemParams.SET_NAME -> zonalSystemParams = (ZonalSystemParams)set; - } - - super.addParameterSet(set); + private void initSingletonParameterSets() { + //insertion search params (one of: extensive, selective, repeated selective) + addDefinition(RuleBasedTaxiOptimizerParams.SET_NAME, RuleBasedTaxiOptimizerParams::new, + () -> ruleBasedTaxiOptimizerParams, + params -> ruleBasedTaxiOptimizerParams = (RuleBasedTaxiOptimizerParams)params); + addDefinition(ZonalSystemParams.SET_NAME, ZonalSystemParams::new, + () -> zonalSystemParams, + params -> zonalSystemParams = (ZonalSystemParams)params); } public ZonalSystemParams getZonalSystemParams() { diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/run/TaxiConfigGroup.java b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/run/TaxiConfigGroup.java index daaaf36f914..5e76b1a8f41 100644 --- a/contribs/taxi/src/main/java/org/matsim/contrib/taxi/run/TaxiConfigGroup.java +++ b/contribs/taxi/src/main/java/org/matsim/contrib/taxi/run/TaxiConfigGroup.java @@ -36,7 +36,7 @@ import org.matsim.contrib.taxi.optimizer.fifo.FifoTaxiOptimizerParams; import org.matsim.contrib.taxi.optimizer.rules.RuleBasedTaxiOptimizerParams; import org.matsim.contrib.taxi.optimizer.zonal.ZonalTaxiOptimizerParams; -import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; +import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.Config; import com.google.common.base.Preconditions; diff --git a/contribs/taxi/src/test/java/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT.java b/contribs/taxi/src/test/java/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT.java index 5e029c8a29e..7138bf21c82 100644 --- a/contribs/taxi/src/test/java/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT.java +++ b/contribs/taxi/src/test/java/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT.java @@ -26,6 +26,7 @@ import org.matsim.core.config.ConfigUtils; import org.matsim.core.events.EventsUtils; import org.matsim.core.population.PopulationUtils; +import org.matsim.core.population.routes.PopulationComparison; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; @@ -67,8 +68,9 @@ private void runScenario(String configPath) { Population actual = PopulationUtils.createPopulation(ConfigUtils.createConfig()); PopulationUtils.readPopulation(actual, utils.getOutputDirectory() + "/output_plans.xml.gz"); - boolean result = PopulationUtils.comparePopulations(expected, actual); - Assertions.assertTrue(result); + PopulationComparison populationComparison = new PopulationComparison(); + PopulationComparison.Result result = populationComparison.compare(expected, actual); + Assertions.assertEquals(PopulationComparison.Result.equal, result); } { String expected = utils.getInputDirectory() + "/output_events.xml.gz"; diff --git a/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/TaxiOptimizerTests.java b/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/TaxiOptimizerTests.java index 3a3800467af..28dd7087e40 100644 --- a/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/TaxiOptimizerTests.java +++ b/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/TaxiOptimizerTests.java @@ -25,13 +25,16 @@ import org.junit.jupiter.api.Assertions; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.taxi.benchmark.RunTaxiBenchmark; import org.matsim.contrib.taxi.run.MultiModeTaxiConfigGroup; import org.matsim.contrib.taxi.run.TaxiConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; import org.matsim.core.config.ConfigUtils; import org.matsim.core.events.EventsUtils; import org.matsim.core.population.PopulationUtils; +import org.matsim.core.population.routes.PopulationComparison; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; @@ -40,9 +43,15 @@ public class TaxiOptimizerTests { public static void runBenchmark(boolean vehicleDiversion, AbstractTaxiOptimizerParams taxiOptimizerParams, MatsimTestUtils utils) { Id.resetCaches(); + + DvrpConfigGroup dvrpConfig = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfig.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + + // mielec taxi mini benchmark contains only the morning peak (6:00 - 12:00) that is shifted by -6 hours (i.e. 0:00 - 6:00). URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_taxi_mini_benchmark_config.xml"); - var config = ConfigUtils.loadConfig(configUrl, new MultiModeTaxiConfigGroup(), new DvrpConfigGroup()); + var config = ConfigUtils.loadConfig(configUrl, new MultiModeTaxiConfigGroup(), dvrpConfig); config.controller().setOutputDirectory(utils.getOutputDirectory()); TaxiConfigGroup taxiCfg = TaxiConfigGroup.getSingleModeTaxiConfig(config); @@ -64,8 +73,9 @@ public static void runBenchmark(boolean vehicleDiversion, AbstractTaxiOptimizerP Population actual = PopulationUtils.createPopulation(ConfigUtils.createConfig()); PopulationUtils.readPopulation(actual, utils.getOutputDirectory() + "/output_plans.xml.gz"); - boolean result = PopulationUtils.comparePopulations(expected, actual); - Assertions.assertTrue(result); + PopulationComparison populationComparison = new PopulationComparison(); + PopulationComparison.Result result = populationComparison.compare(expected, actual); + Assertions.assertEquals(PopulationComparison.Result.equal, result); } { String expected = utils.getInputDirectory() + "/output_events.xml.gz"; diff --git a/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT.java b/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT.java index f70fc0d0d97..8189364d3ee 100644 --- a/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT.java +++ b/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT.java @@ -23,7 +23,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.taxi.optimizer.rules.RuleBasedRequestInserter.Goal; +import org.matsim.core.config.ConfigGroup; import org.matsim.testcases.MatsimTestUtils; public class RuleBasedTaxiOptimizerIT { @@ -36,7 +38,8 @@ void testRuleBased_dse() { params.goal = Goal.DEMAND_SUPPLY_EQUIL; params.nearestRequestsLimit = 99999; params.nearestVehiclesLimit = 99999; - params.cellSize = 99999.; + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) params.getZoneSystemParams(); + zoneParams.cellSize = 99999.; runBenchmark(false, params, utils); } @@ -46,7 +49,8 @@ void testRuleBased_minWaitTime() { params.goal = Goal.MIN_WAIT_TIME; params.nearestRequestsLimit = 10; params.nearestVehiclesLimit = 10; - params.cellSize = 1000.; + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) params.getZoneSystemParams(); + zoneParams.cellSize = 1000.; runBenchmark(false, params, utils); } @@ -56,7 +60,8 @@ void testRuleBased_minPickupTime() { params.goal = Goal.MIN_PICKUP_TIME; params.nearestRequestsLimit = 1; params.nearestVehiclesLimit = 1; - params.cellSize = 100.; + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) params.getZoneSystemParams(); + zoneParams.cellSize = 100.; runBenchmark(false, params, utils); } } diff --git a/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT.java b/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT.java index 575f26a4603..87de0493150 100644 --- a/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT.java +++ b/contribs/taxi/src/test/java/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.taxi.optimizer.rules.RuleBasedRequestInserter.Goal; import org.matsim.contrib.taxi.optimizer.rules.RuleBasedTaxiOptimizerParams; import org.matsim.contrib.zone.ZonalSystemParams; @@ -39,7 +40,8 @@ void testZonal_dse() { rbParams.goal = Goal.DEMAND_SUPPLY_EQUIL; rbParams.nearestRequestsLimit = 99999; rbParams.nearestVehiclesLimit = 99999; - rbParams.cellSize = 99999.; + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) rbParams.getZoneSystemParams(); + zoneParams.cellSize = 99999.; ZonalSystemParams zsParams = new ZonalSystemParams(); zsParams.zonesShpFile = "zones/zones.shp"; @@ -59,7 +61,8 @@ void testZonal_minWaitTime() { rbParams.goal = Goal.MIN_WAIT_TIME; rbParams.nearestRequestsLimit = 10; rbParams.nearestVehiclesLimit = 10; - rbParams.cellSize = 1000.; + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) rbParams.getZoneSystemParams(); + zoneParams.cellSize = 1000.; ZonalSystemParams zsParams = new ZonalSystemParams(); zsParams.zonesShpFile = "zones/zones.shp"; diff --git a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_events.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_events.xml.gz index 625f9d0073a..fa87157f1e8 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_events.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_events.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_plans.xml.gz index d0b3f49d5b5..6926e4e0d13 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testAssignment/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testOneTaxi/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testOneTaxi/output_plans.xml.gz index a423bf11d2c..795113f0133 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testOneTaxi/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testOneTaxi/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_events.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_events.xml.gz index 625f9d0073a..fa87157f1e8 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_events.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_events.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_plans.xml.gz index d0b3f49d5b5..6926e4e0d13 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/etaxi/run/RunETaxiScenarioIT/testRuleBased/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_arrivalTime/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_arrivalTime/output_plans.xml.gz index 7f3683fe733..0eabb684e27 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_arrivalTime/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_arrivalTime/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_dse/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_dse/output_plans.xml.gz index c5960ee0794..98b20327ea6 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_dse/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_dse/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_pickupTime/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_pickupTime/output_plans.xml.gz index ad3aea06944..195366627e9 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_pickupTime/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_pickupTime/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_totalWaitTime/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_totalWaitTime/output_plans.xml.gz index eabe3b28dd2..55ecec4654d 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_totalWaitTime/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/assignment/AssignmentTaxiOptimizerIT/testAssignment_totalWaitTime/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/fifo/FifoTaxiOptimizerIT/testFifo/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/fifo/FifoTaxiOptimizerIT/testFifo/output_plans.xml.gz index 4c532baa5c5..41a30561323 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/fifo/FifoTaxiOptimizerIT/testFifo/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/fifo/FifoTaxiOptimizerIT/testFifo/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_dse/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_dse/output_plans.xml.gz index ed20dc628fc..6d434d623df 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_dse/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_dse/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_events.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_events.xml.gz index dc301f3138d..c74ecd38aba 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_events.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_events.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_plans.xml.gz index 35560847305..0b5b8e4c2c9 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minPickupTime/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minWaitTime/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minWaitTime/output_plans.xml.gz index e09d65480a9..8c1334661d2 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minWaitTime/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/rules/RuleBasedTaxiOptimizerIT/testRuleBased_minWaitTime/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_dse/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_dse/output_plans.xml.gz index fc1ffd599e5..f09eb9f894b 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_dse/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_dse/output_plans.xml.gz differ diff --git a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_minWaitTime/output_plans.xml.gz b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_minWaitTime/output_plans.xml.gz index acddf468ac1..9df1e6b1a8a 100644 Binary files a/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_minWaitTime/output_plans.xml.gz and b/contribs/taxi/test/input/org/matsim/contrib/taxi/optimizer/zonal/ZonalTaxiOptimizerIT/testZonal_minWaitTime/output_plans.xml.gz differ diff --git a/contribs/vsp/src/test/java/org/matsim/integration/drtAndPt/PtAlongALine2Test.java b/contribs/vsp/src/test/java/org/matsim/integration/drtAndPt/PtAlongALine2Test.java index 3a1e217d4f4..3e00dd03d50 100644 --- a/contribs/vsp/src/test/java/org/matsim/integration/drtAndPt/PtAlongALine2Test.java +++ b/contribs/vsp/src/test/java/org/matsim/integration/drtAndPt/PtAlongALine2Test.java @@ -23,6 +23,7 @@ import org.matsim.api.core.v01.population.PlanElement; import org.matsim.api.core.v01.population.Population; import org.matsim.api.core.v01.population.PopulationFactory; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; import org.matsim.contrib.drt.routing.DrtRoute; import org.matsim.contrib.drt.routing.DrtRouteFactory; @@ -35,6 +36,7 @@ import org.matsim.contrib.dvrp.run.DvrpQSimComponents; import org.matsim.contrib.otfvis.OTFVisLiveModule; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.ScoringConfigGroup.ModeParams; import org.matsim.core.config.groups.RoutingConfigGroup; @@ -220,6 +222,8 @@ void testPtAlongALineWithRaptorAndDrtServiceArea() { DvrpConfigGroup dvrpConfig = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); dvrpConfig.networkModes = ImmutableSet.copyOf(Arrays.asList(TransportMode.drt, "drt2", "drt3")); + ConfigGroup zoneParams = dvrpConfig.getTravelTimeMatrixParams().createParameterSet(SquareGridZoneSystemParams.SET_NAME); + dvrpConfig.getTravelTimeMatrixParams().addParameterSet(zoneParams); MultiModeDrtConfigGroup mm = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); { diff --git a/contribs/vsp/src/test/java/playground/vsp/flowEfficiency/HierarchicalFLowEfficiencyCalculatorTest.java b/contribs/vsp/src/test/java/playground/vsp/flowEfficiency/HierarchicalFLowEfficiencyCalculatorTest.java index 4e11d41f780..aaf0d796e91 100644 --- a/contribs/vsp/src/test/java/playground/vsp/flowEfficiency/HierarchicalFLowEfficiencyCalculatorTest.java +++ b/contribs/vsp/src/test/java/playground/vsp/flowEfficiency/HierarchicalFLowEfficiencyCalculatorTest.java @@ -15,6 +15,7 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.api.core.v01.population.PopulationFactory; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; import org.matsim.contrib.drt.routing.DrtRoute; import org.matsim.contrib.drt.routing.DrtRouteFactory; import org.matsim.contrib.drt.run.DrtConfigGroup; @@ -27,6 +28,7 @@ import org.matsim.contrib.dvrp.run.DvrpQSimComponents; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; @@ -87,7 +89,11 @@ public void simulate(){ URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "eight_shared_taxi_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, new DvrpConfigGroup(), new MultiModeDrtConfigGroup(), new OTFVisConfigGroup()); + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + ConfigGroup zoneParams = dvrpConfigGroup.getTravelTimeMatrixParams().createParameterSet(SquareGridZoneSystemParams.SET_NAME); + dvrpConfigGroup.getTravelTimeMatrixParams().addParameterSet(zoneParams); + + Config config = ConfigUtils.loadConfig(configUrl, dvrpConfigGroup, new MultiModeDrtConfigGroup(), new OTFVisConfigGroup()); config.controller().setOutputDirectory(utils.getOutputDirectory()); config.qsim().setEndTime(4*3600); diff --git a/examples/scenarios/dvrp-grid/multi_mode_one_shared_taxi_config.xml b/examples/scenarios/dvrp-grid/multi_mode_one_shared_taxi_config.xml index 4c218d03a23..bb0c4beed1f 100644 --- a/examples/scenarios/dvrp-grid/multi_mode_one_shared_taxi_config.xml +++ b/examples/scenarios/dvrp-grid/multi_mode_one_shared_taxi_config.xml @@ -3,7 +3,9 @@ - + + + diff --git a/examples/scenarios/dvrp-grid/one_shared_taxi_config.xml b/examples/scenarios/dvrp-grid/one_shared_taxi_config.xml index 4e59438bbff..6f727d250e8 100644 --- a/examples/scenarios/dvrp-grid/one_shared_taxi_config.xml +++ b/examples/scenarios/dvrp-grid/one_shared_taxi_config.xml @@ -3,7 +3,9 @@ - + + + diff --git a/examples/scenarios/kelheim/config-with-drt.xml b/examples/scenarios/kelheim/config-with-drt.xml index 76020e10903..7657d679502 100644 --- a/examples/scenarios/kelheim/config-with-drt.xml +++ b/examples/scenarios/kelheim/config-with-drt.xml @@ -267,11 +267,11 @@ - - - - - + + + + + - - - - - + + + + + - + + + diff --git a/examples/scenarios/mielec/mielec_drt_config.xml b/examples/scenarios/mielec/mielec_drt_config.xml index db2a8763ade..403207359f5 100644 --- a/examples/scenarios/mielec/mielec_drt_config.xml +++ b/examples/scenarios/mielec/mielec_drt_config.xml @@ -16,8 +16,9 @@ - - + + + diff --git a/examples/scenarios/mielec/mielec_edrt_config.xml b/examples/scenarios/mielec/mielec_edrt_config.xml index fdb3bd3c0f6..5ab35db759d 100644 --- a/examples/scenarios/mielec/mielec_edrt_config.xml +++ b/examples/scenarios/mielec/mielec_edrt_config.xml @@ -3,7 +3,9 @@ - + + + @@ -20,8 +22,9 @@ - - + + + diff --git a/examples/scenarios/mielec/mielec_multiModeEdrt_config.xml b/examples/scenarios/mielec/mielec_multiModeEdrt_config.xml index aa5d99b31a2..2d20b7b5756 100644 --- a/examples/scenarios/mielec/mielec_multiModeEdrt_config.xml +++ b/examples/scenarios/mielec/mielec_multiModeEdrt_config.xml @@ -3,7 +3,9 @@ - + + + @@ -21,8 +23,9 @@ - - + + + @@ -46,8 +49,9 @@ - - + + + diff --git a/examples/scenarios/mielec/mielec_serviceArea_based_drt_config.xml b/examples/scenarios/mielec/mielec_serviceArea_based_drt_config.xml index d2bdd9305f7..ceb0ca0a3cb 100644 --- a/examples/scenarios/mielec/mielec_serviceArea_based_drt_config.xml +++ b/examples/scenarios/mielec/mielec_serviceArea_based_drt_config.xml @@ -3,7 +3,9 @@ - + + + @@ -22,8 +24,9 @@ - - + + + diff --git a/examples/scenarios/mielec/mielec_stop_based_drt_config.xml b/examples/scenarios/mielec/mielec_stop_based_drt_config.xml index dd3df82fa60..5b9da8ef8d0 100644 --- a/examples/scenarios/mielec/mielec_stop_based_drt_config.xml +++ b/examples/scenarios/mielec/mielec_stop_based_drt_config.xml @@ -3,7 +3,9 @@ - + + + @@ -26,8 +28,9 @@ - - + + + diff --git a/matsim/src/main/java/org/matsim/core/population/routes/PopulationComparison.java b/matsim/src/main/java/org/matsim/core/population/routes/PopulationComparison.java index d6cc75e3923..8dac954aa3f 100644 --- a/matsim/src/main/java/org/matsim/core/population/routes/PopulationComparison.java +++ b/matsim/src/main/java/org/matsim/core/population/routes/PopulationComparison.java @@ -2,12 +2,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.Plan; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.api.core.v01.population.Population; +import org.matsim.api.core.v01.population.*; import java.util.Iterator; +import java.util.List; public class PopulationComparison{ public enum Result { equal, notEqual } @@ -39,7 +37,8 @@ public Result compare( Population population1, Population population2 ){ } Plan plan1 = person1.getSelectedPlan(); Plan plan2 = person2.getSelectedPlan(); - if ( Math.abs( plan1.getScore() - plan2.getScore() ) > 100.*Double.MIN_VALUE ) { + if ( Math.abs( plan1.getScore() - plan2.getScore() ) > 100.*Double.MIN_VALUE || + !equals(plan1.getPlanElements(), plan2.getPlanElements())) { double maxScore = Double.NEGATIVE_INFINITY; for( Plan plan : person2.getPlans() ){ @@ -61,10 +60,70 @@ public Result compare( Population population1, Population population2 ){ log.warn( "" ); } - } + return result ; + } - return result ; + public static boolean equals(List planElements, + List planElements2) { + int nElements = planElements.size(); + if (nElements != planElements2.size()) { + return false; + } else { + for (int i = 0; i < nElements; i++) { + if (!equals(planElements.get(i), planElements2.get(i))) { + return false; + } + } + } + return true; + } + + /* Warning: This is NOT claimed to be correct. (It isn't.) + * + */ + private static boolean equals(PlanElement o1, PlanElement o2) { + if (o1 instanceof Leg) { + if (o2 instanceof Leg) { + Leg leg1 = (Leg) o1; + Leg leg2 = (Leg) o2; + if (!leg1.getDepartureTime().equals(leg2.getDepartureTime())) { + return false; + } + if (!leg1.getMode().equals(leg2.getMode())) { + return false; + } + if (!leg1.getTravelTime().equals(leg2.getTravelTime())) { + return false; + } + } else { + return false; + } + } else if (o1 instanceof Activity) { + if (o2 instanceof Activity) { + Activity activity1 = (Activity) o1; + Activity activity2 = (Activity) o2; + if (activity1.getEndTime().isUndefined() ^ activity2.getEndTime().isUndefined()) { + return false; + } + if (activity1.getEndTime().isDefined() && activity1.getEndTime().seconds() + != activity2.getEndTime().seconds()) { + return false; + } + if (activity1.getStartTime().isUndefined() ^ activity2.getStartTime().isUndefined()) { + return false; + } + if (activity1.getStartTime().isDefined() && activity1.getStartTime().seconds() + != activity2.getStartTime().seconds()) { + return false; + } + } else { + return false; + } + } else { + throw new RuntimeException ("Unexpected PlanElement"); + } + return true; } } diff --git a/matsim/src/main/java/org/matsim/utils/gis/shp2matsim/ShpGeometryUtils.java b/matsim/src/main/java/org/matsim/utils/gis/shp2matsim/ShpGeometryUtils.java index 4c5d56e9f98..77cc026e3f7 100644 --- a/matsim/src/main/java/org/matsim/utils/gis/shp2matsim/ShpGeometryUtils.java +++ b/matsim/src/main/java/org/matsim/utils/gis/shp2matsim/ShpGeometryUtils.java @@ -25,8 +25,10 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygonal; import org.locationtech.jts.geom.prep.PreparedGeometry; import org.locationtech.jts.geom.prep.PreparedGeometryFactory; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.matsim.api.core.v01.Coord; import org.matsim.core.utils.geometry.geotools.MGC; import org.matsim.core.utils.gis.GeoFileReader; @@ -47,6 +49,13 @@ public static List loadPreparedGeometries(URL url) { .collect(Collectors.toList()); } + public static List loadPreparedPolygons(URL url) { + return GeoFileReader.getAllFeatures(url) + .stream() + .map(sf -> new PreparedPolygon((Polygonal)sf.getDefaultGeometry())) + .collect(Collectors.toList()); + } + public static boolean isCoordInGeometries(Coord coord, List geometries) { Point point = MGC.coord2Point(coord); return geometries.stream().anyMatch(g -> g.contains(point)); diff --git a/matsim/src/test/java/org/matsim/population/algorithms/ChooseRandomLegModeForSubtourTest.java b/matsim/src/test/java/org/matsim/population/algorithms/ChooseRandomLegModeForSubtourTest.java index 93986fe0404..0bb065a1ee5 100644 --- a/matsim/src/test/java/org/matsim/population/algorithms/ChooseRandomLegModeForSubtourTest.java +++ b/matsim/src/test/java/org/matsim/population/algorithms/ChooseRandomLegModeForSubtourTest.java @@ -46,6 +46,7 @@ import org.matsim.core.population.PopulationUtils; import org.matsim.core.population.algorithms.ChooseRandomLegModeForSubtour; import org.matsim.core.population.algorithms.PermissibleModesCalculator; +import org.matsim.core.population.routes.PopulationComparison; import org.matsim.core.replanning.modules.SubtourModeChoice; import org.matsim.core.router.MainModeIdentifierImpl; import org.matsim.core.router.TripStructureUtils; @@ -291,7 +292,7 @@ private void testSubTourMutationToCar(Network network, double probaForRandomSing Plan plan = createPlan(network, activityChainString, originalMode); Plan originalPlan = PopulationUtils.createPlan(person); PopulationUtils.copyFromTo(plan, originalPlan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); testee.run(plan); assertSubTourMutated(plan, originalPlan, expectedMode, false); } @@ -307,7 +308,7 @@ private void testSubTourMutationToCar(ActivityFacilities facilities, double prob Plan plan = createPlan(facilities, activityChainString, originalMode); Plan originalPlan = PopulationUtils.createPlan(person); PopulationUtils.copyFromTo(plan, originalPlan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); testee.run(plan); assertSubTourMutated(plan, originalPlan, expectedMode, true); } @@ -322,9 +323,9 @@ private void testUnknownModeDoesntMutate(Network network, double probaForRandomS Plan plan = createPlan(network, activityChainString, originalMode); Plan originalPlan = PopulationUtils.createPlan(person); PopulationUtils.copyFromTo(plan, originalPlan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); testee.run(plan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); } } @@ -337,9 +338,9 @@ private void testUnknownModeDoesntMutate(ActivityFacilities facilities, double p Plan plan = createPlan(facilities, activityChainString, originalMode); Plan originalPlan = PopulationUtils.createPlan(person); PopulationUtils.copyFromTo(plan, originalPlan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); testee.run(plan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); } } @@ -353,7 +354,7 @@ private void testSubTourMutationToPt(ActivityFacilities facilities, double proba Plan plan = createPlan(facilities, activityChainString, originalMode); Plan originalPlan = PopulationUtils.createPlan(person); PopulationUtils.copyFromTo(plan, originalPlan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); testee.run(plan); assertSubTourMutated(plan, originalPlan, expectedMode, true); } @@ -369,7 +370,7 @@ private void testSubTourMutationToPt(Network network, double probaForRandomSingl Plan plan = createPlan(network, activityChainString, originalMode); Plan originalPlan = PopulationUtils.createPlan(person); PopulationUtils.copyFromTo(plan, originalPlan); - assertTrue(TestsUtil.equals(plan.getPlanElements(), originalPlan.getPlanElements())); + assertTrue(PopulationComparison.equals(plan.getPlanElements(), originalPlan.getPlanElements())); testee.run(plan); assertSubTourMutated(plan, originalPlan, expectedMode, false); } diff --git a/matsim/src/test/java/org/matsim/population/algorithms/TestsUtil.java b/matsim/src/test/java/org/matsim/population/algorithms/TestsUtil.java index 2c18cc6e194..34364d60d6f 100644 --- a/matsim/src/test/java/org/matsim/population/algorithms/TestsUtil.java +++ b/matsim/src/test/java/org/matsim/population/algorithms/TestsUtil.java @@ -68,66 +68,5 @@ static Plan createPlanFromLinks(Network layer, Person person, String mode, Strin return plan; } - /* Warning: This is NOT claimed to be correct. (It isn't.) - * - */ - static boolean equals(PlanElement o1, PlanElement o2) { - if (o1 instanceof Leg) { - if (o2 instanceof Leg) { - Leg leg1 = (Leg) o1; - Leg leg2 = (Leg) o2; - if (!leg1.getDepartureTime().equals(leg2.getDepartureTime())) { - return false; - } - if (!leg1.getMode().equals(leg2.getMode())) { - return false; - } - if (!leg1.getTravelTime().equals(leg2.getTravelTime())) { - return false; - } - } else { - return false; - } - } else if (o1 instanceof Activity) { - if (o2 instanceof Activity) { - Activity activity1 = (Activity) o1; - Activity activity2 = (Activity) o2; - if (activity1.getEndTime().isUndefined() ^ activity2.getEndTime().isUndefined()) { - return false; - } - if (activity1.getEndTime().isDefined() && activity1.getEndTime().seconds() - != activity2.getEndTime().seconds()) { - return false; - } - if (activity1.getStartTime().isUndefined() ^ activity2.getStartTime().isUndefined()) { - return false; - } - if (activity1.getStartTime().isDefined() && activity1.getStartTime().seconds() - != activity2.getStartTime().seconds()) { - return false; - } - } else { - return false; - } - } else { - throw new RuntimeException ("Unexpected PlanElement"); - } - return true; - } - - public static boolean equals(List planElements, - List planElements2) { - int nElements = planElements.size(); - if (nElements != planElements2.size()) { - return false; - } else { - for (int i = 0; i < nElements; i++) { - if (!equals(planElements.get(i), planElements2.get(i))) { - return false; - } - } - } - return true; - } }