From 213fae045ebc45a9adda8941d87b7afee170a338 Mon Sep 17 00:00:00 2001 From: nkuehnel Date: Sat, 27 Jul 2024 21:26:29 +0200 Subject: [PATCH] optimize h3 zone system initialization; move h3 test to common module --- .../zones/systems/grid/h3/H3ZoneSystem.java | 63 ++++++++++--------- .../grid/square/SquareGridZoneSystem.java | 4 +- .../systems/h3}/H3DrtZonalSystemTest.java | 62 +++++++++--------- 3 files changed, 65 insertions(+), 64 deletions(-) rename contribs/{drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone => common/src/test/java/org/matsim/contrib/common/zones/systems/h3}/H3DrtZonalSystemTest.java (55%) 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 index e9c84bccc4a..286bc9a09ca 100644 --- 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 @@ -13,8 +13,12 @@ import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.core.utils.geometry.transformations.TransformationFactory; -import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * @author nkuehnel / MOIA @@ -39,41 +43,38 @@ public H3ZoneSystem(String crs, int resolution, Network network, Predicate this.resolution = resolution; this.network = network; this.filter = filter; - this.network.getLinks().values().forEach(l -> getZoneForCoord(l.getToNode().getCoord())); + init(); } - - @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 init() { + Map> linksToH3 = + this.network.getLinks().values() + .stream() + .collect(Collectors.groupingBy(link -> getH3Cell(link.getToNode().getCoord()))); + for (Map.Entry> linksH3 : linksToH3.entrySet()) { + Optional maybeZone = createZone(linksH3.getKey()); + maybeZone.ifPresent(z -> { + zones.put(z.getId(), z); + zoneToLinksMap.put(z.getId(), linksH3.getValue()); + }); } } - 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 Optional createZone(Long h3) { + Optional zone = H3Utils.createZone(h3, fromLatLong); + if(zone.isPresent() && filter.test(zone.get())) { + return zone; } + return Optional.empty(); + } + + @Override + public Optional getZoneForCoord(Coord coord) { + long h3Address = getH3Cell(coord); + Id zoneId = Id.create(h3Address, Zone.class); + // create new zone if absent, should not be linked to existing links in the network, + // as all of them are covered in the init() phase. + return Optional.ofNullable(zones.computeIfAbsent(zoneId, id -> createZone(h3Address).orElse(null))); } private long getH3Cell(Coord coord) { @@ -106,4 +107,4 @@ public List getLinksForZoneId(Id zone) { public Map, Zone> getZones() { return Collections.unmodifiableMap(zones); } -} +} \ No newline at end of file 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 index f11fa58f614..b1319fed1a9 100644 --- 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 @@ -66,11 +66,11 @@ public SquareGridZoneSystem(Network network, double cellSize, Predicate zo } 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; + Preconditions.checkArgument(!network.getNodes().isEmpty(), "Cannot create SquareGrid if no nodes"); + initBounds(); this.rows = Math.max(1, (int) Math.ceil((maxY - minY) / cellSize)); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone/H3DrtZonalSystemTest.java b/contribs/common/src/test/java/org/matsim/contrib/common/zones/systems/h3/H3DrtZonalSystemTest.java similarity index 55% rename from contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone/H3DrtZonalSystemTest.java rename to contribs/common/src/test/java/org/matsim/contrib/common/zones/systems/h3/H3DrtZonalSystemTest.java index 3724d5d8eac..723e4026825 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/h3/drtZone/H3DrtZonalSystemTest.java +++ b/contribs/common/src/test/java/org/matsim/contrib/common/zones/systems/h3/H3DrtZonalSystemTest.java @@ -18,7 +18,7 @@ * *********************************************************************** * */ -package org.matsim.contrib.drt.extension.h3.drtZone; +package org.matsim.contrib.common.zones.systems.h3; import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; @@ -48,20 +48,20 @@ void test_Holzkirchen_Resolution3() { Network network = getNetwork(); String crs = TransformationFactory.DHDN_GK4; int resolution = 3; - ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); + ZoneSystem zoneSystem = new H3ZoneSystem(crs, resolution, network, z -> true); - assertThat(drtZonalSystem.getZones().containsKey(createZoneId("590526392240701439"))).isTrue(); + assertThat(zoneSystem.getZones().containsKey(createZoneId("590526392240701439"))).isTrue(); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("590526667118608383")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("590526667118608383")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("590526667118608383")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("590526667118608383")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("590526392240701439")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("590526392240701439")); //check all links are mapped for (Link link : network.getLinks().values()) { - assertNotNull(drtZonalSystem.getZoneForLinkId(link.getId())); + assertNotNull(zoneSystem.getZoneForLinkId(link.getId())); } } @@ -71,23 +71,23 @@ void test_Holzkirchen_Resolution5() { String crs = TransformationFactory.DHDN_GK4; int resolution = 5; - ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); + ZoneSystem zoneSystem = 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(); + assertThat(zoneSystem.getZones().containsKey(createZoneId("599533579684282367"))).isTrue(); + assertThat(zoneSystem.getZones().containsKey(createZoneId("599533826644901887"))).isTrue(); + assertThat(zoneSystem.getZones().containsKey(createZoneId("599533499153645567"))).isTrue(); + assertThat(zoneSystem.getZones().containsKey(createZoneId("599533503448612863"))).isTrue(); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("599533826644901887")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("599533826644901887")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("599533503448612863")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("599533503448612863")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("599533579684282367")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("599533579684282367")); //check all links are mapped for (Link link : network.getLinks().values()) { - assertNotNull(drtZonalSystem.getZoneForLinkId(link.getId())); + assertNotNull(zoneSystem.getZoneForLinkId(link.getId())); } } @@ -97,18 +97,18 @@ void test_Holzkirchen_Resolution6() { String crs = TransformationFactory.DHDN_GK4; int resolution = 6; - ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); + ZoneSystem zoneSystem = new H3ZoneSystem(crs, resolution, network, z -> true); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("604037425601183743")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("604037425601183743")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("604037102136459263")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("604037102136459263")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("604037178372128767")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("604037178372128767")); //check all links are mapped for (Link link : network.getLinks().values()) { - assertNotNull(drtZonalSystem.getZoneForLinkId(link.getId())); + assertNotNull(zoneSystem.getZoneForLinkId(link.getId())); } } @@ -117,18 +117,18 @@ void test_Holzkirchen_Resolution10() { Network network = getNetwork(); String crs = TransformationFactory.DHDN_GK4; int resolution = 10; - ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); + ZoneSystem zoneSystem = new H3ZoneSystem(crs, resolution, network, z -> true); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("622051824027533311")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("622051824027533311")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("622051500514213887")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("622051500514213887")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("622051576862081023")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("622051576862081023")); //check all links are mapped for (Link link : network.getLinks().values()) { - assertNotNull(drtZonalSystem.getZoneForLinkId(link.getId())); + assertNotNull(zoneSystem.getZoneForLinkId(link.getId())); } } @@ -138,19 +138,19 @@ void test_Holzkirchen_Resolution12() { String crs = TransformationFactory.DHDN_GK4; int resolution = 12; - ZoneSystem drtZonalSystem = new H3ZoneSystem(crs, resolution, network, z -> true); + ZoneSystem zoneSystem = new H3ZoneSystem(crs, resolution, network, z -> true); // center of Holzkirchen - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("631059023282267135")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(358598)).orElseThrow().getId()).isEqualTo(createZoneId("631059023282267135")); // Thanning (Western border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("631058699768943103")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(78976)).orElseThrow().getId()).isEqualTo(createZoneId("631058699768943103")); // between Gross- and Kleinpienzenau (Southeastern border of network) - assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("631058776116789759")); + assertThat(zoneSystem.getZoneForLinkId(Id.createLinkId(59914)).orElseThrow().getId()).isEqualTo(createZoneId("631058776116789759")); //check all links are mapped for (Link link : network.getLinks().values()) { - assertNotNull(drtZonalSystem.getZoneForLinkId(link.getId())); + assertNotNull(zoneSystem.getZoneForLinkId(link.getId())); } }