Skip to content

Commit 551d484

Browse files
author
Laurens de Mooij
committed
Merged PR 39310: #65206 Add option to expand network bounding box, add Prorail profile
#65206 Fix issues with nodes on network boundary, add Prorail profile Related work items: #65206
1 parent c3f584f commit 551d484

File tree

7 files changed

+205
-5
lines changed

7 files changed

+205
-5
lines changed

map-matcher-library/src/main/java/nu/ndw/nls/routingmapmatcher/domain/model/RoutingNetwork.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@ public class RoutingNetwork {
1717
private final String networkNameAndVersion;
1818
private final Supplier<Iterator<Link>> linkSupplier;
1919
private final Instant dataDate;
20+
@Builder.Default
21+
private final boolean expandBounds = false;
22+
2023
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package nu.ndw.nls.routingmapmatcher.graphhopper;
2+
3+
4+
import com.graphhopper.coll.LongLongMap;
5+
import com.graphhopper.routing.util.EncodingManager;
6+
import com.graphhopper.routing.util.parsers.TagParser;
7+
import com.graphhopper.storage.BaseGraph;
8+
import java.util.Arrays;
9+
import java.util.Iterator;
10+
import java.util.List;
11+
import java.util.OptionalInt;
12+
import java.util.function.Supplier;
13+
import lombok.extern.slf4j.Slf4j;
14+
import nu.ndw.nls.routingmapmatcher.domain.model.Link;
15+
import org.locationtech.jts.geom.Coordinate;
16+
17+
@Slf4j
18+
public class ExpandedBoundsNetworkReader extends NetworkReader {
19+
20+
private static final double BOUND_EXPAND = .000001;
21+
22+
public ExpandedBoundsNetworkReader(BaseGraph baseGraph, EncodingManager encodingManager,
23+
Supplier<Iterator<Link>> linkSupplier, List<TagParser> vehicleTagParsers,
24+
LongLongMap nodeIdToInternalNodeIdMap) {
25+
super(baseGraph, encodingManager, linkSupplier, vehicleTagParsers, nodeIdToInternalNodeIdMap);
26+
}
27+
28+
@Override
29+
protected OptionalInt addLink(Link link) {
30+
OptionalInt edgeKey = super.addLink(link);
31+
if(edgeKey.isPresent()) {
32+
Coordinate[] coordinates = link.getGeometry().getCoordinates();
33+
Arrays.stream(coordinates).forEach(coord -> {
34+
baseGraph.getBounds().update(coord.y + BOUND_EXPAND, coord.x + BOUND_EXPAND);
35+
baseGraph.getBounds().update(coord.y - BOUND_EXPAND, coord.x - BOUND_EXPAND);
36+
});
37+
}
38+
return edgeKey;
39+
}
40+
}

map-matcher-library/src/main/java/nu/ndw/nls/routingmapmatcher/graphhopper/NetworkGraphHopper.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import com.graphhopper.config.Profile;
88
import com.graphhopper.routing.Path;
99
import com.graphhopper.routing.PathRouter;
10+
import com.graphhopper.routing.util.parsers.TagParser;
11+
import com.graphhopper.storage.BaseGraph;
1012
import com.graphhopper.storage.index.LocationIndexTree;
1113
import java.time.Instant;
1214
import java.time.format.DateTimeFormatter;
@@ -18,6 +20,7 @@
1820
import java.util.function.Function;
1921
import java.util.function.Supplier;
2022
import java.util.stream.Collectors;
23+
import lombok.Getter;
2124
import lombok.extern.slf4j.Slf4j;
2225
import nu.ndw.nls.routingmapmatcher.domain.Network;
2326
import nu.ndw.nls.routingmapmatcher.domain.model.Link;
@@ -35,22 +38,29 @@ public class NetworkGraphHopper extends GraphHopper implements Network {
3538
private Instant dataDate;
3639

3740
private LongLongMap nodeIdToInternalNodeIdMap;
41+
@Getter
42+
private final boolean expandBounds;
3843

3944
public NetworkGraphHopper(Supplier<Iterator<Link>> linkSupplier) {
4045
this(linkSupplier, null);
4146
}
4247

4348
public NetworkGraphHopper(Supplier<Iterator<Link>> linkSupplier, Instant dataDate) {
49+
this(linkSupplier, dataDate, false);
50+
}
51+
52+
public NetworkGraphHopper(Supplier<Iterator<Link>> linkSupplier, Instant dataDate, boolean expandBounds) {
4453
this.linkSupplier = linkSupplier;
4554
this.dataDate = dataDate;
4655
this.nodeIdToInternalNodeIdMap = new GHLongLongBTree(MAX_LEAF_ENTRIES, BYTES_PER_INTEGER, EMPTY_VALUE);
56+
this.expandBounds = expandBounds;
4757
}
4858

4959
/**
5060
* Loading an existing network from disk does not require a link supplier and nodeIdToInternalNodeIdMap
5161
*/
5262
public NetworkGraphHopper() {
53-
63+
expandBounds = false;
5464
}
5565

5666
/**
@@ -73,8 +83,15 @@ protected void importOSM() {
7383

7484
protected NetworkReader getNetworkReader(Supplier<Iterator<Link>> linkSupplier,
7585
LongLongMap nodeIdToInternalNodeIdMap) {
76-
return new NetworkReader(getBaseGraph().getBaseGraph(), getEncodingManager(), linkSupplier,
77-
getOSMParsers().getWayTagParsers(), nodeIdToInternalNodeIdMap);
86+
BaseGraph baseGraph = getBaseGraph().getBaseGraph();
87+
List<TagParser> wayTagParsers = getOSMParsers().getWayTagParsers();
88+
if (expandBounds) {
89+
return new ExpandedBoundsNetworkReader(baseGraph, getEncodingManager(), linkSupplier, wayTagParsers,
90+
nodeIdToInternalNodeIdMap);
91+
} else {
92+
return new NetworkReader(baseGraph, getEncodingManager(), linkSupplier, wayTagParsers,
93+
nodeIdToInternalNodeIdMap);
94+
}
7895
}
7996

8097
@Override

map-matcher-library/src/main/java/nu/ndw/nls/routingmapmatcher/graphhopper/NetworkGraphHopperFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public NetworkGraphHopper createNetwork(RoutingNetwork routingNetwork) {
1717
public NetworkGraphHopper createNetwork(RoutingNetwork routingNetwork, boolean storeOnDisk,
1818
Path graphhopperRootPath) {
1919
NetworkGraphHopper graphHopper = new NetworkGraphHopper(routingNetwork.getLinkSupplier(),
20-
routingNetwork.getDataDate());
20+
routingNetwork.getDataDate(), routingNetwork.isExpandBounds());
2121
Path path = GraphHopperNetworkPathUtils.formatNormalizedPath(graphhopperRootPath,
2222
routingNetwork.getNetworkNameAndVersion());
2323
graphHopper.setStoreOnFlush(storeOnDisk);

map-matcher-library/src/main/java/nu/ndw/nls/routingmapmatcher/graphhopper/NetworkReader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public class NetworkReader {
3434
private final List<TagParser> vehicleTagParsers;
3535
private final IntEncodedValue idEncoder;
3636

37-
private final BaseGraph baseGraph;
37+
protected final BaseGraph baseGraph;
3838

3939
public NetworkReader(BaseGraph baseGraph, EncodingManager encodingManager, Supplier<Iterator<Link>> linkSupplier,
4040
List<TagParser> vehicleTagParsers, LongLongMap nodeIdToInternalNodeIdMap) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package nu.ndw.nls.routingmapmatcher.graphhopper;
2+
3+
import static nu.ndw.nls.routingmapmatcher.graphhopper.ev.EncodedTag.WAY_ID;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
import static org.hamcrest.Matchers.is;
6+
import static org.junit.jupiter.api.Assertions.*;
7+
import static org.mockito.Mockito.verify;
8+
import static org.mockito.Mockito.when;
9+
10+
import com.graphhopper.coll.GHLongLongBTree;
11+
import com.graphhopper.coll.LongLongMap;
12+
import com.graphhopper.routing.ev.EdgeIntAccess;
13+
import com.graphhopper.routing.ev.IntEncodedValue;
14+
import com.graphhopper.routing.util.EncodingManager;
15+
import com.graphhopper.routing.util.parsers.TagParser;
16+
import com.graphhopper.storage.BaseGraph;
17+
import com.graphhopper.storage.IntsRef;
18+
import com.graphhopper.storage.NodeAccess;
19+
import com.graphhopper.util.EdgeIteratorState;
20+
import com.graphhopper.util.PointList;
21+
import com.graphhopper.util.shapes.BBox;
22+
import java.util.List;
23+
import nu.ndw.nls.routingmapmatcher.domain.model.Link;
24+
import org.junit.jupiter.api.BeforeEach;
25+
import org.junit.jupiter.api.Test;
26+
import org.junit.jupiter.api.extension.ExtendWith;
27+
import org.locationtech.jts.geom.Coordinate;
28+
import org.locationtech.jts.geom.LineString;
29+
import org.mockito.ArgumentCaptor;
30+
import org.mockito.Captor;
31+
import org.mockito.Mock;
32+
import org.mockito.junit.jupiter.MockitoExtension;
33+
34+
@ExtendWith(MockitoExtension.class)
35+
class ExpandedBoundsNetworkReaderTest extends NetworkReaderTest {
36+
37+
private static final double LONG_1 = 5.358247;
38+
private static final double LAT_1 = 52.161257;
39+
private static final double LONG_2 = 5.379687;
40+
private static final double LAT_2 = 52.158304;
41+
private static final double LONG_3 = 5.379667;
42+
private static final double LAT_3 = 52.158280;
43+
44+
// Link fields
45+
private static final long FROM_NODE_ID = 101;
46+
private static final long TO_NODE_ID = 102;
47+
private static final double DISTANCE = 12.15;
48+
private static final double SPEED = 50D;
49+
private static final long LINK_ID = 100;
50+
51+
// Internal fields
52+
private static final int FROM_NODE_ID_INTERNAL = 0;
53+
private static final int TO_NODE_ID_INTERNAL = 1;
54+
private static final int EDGE_ID = 2;
55+
56+
private static final Coordinate coordinateA1 = new Coordinate(LONG_1, LAT_1);
57+
private static final Coordinate coordinateA2 = new Coordinate(LONG_2, LAT_2);
58+
private static final Coordinate coordinateA3 = new Coordinate(LONG_3, LAT_3);
59+
60+
@Captor
61+
private ArgumentCaptor<PointList> pointListArgumentCaptor;
62+
63+
@Mock
64+
private BaseGraph baseGraph;
65+
@Mock
66+
private BBox bBox;
67+
@Mock
68+
private EncodingManager encodingManager;
69+
@Mock
70+
private Link link;
71+
@Mock
72+
private TagParser tagParser;
73+
74+
private LongLongMap nodeIdToInternalNodeIdMap;
75+
76+
@Mock
77+
private EdgeIntAccess edgeIntAccess;
78+
@Mock
79+
private IntEncodedValue idEncoder;
80+
@Mock
81+
private LineString lineString;
82+
@Mock
83+
private NodeAccess nodeAccess;
84+
@Mock
85+
private EdgeIteratorState edge;
86+
87+
private ExpandedBoundsNetworkReader expandedBoundsNetworkReader;
88+
89+
@BeforeEach
90+
void setUp() {
91+
// Use parameters from NetworkGraphHopper class
92+
nodeIdToInternalNodeIdMap = new GHLongLongBTree(200, 4, -1);
93+
when(baseGraph.createEdgeIntAccess()).thenReturn(edgeIntAccess);
94+
when(encodingManager.getIntEncodedValue(WAY_ID.getKey())).thenReturn(idEncoder);
95+
expandedBoundsNetworkReader = new ExpandedBoundsNetworkReader(baseGraph, encodingManager,
96+
List.of(link)::iterator, List.of(tagParser), nodeIdToInternalNodeIdMap);
97+
}
98+
99+
@Test
100+
void readGraph_ok() {
101+
when(link.getGeometry()).thenReturn(lineString);
102+
Coordinate[] coordinates = {coordinateA1, coordinateA2, coordinateA3};
103+
when(lineString.getCoordinates()).thenReturn(coordinates);
104+
when(link.getFromNodeId()).thenReturn(FROM_NODE_ID);
105+
when(link.getToNodeId()).thenReturn(TO_NODE_ID);
106+
when(baseGraph.getNodeAccess()).thenReturn(nodeAccess);
107+
when(baseGraph.getBounds()).thenReturn(bBox);
108+
when(baseGraph.edge(FROM_NODE_ID_INTERNAL, TO_NODE_ID_INTERNAL)).thenReturn(edge);
109+
when(link.getDistanceInMeters()).thenReturn(DISTANCE);
110+
when(edge.setDistance(DISTANCE)).thenReturn(edge);
111+
when(edge.getEdge()).thenReturn(EDGE_ID);
112+
when(link.getSpeedInKilometersPerHour()).thenReturn(SPEED);
113+
when(link.getId()).thenReturn(LINK_ID);
114+
115+
expandedBoundsNetworkReader.readGraph();
116+
117+
assertEquals(FROM_NODE_ID_INTERNAL, nodeIdToInternalNodeIdMap.get(FROM_NODE_ID));
118+
assertEquals(TO_NODE_ID_INTERNAL, nodeIdToInternalNodeIdMap.get(TO_NODE_ID));
119+
verify(nodeAccess).setNode(FROM_NODE_ID_INTERNAL, LAT_1, LONG_1);
120+
verify(nodeAccess).setNode(TO_NODE_ID_INTERNAL, LAT_3, LONG_3);
121+
verify(tagParser).handleWayTags(EDGE_ID, edgeIntAccess, link, IntsRef.EMPTY);
122+
verify(idEncoder).setInt(false, EDGE_ID, edgeIntAccess, (int) LINK_ID);
123+
verify(edge).setWayGeometry(pointListArgumentCaptor.capture());
124+
verify(bBox).update(LAT_1 + .000001, LONG_1 + .000001);
125+
verify(bBox).update(LAT_1 - .000001, LONG_1 - .000001);
126+
verify(bBox).update(LAT_2 + .000001, LONG_2 + .000001);
127+
verify(bBox).update(LAT_2 - .000001, LONG_2 - .000001);
128+
verify(bBox).update(LAT_3 + .000001, LONG_3 + .000001);
129+
verify(bBox).update(LAT_3 - .000001, LONG_3 - .000001);
130+
PointList pointList = pointListArgumentCaptor.getValue();
131+
assertThat(pointList.size(), is(1));
132+
assertThat(pointList.getLon(0), is(LONG_2));
133+
assertThat(pointList.getLat(0), is(LAT_2));
134+
}
135+
}

map-matcher-library/src/test/java/nu/ndw/nls/routingmapmatcher/graphhopper/NetworkGraphHopperFactoryTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static org.hamcrest.Matchers.is;
55
import static org.hamcrest.Matchers.notNullValue;
66
import static org.junit.jupiter.api.Assertions.assertFalse;
7+
import static org.junit.jupiter.api.Assertions.assertTrue;
78
import static org.mockito.Mockito.when;
89

910
import java.nio.file.Path;
@@ -38,6 +39,7 @@ class NetworkGraphHopperFactoryTest {
3839
private static final String DEFAULT_GRAPHHOPPER_ROOT_DIRECTORY = "graphhopper_";
3940
private static final Instant DATA_DATE = Instant.parse("2023-11-07T15:37:23.129Z");
4041
private static final Instant DATA_DATE_TRUNCATED = Instant.parse("2023-11-07T15:37:23Z");
42+
private static final boolean EXPAND_BOUNDS = true;
4143

4244
@Mock
4345
private RoutingNetwork routingNetwork;
@@ -65,6 +67,7 @@ void setUp() {
6567
when(routingNetwork.getNetworkNameAndVersion()).thenReturn(TEST_NETWORK);
6668
when(routingNetwork.getLinkSupplier()).thenReturn(() -> Collections.singletonList(link).iterator());
6769
when(routingNetwork.getDataDate()).thenReturn(DATA_DATE);
70+
when(routingNetwork.isExpandBounds()).thenReturn(EXPAND_BOUNDS);
6871
networkGraphHopperFactory = new NetworkGraphHopperFactory();
6972
}
7073

@@ -77,6 +80,7 @@ void createNetwork_ok() {
7780
assertFalse(graphHopper.hasElevation());
7881
assertThat(graphHopper.getImportDate(), notNullValue());
7982
assertThat(graphHopper.getDataDate(), is(DATA_DATE_TRUNCATED));
83+
assertTrue(graphHopper.isExpandBounds());
8084
}
8185

8286
@Test
@@ -89,5 +93,6 @@ void createNetwork_ok_withNetwork() {
8993
assertFalse(graphHopper.hasElevation());
9094
assertThat(graphHopper.getImportDate(), notNullValue());
9195
assertThat(graphHopper.getDataDate(), is(DATA_DATE_TRUNCATED));
96+
assertTrue(graphHopper.isExpandBounds());
9297
}
9398
}

0 commit comments

Comments
 (0)