implement online routing

git-svn-id: https://osmand.googlecode.com/svn/trunk@171 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-06-19 12:37:27 +00:00
parent d7b27a8ebf
commit 529fe52976
7 changed files with 127 additions and 34 deletions

View file

@ -40,10 +40,9 @@ public class ToDoConstants {
// DONE: Load transport routes in swing. // DONE: Load transport routes in swing.
// TODO: Create transport index, create transport activity // TODO: Create transport index, create transport activity
// 34. Suppport navigation for calculated route (example of get route from internet is in swing app). // 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 // FUTURE RELEASES
@ -62,7 +61,8 @@ public class ToDoConstants {
// BUGS Android // BUGS Android
// 5. Improvement : Implement caching files existing on FS, implement specific method in RM // 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) // 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 // TODO swing

View file

@ -96,17 +96,20 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
mapView.setMapLocationListener(this); mapView.setMapLocationListener(this);
poiMapLayer = new POIMapLayer(); poiMapLayer = new POIMapLayer();
mapView.addLayer(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(); navigationLayer = new PointNavigationLayer();
mapView.addLayer(navigationLayer); mapView.addLayer(navigationLayer);
locationLayer = new PointLocationLayer(); locationLayer = new PointLocationLayer();
mapView.addLayer(locationLayer); mapView.addLayer(locationLayer);
mapInfoLayer = new MapInfoLayer(this);
mapView.addLayer(mapInfoLayer);
osmBugsLayer = new OsmBugsLayer(this);
savingTrackHelper = new SavingTrackHelper(this); savingTrackHelper = new SavingTrackHelper(this);
routingHelper = new RoutingHelper(this);
routeLayer = new RouteLayer(routingHelper);
mapView.addLayer(routeLayer);
locationLayer.setAppMode(OsmandSettings.getApplicationMode(this)); locationLayer.setAppMode(OsmandSettings.getApplicationMode(this));
@ -256,9 +259,18 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
} }
} }
Log.d(LogUtil.TAG, "Location changed"); 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){ 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); locationLayer.setLastKnownLocation(location);

View file

