Skip to content

Commit d27c369

Browse files
authored
Merge branch 'master' into fix/upgrade-to-java11
2 parents 19392ec + 8705cd4 commit d27c369

File tree

5 files changed

+127
-5
lines changed

5 files changed

+127
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55

66
## [Unreleased]
77
### Added
8+
- Check whether routing points are within different countries before routing and break if they are and all borders should be avoided
89
### Fixed
910
### Changed
1011
### Deprecated

ISSUE_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<!-- https://ask.openrouteservice.org/c/ors-->
44

55
#### Here's what I did
6-
<!-- include request URLs, link to app.config or other relevant ifnormation -->
6+
<!-- include request URLs, link to app.config or other relevant information -->
77

88
---
99
#### Here's what I got

openrouteservice/src/main/java/org/heigit/ors/routing/graphhopper/extensions/ORSGraphHopper.java

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,33 @@
3333
import com.graphhopper.storage.GraphHopperStorage;
3434
import com.graphhopper.storage.index.QueryResult;
3535
import com.graphhopper.util.*;
36+
import com.graphhopper.util.exceptions.ConnectionNotFoundException;
3637
import com.graphhopper.util.exceptions.PointNotFoundException;
3738
import com.graphhopper.util.shapes.GHPoint;
3839
import com.vividsolutions.jts.geom.Coordinate;
3940
import com.vividsolutions.jts.geom.GeometryFactory;
4041
import com.vividsolutions.jts.geom.LineString;
4142
import org.heigit.ors.mapmatching.RouteSegmentInfo;
43+
import org.heigit.ors.routing.RouteSearchParameters;
4244
import org.heigit.ors.routing.RoutingProfileCategory;
4345
import org.heigit.ors.routing.graphhopper.extensions.core.CoreAlgoFactoryDecorator;
4446
import org.heigit.ors.routing.graphhopper.extensions.core.CoreLMAlgoFactoryDecorator;
4547
import org.heigit.ors.routing.graphhopper.extensions.core.PrepareCore;
48+
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.AvoidBordersEdgeFilter;
4649
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.EdgeFilterSequence;
4750
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.AvoidBordersCoreEdgeFilter;
4851
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.AvoidFeaturesCoreEdgeFilter;
4952
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.HeavyVehicleCoreEdgeFilter;
5053
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.WheelchairCoreEdgeFilter;
5154
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.core.MaximumSpeedCoreEdgeFilter;
55+
import org.heigit.ors.routing.graphhopper.extensions.reader.borders.CountryBordersReader;
56+
import org.heigit.ors.routing.graphhopper.extensions.storages.BordersGraphStorage;
57+
import org.heigit.ors.routing.graphhopper.extensions.storages.GraphStorageUtils;
58+
import org.heigit.ors.routing.graphhopper.extensions.storages.builders.GraphStorageBuilder;
59+
import org.heigit.ors.routing.graphhopper.extensions.util.ORSPMap;
5260
import org.heigit.ors.routing.graphhopper.extensions.weighting.MaximumSpeedWeighting;
5361
import org.heigit.ors.routing.graphhopper.extensions.util.ORSParameters;
62+
import org.heigit.ors.routing.pathprocessors.BordersExtractor;
5463
import org.heigit.ors.util.CoordTools;
5564
import org.slf4j.Logger;
5665
import org.slf4j.LoggerFactory;
@@ -256,6 +265,7 @@ else if (ALT_ROUTE.equalsIgnoreCase(algoStr))
256265
StopWatch sw = new StopWatch().start();
257266
List<QueryResult> qResults = routingTemplate.lookup(points, encoder);
258267
double[] radiuses = request.getMaxSearchDistances();
268+
checkAvoidBorders(processContext, request, qResults);
259269
if (points.size() == qResults.size()) {
260270
for (int placeIndex = 0; placeIndex < points.size(); placeIndex++) {
261271
QueryResult qr = qResults.get(placeIndex);
@@ -264,7 +274,6 @@ else if (ALT_ROUTE.equalsIgnoreCase(algoStr))
264274
}
265275
}
266276
}
267-
268277
ghRsp.addDebugInfo("idLookup:" + sw.stop().getSeconds() + "s");
269278
if (ghRsp.hasErrors())
270279
return Collections.emptyList();
@@ -435,6 +444,61 @@ public RouteSegmentInfo getRouteSegment(double[] latitudes, double[] longitudes,
435444
return result;
436445
}
437446

