diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index f81c071..a42d568 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -84,8 +84,8 @@ public final class RoutingContext { pm = new StdModel(); } else { try { - Class clazz = Class.forName(className); - pm = (OsmPathModel) clazz.newInstance(); + Class clazz = Class.forName(className); + pm = (OsmPathModel) clazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException("Cannot create path-model: " + e); } diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 596dc75..58e7e3e 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -292,16 +292,16 @@ public class RoutingEngine extends Thread { private OsmTrack tryFindTrack(OsmTrack[] refTracks, OsmTrack[] lastTracks) { OsmTrack totaltrack = new OsmTrack(); int nUnmatched = waypoints.size(); + boolean hasDirectRouting = false; - if (hasInfo()) { - for (OsmNodeNamed wp : waypoints) { - logInfo("wp=" + wp); - } + for (OsmNodeNamed wp : waypoints) { + if (hasInfo()) logInfo("wp=" + wp + (wp.direct ? " direct" : "")); + if (wp.direct) hasDirectRouting = true; } // check for a track for that target OsmTrack nearbyTrack = null; - if (lastTracks[waypoints.size() - 2] == null) { + if (!hasDirectRouting && lastTracks[waypoints.size() - 2] == null) { StringBuilder debugInfo = hasInfo() ? new StringBuilder() : null; nearbyTrack = OsmTrack.readBinary(routingContext.rawTrackPath, waypoints.get(waypoints.size() - 1), routingContext.getNogoChecksums(), routingContext.profileTimestamp, debugInfo); if (nearbyTrack != null) { @@ -314,13 +314,13 @@ public class RoutingEngine extends Thread { } } - if (matchedWaypoints == null) // could exist from the previous alternative level - { + if (matchedWaypoints == null) { // could exist from the previous alternative level matchedWaypoints = new ArrayList(); for (int i = 0; i < nUnmatched; i++) { MatchedWaypoint mwp = new MatchedWaypoint(); mwp.waypoint = waypoints.get(i); mwp.name = waypoints.get(i).name; + mwp.direct = waypoints.get(i).direct; matchedWaypoints.add(mwp); } matchWaypointsToNodes(matchedWaypoints); @@ -330,6 +330,7 @@ public class RoutingEngine extends Thread { airDistanceCostFactor = 0.; for (int i = 0; i < matchedWaypoints.size() - 1; i++) { nodeLimit = MAXNODES_ISLAND_CHECK; + if (matchedWaypoints.get(i).direct) continue; if (routingContext.inverseRouting) { OsmTrack seg = findTrack("start-island-check", matchedWaypoints.get(i), matchedWaypoints.get(i + 1), null, null, false); if (seg == null && nodeLimit > 0) { @@ -383,10 +384,7 @@ public class RoutingEngine extends Thread { private OsmTrack searchTrack(MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack) { // remove nogos with waypoints inside try { - List wpts2 = new ArrayList(); - wpts2.add(startWp.waypoint); - wpts2.add(endWp.waypoint); - boolean calcBeeline = routingContext.allInOneNogo(wpts2); + boolean calcBeeline = startWp.direct; if (!calcBeeline) return searchRoutedTrack(startWp, endWp, nearbyTrack, refTrack); diff --git a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java index c0ff9bc..5d6bf05 100644 --- a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java +++ b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java @@ -850,7 +850,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier { Integer num = variableNumbers.get(name); if (num == null) { if (create) { - num = new Integer(variableNumbers.size()); + num = Integer.valueOf(variableNumbers.size()); variableNumbers.put(name, num); } else { return -1; diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java index cef46b0..ab89a68 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java @@ -290,9 +290,20 @@ public final class NodesCache { if (first_file_access_failed) { throw new IllegalArgumentException("datafile " + first_file_access_name + " not found"); } - for (MatchedWaypoint mwp : unmatchedWaypoints) { + int len = unmatchedWaypoints.size(); + for (int i = 0; i < len; i++) { + MatchedWaypoint mwp = unmatchedWaypoints.get(i); if (mwp.crosspoint == null) { - throw new IllegalArgumentException(mwp.name + "-position not mapped in existing datafile"); + if (unmatchedWaypoints.size() > 1 && i == unmatchedWaypoints.size()-1 && unmatchedWaypoints.get(i-1).direct) { + mwp.crosspoint = new OsmNode(mwp.waypoint.ilon, mwp.waypoint.ilat); + mwp.direct = true; + } else { + throw new IllegalArgumentException(mwp.name + "-position not mapped in existing datafile"); + } + } + if (unmatchedWaypoints.size() > 1 && i == unmatchedWaypoints.size()-1 && unmatchedWaypoints.get(i-1).direct) { + mwp.crosspoint = new OsmNode(mwp.waypoint.ilon, mwp.waypoint.ilat); + mwp.direct = true; } } } diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java index 446b873..35e9f88 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java @@ -25,7 +25,7 @@ public class OsmNode extends OsmLink implements OsmPos { /** * The elevation */ - public short selev; + public short selev = Short.MIN_VALUE; /** * The node-tags, if any diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java index 11618da..1e917f8 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java @@ -46,7 +46,24 @@ public final class WaypointMatcherImpl implements WaypointMatcher { if (d == 0.) return; - for (MatchedWaypoint mwp : waypoints) { + int len = waypoints.size(); + for (int i = 0; i < len; i++) { + MatchedWaypoint mwp = waypoints.get(i); + + if (mwp.direct && + (i == 0 || + waypoints.get(i - 1).direct) + ) { + if (mwp.crosspoint == null) { + mwp.crosspoint = new OsmNode(); + mwp.crosspoint.ilon = mwp.waypoint.ilon; + mwp.crosspoint.ilat = mwp.waypoint.ilat; + mwp.hasUpdate = true; + anyUpdate = true; + } + continue; + } + OsmNode wp = mwp.waypoint; double x1 = (lon1 - wp.ilon) * dlon2m; diff --git a/brouter-server/src/test/java/btools/server/RouteServerTest.java b/brouter-server/src/test/java/btools/server/RouteServerTest.java index e5d3521..7e1a253 100644 --- a/brouter-server/src/test/java/btools/server/RouteServerTest.java +++ b/brouter-server/src/test/java/btools/server/RouteServerTest.java @@ -92,6 +92,60 @@ public class RouteServerTest { Assert.assertEquals("1902", geoJson.query("/features/0/properties/track-length")); } + @Test + public void voiceHints() throws IOException { + URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.705796,50.003124|8.705859,50.0039599&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=2"); + HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); + httpConnection.connect(); + + Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode()); + + InputStream inputStream = httpConnection.getInputStream(); + JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8)); + Assert.assertEquals(2, geoJson.query("/features/0/properties/voicehints/0/1")); // TL + Assert.assertEquals(1, geoJson.query("/features/0/properties/voicehints/1/1")); // C + } + + @Test + public void directRoutingFirst() throws IOException { + URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.718354,50.001514|8.718917,50.001361|8.716986,50.000105|8.718306,50.00145&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=0&timode=3"); + HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); + httpConnection.connect(); + + Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode()); + + InputStream inputStream = httpConnection.getInputStream(); + JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8)); + Assert.assertEquals("521", geoJson.query("/features/0/properties/track-length")); + } + + @Test + public void directRoutingLast() throws IOException { + URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.718306,50.00145|8.717464,50.000405|8.718917,50.001361|8.718354,50.001514&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=2&timode=3"); + HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); + httpConnection.connect(); + + Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode()); + + InputStream inputStream = httpConnection.getInputStream(); + JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8)); + Assert.assertEquals("520", geoJson.query("/features/0/properties/track-length")); + } + + @Test + public void directRoutingMiddle() throws IOException { + URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.718539,50.006581|8.718198,50.006065,d|8.71785,50.006034|8.7169,50.004456&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=3"); + HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); + httpConnection.connect(); + + Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode()); + + InputStream inputStream = httpConnection.getInputStream(); + JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8)); + Assert.assertEquals("350", geoJson.query("/features/0/properties/track-length")); + } + + @Test public void uploadValidProfile() throws IOException { URL requestUrl = new URL(baseUrl + "brouter/profile");