@ -117,6 +117,10 @@ public class RoutingHelper {
} }
public boolean isRouterEnabled(){
return finalLocation != null && lastFixedLocation != null;
}
public boolean finishAtLocation(Location currentLocation) { public boolean finishAtLocation(Location currentLocation) {
Location lastPoint = routeNodes.get(routeNodes.size() - 1); Location lastPoint = routeNodes.get(routeNodes.size() - 1);
@ -237,9 +241,12 @@ public class RoutingHelper {
currentRoute = 0; currentRoute = 0;
} }
public int getDistance(){ public synchronized int getDistance(double lat, double lon){
if(listDistance != null && currentRoute < listDistance.length){ 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; return 0;
} }
@ -323,16 +330,17 @@ public class RoutingHelper {
} }
} }
for(int i=currentRoute; i<routeNodes.size(); i++){ for (int i = currentRoute; i < routeNodes.size(); i++) {
Location ls = routeNodes.get(i); Location ls = routeNodes.get(i);
if(leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude && if(leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude &&
bottomLatitude <= ls.getLatitude() && ls.getLatitude() <= topLatitude){ bottomLatitude <= ls.getLatitude() && ls.getLatitude() <= topLatitude){
l.add(ls); l.add(ls);
if (i > currentRoute) { if (!previousVisible) {
l.add(0, ls); if (i > currentRoute) {
previousVisible = true; l.add(0, routeNodes.get(i - 1));
} else if(lastFixedLocation != null){ } else if (lastFixedLocation != null) {
l.add(0, ls); l.add(0, lastFixedLocation);
}
} }
previousVisible = true; previousVisible = true;
} else if(previousVisible){ } else if(previousVisible){

View file

@ -17,8 +17,10 @@ public class MapInfoLayer implements OsmandMapLayer {
private OsmandMapTileView view; private OsmandMapTileView view;
private final MapActivity map; private final MapActivity map;
private final RouteLayer routeLayer;
private Paint paintBlack; private Paint paintBlack;
private Paint paintMiniRoute;
private Path pathForCompass; private Path pathForCompass;
private Path pathForCompass2; private Path pathForCompass2;
private Paint fillBlack; private Paint fillBlack;
@ -26,6 +28,7 @@ public class MapInfoLayer implements OsmandMapLayer {
private RectF boundsForCompass; private RectF boundsForCompass;
private RectF boundsForZoom; private RectF boundsForZoom;
private RectF boundsForDist; private RectF boundsForDist;
private RectF boundsForMiniRoute;
private RectF boundsForSpeed; private RectF boundsForSpeed;
private Paint paintAlphaGray; private Paint paintAlphaGray;
@ -38,10 +41,14 @@ public class MapInfoLayer implements OsmandMapLayer {
private float cachedSpeed = 0; private float cachedSpeed = 0;
private int cachedZoom = 0; private int cachedZoom = 0;
private String cachedZoomString = ""; 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.map = map;
this.routeLayer = layer;
} }
@Override @Override
@ -63,15 +70,26 @@ public class MapInfoLayer implements OsmandMapLayer {
fillBlack.setColor(Color.BLACK); fillBlack.setColor(Color.BLACK);
fillBlack.setAntiAlias(true); fillBlack.setAntiAlias(true);
paintMiniRoute = new Paint();
paintMiniRoute.setStyle(Style.STROKE);
paintMiniRoute.setStrokeWidth(35);
paintMiniRoute.setColor(Color.BLUE);
paintMiniRoute.setAntiAlias(true);
fillRed = new Paint(); fillRed = new Paint();
fillRed.setStyle(Style.FILL_AND_STROKE); fillRed.setStyle(Style.FILL_AND_STROKE);
fillRed.setColor(Color.RED); fillRed.setColor(Color.RED);
fillRed.setAntiAlias(true); fillRed.setAntiAlias(true);
boundsForCompass = new RectF(0, 0, 32, 32); boundsForCompass = new RectF(0, 0, 35, 32);
boundsForDist = new RectF(32, 0, 110, 32); boundsForDist = new RectF(35, 0, 110, 32);
boundsForZoom = new RectF(0, 32, 32, 64); boundsForZoom = new RectF(0, 32, 35, 64);
boundsForSpeed = new RectF(32, 32, 110, 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 = new Path();
pathForCompass.moveTo(9, 15.5f); pathForCompass.moveTo(9, 15.5f);
@ -87,7 +105,7 @@ public class MapInfoLayer implements OsmandMapLayer {
} }
public boolean distChanged(int oldDist, int dist){ 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 false;
} }
return true; return true;
@ -97,8 +115,8 @@ public class MapInfoLayer implements OsmandMapLayer {
public void onDraw(Canvas canvas) { public void onDraw(Canvas canvas) {
if(map.getPointToNavigate() != null){ if(map.getPointToNavigate() != null){
int d = 0; int d = 0;
if(map.getRoutingHelper().getFinalLocation() != null){ if(map.getRoutingHelper().isRouterEnabled()){
d = map.getRoutingHelper().getDistance(); d = map.getRoutingHelper().getDistance(view.getLatitude(), view.getLongitude());
} }
if (d == 0) { if (d == 0) {
Location.distanceBetween(view.getLatitude(), view.getLongitude(), map.getPointToNavigate().getLatitude(), map Location.distanceBetween(view.getLatitude(), view.getLongitude(), map.getPointToNavigate().getLatitude(), map
@ -130,7 +148,8 @@ public class MapInfoLayer implements OsmandMapLayer {
} }
// draw zoom // draw zoom
canvas.drawRoundRect(boundsForZoom, 3, 3, paintAlphaGray); 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 // draw speed
if(map.getLastKnownLocation() != null && map.getLastKnownLocation().hasSpeed()){ if(map.getLastKnownLocation() != null && map.getLastKnownLocation().hasSpeed()){
@ -142,22 +161,45 @@ public class MapInfoLayer implements OsmandMapLayer {
} }
if(cachedSpeed > 0){ if(cachedSpeed > 0){
canvas.drawRoundRect(boundsForSpeed, 3, 3, paintAlphaGray); canvas.drawRoundRect(boundsForSpeed, 3, 3, paintAlphaGray);
canvas.drawRoundRect(boundsForSpeed, 3, 3, paintBlack);
canvas.drawText(cachedSpeedString, boundsForSpeed.left + 8, boundsForSpeed.bottom - 9, paintBlack); canvas.drawText(cachedSpeedString, boundsForSpeed.left + 8, boundsForSpeed.bottom - 9, paintBlack);
} }
} }
// draw distance to point // draw distance to point
if(cachedDistString != null){ if(cachedDistString != null){
canvas.drawRoundRect(boundsForDist, 3, 3, paintAlphaGray); canvas.drawRoundRect(boundsForDist, 3, 3, paintAlphaGray);
canvas.drawRoundRect(boundsForDist, 3, 3, paintBlack);
canvas.drawCircle(boundsForDist.left + 8, boundsForDist.bottom - 15, 4, fillRed); canvas.drawCircle(boundsForDist.left + 8, boundsForDist.bottom - 15, 4, fillRed);
canvas.drawText(cachedDistString, boundsForDist.left + 15, boundsForDist.bottom - 9, paintBlack); 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 // draw compass the last because it use rotating
canvas.drawRoundRect(boundsForCompass, 3, 3, paintAlphaGray); canvas.drawRoundRect(boundsForCompass, 3, 3, paintAlphaGray);
canvas.drawRoundRect(boundsForCompass, 3, 3, paintBlack);
canvas.rotate(view.getRotate(), 15, 15); canvas.rotate(view.getRotate(), 15, 15);
canvas.drawPath(pathForCompass2, fillRed); canvas.drawPath(pathForCompass2, fillRed);
canvas.drawPath(pathForCompass, fillBlack); canvas.drawPath(pathForCompass, fillBlack);
} }

View file

@ -160,8 +160,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
} }
public void addLayer(OsmandMapLayer layer){ public void addLayer(OsmandMapLayer layer){
layers.add(layer);
layer.initLayer(this); layer.initLayer(this);
layers.add(layer);
} }
public void removeLayer(OsmandMapLayer layer){ public void removeLayer(OsmandMapLayer layer){

View file

@ -20,6 +20,7 @@ public class PointLocationLayer implements OsmandMapLayer {
private Paint location; private Paint location;
private Paint bearing; private Paint bearing;
private Paint bearingOver;
private Paint area; private Paint area;
private Paint headingPaint; private Paint headingPaint;
private Path pathForDirection; private Path pathForDirection;
@ -54,6 +55,11 @@ public class PointLocationLayer implements OsmandMapLayer {
bearing.setAntiAlias(true); bearing.setAntiAlias(true);
bearing.setStyle(Style.FILL); bearing.setStyle(Style.FILL);
bearingOver = new Paint();
bearingOver.setColor(Color.BLACK);
bearingOver.setAntiAlias(true);
bearingOver.setStyle(Style.STROKE);
pathForDirection = new Path(); pathForDirection = new Path();
} }
@ -124,6 +130,7 @@ public class PointLocationLayer implements OsmandMapLayer {
pathForDirection.transform(m); pathForDirection.transform(m);
canvas.drawPath(pathForDirection, this.bearing); canvas.drawPath(pathForDirection, this.bearing);
canvas.drawPath(pathForDirection, this.bearingOver);
} }
} }
@ -169,6 +176,11 @@ public class PointLocationLayer implements OsmandMapLayer {
} }
public void setAppMode(ApplicationMode appMode) { public void setAppMode(ApplicationMode appMode) {
this.appMode = appMode; this.appMode = appMode;
if(this.appMode == ApplicationMode.CAR || this.appMode == ApplicationMode.BICYCLE){
this.bearing.setAlpha(180);
} else {
this.bearing.setAlpha(150);
}
} }
@Override @Override
public boolean drawInScreenPixels() { public boolean drawInScreenPixels() {

View file

@ -29,6 +29,7 @@ public class RouteLayer implements OsmandMapLayer {
private Paint paint; private Paint paint;
private Path path; private Path path;
private float pathBearing;
public RouteLayer(RoutingHelper helper){ public RouteLayer(RoutingHelper helper){
this.helper = helper; this.helper = helper;
@ -39,7 +40,7 @@ public class RouteLayer implements OsmandMapLayer {
boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight()); boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight());
tileRect = new RectF(); tileRect = new RectF();
paint = new Paint(); paint = new Paint();
paint.setColor(Color.GRAY); paint.setColor(Color.BLUE);
paint.setStyle(Style.STROKE); paint.setStyle(Style.STROKE);
paint.setStrokeWidth(14); paint.setStrokeWidth(14);
paint.setAlpha(150); paint.setAlpha(150);
@ -53,11 +54,16 @@ public class RouteLayer implements OsmandMapLayer {
} }
@Override @Override
public void onDraw(Canvas canvas) { public void onDraw(Canvas canvas) {
path.reset();
if (helper.hasPointsToShow()) { if (helper.hasPointsToShow()) {
long time = System.currentTimeMillis(); 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(), view.calculateTileRectangle(boundsRect, view.getCenterPointX(), view.getCenterPointY(), view.getXTile(), view.getYTile(),
tileRect); tileRect);
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top); double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
@ -68,14 +74,18 @@ public class RouteLayer implements OsmandMapLayer {
if((System.currentTimeMillis() - time) > 40){ if((System.currentTimeMillis() - time) > 40){
Log.e(LogUtil.TAG, "Calculate route layer " + (System.currentTimeMillis() - time)); Log.e(LogUtil.TAG, "Calculate route layer " + (System.currentTimeMillis() - time));
} }
if (points.size() > 0) { if (points.size() > 0) {
int px = view.getMapXForPoint(points.get(0).getLongitude()); int px = view.getMapXForPoint(points.get(0).getLongitude());
int py = view.getMapYForPoint(points.get(0).getLatitude()); int py = view.getMapYForPoint(points.get(0).getLatitude());
path.reset();
path.moveTo(px, py); path.moveTo(px, py);
for (Location o : points) { for (int i=1; i<points.size(); i++) {
Location o = points.get(i);
int x = view.getMapXForPoint(o.getLongitude()); int x = view.getMapXForPoint(o.getLongitude());
int y = view.getMapYForPoint(o.getLatitude()); int y = view.getMapYForPoint(o.getLatitude());
if (i == 1) {
pathBearing = (float) (Math.atan2(y - py, x - px) / Math.PI * 180);
}
path.lineTo(x, y); path.lineTo(x, y);
} }
canvas.drawPath(path, paint); canvas.drawPath(path, paint);
@ -83,6 +93,15 @@ public class RouteLayer implements OsmandMapLayer {
} }
} }
// to show further direction
public Path getPath() {
return path;
}
public float getPathBearing(){
return pathBearing;
}
@Override @Override