447+
/**
448+
* Check whether the route processing has to start. If avoid all borders is set and the routing points are in different countries,
449+
* there is no need to even start routing.
450+
* @param processContext Used to get the bordersReader to check isOpen for avoid Controlled. Currently not used
451+
* @param request To get the avoid borders setting
452+
* @param queryResult To get the edges of the queries and check which country they're in
453+
*/
454+
private void checkAvoidBorders(GraphProcessContext processContext, GHRequest request, List<QueryResult> queryResult) {
455+
/* Avoid borders */
456+
ORSPMap params = (ORSPMap)request.getAdditionalHints();
457+
boolean isRouteable = true;
458+
459+
if (params.hasObj("avoid_borders")) {
460+
RouteSearchParameters routeSearchParameters = (RouteSearchParameters) params.getObj("avoid_borders");
461+
//Avoiding All borders
462+
if(routeSearchParameters.hasAvoidBorders() && routeSearchParameters.getAvoidBorders() == BordersExtractor.Avoid.ALL) {
463+
List<Integer> edgeIds = new ArrayList<>();
464+
for (int placeIndex = 0; placeIndex < queryResult.size(); placeIndex++) {
465+
edgeIds.add(queryResult.get(placeIndex).getClosestEdge().getEdge());
466+
}
467+
BordersExtractor bordersExtractor = new BordersExtractor(GraphStorageUtils.getGraphExtension(getGraphHopperStorage(), BordersGraphStorage.class), null);
468+
isRouteable = bordersExtractor.isSameCountry(edgeIds);
469+
}
470+
//TODO Avoiding CONTROLLED borders
471+
//Currently this is extremely messy, as for some reason the READER stores data in addition to the BordersStorage.
472+
//At the same time, it is not possible to get isOpen from the Reader via ids, because it only takes Strings. But there are no Strings in the Storage.
473+
//So no controlled borders for now until this whole thing is refactored and the Reader is an actual reader and not a storage.
474+
475+
// if(routeSearchParameters.hasAvoidBorders() && routeSearchParameters.getAvoidBorders() == BordersExtractor.Avoid.CONTROLLED) {
476+
// GraphStorageBuilder countryBordersReader;
477+
// if(processContext.getStorageBuilders().size() > 0) {
478+
// countryBordersReader = processContext.getStorageBuilders().get(0);
479+
// int i = 1;
480+
// while (i < processContext.getStorageBuilders().size() && !(countryBordersReader instanceof CountryBordersReader)) {
481+
// countryBordersReader = processContext.getStorageBuilders().get(i);
482+
// i++;
483+
// }
484+
//
485+
// List<Integer> edgeIds = new ArrayList<>();
486+
// for (int placeIndex = 0; placeIndex < queryResult.size(); placeIndex++) {
487+
// edgeIds.add(queryResult.get(placeIndex).getClosestEdge().getEdge());
488+
// }
489+
// BordersExtractor bordersExtractor = new BordersExtractor(GraphStorageUtils.getGraphExtension(getGraphHopperStorage(), BordersGraphStorage.class), null);
490+
// if (!bordersExtractor.isSameCountry(edgeIds)) {
491+
// isRouteable == ((CountryBordersReader) countryBordersReader).isOpen(id0, id1)
492+
// ...
493+
// }
494+
// }
495+
// }
496+
}
497+
if(!isRouteable)
498+
throw new ConnectionNotFoundException("Route not found due to avoiding borders", Collections.<String, Object>emptyMap());
499+
500+
}
501+
438502
public GHResponse constructFreeHandRoute(GHRequest request) {
439503
LineString directRouteGeometry = constructFreeHandRouteGeometry(request);
440504
PathWrapper directRoutePathWrapper = constructFreeHandRoutePathWrapper(directRouteGeometry);

openrouteservice/src/main/java/org/heigit/ors/routing/pathprocessors/BordersExtractor.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package org.heigit.ors.routing.pathprocessors;
22

3+
import com.carrotsearch.hppc.IntHashSet;
34
import org.heigit.ors.routing.graphhopper.extensions.storages.BordersGraphStorage;
45

6+
import java.util.ArrayList;
7+
import java.util.List;
58

69
public class BordersExtractor {
710
public enum Avoid { CONTROLLED, NONE, ALL }
@@ -42,4 +45,27 @@ public boolean restrictedCountry(int edgeId) {
4245
}
4346
return false;
4447
}
48+
49+
/**
50+
* Check whether the start and end nodes of a list of edges are in the same country.
51+
* @param edgeIds Edges that the country should be checked for
52+
* @return true if at least one node is in the same country
53+
*/
54+
public boolean isSameCountry(List<Integer> edgeIds){
55+
if(edgeIds.isEmpty())
56+
return true;
57+
58+
short country0 = storage.getEdgeValue(edgeIds.get(0), BordersGraphStorage.Property.START);
59+
short country1 = storage.getEdgeValue(edgeIds.get(0), BordersGraphStorage.Property.END);
60+
for(int edgeId : edgeIds) {
61+
short country2 = storage.getEdgeValue(edgeId, BordersGraphStorage.Property.START);
62+
short country3 = storage.getEdgeValue(edgeId, BordersGraphStorage.Property.END);
63+
if(country0 != country2
64+
&& country0 != country3
65+
&& country1 != country2
66+
&& country1 != country3)
67+
return false;
68+
}
69+
return true;
70+
}
4571
}

