diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index b52a9ceed2..ad4d926329 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -1108,7 +1108,6 @@ Memoria proporcional %4$s MB (Limite Android %5$s MB, Dalvik %6$s MB). Hacer una foto ¿Seguro que quieres parar la navegación? ¿Seguro que quieres borrar tu punto de destino? - Activa el enrutamiento preciso para calcular rutas precisas sin fallos. Está muy limitado por la distancia y no utiliza la biblioteca nativa. Enrutado preciso (alfa) diff --git a/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java new file mode 100644 index 0000000000..e28219fce7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/CurrentPositionHelper.java @@ -0,0 +1,118 @@ +package net.osmand.plus; + +import java.io.IOException; + +import net.osmand.Location; +import net.osmand.binary.RouteDataObject; +import net.osmand.osm.MapUtils; +import net.osmand.router.BinaryRoutePlanner.RouteSegment; +import net.osmand.router.GeneralRouter.GeneralRouterProfile; +import net.osmand.router.RoutePlannerFrontEnd; +import net.osmand.router.RoutingConfiguration; +import net.osmand.router.RoutingContext; + +public class CurrentPositionHelper { + + private RouteDataObject lastFound; + private Location lastAskedLocation = null; + private Thread calculatingThread = null; + private RoutingContext ctx; + private OsmandApplication app; + private ApplicationMode am; + + public CurrentPositionHelper(OsmandApplication app) { + this.app = app; + } + + private void initCtx(OsmandApplication app) { + ResourceManager r = app.getResourceManager(); + am = app.getSettings().getApplicationMode(); + GeneralRouterProfile p ; + if (am == ApplicationMode.BICYCLE) { + p = GeneralRouterProfile.BICYCLE; + } else if (am == ApplicationMode.PEDESTRIAN) { + p = GeneralRouterProfile.PEDESTRIAN; + } else { + p = GeneralRouterProfile.CAR; + } + RoutingConfiguration cfg = RoutingConfiguration.getDefault().build(p.name().toLowerCase(), 10); + ctx = new RoutingContext(cfg, null, r.getRoutingMapFiles()); + } + + private RouteDataObject runUpdateInThread(Location loc) { + RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd(false); + try { + if(ctx == null || am != app.getSettings().getApplicationMode()) { + initCtx(app); + } + RouteSegment sg = rp.findRouteSegment(loc.getLatitude(), loc.getLongitude(), ctx); + return sg.getRoad(); + } catch (IOException e) { + return null; + } + } + + + private void scheduleRouteSegmentFind(final Location loc){ + if(calculatingThread == Thread.currentThread()) { + lastFound = runUpdateInThread(loc); + } else if(calculatingThread == null && loc != null) { + calculatingThread = new Thread(new Runnable() { + @Override + public void run() { + try { + lastFound = runUpdateInThread(loc); + if (lastAskedLocation != loc) { + // refresh and run new task if needed + getLastKnownRouteSegment(lastAskedLocation); + } + } finally { + calculatingThread = null; + } + } + }); + calculatingThread.start(); + } + + } + + private static double getOrthogonalDistance(RouteDataObject r, Location loc){ + double d = 1000; + if (r.getPointsLength() > 0) { + double pLt = MapUtils.get31LatitudeY(r.getPoint31YTile(0)); + double pLn = MapUtils.get31LongitudeX(r.getPoint31XTile(0)); + for (int i = 1; i < r.getPointsLength(); i++) { + double lt = MapUtils.get31LatitudeY(r.getPoint31YTile(i)); + double ln = MapUtils.get31LongitudeX(r.getPoint31XTile(i)); + double od = MapUtils.getOrthogonalDistance(loc.getLatitude(), loc.getLongitude(), pLt, pLn, lt, ln); + if (od < d) { + d = od; + } + pLt = lt; + pLn = ln; + } + } + return d; + } + + public RouteDataObject getLastKnownRouteSegment(Location loc) { + lastAskedLocation = loc; + RouteDataObject r = lastFound; + if (loc == null || loc.getAccuracy() > 50) { + return null; + } + if (r == null) { + scheduleRouteSegmentFind(loc); + return null; + } + double d = getOrthogonalDistance(r, loc); + if (d > 25) { + scheduleRouteSegmentFind(loc); + } + if (d < 70) { + return r; + } + return null; + } + +} diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 5c3b862b11..e342240526 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -14,6 +14,7 @@ import net.osmand.access.AccessibleActivity; import net.osmand.access.AccessibleAlertBuilder; import net.osmand.access.AccessibleToast; import net.osmand.access.NavigationInfo; +import net.osmand.binary.RouteDataObject; import net.osmand.data.MapTileDownloader.DownloadRequest; import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.IMapLocationListener; @@ -24,6 +25,7 @@ import net.osmand.plus.BusyIndicator; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities.GPXFile; +import net.osmand.plus.CurrentPositionHelper; import net.osmand.plus.MapScreen; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -119,6 +121,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe private OsmandMapTileView mapView; private MapActivityActions mapActions; private MapActivityLayers mapLayers; + private CurrentPositionHelper currentPositionHelper; private NavigationInfo navigationInfo; private SavingTrackHelper savingTrackHelper; @@ -167,6 +170,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe settings = getMyApplication().getSettings(); mapActions = new MapActivityActions(this); mapLayers = new MapActivityLayers(this); + currentPositionHelper = new CurrentPositionHelper(getMyApplication()); navigationInfo = new NavigationInfo(this); requestWindowFeature(Window.FEATURE_NO_TITLE); // Full screen is not used here @@ -1044,6 +1048,10 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe return mapLayers.getLocationLayer().getLastKnownLocation(); } + public RouteDataObject getLastRouteDataObject(){ + return currentPositionHelper.getLastKnownRouteSegment(getLastKnownLocation()); + } + public LatLon getMapLocation(){ return new LatLon(mapView.getLatitude(), mapView.getLongitude()); } @@ -1438,7 +1446,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } - private boolean isMapLinkedToLocation(){ + public boolean isMapLinkedToLocation(){ return isMapLinkedToLocation; } diff --git a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java index 5144811999..966d58f2cb 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java @@ -11,6 +11,7 @@ import java.util.Set; import net.osmand.Algoritms; import net.osmand.access.AccessibleToast; +import net.osmand.binary.RouteDataObject; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -902,9 +903,14 @@ public class MapInfoLayer extends OsmandMapLayer { int di = map.getMapLayers().getRouteInfoLayer().getDirectionInfo(); if (di >= 0 && map.getMapLayers().getRouteInfoLayer().isVisible()) { RouteDirectionInfo next = routingHelper.getRouteDirections().get(di); - text = routingHelper.formatStreetName(next.getStreetName(), next.getRef()); + text = RoutingHelper.formatStreetName(next.getStreetName(), next.getRef()); } } + } else if(map.isMapLinkedToLocation()) { + RouteDataObject rt = map.getLastRouteDataObject(); + if(rt != null) { + text = RoutingHelper.formatStreetName(rt.getName(), rt.getRef()); + } } if(text == null) { text = ""; diff --git a/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java b/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java index 5242f8eadd..7e46d725ab 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java @@ -6,6 +6,7 @@ import java.util.Arrays; import net.osmand.Algoritms; import net.osmand.GeoidAltitudeCorrection; import net.osmand.Location; +import net.osmand.binary.RouteDataObject; import net.osmand.osm.LatLon; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; @@ -316,7 +317,15 @@ public class RouteInfoControls { @Override public boolean updateInfo() { - float mx = rh == null ? 0 : rh.getCurrentMaxSpeed(); + float mx = 0; + if ((rh == null || !rh.isFollowingMode()) && map.isMapLinkedToLocation()) { + RouteDataObject ro = map.getLastRouteDataObject(); + if(ro != null) { + mx = ro.getMaximumSpeed(); + } + } else { + mx = rh.getCurrentMaxSpeed(); + } if (cachedSpeed != mx) { cachedSpeed = mx; if (cachedSpeed == 0) {