Update max speed alarm control. Fix speed determinition issue.

This commit is contained in:
Victor Shcherb 2012-07-10 01:14:44 +02:00
parent 2d53daa8e2
commit 52a8fa3e7b
10 changed files with 154 additions and 22 deletions

View file

@ -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))) {

View file

@ -10,11 +10,11 @@
<!-- not visible by default -->
<item android:id="@+id/map_navigate_to_point" android:title="@string/stop_navigation" android:visible="false" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item>
<item android:id="@+id/map_mute" android:title="@string/menu_mute_off" android:visible="false"></item>
<item android:id="@+id/map_animate_route" android:title="@string/animate_route" android:visible="false"></item>
<item android:id="@+id/map_get_directions" android:title="@string/get_directions" android:icon="@android:drawable/ic_menu_directions"></item>
<item android:title="@string/search_button" android:id="@+id/map_specify_point" android:icon="@android:drawable/ic_menu_search"></item>
<item android:id="@+id/map_animate_route" android:title="@string/animate_route" android:visible="false"></item>
<item android:title="@string/show_gps_status" android:id="@+id/map_show_gps_status" android:icon="@android:drawable/ic_menu_compass"></item>
<item android:id="@+id/map_show_point_options" android:title="@string/show_point_options"></item>
</group>

View file

@ -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);

View file

@ -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];

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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) {

View file

@ -66,6 +66,7 @@ public abstract class MapInfoControl extends View {
setVisibility(View.GONE);
}
requestLayout();
invalidate();
return true;
}
return false;

View file

@ -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) {

View file

@ -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);
}
}
}