From 529fe52976091043d79c625caa393f8f17afb86b Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sat, 19 Jun 2010 12:37:27 +0000 Subject: [PATCH] implement online routing git-svn-id: https://osmand.googlecode.com/svn/trunk@171 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8 --- .../src/com/osmand/ToDoConstants.java | 8 +-- .../com/osmand/activities/MapActivity.java | 28 ++++++--- .../com/osmand/activities/RoutingHelper.java | 24 +++++--- OsmAnd/src/com/osmand/views/MapInfoLayer.java | 60 ++++++++++++++++--- .../com/osmand/views/OsmandMapTileView.java | 2 +- .../com/osmand/views/PointLocationLayer.java | 12 ++++ OsmAnd/src/com/osmand/views/RouteLayer.java | 27 +++++++-- 7 files changed, 127 insertions(+), 34 deletions(-) diff --git a/DataExtractionOSM/src/com/osmand/ToDoConstants.java b/DataExtractionOSM/src/com/osmand/ToDoConstants.java index 409f88b306..c2d84b8d16 100644 --- a/DataExtractionOSM/src/com/osmand/ToDoConstants.java +++ b/DataExtractionOSM/src/com/osmand/ToDoConstants.java @@ -40,10 +40,9 @@ public class ToDoConstants { // DONE: Load transport routes in swing. // TODO: Create transport index, create transport activity - - // 34. Suppport navigation for calculated route (example of get route from internet is in swing app). -// IDEA : Victor have ideas +// DONE : MiniMap done, Routing settings done, RouteLayer done, RoutingHelper done. +// TODO : Test again? // FUTURE RELEASES @@ -62,7 +61,8 @@ public class ToDoConstants { // BUGS Android // 5. Improvement : Implement caching files existing on FS, implement specific method in RM // Introducing cache of file names that are on disk (creating new File() consumes a lot of memory) - // 6. Improvement postal_code search : replace search city <-> postal_code (show streets for postal_code) + // 6. Improvement postal_code search : replace search city <-> postal_code (show streets for postal_code) + // 7. Update map is duplicated in target & in update menu (context menu) // TODO swing diff --git a/OsmAnd/src/com/osmand/activities/MapActivity.java b/OsmAnd/src/com/osmand/activities/MapActivity.java index fd9a253b31..d3ed8fce2f 100644 --- a/OsmAnd/src/com/osmand/activities/MapActivity.java +++ b/OsmAnd/src/com/osmand/activities/MapActivity.java @@ -96,17 +96,20 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat mapView.setMapLocationListener(this); poiMapLayer = new POIMapLayer(); mapView.addLayer(poiMapLayer); + routingHelper = new RoutingHelper(this); + routeLayer = new RouteLayer(routingHelper); + mapView.addLayer(routeLayer); + osmBugsLayer = new OsmBugsLayer(this); + mapInfoLayer = new MapInfoLayer(this, routeLayer); + mapView.addLayer(mapInfoLayer); navigationLayer = new PointNavigationLayer(); mapView.addLayer(navigationLayer); locationLayer = new PointLocationLayer(); mapView.addLayer(locationLayer); - mapInfoLayer = new MapInfoLayer(this); - mapView.addLayer(mapInfoLayer); - osmBugsLayer = new OsmBugsLayer(this); + savingTrackHelper = new SavingTrackHelper(this); - routingHelper = new RoutingHelper(this); - routeLayer = new RouteLayer(routingHelper); - mapView.addLayer(routeLayer); + + locationLayer.setAppMode(OsmandSettings.getApplicationMode(this)); @@ -256,9 +259,18 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat } } Log.d(LogUtil.TAG, "Location changed"); - // TODO delete !!! (only for test purposes) + // TODO delete !!! (only for test purposes) devices support that information (possibly keep for other providers?) if(!location.hasSpeed() && locationLayer.getLastKnownLocation() != null){ - location.setSpeed(location.distanceTo(locationLayer.getLastKnownLocation())); + float d = location.distanceTo(locationLayer.getLastKnownLocation()); + if(d > 100){ + d = 100; + } + location.setSpeed(d); + } + if(!location.hasBearing() && locationLayer.getLastKnownLocation() != null){ + if(locationLayer.getLastKnownLocation().distanceTo(location) > 10){ + location.setBearing(locationLayer.getLastKnownLocation().bearingTo(location)); + } } locationLayer.setLastKnownLocation(location); diff --git a/OsmAnd/src/com/osmand/activities/RoutingHelper.java b/OsmAnd/src/com/osmand/activities/RoutingHelper.java index de71333d16..5e5947ee0c 100644 --- a/OsmAnd/src/com/osmand/activities/RoutingHelper.java +++ b/OsmAnd/src/com/osmand/activities/RoutingHelper.java @@ -117,6 +117,10 @@ public class RoutingHelper { } + public boolean isRouterEnabled(){ + return finalLocation != null && lastFixedLocation != null; + } + public boolean finishAtLocation(Location currentLocation) { Location lastPoint = routeNodes.get(routeNodes.size() - 1); @@ -237,9 +241,12 @@ public class RoutingHelper { currentRoute = 0; } - public int getDistance(){ + public synchronized int getDistance(double lat, double lon){ if(listDistance != null && currentRoute < listDistance.length){ - return listDistance[currentRoute]; + int dist = listDistance[currentRoute]; + Location l = routeNodes.get(currentRoute); + dist += MapUtils.getDistance(lat, lon, l.getLatitude(), l.getLongitude()); + return dist; } return 0; } @@ -323,16 +330,17 @@ public class RoutingHelper { } } - for(int i=currentRoute; i currentRoute) { - l.add(0, ls); - previousVisible = true; - } else if(lastFixedLocation != null){ - l.add(0, ls); + if (!previousVisible) { + if (i > currentRoute) { + l.add(0, routeNodes.get(i - 1)); + } else if (lastFixedLocation != null) { + l.add(0, lastFixedLocation); + } } previousVisible = true; } else if(previousVisible){ diff --git a/OsmAnd/src/com/osmand/views/MapInfoLayer.java b/OsmAnd/src/com/osmand/views/MapInfoLayer.java index 4b5191e238..68a171efae 100644 --- a/OsmAnd/src/com/osmand/views/MapInfoLayer.java +++ b/OsmAnd/src/com/osmand/views/MapInfoLayer.java @@ -17,8 +17,10 @@ public class MapInfoLayer implements OsmandMapLayer { private OsmandMapTileView view; private final MapActivity map; + private final RouteLayer routeLayer; private Paint paintBlack; + private Paint paintMiniRoute; private Path pathForCompass; private Path pathForCompass2; private Paint fillBlack; @@ -26,6 +28,7 @@ public class MapInfoLayer implements OsmandMapLayer { private RectF boundsForCompass; private RectF boundsForZoom; private RectF boundsForDist; + private RectF boundsForMiniRoute; private RectF boundsForSpeed; private Paint paintAlphaGray; @@ -38,10 +41,14 @@ public class MapInfoLayer implements OsmandMapLayer { private float cachedSpeed = 0; private int cachedZoom = 0; private String cachedZoomString = ""; + private int centerMiniRouteY; + private int centerMiniRouteX; + private float scaleMiniRoute; - public MapInfoLayer(MapActivity map){ + public MapInfoLayer(MapActivity map, RouteLayer layer){ this.map = map; + this.routeLayer = layer; } @Override @@ -63,15 +70,26 @@ public class MapInfoLayer implements OsmandMapLayer { fillBlack.setColor(Color.BLACK); fillBlack.setAntiAlias(true); + paintMiniRoute = new Paint(); + paintMiniRoute.setStyle(Style.STROKE); + paintMiniRoute.setStrokeWidth(35); + paintMiniRoute.setColor(Color.BLUE); + paintMiniRoute.setAntiAlias(true); + fillRed = new Paint(); fillRed.setStyle(Style.FILL_AND_STROKE); fillRed.setColor(Color.RED); fillRed.setAntiAlias(true); - boundsForCompass = new RectF(0, 0, 32, 32); - boundsForDist = new RectF(32, 0, 110, 32); - boundsForZoom = new RectF(0, 32, 32, 64); - boundsForSpeed = new RectF(32, 32, 110, 64); + boundsForCompass = new RectF(0, 0, 35, 32); + boundsForDist = new RectF(35, 0, 110, 32); + boundsForZoom = new RectF(0, 32, 35, 64); + boundsForSpeed = new RectF(35, 32, 110, 64); + + boundsForMiniRoute = new RectF(0, 64, 96, 196); + centerMiniRouteX = 48; + centerMiniRouteY= 160; + scaleMiniRoute = 0.1f; pathForCompass = new Path(); pathForCompass.moveTo(9, 15.5f); @@ -87,7 +105,7 @@ public class MapInfoLayer implements OsmandMapLayer { } public boolean distChanged(int oldDist, int dist){ - if(oldDist != 0 && ((oldDist - dist > 100) || (Math.abs(((float) dist - oldDist)/oldDist) < 0.01))){ + if(oldDist != 0 && oldDist - dist < 100 && Math.abs(((float) dist - oldDist)/oldDist) < 0.01){ return false; } return true; @@ -97,8 +115,8 @@ public class MapInfoLayer implements OsmandMapLayer { public void onDraw(Canvas canvas) { if(map.getPointToNavigate() != null){ int d = 0; - if(map.getRoutingHelper().getFinalLocation() != null){ - d = map.getRoutingHelper().getDistance(); + if(map.getRoutingHelper().isRouterEnabled()){ + d = map.getRoutingHelper().getDistance(view.getLatitude(), view.getLongitude()); } if (d == 0) { Location.distanceBetween(view.getLatitude(), view.getLongitude(), map.getPointToNavigate().getLatitude(), map @@ -130,7 +148,8 @@ public class MapInfoLayer implements OsmandMapLayer { } // draw zoom canvas.drawRoundRect(boundsForZoom, 3, 3, paintAlphaGray); - canvas.drawText(cachedZoomString, boundsForZoom.left + 5, boundsForZoom.bottom - 9, paintBlack); + canvas.drawRoundRect(boundsForZoom, 3, 3, paintBlack); + canvas.drawText(cachedZoomString, boundsForZoom.left + 5, boundsForZoom.bottom - 7, paintBlack); // draw speed if(map.getLastKnownLocation() != null && map.getLastKnownLocation().hasSpeed()){ @@ -142,22 +161,45 @@ public class MapInfoLayer implements OsmandMapLayer { } if(cachedSpeed > 0){ canvas.drawRoundRect(boundsForSpeed, 3, 3, paintAlphaGray); + canvas.drawRoundRect(boundsForSpeed, 3, 3, paintBlack); canvas.drawText(cachedSpeedString, boundsForSpeed.left + 8, boundsForSpeed.bottom - 9, paintBlack); } } // draw distance to point if(cachedDistString != null){ canvas.drawRoundRect(boundsForDist, 3, 3, paintAlphaGray); + canvas.drawRoundRect(boundsForDist, 3, 3, paintBlack); canvas.drawCircle(boundsForDist.left + 8, boundsForDist.bottom - 15, 4, fillRed); canvas.drawText(cachedDistString, boundsForDist.left + 15, boundsForDist.bottom - 9, paintBlack); } + + + + if(routeLayer != null && !routeLayer.getPath().isEmpty()){ + canvas.save(); + canvas.clipRect(boundsForMiniRoute); + canvas.drawRoundRect(boundsForMiniRoute, 3, 3, paintAlphaGray); + canvas.drawRoundRect(boundsForMiniRoute, 3, 3, paintBlack); + + canvas.translate(centerMiniRouteX - view.getCenterPointX(), centerMiniRouteY - view.getCenterPointY()); + canvas.scale(scaleMiniRoute, scaleMiniRoute, view.getCenterPointX(), view.getCenterPointY()); + canvas.rotate(view.getRotate(), view.getCenterPointX(), view.getCenterPointY()); + + canvas.drawCircle(view.getCenterPointX(), view.getCenterPointY(), 3/scaleMiniRoute, fillBlack); + canvas.drawPath(routeLayer.getPath(), paintMiniRoute); + canvas.restore(); + } + // draw compass the last because it use rotating canvas.drawRoundRect(boundsForCompass, 3, 3, paintAlphaGray); + canvas.drawRoundRect(boundsForCompass, 3, 3, paintBlack); canvas.rotate(view.getRotate(), 15, 15); canvas.drawPath(pathForCompass2, fillRed); canvas.drawPath(pathForCompass, fillBlack); + + } diff --git a/OsmAnd/src/com/osmand/views/OsmandMapTileView.java b/OsmAnd/src/com/osmand/views/OsmandMapTileView.java index 388e1fb7f6..54092b3e76 100644 --- a/OsmAnd/src/com/osmand/views/OsmandMapTileView.java +++ b/OsmAnd/src/com/osmand/views/OsmandMapTileView.java @@ -160,8 +160,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall } public void addLayer(OsmandMapLayer layer){ - layers.add(layer); layer.initLayer(this); + layers.add(layer); } public void removeLayer(OsmandMapLayer layer){ diff --git a/OsmAnd/src/com/osmand/views/PointLocationLayer.java b/OsmAnd/src/com/osmand/views/PointLocationLayer.java index 02e895672c..f7ad11f1e0 100644 --- a/OsmAnd/src/com/osmand/views/PointLocationLayer.java +++ b/OsmAnd/src/com/osmand/views/PointLocationLayer.java @@ -20,6 +20,7 @@ public class PointLocationLayer implements OsmandMapLayer { private Paint location; private Paint bearing; + private Paint bearingOver; private Paint area; private Paint headingPaint; private Path pathForDirection; @@ -54,6 +55,11 @@ public class PointLocationLayer implements OsmandMapLayer { bearing.setAntiAlias(true); bearing.setStyle(Style.FILL); + bearingOver = new Paint(); + bearingOver.setColor(Color.BLACK); + bearingOver.setAntiAlias(true); + bearingOver.setStyle(Style.STROKE); + pathForDirection = new Path(); } @@ -124,6 +130,7 @@ public class PointLocationLayer implements OsmandMapLayer { pathForDirection.transform(m); canvas.drawPath(pathForDirection, this.bearing); + canvas.drawPath(pathForDirection, this.bearingOver); } } @@ -169,6 +176,11 @@ public class PointLocationLayer implements OsmandMapLayer { } public void setAppMode(ApplicationMode appMode) { this.appMode = appMode; + if(this.appMode == ApplicationMode.CAR || this.appMode == ApplicationMode.BICYCLE){ + this.bearing.setAlpha(180); + } else { + this.bearing.setAlpha(150); + } } @Override public boolean drawInScreenPixels() { diff --git a/OsmAnd/src/com/osmand/views/RouteLayer.java b/OsmAnd/src/com/osmand/views/RouteLayer.java index b8af9c0925..6777c2a89f 100644 --- a/OsmAnd/src/com/osmand/views/RouteLayer.java +++ b/OsmAnd/src/com/osmand/views/RouteLayer.java @@ -29,6 +29,7 @@ public class RouteLayer implements OsmandMapLayer { private Paint paint; private Path path; + private float pathBearing; public RouteLayer(RoutingHelper helper){ this.helper = helper; @@ -39,7 +40,7 @@ public class RouteLayer implements OsmandMapLayer { boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight()); tileRect = new RectF(); paint = new Paint(); - paint.setColor(Color.GRAY); + paint.setColor(Color.BLUE); paint.setStyle(Style.STROKE); paint.setStrokeWidth(14); paint.setAlpha(150); @@ -53,11 +54,16 @@ public class RouteLayer implements OsmandMapLayer { } + @Override public void onDraw(Canvas canvas) { + path.reset(); if (helper.hasPointsToShow()) { long time = System.currentTimeMillis(); - boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight()); + int w = view.getWidth(); + int h = view.getHeight(); + boundsRect = new Rect(-w / 2, -h, 3 * w / 2, h); +// boundsRect = new Rect(0, 0, w, h); view.calculateTileRectangle(boundsRect, view.getCenterPointX(), view.getCenterPointY(), view.getXTile(), view.getYTile(), tileRect); double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top); @@ -68,14 +74,18 @@ public class RouteLayer implements OsmandMapLayer { if((System.currentTimeMillis() - time) > 40){ Log.e(LogUtil.TAG, "Calculate route layer " + (System.currentTimeMillis() - time)); } + if (points.size() > 0) { int px = view.getMapXForPoint(points.get(0).getLongitude()); int py = view.getMapYForPoint(points.get(0).getLatitude()); - path.reset(); path.moveTo(px, py); - for (Location o : points) { + for (int i=1; i