openrouteservice/src/test/java/org/heigit/ors/routing/pathprocessors/BordersExtractorTest.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
import org.heigit.ors.routing.graphhopper.extensions.storages.BordersGraphStorage;
2626
import org.junit.Test;
2727

28-
import static org.junit.Assert.assertEquals;
29-
import static org.junit.Assert.assertFalse;
28+
import java.util.ArrayList;
29+
import java.util.List;
30+
31+
import static org.junit.Assert.*;
3032

3133
public class BordersExtractorTest {
3234
private final EncodingManager encodingManager= EncodingManager.create(new ORSDefaultFlagEncoderFactory(), FlagEncoderNames.CAR_ORS, 4);
@@ -37,13 +39,17 @@ public BordersExtractorTest() {
3739
// Initialise a graph storage with dummy data
3840
_graphstorage = new BordersGraphStorage();
3941
_graphstorage.init(null, new GHDirectory("", DAType.RAM_STORE));
40-
_graphstorage.create(3);
42+
_graphstorage.create(5);
4143

4244
// (edgeId, borderType, startCountry, endCountry)
4345

4446
_graphstorage.setEdgeValue(1, BordersGraphStorage.CONTROLLED_BORDER, (short)1, (short)2);
4547
_graphstorage.setEdgeValue(2, BordersGraphStorage.OPEN_BORDER, (short)3, (short)4);
4648
_graphstorage.setEdgeValue(3, BordersGraphStorage.NO_BORDER, (short)5, (short)5);
49+
_graphstorage.setEdgeValue(4, BordersGraphStorage.NO_BORDER, (short)5, (short)6);
50+
_graphstorage.setEdgeValue(5, BordersGraphStorage.NO_BORDER, (short)7, (short)7);
51+
_graphstorage.setEdgeValue(6, BordersGraphStorage.NO_BORDER, (short)7, (short)7);
52+
4753
}
4854

4955
private VirtualEdgeIteratorState generateEdge(int id) {
@@ -103,4 +109,29 @@ public void TestAvoidCountry() {
103109
assertEquals(true, be.restrictedCountry(2));
104110
assertEquals(false, be.restrictedCountry(3));
105111
}
112+
113+
@Test
114+
public void TestIsSameCountry() {
115+
VirtualEdgeIteratorState ve1 = generateEdge(1);
116+
VirtualEdgeIteratorState ve2 = generateEdge(2);
117+
VirtualEdgeIteratorState ve3 = generateEdge(3);
118+
119+
BordersExtractor be = new BordersExtractor(_graphstorage, new int[] {2, 4});
120+
List<Integer> countries = new ArrayList<>();
121+
countries.add(1);
122+
countries.add(2);
123+
assertFalse(be.isSameCountry(countries));
124+
countries = new ArrayList<>();
125+
countries.add(3);
126+
countries.add(4);
127+
assertTrue(be.isSameCountry(countries));
128+
countries = new ArrayList<>();
129+
countries.add(4);
130+
countries.add(5);
131+
assertFalse(be.isSameCountry(countries));
132+
countries = new ArrayList<>();
133+
countries.add(5);
134+
countries.add(6);
135+
assertTrue(be.isSameCountry(countries));
136+
}
106137
}

0 commit comments

Comments
 (0)