From 52a8fa3e7b1ac0b24c974506311f6d08a84bb9ca Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 10 Jul 2012 01:14:44 +0200 Subject: [PATCH] Update max speed alarm control. Fix speed determinition issue. --- .../binary/BinaryMapRouteReaderAdapter.java | 1 + OsmAnd/res/menu/map_menu.xml | 2 +- .../plus/activities/MapActivityActions.java | 2 +- .../parkingpoint/ParkingPositionLayer.java | 5 +- .../net/osmand/plus/routing/AlarmInfo.java | 34 +++++++-- .../plus/routing/RouteCalculationResult.java | 33 ++++++++ .../osmand/plus/routing/RoutingHelper.java | 19 +++++ .../net/osmand/plus/views/MapInfoControl.java | 1 + .../net/osmand/plus/views/MapInfoLayer.java | 75 +++++++++++++++++-- .../plus/views/NextTurnInfoControl.java | 4 +- 10 files changed, 154 insertions(+), 22 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapRouteReaderAdapter.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapRouteReaderAdapter.java index eb9f23a771..5d0e889797 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapRouteReaderAdapter.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapRouteReaderAdapter.java @@ -119,6 +119,7 @@ public class BinaryMapRouteReaderAdapter { } else if(t.startsWith("access") && v != null){ type = ACCESS; } else if(t.equalsIgnoreCase("maxspeed") && v != null){ + type = MAXSPEED; floatValue = -1; int i = 0; while(i < v.length() && Character.isDigit(v.charAt(i))) { diff --git a/OsmAnd/res/menu/map_menu.xml b/OsmAnd/res/menu/map_menu.xml index ae7b1153d7..82c0fb82bd 100644 --- a/OsmAnd/res/menu/map_menu.xml +++ b/OsmAnd/res/menu/map_menu.xml @@ -10,11 +10,11 @@ - + diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 0334bac5f5..2a76cc4d8a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -854,8 +854,8 @@ public class MapActivityActions implements DialogProvider { helper.registerOptionsMenuItem(R.id.map_show_settings, R.string.settings_Button, android.R.drawable.ic_menu_preferences); helper.registerOptionsMenuItem(R.id.map_navigate_to_point, R.string.stop_navigation, android.R.drawable.ic_menu_close_clear_cancel, false); helper.registerOptionsMenuItem(R.id.map_mute, R.string.menu_mute_off, false); - helper.registerOptionsMenuItem(R.id.map_animate_route, R.string.animate_route, false); helper.registerOptionsMenuItem(R.id.map_get_directions, R.string.get_directions, android.R.drawable.ic_menu_directions); + helper.registerOptionsMenuItem(R.id.map_animate_route, R.string.animate_route, false); helper.registerOptionsMenuItem(R.id.map_specify_point, R.string.search_button, android.R.drawable.ic_menu_search); helper.registerOptionsMenuItem(R.id.map_show_gps_status, R.string.show_gps_status, android.R.drawable.ic_menu_compass); helper.registerOptionsMenuItem(R.id.map_show_point_options, R.string.show_point_options); diff --git a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionLayer.java b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionLayer.java index 55f5c7cea6..2da1c09c27 100644 --- a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionLayer.java +++ b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionLayer.java @@ -236,11 +236,8 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL @Override public boolean updateInfo() { - if( parkingPoint != null) { + if( parkingPoint != null && !map.getRoutingHelper().isFollowingMode()) { int d = 0; - if (map.getRoutingHelper().isRouterEnabled()) { - d = map.getRoutingHelper().getLeftDistance(); - } if (d == 0) { Location.distanceBetween(view.getLatitude(), view.getLongitude(), parkingPoint.getLatitude(), parkingPoint.getLongitude(), calculations); d = (int) calculations[0]; diff --git a/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java b/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java index bceb8fe1a6..a777a478e1 100644 --- a/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java +++ b/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java @@ -6,10 +6,10 @@ public class AlarmInfo { public static int SPEED_CAMERA = 1; public static int SPEED_LIMIT = SPEED_CAMERA + 1; public static int BORDER_CONTROL = SPEED_LIMIT + 1; - public static int BARRIER = BORDER_CONTROL + 1; - public static int TRAFFIC_CALMING = BARRIER + 1; + public static int TRAFFIC_CALMING = BORDER_CONTROL + 1; public static int TOLL_BOOTH = TRAFFIC_CALMING + 1; public static int STOP = TOLL_BOOTH + 1; + public static int MAXIMUM = STOP + 1; private int type; private float distance; @@ -51,12 +51,12 @@ public class AlarmInfo { this.intValue = intValue; } - public boolean isSpeedLimit(){ - return type == SPEED_LIMIT; - } - public boolean isSpeedCamera(){ - return type == SPEED_CAMERA; + + public static AlarmInfo createSpeedLimit(int speed){ + AlarmInfo info = new AlarmInfo(SPEED_LIMIT, 0); + info.setIntValue(speed); + return info; } public static AlarmInfo createAlarmInfo(RouteTypeRule ruleType, int locInd) { @@ -77,5 +77,25 @@ public class AlarmInfo { } return null; } + + public int updateDistanceAndGetPriority(float time, float distance){ + this.distance = distance; + this.time = time; + if(distance > 1500) { + return 0; + } + // 1 level of priorities + if((time > 0 && time < 12) || distance < 150 || type == SPEED_LIMIT) { + return type; + } + if(type == SPEED_CAMERA && (time < 20 || distance < 250)) { + return type; + } + // 2nd level + if((time > 0 && time < 18) || distance < 300 ) { + return type + MAXIMUM; + } + return 0; + } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index a85cc4844f..ca13d9749e 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -639,6 +639,39 @@ public class RouteCalculationResult { return null; } + public AlarmInfo getMostImportantAlarm(Location fromLoc, AlarmInfo speedAlarm) { + int aInfo = currentDirectionInfo; + int cRoute = currentRoute; + AlarmInfo mostImportant = speedAlarm; + int value = speedAlarm != null? speedAlarm.updateDistanceAndGetPriority(0, 0) : Integer.MAX_VALUE; + if (aInfo < alarmInfo.size()) { + int dist = 0; + float speed = 0; + if (fromLoc != null && fromLoc.hasSpeed()) { + speed = fromLoc.getSpeed(); + } + if (fromLoc != null) { + dist += fromLoc.distanceTo(locations.get(cRoute)); + } + dist += listDistance[cRoute]; + while(aInfo < alarmInfo.size()) { + AlarmInfo inf = alarmInfo.get(aInfo); + int d = dist - listDistance[inf.locationIndex]; + if(d > 3000){ + break; + } + float time = speed > 0 ? d / speed : 0; + int vl = inf.updateDistanceAndGetPriority(time, d); + if(vl < value){ + mostImportant = inf; + value = vl; + } + aInfo++; + } + } + return mostImportant; + } + public Location getNextRouteLocation(int after) { if(currentRoute + after < locations.size()) { return locations.get(currentRoute + after); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index e00702fb4c..dbcdd24790 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -12,6 +12,7 @@ import net.osmand.osm.LatLon; import net.osmand.osm.MapUtils; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; +import net.osmand.plus.OsmandSettings.MetricsConstants; import net.osmand.plus.activities.ApplicationMode; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteProvider.GPXRouteParams; @@ -464,6 +465,24 @@ public class RoutingHelper { return i; } + public synchronized AlarmInfo getMostImportantAlarm(MetricsConstants mc){ + float mxspeed = route.getCurrentMaxSpeed(); + AlarmInfo speedAlarm = null; + if(mxspeed != 0 && lastFixedLocation != null && lastFixedLocation.hasSpeed()) { + float delta = 5f/3.6f; + if(lastFixedLocation.getSpeed() > mxspeed + delta) { + int speed; + if(mc == MetricsConstants.KILOMETERS_AND_METERS) { + speed = Math.round(mxspeed * 3.6f); + } else { + speed = Math.round(mxspeed * 3.6f / 1.6f); + } + speedAlarm = AlarmInfo.createSpeedLimit(speed); + } + } + return route.getMostImportantAlarm(lastFixedLocation, speedAlarm); + } + public synchronized NextDirectionInfo getNextRouteDirectionInfoAfter(NextDirectionInfo previous, NextDirectionInfo to, boolean toSpeak){ NextDirectionInfo i = route.getNextRouteDirectionInfoAfter(previous, to, toSpeak); if(i != null) { diff --git a/OsmAnd/src/net/osmand/plus/views/MapInfoControl.java b/OsmAnd/src/net/osmand/plus/views/MapInfoControl.java index 2829350f59..18e5fe3eeb 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapInfoControl.java +++ b/OsmAnd/src/net/osmand/plus/views/MapInfoControl.java @@ -66,6 +66,7 @@ public abstract class MapInfoControl extends View { setVisibility(View.GONE); } requestLayout(); + invalidate(); return true; } return false; diff --git a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java index 4268b05d10..8398c9417a 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java @@ -8,6 +8,7 @@ import net.osmand.OsmAndFormatter; import net.osmand.osm.LatLon; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.routing.AlarmInfo; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; @@ -18,6 +19,7 @@ import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; +import android.graphics.Paint.Align; import android.graphics.Paint.Style; import android.graphics.Rect; import android.graphics.RectF; @@ -66,8 +68,11 @@ public class MapInfoLayer extends OsmandMapLayer { private MapStackControl leftStack; private ViewGroup statusBar; private MapInfoControl lanesControl; + private MapInfoControl alarmControl; private TextView topText; + + @@ -155,6 +160,8 @@ public class MapInfoLayer extends OsmandMapLayer { lanesControl = createLanesControl(); lanesControl.setBackgroundDrawable(view.getResources().getDrawable(R.drawable.box_free)); + alarmControl = createAlarmInfoControl(); + rightStack = new MapStackControl(view.getContext()); rightStack.addStackView(createAltitudeControl()); rightStack.addStackView(createDistanceControl()); @@ -165,7 +172,6 @@ public class MapInfoLayer extends OsmandMapLayer { leftStack.addStackView(createNextInfoControl()); leftStack.addStackView(createMiniMapControl()); leftStack.addStackView(createNextNextInfoControl()); -// leftStack.addStackView(createAlarmInfoControl()); // 2. Preparations Rect topRectPadding = new Rect(); @@ -207,11 +213,20 @@ public class MapInfoLayer extends OsmandMapLayer { flp.rightMargin = STATUS_BAR_MARGIN_X; flp.topMargin = -topRectPadding.top; statusBar.setLayoutParams(flp); + + flp = new FrameLayout.LayoutParams((int)(78 * scaleCoefficient), + (int)(78 * scaleCoefficient), Gravity.RIGHT | Gravity.BOTTOM); + flp.rightMargin = STATUS_BAR_MARGIN_X; + flp.bottomMargin = (int) (85*scaleCoefficient); + alarmControl.setLayoutParams(flp); parent.addView(rightStack); parent.addView(leftStack); parent.addView(statusBar); parent.addView(lanesControl); + parent.addView(alarmControl); + alarmControl.setVisibility(View.GONE); + lanesControl.setVisibility(View.GONE); } @@ -246,6 +261,7 @@ public class MapInfoLayer extends OsmandMapLayer { compassView.invalidate(); } lanesControl.updateInfo(); + alarmControl.updateInfo(); // topText.setTextColor(color); // String text = "Пр.Независимости"; // float ts = topText.getPaint().measureText(text); @@ -519,9 +535,11 @@ public class MapInfoLayer extends OsmandMapLayer { turnType = r.directionInfo.getTurnType(); TurnPathHelper.calcTurnPath(pathForTurn, turnType, pathTransform); invalidate(); + requestLayout(); } if (distChanged(r.distanceTo, nextTurnDirection)) { invalidate(); + requestLayout(); nextTurnDirection = r.distanceTo; } int imminent = r.imminent; @@ -565,23 +583,64 @@ public class MapInfoLayer extends OsmandMapLayer { return nextTurnInfo; } - // FIXME alarm control - protected NextTurnInfoControl createAlarmInfoControl() { + private MapInfoControl createAlarmInfoControl() { final RoutingHelper routingHelper = routeLayer.getHelper(); - final NextTurnInfoControl nextTurnInfo = new NextTurnInfoControl(map, paintSmallText, paintSmallSubText, true) { + final Paint paintCircle = new Paint(); + final float th = 11 * scaleCoefficient; + paintCircle.setColor(Color.rgb(225, 15, 15)); + paintCircle.setStrokeWidth(11 * scaleCoefficient); + paintCircle.setStyle(Style.STROKE); + paintCircle.setAntiAlias(true); + final Paint content = new Paint(); + content.setColor(Color.WHITE); + content.setStyle(Style.FILL); + final Paint ptext = new Paint(); + ptext.setTextSize(27 * scaleCoefficient); + ptext.setFakeBoldText(true); + ptext.setAntiAlias(true); + ptext.setTextAlign(Align.CENTER); + + final MapInfoControl alarm = new MapInfoControl(map) { + private String text = ""; @Override public boolean updateInfo() { boolean visible = false; if (routeLayer != null && routingHelper.isRouterEnabled() && routingHelper.isFollowingMode()) { -// boolean uturnWhenPossible = routingHelper.makeUturnWhenPossible(); + AlarmInfo alarm = routingHelper.getMostImportantAlarm(view.getSettings().METRIC_SYSTEM.get()); + if(alarm != null) { + if(alarm.getType() == AlarmInfo.SPEED_LIMIT) { + text = alarm.getIntValue() +""; + } else if(alarm.getType() == AlarmInfo.SPEED_CAMERA) { + text = "CAM"; + } else if(alarm.getType() == AlarmInfo.BORDER_CONTROL) { + text = "CLO"; + } else if(alarm.getType() == AlarmInfo.TOLL_BOOTH) { + text = "$"; + } else if(alarm.getType() == AlarmInfo.TRAFFIC_CALMING) { + // temporary omega + text = "~^~"; + } else if(alarm.getType() == AlarmInfo.STOP) { + // text = "STOP"; + } + visible = text.length() > 0; + } } updateVisibility(visible); return true; } + + @Override + protected void onDraw(Canvas canvas) { + RectF f = new RectF(th / 2, th / 2, getWidth() - th / 2, getHeight() - th / 2); + canvas.drawOval(f, content); + canvas.drawOval(f, paintCircle); + canvas.drawText(text, getWidth() / 2, getHeight() / 2 + ptext.descent() + 3 * scaleCoefficient, ptext); + } + }; // initial state -// nextTurnInfo.setVisibility(View.GONE); - return nextTurnInfo; + // nextTurnInfo.setVisibility(View.GONE); + return alarm; } private NextTurnInfoControl createNextInfoControl() { @@ -631,10 +690,12 @@ public class MapInfoLayer extends OsmandMapLayer { } else { exitOut = null; } + requestLayout(); invalidate(); } if (distChanged(r.distanceTo, nextTurnDirection)) { invalidate(); + requestLayout(); nextTurnDirection = r.distanceTo; } if (turnImminent != r.imminent) { diff --git a/OsmAnd/src/net/osmand/plus/views/NextTurnInfoControl.java b/OsmAnd/src/net/osmand/plus/views/NextTurnInfoControl.java index 8d7ca62b67..a22fdfd813 100644 --- a/OsmAnd/src/net/osmand/plus/views/NextTurnInfoControl.java +++ b/OsmAnd/src/net/osmand/plus/views/NextTurnInfoControl.java @@ -123,10 +123,10 @@ public class NextTurnInfoControl extends MapInfoControl { } } else { drawShadowText(canvas, text, 72 * scaleCoefficient / miniCoeff + 2 * scaleCoefficient, - height / 2 + 5 * scaleCoefficient, textPaint); + height / 2 + 7 * scaleCoefficient, textPaint); if (subtext != null) { drawShadowText(canvas, subtext, 72 * scaleCoefficient / miniCoeff + mt - + 2 * scaleCoefficient, height / 2 + 5 * scaleCoefficient, subtextPaint); + + 2 * scaleCoefficient, height / 2 + 7 * scaleCoefficient, subtextPaint); } } }