diff --git a/brouter-core/src/main/java/btools/router/FormatGpx.java b/brouter-core/src/main/java/btools/router/FormatGpx.java index 6f969d1..1d0b88c 100644 --- a/brouter-core/src/main/java/btools/router/FormatGpx.java +++ b/brouter-core/src/main/java/btools/router/FormatGpx.java @@ -212,10 +212,14 @@ public class FormatGpx extends Formatter { } } } - if (t.exportCorrectedWaypoints && t.correctedWaypoints != null) { - for (int i = 0; i <= t.correctedWaypoints.size() - 1; i++) { - OsmNodeNamed n = t.correctedWaypoints.get(i); - formatWaypointGpx(sb, n, "via_corr"); + if (t.exportCorrectedWaypoints) { + for (int i = 0; i <= t.matchedWaypoints.size() - 1; i++) { + MatchedWaypoint wt = t.matchedWaypoints.get(i); + if (wt.correctedpoint != null) { + OsmNodeNamed n = new OsmNodeNamed(wt.correctedpoint); + n.name = wt.name + "_corr"; + formatWaypointGpx(sb, n, "via_corr"); + } } } diff --git a/brouter-core/src/main/java/btools/router/FormatJson.java b/brouter-core/src/main/java/btools/router/FormatJson.java index c380fa4..d5ba17b 100644 --- a/brouter-core/src/main/java/btools/router/FormatJson.java +++ b/brouter-core/src/main/java/btools/router/FormatJson.java @@ -158,15 +158,19 @@ public class FormatJson extends Formatter { } if (t.exportCorrectedWaypoints) { if (t.exportWaypoints) sb.append(" ,\n"); - for (int i = 0; i <= t.correctedWaypoints.size() - 1; i++) { + boolean hasCorrPoints = false; + for (int i = 0; i <= t.matchedWaypoints.size() - 1; i++) { String type = "via_corr"; - OsmNodeNamed wp = t.correctedWaypoints.get(i); - addFeature(sb, type, wp.name, wp.ilat, wp.ilon, wp.getSElev()); - if (i < t.correctedWaypoints.size() - 1) { - sb.append(","); + MatchedWaypoint wp = t.matchedWaypoints.get(i); + if (wp.correctedpoint != null) { + if (hasCorrPoints) { + sb.append(","); + } + addFeature(sb, type, wp.name + "_corr", wp.correctedpoint.ilat, wp.correctedpoint.ilon, wp.correctedpoint.getSElev()); + sb.append(" \n"); + hasCorrPoints = true; } - sb.append(" \n"); } } } else { diff --git a/brouter-core/src/main/java/btools/router/FormatKml.java b/brouter-core/src/main/java/btools/router/FormatKml.java index 79d1e08..931689a 100644 --- a/brouter-core/src/main/java/btools/router/FormatKml.java +++ b/brouter-core/src/main/java/btools/router/FormatKml.java @@ -1,5 +1,6 @@ package btools.router; +import java.util.ArrayList; import java.util.List; import btools.mapaccess.MatchedWaypoint; @@ -63,8 +64,17 @@ public class FormatKml extends Formatter { createFolder(sb, "end", t.matchedWaypoints.subList(size - 1, size)); } if (t.exportCorrectedWaypoints) { - int size = t.correctedWaypoints.size(); - createViaFolder(sb, "via_cor", t.correctedWaypoints.subList(0, size)); + List list = new ArrayList<>(); + for (int i = 0; i < t.matchedWaypoints.size(); i++) { + MatchedWaypoint wp = t.matchedWaypoints.get(i); + if (wp.correctedpoint != null) { + OsmNodeNamed n = new OsmNodeNamed(wp.correctedpoint); + n.name = wp.name + "_corr"; + list.add(n); + } + } + int size = list.size(); + createViaFolder(sb, "via_corr", list.subList(0, size)); } } sb.append(" \n"); @@ -84,6 +94,7 @@ public class FormatKml extends Formatter { } private void createViaFolder(StringBuilder sb, String type, List waypoints) { + if (waypoints.isEmpty()) return; sb.append(" \n"); sb.append(" " + type + "\n"); for (int i = 0; i < waypoints.size(); i++) { diff --git a/brouter-core/src/main/java/btools/router/OsmTrack.java b/brouter-core/src/main/java/btools/router/OsmTrack.java index b56a7df..cece041 100644 --- a/brouter-core/src/main/java/btools/router/OsmTrack.java +++ b/brouter-core/src/main/java/btools/router/OsmTrack.java @@ -61,7 +61,6 @@ public final class OsmTrack { public String name = "unset"; protected List matchedWaypoints; - protected List correctedWaypoints; public boolean exportWaypoints = false; public boolean exportCorrectedWaypoints = false; @@ -340,6 +339,7 @@ public final class OsmTrack { } float t0 = ourSize > 0 ? nodes.get(ourSize - 1).getTime() : 0; float e0 = ourSize > 0 ? nodes.get(ourSize - 1).getEnergy() : 0; + int c0 = ourSize > 0 ? nodes.get(ourSize - 1).cost : 0; for (i = 0; i < t.nodes.size(); i++) { OsmPathElement e = t.nodes.get(i); if (i == 0 && ourSize > 0 && nodes.get(ourSize - 1).getSElev() == Short.MIN_VALUE) @@ -347,6 +347,7 @@ public final class OsmTrack { if (i > 0 || ourSize == 0) { e.setTime(e.getTime() + t0); e.setEnergy(e.getEnergy() + e0); + e.cost = e.cost + c0; if (e.message != null){ if (!(e.message.lon == e.getILon() && e.message.lat == e.getILat())) { e.message.lon = e.getILon(); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index b86f4a0..42ae5a1 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -23,6 +23,7 @@ import btools.mapaccess.OsmLinkHolder; import btools.mapaccess.OsmNode; import btools.mapaccess.OsmNodePairSet; import btools.mapaccess.OsmPos; +import btools.util.CheapAngleMeter; import btools.util.CheapRuler; import btools.util.CompactLongMap; import btools.util.SortedHeap; @@ -41,7 +42,6 @@ public class RoutingEngine extends Thread { private boolean finished = false; protected List waypoints = null; - protected List correctedWaypoints = null; List extraWaypoints = null; protected List matchedWaypoints; private int linksProcessed = 0; @@ -1021,7 +1021,7 @@ public class RoutingEngine extends Thread { boolean changed = false; if (routingContext.correctMisplacedViaPoints && !matchedWaypoints.get(i).direct && !routingContext.allowSamewayback) { - changed = snappPathConnection(totaltrack, seg, routingContext.inverseRouting ? matchedWaypoints.get(i + 1) : matchedWaypoints.get(i)); + changed = snapPathConnection(totaltrack, seg, routingContext.inverseRouting ? matchedWaypoints.get(i + 1) : matchedWaypoints.get(i)); } if (wptIndex > 0) matchedWaypoints.get(wptIndex).indexInTrack = totaltrack.nodes.size() - 1; @@ -1036,7 +1036,6 @@ public class RoutingEngine extends Thread { matchedWaypoints.get(matchedWaypoints.size() - 1).indexInTrack = totaltrack.nodes.size() - 1; totaltrack.matchedWaypoints = matchedWaypoints; - totaltrack.correctedWaypoints = correctedWaypoints; totaltrack.processVoiceHints(routingContext); totaltrack.prepareSpeedProfile(routingContext); @@ -1045,12 +1044,198 @@ public class RoutingEngine extends Thread { if (routingContext.poipoints != null) totaltrack.pois = routingContext.poipoints; - totaltrack.matchedWaypoints = matchedWaypoints; + return totaltrack; } + OsmTrack getExtraSegment(OsmPathElement start, OsmPathElement end) { + + List wptlist = new ArrayList<>(); + MatchedWaypoint wpt1 = new MatchedWaypoint(); + wpt1.waypoint = new OsmNode(start.getILon(), start.getILat()); + wpt1.name = "wptx1"; + wpt1.crosspoint = new OsmNode(start.getILon(), start.getILat()); + wpt1.node1 = new OsmNode(start.getILon(), start.getILat()); + wpt1.node2 = new OsmNode(end.getILon(), end.getILat()); + wptlist.add(wpt1); + MatchedWaypoint wpt2 = new MatchedWaypoint(); + wpt2.waypoint = new OsmNode(end.getILon(), end.getILat()); + wpt2.name = "wptx2"; + wpt2.crosspoint = new OsmNode(end.getILon(), end.getILat()); + wpt2.node2 = new OsmNode(start.getILon(), start.getILat()); + wpt2.node1 = new OsmNode(end.getILon(), end.getILat()); + wptlist.add(wpt2); + + MatchedWaypoint mwp1 = wptlist.get(0); + MatchedWaypoint mwp2 = wptlist.get(1); + + OsmTrack mid = null; + + boolean corr = routingContext.correctMisplacedViaPoints; + routingContext.correctMisplacedViaPoints = false; + + guideTrack = new OsmTrack(); + guideTrack.addNode(start); + guideTrack.addNode(end); + + mid = findTrack("getinfo", mwp1, mwp2, null, null, false); + + guideTrack = null; + routingContext.correctMisplacedViaPoints = corr; + + return mid; + } + + private int snapRoundaboutConnection(OsmTrack tt, OsmTrack t, int indexStart, int indexEnd, int indexMeeting, MatchedWaypoint startWp) { + + int indexMeetingBack = (indexMeeting == -1 ? tt.nodes.size() - 1 : indexMeeting); + int indexMeetingFore = 0; + int indexStartBack = indexStart; + int indexStartFore = 0; + + OsmPathElement ptStart = tt.nodes.get(indexStartBack); + OsmPathElement ptMeeting = tt.nodes.get(indexMeetingBack); + OsmPathElement ptEnd = t.nodes.get(indexEnd); + + boolean bMeetingIsOnRoundabout = ptMeeting.message.isRoundabout(); + boolean bMeetsRoundaboutStart = false; + + int i; + for (i = 0; i < indexEnd; i++) { + OsmPathElement n = t.nodes.get(i); + if (n.positionEquals(ptStart)) { + indexStartFore = i; + bMeetsRoundaboutStart = true; + } + if (n.positionEquals(ptMeeting)) { + indexMeetingFore = i; + } + + } + + if (!bMeetsRoundaboutStart && bMeetingIsOnRoundabout) { + indexEnd = indexMeetingFore; + } + if (bMeetsRoundaboutStart && bMeetingIsOnRoundabout) { + indexEnd = indexStartFore; + } + + List removeList = new ArrayList<>(); + if (!bMeetsRoundaboutStart) { + indexStartBack = indexMeetingBack; + while (!tt.nodes.get(indexStartBack).message.isRoundabout()) { + indexStartBack--; + if (indexStartBack == 2) break; + } + } + + for (i = indexStartBack + 1; i < tt.nodes.size(); i++) { + OsmPathElement n = tt.nodes.get(i); + OsmTrack.OsmPathElementHolder detours = tt.getFromDetourMap(n.getIdFromPos()); + OsmTrack.OsmPathElementHolder h = detours; + while (h != null) { + h = h.nextHolder; + } + removeList.add(n); + } + + OsmPathElement ttend = null; + OsmPathElement ttend_next = null; + if (!bMeetingIsOnRoundabout && !bMeetsRoundaboutStart) { + ttend = tt.nodes.get(indexStartBack); + ttend_next = tt.nodes.get(indexStartBack + 1); + OsmTrack.OsmPathElementHolder ttend_detours = tt.getFromDetourMap(ttend.getIdFromPos()); + + tt.registerDetourForId(ttend.getIdFromPos(), null); + } + + for (OsmPathElement e : removeList) { + tt.nodes.remove(e); + } + removeList.clear(); + + + for (i = 0; i < indexEnd; i++) { + OsmPathElement n = t.nodes.get(i); + if (n.positionEquals(bMeetsRoundaboutStart ? ptStart : ptEnd)) break; + if (!bMeetingIsOnRoundabout && !bMeetsRoundaboutStart && n.message.isRoundabout()) break; + + OsmTrack.OsmPathElementHolder detours = t.getFromDetourMap(n.getIdFromPos()); + OsmTrack.OsmPathElementHolder h = detours; + while (h != null) { + h = h.nextHolder; + } + removeList.add(n); + } + + // time hold + float atime = 0; + float aenergy = 0; + int acost = 0; + if (i > 1) { + atime = t.nodes.get(i).getTime(); + aenergy = t.nodes.get(i).getEnergy(); + acost = t.nodes.get(i).cost; + } + + for (OsmPathElement e : removeList) { + t.nodes.remove(e); + } + removeList.clear(); + + if (atime > 0f) { + for (OsmPathElement e : t.nodes) { + e.setTime(e.getTime() - atime); + e.setEnergy(e.getEnergy() - aenergy); + e.cost = e.cost - acost; + } + } + + if (!bMeetingIsOnRoundabout && !bMeetsRoundaboutStart) { + + OsmPathElement tstart = t.nodes.get(0); + OsmPathElement tstart_next = null; + OsmTrack.OsmPathElementHolder tstart_detours = t.getFromDetourMap(tstart.getIdFromPos()); + OsmTrack.OsmPathElementHolder ttend_detours = tt.getFromDetourMap(ttend.getIdFromPos()); + + OsmTrack mid = getExtraSegment(ttend, ttend_detours.node); + OsmPathElement tt_end = tt.nodes.get(tt.nodes.size() - 1); + + int last_cost = tt_end.cost; + int tmp_cost = 0; + + if (mid != null) { + boolean start = false; + for (OsmPathElement e : mid.nodes) { + if (start) { + if (e.positionEquals(ttend_detours.node)) { + tmp_cost = e.cost; + break; + } + e.cost = last_cost + e.cost; + tt.nodes.add(e); + } + if (e.positionEquals(tt_end)) start = true; + } + + } + + ttend_detours.node.cost = last_cost + tmp_cost; + tt.nodes.add(ttend_detours.node); + t.nodes.add(0, ttend_detours.node); + + } + + tt.cost = tt.nodes.get(tt.nodes.size()-1).cost; + t.cost = t.nodes.get(t.nodes.size()-1).cost; + + startWp.correctedpoint = new OsmNode(ptStart.getILon(), ptStart.getILat()); + + return (t.nodes.size()); + } + // check for way back on way point - private boolean snappPathConnection(OsmTrack tt, OsmTrack t, MatchedWaypoint startWp) { + private boolean snapPathConnection(OsmTrack tt, OsmTrack t, MatchedWaypoint startWp) { if (!startWp.name.startsWith("via") && !startWp.name.startsWith("rt")) return false; @@ -1082,29 +1267,88 @@ public class RoutingEngine extends Thread { OsmPathElement newTarget = null; OsmPathElement tmpback = null; OsmPathElement tmpfore = null; + OsmPathElement tmpStart = null; int indexback = ourSize - 1; int indexfore = 0; int stop = (indexback - MAX_STEPS_CHECK > 1 ? indexback - MAX_STEPS_CHECK : 1); double wayDistance = 0; double nextDist = 0; + boolean bCheckRoundAbout = false; + boolean bBackRoundAbout = false; + boolean bForeRoundAbout = false; + int indexBackFound = 0; + int indexForeFound = 0; + int differentLanePoints = 0; + int indexMeeting = -1; + while (indexback >= 1 && indexback >= stop && indexfore < t.nodes.size()) { + tmpback = tt.nodes.get(indexback); + tmpfore = t.nodes.get(indexfore); + if (!bBackRoundAbout && tmpback.message != null && tmpback.message.isRoundabout()) { + bBackRoundAbout = true; + indexBackFound = indexfore; + } + if (!bForeRoundAbout && + tmpfore.message != null && tmpfore.message.isRoundabout() || + (tmpback.positionEquals(tmpfore) && tmpback.message.isRoundabout())) { + bForeRoundAbout = true; + indexForeFound = indexfore; + } + if (indexfore == 0) { + tmpStart = t.nodes.get(0); + } else { + double dirback = CheapAngleMeter.getDirection(tmpStart.getILon(), tmpStart.getILat(), tmpback.getILon(), tmpback.getILat()); + double dirfore = CheapAngleMeter.getDirection(tmpStart.getILon(), tmpStart.getILat(), tmpfore.getILon(), tmpfore.getILat()); + double dirdiff = CheapAngleMeter.getDifferenceFromDirection(dirback, dirfore); + // walking wrong direction + if (dirdiff > 60 && !bBackRoundAbout && !bForeRoundAbout) break; + } + // seems no roundabout, only on one end + if (bBackRoundAbout != bForeRoundAbout && indexfore - Math.abs(indexForeFound - indexBackFound) > 8) break; + if (!tmpback.positionEquals(tmpfore)) differentLanePoints++; + if (tmpback.positionEquals(tmpfore)) indexMeeting = indexback; + bCheckRoundAbout = bBackRoundAbout && bForeRoundAbout; + if (bCheckRoundAbout) break; + indexback--; + indexfore++; + } + //System.out.println("snap round result " + indexback + ": " + bBackRoundAbout + " - " + indexfore + "; " + bForeRoundAbout + " pts " + differentLanePoints); + if (bCheckRoundAbout) { + + tmpback = tt.nodes.get(--indexback); + while (tmpback.message != null && tmpback.message.isRoundabout()) { + tmpback = tt.nodes.get(--indexback); + } + + int ifore = ++indexfore; + OsmPathElement testfore = t.nodes.get(ifore); + while (ifore < t.nodes.size() && testfore.message != null && testfore.message.isRoundabout()) { + testfore = t.nodes.get(ifore); + ifore++; + } + + snapRoundaboutConnection(tt, t, indexback, --ifore, indexMeeting, startWp); + + // remove filled arrays + removeVoiceHintList.clear(); + removeBackList.clear(); + removeForeList.clear(); + return true; + } + indexback = ourSize - 1; + indexfore = 0; while (indexback >= 1 && indexback >= stop && indexfore < t.nodes.size()) { int junctions = 0; tmpback = tt.nodes.get(indexback); tmpfore = t.nodes.get(indexfore); if (tmpback.message != null && tmpback.message.isRoundabout()) { - removeBackList.clear(); - removeForeList.clear(); - removeVoiceHintList.clear(); - return false; + bCheckRoundAbout = true; } if (tmpfore.message != null && tmpfore.message.isRoundabout()) { - removeBackList.clear(); - removeForeList.clear(); - removeVoiceHintList.clear(); - return false; + bCheckRoundAbout = true; } - int dist = tmpback.calcDistance(tmpfore); - if (1 == 1) { + { + + int dist = tmpback.calcDistance(tmpfore); OsmTrack.OsmPathElementHolder detours = tt.getFromDetourMap(tmpback.getIdFromPos()); OsmTrack.OsmPathElementHolder h = detours; while (h != null) { @@ -1112,53 +1356,56 @@ public class RoutingEngine extends Thread { lastJunctions.put(h.node.getIdFromPos(), h); h = h.nextHolder; } - } - if (dist == 1 && indexfore > 0) { - if (indexfore == 1) { - removeBackList.add(tt.nodes.get(tt.nodes.size() - 1)); // last and first should be equal, so drop only on second also equal - removeForeList.add(t.nodes.get(0)); - removeBackList.add(tmpback); - removeForeList.add(tmpfore); - removeVoiceHintList.add(tt.nodes.size() - 1); - removeVoiceHintList.add(indexback); - } else { - removeBackList.add(tmpback); - removeForeList.add(tmpfore); - removeVoiceHintList.add(indexback); - } - nextDist = t.nodes.get(indexfore - 1).calcDistance(tmpfore); - wayDistance += nextDist; - } - if (dist > 1 || indexback == 1) { - if (removeBackList.size() != 0) { - // recover last - should be the cross point - removeBackList.remove(removeBackList.get(removeBackList.size() - 1)); - removeForeList.remove(removeForeList.get(removeForeList.size() - 1)); - break; - } else { + if (dist == 1 && indexfore > 0) { + if (indexfore == 1) { + removeBackList.add(tt.nodes.get(tt.nodes.size() - 1)); // last and first should be equal, so drop only on second also equal + removeForeList.add(t.nodes.get(0)); + removeBackList.add(tmpback); + removeForeList.add(tmpfore); + removeVoiceHintList.add(tt.nodes.size() - 1); + removeVoiceHintList.add(indexback); + } else { + removeBackList.add(tmpback); + removeForeList.add(tmpfore); + removeVoiceHintList.add(indexback); + } + nextDist = t.nodes.get(indexfore - 1).calcDistance(tmpfore); + wayDistance += nextDist; + + } + if (dist > 1 || indexback == 1) { + if (removeBackList.size() != 0) { + // recover last - should be the cross point + removeBackList.remove(removeBackList.get(removeBackList.size() - 1)); + removeForeList.remove(removeForeList.get(removeForeList.size() - 1)); + break; + } else { + return false; + } + } + indexback--; + indexfore++; + + if (routingContext.correctMisplacedViaPointsDistance > 0 && + wayDistance > routingContext.correctMisplacedViaPointsDistance) { + removeVoiceHintList.clear(); + removeBackList.clear(); + removeForeList.clear(); return false; } } - indexback--; - indexfore++; - - if (routingContext.correctMisplacedViaPointsDistance > 0 && - wayDistance > routingContext.correctMisplacedViaPointsDistance) { - removeVoiceHintList.clear(); - removeBackList.clear(); - removeForeList.clear(); - return false; - } } // time hold float atime = 0; float aenergy = 0; + int acost = 0; if (removeForeList.size() > 1) { - atime = t.nodes.get(removeForeList.size() - 2).getTime(); - aenergy = t.nodes.get(removeForeList.size() - 2).getEnergy(); + atime = t.nodes.get(indexfore -1).getTime(); + aenergy = t.nodes.get(indexfore -1).getEnergy(); + acost = t.nodes.get(indexfore -1).cost; } for (OsmPathElement e : removeBackList) { @@ -1178,6 +1425,7 @@ public class RoutingEngine extends Thread { for (OsmPathElement e : t.nodes) { e.setTime(e.getTime() - atime); e.setEnergy(e.getEnergy() - aenergy); + e.cost = e.cost - acost; } } @@ -1193,42 +1441,17 @@ public class RoutingEngine extends Thread { newJunction = t.nodes.get(0); newTarget = t.nodes.get(1); - setNewVoiceHint(t, last, lastJunctions, newJunction, newTarget); + tt.cost = tt.nodes.get(tt.nodes.size()-1).cost; + t.cost = t.nodes.get(t.nodes.size()-1).cost; - if (correctedWaypoints == null) correctedWaypoints = new ArrayList<>(); - OsmNodeNamed n = new OsmNodeNamed(); - n.ilon = newJunction.getILon(); - n.ilat = newJunction.getILat(); - n.name = startWp.name + "_corr"; - correctedWaypoints.add(n); + // fill to correctedpoint + startWp.correctedpoint = new OsmNode(newJunction.getILon(), newJunction.getILat()); return true; } return false; } - private void setNewVoiceHint(OsmTrack t, OsmPathElement last, CompactLongMap lastJunctiona, OsmPathElement newJunction, OsmPathElement newTarget) { - - if (last == null || newJunction == null || newTarget == null) - return; - int lon0, - lat0, - lon1, - lat1, - lon2, - lat2; - lon0 = last.getILon(); - lat0 = last.getILat(); - lon1 = newJunction.getILon(); - lat1 = newJunction.getILat(); - lon2 = newTarget.getILon(); - lat2 = newTarget.getILat(); - // get a new angle - double angle = routingContext.anglemeter.calcAngle(lon0, lat0, lon1, lat1, lon2, lat2); - - newTarget.message.turnangle = (float) angle; - } - private void recalcTrack(OsmTrack t) { int totaldist = 0; int totaltime = 0; @@ -1572,7 +1795,7 @@ public class RoutingEngine extends Thread { OsmPath p = getStartPath(n1, n2, new OsmNodeNamed(mwp.crosspoint), endPos, sameSegmentSearch); // special case: start+end on same segment - if (p.cost >= 0 && sameSegmentSearch && endPos != null && endPos.radius < 1.5) { + if (p != null && p.cost >= 0 && sameSegmentSearch && endPos != null && endPos.radius < 1.5) { p.treedepth = 0; // hack: mark for the final-check } return p; @@ -1611,7 +1834,7 @@ public class RoutingEngine extends Thread { if (bestLink != null) { bestLink.addLinkHolder(bestPath, n1); } - bestPath.treedepth = 1; + if (bestPath != null) bestPath.treedepth = 1; return bestPath; } finally { @@ -1709,6 +1932,9 @@ public class RoutingEngine extends Thread { logInfo("firstMatchCost from initial match=" + firstMatchCost); } + if (startPath1 == null) return null; + if (startPath2 == null) return null; + synchronized (openSet) { openSet.clear(); addToOpenset(startPath1); diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java b/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java index c9556d5..4c2a415 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java @@ -16,6 +16,7 @@ public final class MatchedWaypoint { public OsmNode node2; public OsmNode crosspoint; public OsmNode waypoint; + public OsmNode correctedpoint; public String name; // waypoint name used in error messages public double radius; // distance in meter between waypoint and crosspoint public boolean direct; // from this point go direct to next = beeline routing diff --git a/brouter-server/src/test/java/btools/server/RouteServerTest.java b/brouter-server/src/test/java/btools/server/RouteServerTest.java index d4c971e..ad6776c 100644 --- a/brouter-server/src/test/java/btools/server/RouteServerTest.java +++ b/brouter-server/src/test/java/btools/server/RouteServerTest.java @@ -14,6 +14,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.ConnectException; import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -28,7 +30,7 @@ public class RouteServerTest { public static TemporaryFolder profileDir = new TemporaryFolder(); @BeforeClass - public static void setupServer() throws IOException, InterruptedException { + public static void setupServer() throws IOException, InterruptedException, URISyntaxException { File workingDir = new File(".").getCanonicalFile(); File segmentDir = new File(workingDir, "../brouter-map-creator/build/resources/test/tmp/segments"); File profileSourceDir = new File(workingDir, "../misc/profiles2"); @@ -41,7 +43,7 @@ public class RouteServerTest { try { RouteServer.main(new String[]{segmentDir.getAbsolutePath(), profileDir.getRoot().getAbsolutePath(), customProfileDir, port, "1"}); } catch (Exception e) { - e.printStackTrace(); + e.printStackTrace(System.out); } }; @@ -49,7 +51,7 @@ public class RouteServerTest { thread.start(); // Busy-wait for server startup - URL requestUrl = new URL(baseUrl); + URL requestUrl = new URI(baseUrl).toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); for (int i = 20; i >= 0; i--) { try { @@ -66,8 +68,8 @@ public class RouteServerTest { } @Test - public void defaultRouteTrekking() throws IOException { - URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson"); + public void defaultRouteTrekking() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.723037,50.000491%7C8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -82,8 +84,8 @@ public class RouteServerTest { } @Test - public void overrideParameter() throws IOException { - URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:avoid_unsafe=1"); + public void overrideParameter() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.723037,50.000491%7C8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:avoid_unsafe=1").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -95,8 +97,8 @@ public class RouteServerTest { } @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"); + public void voiceHints() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.705796,50.003124%7C8.705859,50.0039599&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=2").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -108,8 +110,8 @@ public class RouteServerTest { } @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"); + public void directRoutingFirst() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.718354,50.001514%7C8.718917,50.001361%7C8.716986,50.000105%7C8.718306,50.00145&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=0&timode=3").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -121,8 +123,8 @@ public class RouteServerTest { } @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"); + public void directRoutingLast() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.718306,50.00145%7C8.717464,50.000405%7C8.718917,50.001361%7C8.718354,50.001514&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=2&timode=3").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -134,8 +136,8 @@ public class RouteServerTest { } @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"); + public void directRoutingMiddle() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.718539,50.006581%7C8.718198,50.006065,d%7C8.71785,50.006034%7C8.7169,50.004456&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=3").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -147,8 +149,8 @@ public class RouteServerTest { } @Test - public void misplacedPoints() throws IOException { - URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.708678,49.999188|8.71145,49.999761|8.715801,50.00065&nogos=&profile=trekking&alternativeidx=0&format=geojson&correctMisplacedViaPoints=1&timode=3"); + public void misplacedPoints() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.708678,49.999188%7C8.71145,49.999761%7C8.715801,50.00065&nogos=&profile=trekking&alternativeidx=0&format=geojson&correctMisplacedViaPoints=1&timode=3").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -160,8 +162,21 @@ public class RouteServerTest { } @Test - public void uploadValidProfile() throws IOException { - URL requestUrl = new URL(baseUrl + "brouter/profile"); + public void misplacedPointsRoundabout() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.699487,50.001257%7C8.701569,50.000092%7C8.704873,49.998898&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:correctMisplacedViaPoints=1&timode=3").toURL(); + 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("482", geoJson.query("/features/0/properties/track-length")); + } + + @Test + public void uploadValidProfile() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter/profile").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.setRequestMethod("POST"); @@ -192,8 +207,8 @@ public class RouteServerTest { } @Test - public void uploadInvalidProfile() throws IOException { - URL requestUrl = new URL(baseUrl + "brouter/profile"); + public void uploadInvalidProfile() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "brouter/profile").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.setRequestMethod("POST"); @@ -214,8 +229,8 @@ public class RouteServerTest { } @Test - public void robots() throws IOException { - URL requestUrl = new URL(baseUrl + "robots.txt"); + public void robots() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "robots.txt").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect(); @@ -226,8 +241,8 @@ public class RouteServerTest { } @Test - public void invalidUrl() throws IOException { - URL requestUrl = new URL(baseUrl + "invalid"); + public void invalidUrl() throws IOException, URISyntaxException { + URL requestUrl = new URI(baseUrl + "invalid").toURL(); HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection(); httpConnection.connect();