diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 99d564b..917d633 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -15,6 +15,7 @@ import btools.expressions.BExpressionContext; import btools.expressions.BExpressionContextNode; import btools.expressions.BExpressionContextWay; import btools.mapaccess.GeometryDecoder; +import btools.mapaccess.MatchedWaypoint; import btools.mapaccess.OsmLink; import btools.mapaccess.OsmNode; import btools.util.CheapAngleMeter; @@ -301,6 +302,59 @@ public final class RoutingContext { nogopoints = nogos.isEmpty() ? null : nogos; } + public void checkMatchedWaypointAgainstNogos(List matchedWaypoints) { + if (nogopoints == null) return; + List newMatchedWaypoints = new ArrayList<>(); + int theSize = matchedWaypoints.size(); + int removed = 0; + MatchedWaypoint prevMwp = null; + boolean prevMwpIsInside = false; + for (int i = 0; i < theSize; i++) { + MatchedWaypoint mwp = matchedWaypoints.get(i); + boolean isInsideNogo = false; + OsmNode wp = mwp.crosspoint; + for (OsmNodeNamed nogo : nogopoints) { + if (wp.calcDistance(nogo) < nogo.radius + && (!(nogo instanceof OsmNogoPolygon) + || (((OsmNogoPolygon) nogo).isClosed + ? ((OsmNogoPolygon) nogo).isWithin(wp.ilon, wp.ilat) + : ((OsmNogoPolygon) nogo).isOnPolyline(wp.ilon, wp.ilat)))) { + isInsideNogo = true; + break; + } + } + if (isInsideNogo) { + boolean useAnyway = false; + if (prevMwp == null) useAnyway = true; + else if (mwp.direct) useAnyway = true; + else if (prevMwp.direct) useAnyway = true; + else if (prevMwpIsInside) useAnyway = true; + else if (i == theSize-1) { + throw new IllegalArgumentException("last wpt in restricted area "); + } + if (useAnyway) { + prevMwpIsInside = true; + newMatchedWaypoints.add(mwp); + } else { + removed++; + prevMwpIsInside = false; + } + + } else { + prevMwpIsInside = false; + newMatchedWaypoints.add(mwp); + } + prevMwp = mwp; + } + if (newMatchedWaypoints.size() < 2) { + throw new IllegalArgumentException("a wpt in restricted area "); + } + if (removed > 0) { + matchedWaypoints.clear(); + matchedWaypoints.addAll(newMatchedWaypoints); + } + } + public boolean allInOneNogo(List waypoints) { if (nogopoints == null) return false; boolean allInTotal = false; diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 125aa4b..fcef247 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -446,6 +446,8 @@ public class RoutingEngine extends Thread { } matchWaypointsToNodes(matchedWaypoints); + routingContext.checkMatchedWaypointAgainstNogos(matchedWaypoints); + // detect target islands: restricted search in inverse direction routingContext.inverseDirection = !routingContext.inverseRouting; airDistanceCostFactor = 0.; diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java index abe1305..412ab93 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java @@ -20,6 +20,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.List; import java.util.zip.GZIPOutputStream; import btools.router.OsmNodeNamed; @@ -71,12 +72,15 @@ public class BRouterService extends Service { worker.profileName = profile; worker.profilePath = baseDir + "/brouter/profiles2/" + profile + ".brf"; worker.rawTrackPath = baseDir + "/brouter/modes/" + profile + "_rawtrack.dat"; - if (!new File(worker.profilePath).exists()) + if (!new File(worker.profilePath).exists()) { errMsg = "Profile " + profile + " does not exists"; - try { - readNogos(worker, baseDir); - } catch (Exception e) { - errMsg = e.getLocalizedMessage(); + } else { + try { + readNogos(worker, baseDir); + errMsg = getConfigFromModeForProfile(worker, baseDir, profile); + } catch (Exception e) { + errMsg = e.getLocalizedMessage(); + } } } else { errMsg = getConfigFromMode(worker, baseDir, params.getString("v"), params.getString("fast")); @@ -111,9 +115,20 @@ public class BRouterService extends Service { } } + private String getConfigFromModeForProfile(BRouterWorker worker, String baseDir, String profile) { + return getConfigFromMode(worker, baseDir, profile, null); + } + private String getConfigFromMode(BRouterWorker worker, String baseDir, String mode, String fast) { - boolean isFast = "1".equals(fast) || "true".equals(fast) || "yes".equals(fast); - String mode_key = mode + "_" + (isFast ? "fast" : "short"); + boolean isFast = false; + String profile = null; + String mode_key = null; + if (fast != null) { + isFast = "1".equals(fast) || "true".equals(fast) || "yes".equals(fast); + mode_key = mode + "_" + (isFast ? "fast" : "short"); + } else { + profile = mode; + } BufferedReader br = null; try { @@ -124,7 +139,9 @@ public class BRouterService extends Service { if (line == null) break; ServiceModeConfig smc = new ServiceModeConfig(line); - if (!smc.mode.equals(mode_key)) + if (profile!=null && !smc.profile.equals(profile)) + continue; + else if (profile==null && !smc.mode.equals(mode_key)) continue; worker.profileName = smc.profile; worker.profilePath = baseDir + "/brouter/profiles2/" + smc.profile + ".brf"; @@ -132,6 +149,22 @@ public class BRouterService extends Service { readNogos(worker, baseDir); + // veto nogos by profiles veto list + List nogoList = new ArrayList<>(worker.nogoList); + worker.nogoList.clear(); + for (OsmNodeNamed nogo : nogoList) { + if (!smc.nogoVetos.contains(nogo.ilon + "," + nogo.ilat)) { + worker.nogoList.add(nogo); + } + } + List nogoPolygonsList = new ArrayList<>(worker.nogoPolygonsList); + worker.nogoPolygonsList.clear(); + for (OsmNodeNamed nogo : nogoPolygonsList) { + if (!smc.nogoVetos.contains(nogo.ilon + "," + nogo.ilat)) { + worker.nogoPolygonsList.add(nogo); + } + } + return null; } } catch (Exception e) { @@ -143,7 +176,7 @@ public class BRouterService extends Service { } catch (Exception ee) { } } - return "no brouter service config found for mode " + mode_key; + return "no brouter service config found for mode " + (mode_key!=null?mode_key:profile); } private String getConfigForRemoteProfile(BRouterWorker worker, String baseDir, String remoteProfile) { diff --git a/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java b/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java index 468b910..ce5ba19 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java @@ -67,9 +67,7 @@ public class CoordinateReader { * (with hardcoded name for now) */ public void readPointmap() throws IOException { - if (!_readPointmap(internalDir + "/favourites_bak.gpx")) { - _readPointmap(internalDir + "/favourites.gpx"); - } + _readPointmap(internalDir + "/favourites.gpx"); _readNogoLines(basedir + tracksdir); } @@ -143,17 +141,22 @@ public class CoordinateReader { List tmpPts = new ArrayList<>(); int eventType = xpp.getEventType(); int numSeg = 0; + boolean bIsNogoPoint = false; + String sNogoName = null; while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_TAG: { - if (xpp.getName().equals("trkpt") || xpp.getName().equals("rtept")) { + if (xpp.getName().equals("trkpt") || xpp.getName().equals("rtept") || xpp.getName().equals("wpt")) { final String lon = xpp.getAttributeValue(null, "lon"); final String lat = xpp.getAttributeValue(null, "lat"); if (lon != null && lat != null) { tmpPts.add(new Point( (int) ((Double.parseDouble(lon) + 180.) * 1000000. + 0.5), (int) ((Double.parseDouble(lat) + 90.) * 1000000. + 0.5))); + if (xpp.getName().equals("wpt")) bIsNogoPoint = true; } + } else if (bIsNogoPoint && xpp.getName().equals("name")) { + sNogoName = xpp.nextText(); } break; } @@ -180,6 +183,29 @@ public class CoordinateReader { checkAddPoint("(one-for-all)", nogo); } tmpPts.clear(); + } else if (xpp.getName().equals("wpt")) { + Point p = tmpPts.get(tmpPts.size() - 1); + if (p != null) { + OsmNodeNamed nogo = new OsmNodeNamed(); + nogo.ilon = p.x; + nogo.ilat = p.y; + nogo.name = (sNogoName != null ? sNogoName : "nogo1000 x"); + nogo.isNogo = true; + nogo.radius = 20; + try { + nogo.radius = (sNogoName != null ? Integer.parseInt(sNogoName.substring(4, sNogoName.indexOf(" "))) : 20); + } catch (Exception e) { + try { + nogo.radius = (sNogoName != null ? Integer.parseInt(sNogoName.substring(4)) : 20); + } catch (Exception e1) { + nogo.radius = 20; + } + } + bIsNogoPoint = false; + sNogoName = null; + checkAddPoint("(one-for-all)", nogo); + tmpPts.clear(); + } } break; }