diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java index 71a255bae4..379c98f1bf 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -1,16 +1,32 @@ package net.osmand.plus; +import android.Manifest; import android.app.Activity; -import android.location.GnssNavigationMessage; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.hardware.GeomagneticField; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.location.GnssStatus; +import android.location.GpsSatellite; +import android.location.GpsStatus; +import android.location.GpsStatus.Listener; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Build; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; +import android.os.Bundle; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.support.v7.app.AlertDialog; +import android.util.Log; import net.osmand.GeoidAltitudeCorrection; import net.osmand.PlatformUtil; @@ -22,31 +38,16 @@ import net.osmand.data.LatLon; import net.osmand.data.QuadPoint; import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.routing.RoutingHelper.RouteSegmentSearchResult; import net.osmand.router.RouteSegmentResult; import net.osmand.util.MapUtils; -import android.Manifest; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.hardware.GeomagneticField; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.location.GpsSatellite; -import android.location.GpsStatus; -import android.location.GpsStatus.Listener; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.os.Build; -import android.os.Bundle; -import android.provider.Settings; -import android.support.annotation.Nullable; -import android.support.v4.app.ActivityCompat; -import android.support.v7.app.AlertDialog; -import android.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; public class OsmAndLocationProvider implements SensorEventListener { @@ -146,30 +147,17 @@ public class OsmAndLocationProvider implements SensorEventListener { this.roads = roads; startLocation = new net.osmand.Location(currentLocation); long ms = System.currentTimeMillis(); - if (ms - startLocation.getTime() > 5000 || - ms < startLocation.getTime()) { + if (ms - startLocation.getTime() > 5000 || ms < startLocation.getTime()) { startLocation.setTime(ms); } - currentRoad = -1; - int px = MapUtils.get31TileNumberX(currentLocation.getLongitude()); - int py = MapUtils.get31TileNumberY(currentLocation.getLatitude()); - double dist = 1000; - for (int i = 0; i < roads.size(); i++) { - RouteSegmentResult road = roads.get(i); - boolean plus = road.getStartPointIndex() < road.getEndPointIndex(); - for (int j = road.getStartPointIndex() + 1; j <= road.getEndPointIndex(); ) { - RouteDataObject obj = road.getObject(); - QuadPoint proj = MapUtils.getProjectionPoint31(px, py, obj.getPoint31XTile(j - 1), obj.getPoint31YTile(j - 1), - obj.getPoint31XTile(j), obj.getPoint31YTile(j)); - double dd = MapUtils.squareRootDist31((int) proj.x, (int) proj.y, px, py); - if (dd < dist) { - dist = dd; - currentRoad = i; - currentSegment = j; - currentPoint = proj; - } - j += plus ? 1 : -1; - } + RouteSegmentSearchResult searchResult = + RoutingHelper.searchRouteSegment(currentLocation.getLatitude(), currentLocation.getLongitude(), roads); + if (searchResult != null) { + currentRoad = searchResult.getRoadIndex(); + currentSegment = searchResult.getSegmentIndex(); + currentPoint = searchResult.getPoint(); + } else { + currentRoad = -1; } } diff --git a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java index bee1b4fdf4..fdf17e63a6 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java +++ b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java @@ -23,6 +23,7 @@ import net.osmand.ResultMatcher; import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.data.QuadPoint; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; @@ -31,11 +32,14 @@ import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.routing.RoutingHelper.RouteSegmentSearchResult; import net.osmand.plus.views.ContextMenuLayer; +import net.osmand.router.RouteSegmentResult; import net.osmand.util.MapUtils; import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; public class AvoidSpecificRoads { @@ -215,6 +219,22 @@ public class AvoidSpecificRoads { ll.setLongitude(loc.getLongitude()); ApplicationMode appMode = app.getRoutingHelper().getAppMode(); + List roads = app.getRoutingHelper().getRoute().getOriginalRoute(); + if (roads != null) { + RouteSegmentSearchResult searchResult = + RoutingHelper.searchRouteSegment(loc.getLatitude(), loc.getLongitude(), roads); + if (searchResult != null) { + QuadPoint point = searchResult.getPoint(); + LatLon newLoc = new LatLon(MapUtils.get31LatitudeY((int) point.y), MapUtils.get31LongitudeX((int) point.x)); + ll.setLatitude(newLoc.getLatitude()); + ll.setLongitude(newLoc.getLongitude()); + addImpassableRoadInternal(roads.get(searchResult.getRoadIndex()).getObject(), ll, showDialog, activity, newLoc); + if (!skipWritingSettings) { + app.getSettings().addImpassableRoad(newLoc.getLatitude(), newLoc.getLongitude()); + } + return; + } + } app.getLocationProvider().getRouteSegment(ll, appMode, false, new ResultMatcher() { @Override diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index b9973c6ebe..16673c7d25 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -1,12 +1,14 @@ package net.osmand.plus.routing; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.ValueHolder; +import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; +import net.osmand.data.QuadPoint; import net.osmand.plus.ApplicationMode; -import net.osmand.GPXUtilities.GPXFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmAndAppCustomization.OsmAndAppCustomizationListener; import net.osmand.plus.OsmAndFormatter; @@ -1225,5 +1227,54 @@ public class RoutingHelper { } } + public static class RouteSegmentSearchResult { + private int roadIndex; + private int segmentIndex; + private QuadPoint point; + private RouteSegmentSearchResult(int roadIndex, int segmentIndex, QuadPoint point) { + this.roadIndex = roadIndex; + this.segmentIndex = segmentIndex; + this.point = point; + } + + public int getRoadIndex() { + return roadIndex; + } + + public int getSegmentIndex() { + return segmentIndex; + } + + public QuadPoint getPoint() { + return point; + } + } + + public static RouteSegmentSearchResult searchRouteSegment(double latitude, double longitude, List roads) { + int roadIndex = -1; + int segmentIndex = -1; + QuadPoint point = null; + int px = MapUtils.get31TileNumberX(longitude); + int py = MapUtils.get31TileNumberY(latitude); + double dist = 1000; + for (int i = 0; i < roads.size(); i++) { + RouteSegmentResult road = roads.get(i); + int startPointIndex = road.getStartPointIndex() < road.getEndPointIndex() ? road.getStartPointIndex() : road.getEndPointIndex(); + int endPointIndex = road.getEndPointIndex() > road.getStartPointIndex() ? road.getEndPointIndex() : road.getStartPointIndex(); + RouteDataObject obj = road.getObject(); + for (int j = startPointIndex + 1; j <= endPointIndex; j++) { + QuadPoint proj = MapUtils.getProjectionPoint31(px, py, obj.getPoint31XTile(j - 1), obj.getPoint31YTile(j - 1), + obj.getPoint31XTile(j), obj.getPoint31YTile(j)); + double dd = MapUtils.squareRootDist31((int) proj.x, (int) proj.y, px, py); + if (dd < dist) { + dist = dd; + roadIndex = i; + segmentIndex = j; + point = proj; + } + } + } + return roadIndex != -1 ? new RouteSegmentSearchResult(roadIndex, segmentIndex, point) : null; + } }