diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java index 8431df7244..57b87dcc8c 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java @@ -1,25 +1,9 @@ package net.osmand.binary; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; - import com.google.protobuf.CodedInputStream; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.WireFormat; -import gnu.trove.iterator.TLongObjectIterator; -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.list.array.TLongArrayList; -import gnu.trove.map.hash.TIntObjectHashMap; -import gnu.trove.map.hash.TLongObjectHashMap; import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; @@ -34,6 +18,23 @@ import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import net.osmand.util.OpeningHoursParser; +import org.apache.commons.logging.Log; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import gnu.trove.iterator.TLongObjectIterator; +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.list.array.TLongArrayList; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.map.hash.TLongObjectHashMap; + public class BinaryMapRouteReaderAdapter { protected static final Log LOG = PlatformUtil.getLog(BinaryMapRouteReaderAdapter.class); private static final int SHIFT_COORDINATES = 4; @@ -303,6 +304,7 @@ public class BinaryMapRouteReaderAdapter { public int directionTrafficSignalsBackward = -1; public int trafficSignals = -1; public int stopSign = -1; + public int stopMinor = -1; public int giveWaySign = -1; int nameTypeRule = -1; @@ -363,6 +365,8 @@ public class BinaryMapRouteReaderAdapter { destinationRefTypeRule = id; } else if (tags.equals("highway") && val.equals("traffic_signals")){ trafficSignals = id; + } else if (tags.equals("stop") && val.equals("minor")) { + stopMinor = id; } else if (tags.equals("highway") && val.equals("stop")){ stopSign = id; } else if (tags.equals("highway") && val.equals("give_way")){ diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index bc81ca667e..61d282e5e4 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -8,6 +8,7 @@ import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import net.osmand.util.TransliterationHelper; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.logging.Log; import java.text.MessageFormat; @@ -499,6 +500,17 @@ public class RouteDataObject { } return pointTypes[ind]; } + + public void removePointType(int ind, int type) { + if (pointTypes != null || ind < pointTypes.length) { + int[] typesArr = pointTypes[ind]; + for (int t : typesArr) { + if (t == type) { + pointTypes[ind] = ArrayUtils.removeElement(typesArr, t); + } + } + } + } public int[] getTypes() { return types; diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java index 26d984b2da..417f4f3511 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java @@ -176,11 +176,86 @@ public class RouteResultPreparation { combineWayPointsForAreaRouting(ctx, result); validateAllPointsConnected(result); splitRoadsAndAttachRoadSegments(ctx, result, recalculation); + for (int i = 0; i < result.size(); i++) { + prepareStopSign(result.get(i)); + } calculateTimeSpeed(ctx, result); - prepareTurnResults(ctx, result); return result; } + + public RouteSegmentResult prepareStopSign(RouteSegmentResult seg) { + int start = seg.getStartPointIndex(); + int end = seg.getEndPointIndex(); + List stops = new ArrayList<>(); + + for (int i = start; i > end; i--) { + int[] pointTypes = seg.getObject().getPointTypes(i); + if (pointTypes != null) { + for (int j = 0; j < pointTypes.length; j++) { + if (pointTypes[j] == seg.getObject().region.stopMinor) { + stops.add(i); + } + } + } + } + + for (int stop : stops) { + List attachedRoutes = seg.getAttachedRoutes(stop); + for (RouteSegmentResult attached : attachedRoutes) { + int attStopPriority = highwayStopPriority(attached.getObject().getHighway()); + int segStopPriority = highwayStopPriority(seg.getObject().getHighway()); + if (segStopPriority > attStopPriority) { + seg.getObject().removePointType(stop, seg.getObject().region.stopSign); + } + } + } + + return seg; + } + + private int highwayStopPriority(String highway) { + if (highway.endsWith("trunk")) { + return 13; + } + if (highway.endsWith("trunk_link")) { + return 12; + } + if (highway.endsWith("primary")) { + return 11; + } + if (highway.endsWith("primary_link")) { + return 10; + } + if (highway.endsWith("secondary")) { + return 9; + } + if (highway.endsWith("secondary_link")) { + return 8; + } + if (highway.endsWith("tertiary")) { + return 7; + } + if (highway.endsWith("tertiary_link")) { + return 6; + } + if (highway.endsWith("residential")) { + return 5; + } + if (highway.endsWith("living_street")) { + return 4; + } + if (highway.endsWith("track")) { + return 3; + } + if (highway.endsWith("footway")) { + return 2; + } + if (highway.endsWith("path")) { + return 1; + } + return 0; + } public void prepareTurnResults(RoutingContext ctx, List result) { for (int i = 0; i < result.size(); i ++) {