diff --git a/OsmAnd/res/drawable/warnings_speed_camera_dist.xml b/OsmAnd/res/drawable/warnings_speed_camera_dist.xml
new file mode 100644
index 00000000000..538eb86c1b5
--- /dev/null
+++ b/OsmAnd/res/drawable/warnings_speed_camera_dist.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/drawable/warnings_speed_camera_dist_lim.xml b/OsmAnd/res/drawable/warnings_speed_camera_dist_lim.xml
new file mode 100644
index 00000000000..ddf47415627
--- /dev/null
+++ b/OsmAnd/res/drawable/warnings_speed_camera_dist_lim.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/drawable/warnings_speed_camera_dist_lim_us.xml b/OsmAnd/res/drawable/warnings_speed_camera_dist_lim_us.xml
new file mode 100644
index 00000000000..d5abb8d80c7
--- /dev/null
+++ b/OsmAnd/res/drawable/warnings_speed_camera_dist_lim_us.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/drawable/warnings_speed_camera_dist_us.xml b/OsmAnd/res/drawable/warnings_speed_camera_dist_us.xml
new file mode 100644
index 00000000000..d5e7086417e
--- /dev/null
+++ b/OsmAnd/res/drawable/warnings_speed_camera_dist_us.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/layout-land/map_hud_bottom.xml b/OsmAnd/res/layout-land/map_hud_bottom.xml
index e76b20c7ce5..e11b63a7a02 100644
--- a/OsmAnd/res/layout-land/map_hud_bottom.xml
+++ b/OsmAnd/res/layout-land/map_hud_bottom.xml
@@ -31,8 +31,8 @@
diff --git a/OsmAnd/res/layout/map_hud_bottom.xml b/OsmAnd/res/layout/map_hud_bottom.xml
index cf2311d473a..368e02a6d80 100644
--- a/OsmAnd/res/layout/map_hud_bottom.xml
+++ b/OsmAnd/res/layout/map_hud_bottom.xml
@@ -23,8 +23,8 @@
diff --git a/OsmAnd/res/values-large/sizes.xml b/OsmAnd/res/values-large/sizes.xml
index 64275349747..faa276ce2eb 100644
--- a/OsmAnd/res/values-large/sizes.xml
+++ b/OsmAnd/res/values-large/sizes.xml
@@ -23,13 +23,15 @@
6dp
84dp
138dp
- 12dp
+ 15dp
35sp
30dp
22sp
18sp
131dp
81dp
+ 54dp
+ 22sp
36dp
48dp
diff --git a/OsmAnd/res/values/sizes.xml b/OsmAnd/res/values/sizes.xml
index 4ff0f503942..af2378be663 100644
--- a/OsmAnd/res/values/sizes.xml
+++ b/OsmAnd/res/values/sizes.xml
@@ -123,7 +123,7 @@
120dp
9dp
92dp
- 8dp
+ 10dp
87dp
@@ -157,6 +157,8 @@
20dp
16sp
12sp
+ 36dp
+ 16sp
1sp
3sp
2dp
diff --git a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java
index 4cf45bcfb41..24eda7fa18f 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/WaypointHelper.java
@@ -225,9 +225,9 @@ public AlarmInfo getMostImportantAlarm(SpeedConstants sc, boolean showCameras) {
Location lastProjection = app.getRoutingHelper().getLastProjection();
float mxspeed = route.getCurrentMaxSpeed();
float delta = app.getSettings().SPEED_LIMIT_EXCEED_KMH.get() / 3.6f;
- AlarmInfo speedAlarm = createSpeedAlarm(sc, mxspeed, lastProjection, delta);
+ AlarmInfo speedAlarm = createSpeedAlarm(mxspeed, lastProjection, delta);
if (speedAlarm != null) {
- getVoiceRouter().announceSpeedAlarm(speedAlarm.getIntValue(), lastProjection.getSpeed());
+ getVoiceRouter().announceSpeedAlarm(speedAlarm.getMaxSpeed(sc), lastProjection.getSpeed());
}
AlarmInfo mostImportant = speedAlarm;
int value = speedAlarm != null ? speedAlarm.updateDistanceAndGetPriority(0, 0) : Integer.MAX_VALUE;
@@ -252,6 +252,12 @@ public AlarmInfo getMostImportantAlarm(SpeedConstants sc, boolean showCameras) {
if (!atd.isTurnStateActive(0, d, STATE_LONG_PNT_APPROACH)) {
break;
}
+
+ // Set actual distance to speed camera
+ if (inf.getType() == AlarmInfoType.SPEED_CAMERA) {
+ inf.setFloatValue(d);
+ }
+
float time = speed > 0 ? d / speed : Integer.MAX_VALUE;
int vl = inf.updateDistanceAndGetPriority(time, d);
if (vl < value && (showCameras || inf.getType() != AlarmInfoType.SPEED_CAMERA)) {
@@ -323,9 +329,9 @@ public AlarmInfo calculateMostImportantAlarm(RouteDataObject ro, Location loc, M
SpeedConstants sc, boolean showCameras) {
float mxspeed = ro.getMaximumSpeed(ro.bearingVsRouteDirection(loc));
float delta = app.getSettings().SPEED_LIMIT_EXCEED_KMH.get() / 3.6f;
- AlarmInfo speedAlarm = createSpeedAlarm(sc, mxspeed, loc, delta);
+ AlarmInfo speedAlarm = createSpeedAlarm(mxspeed, loc, delta);
if (speedAlarm != null) {
- getVoiceRouter().announceSpeedAlarm(speedAlarm.getIntValue(), loc.getSpeed());
+ getVoiceRouter().announceSpeedAlarm(speedAlarm.getMaxSpeed(sc), loc.getSpeed());
return speedAlarm;
}
for (int i = 0; i < ro.getPointsLength(); i++) {
@@ -360,17 +366,11 @@ public AlarmInfo calculateMostImportantAlarm(RouteDataObject ro, Location loc, M
return null;
}
- private static AlarmInfo createSpeedAlarm(SpeedConstants sc, float mxspeed, Location loc, float delta) {
+ private static AlarmInfo createSpeedAlarm(float mxspeed, Location loc, float delta) {
AlarmInfo speedAlarm = null;
if (mxspeed != 0 && loc != null && loc.hasSpeed() && mxspeed != RouteDataObject.NONE_MAX_SPEED) {
if (loc.getSpeed() > mxspeed + delta) {
- int speed;
- if (sc.imperial) {
- speed = Math.round(mxspeed * 3.6f / 1.6f);
- } else {
- speed = Math.round(mxspeed * 3.6f);
- }
- speedAlarm = AlarmInfo.createSpeedLimit(speed, loc);
+ speedAlarm = AlarmInfo.createSpeedLimit(mxspeed, loc);
}
}
return speedAlarm;
@@ -482,7 +482,15 @@ public void announceVisibleLocations() {
} else if (type == ALARMS) {
for (LocationPointWrapper pw : approachPoints) {
AlarmInfo alarm = (AlarmInfo) pw.point;
- voiceRouter.announceAlarm(new AlarmInfo(alarm.getType(), -1), lastKnownLocation.getSpeed());
+ AlarmInfo alarmCopy = new AlarmInfo(alarm.getType(), -1);
+
+ // Set actual distance and copy max speed to speed camera
+ if (alarmCopy.getType() == AlarmInfoType.SPEED_CAMERA) {
+ alarmCopy.setFloatValue(route.getDistanceToPoint(alarm.getLocationIndex()));
+ alarmCopy.setMaxSpeed(alarm.getMaxSpeed());
+ }
+
+ voiceRouter.announceAlarm(alarmCopy, lastKnownLocation.getSpeed());
lastAnnouncedAlarms.put(alarm.getType(), alarm);
}
} else if (type == FAVORITES) {
diff --git a/OsmAnd/src/net/osmand/plus/plugins/development/TestVoiceActivity.java b/OsmAnd/src/net/osmand/plus/plugins/development/TestVoiceActivity.java
index 36dd2616cf7..3ac2cd9c7a6 100644
--- a/OsmAnd/src/net/osmand/plus/plugins/development/TestVoiceActivity.java
+++ b/OsmAnd/src/net/osmand/plus/plugins/development/TestVoiceActivity.java
@@ -214,14 +214,15 @@ private void addButtons(final LinearLayout ll, CommandPlayer p) {
addButton(ll, "Attention prompts:", builder(p));
addButton(ll, "\u25BA (9.1) You are exceeding the speed limit '50' (18 m/s)", builder(p).speedAlarm(50, 18f));
- addButton(ll, "\u25BA (9.2) Attention, speed camera", builder(p).attention("SPEED_CAMERA"));
- addButton(ll, "\u25BA (9.3) Attention, border control", builder(p).attention("BORDER_CONTROL"));
- addButton(ll, "\u25BA (9.4) Attention, railroad crossing", builder(p).attention("RAILWAY"));
- addButton(ll, "\u25BA (9.5) Attention, traffic calming", builder(p).attention("TRAFFIC_CALMING"));
- addButton(ll, "\u25BA (9.6) Attention, toll booth", builder(p).attention("TOLL_BOOTH"));
- addButton(ll, "\u25BA (9.7) Attention, stop sign", builder(p).attention("STOP"));
- addButton(ll, "\u25BA (9.8) Attention, pedestrian crosswalk", builder(p).attention("PEDESTRIAN"));
- addButton(ll, "\u25BA (9.9) Attention, tunnel", builder(p).attention("TUNNEL"));
+ addButton(ll, "\u25BA (9.2) Attention, speed camera, distance 650m, speed limit '50' (18 m/s)", builder(p).speedCameraAlarm(650f, 50, "SPEED_CAMERA"));
+ addButton(ll, "\u25BA (9.3) Attention, speed camera", builder(p).attention("SPEED_CAMERA"));
+ addButton(ll, "\u25BA (9.4) Attention, border control", builder(p).attention("BORDER_CONTROL"));
+ addButton(ll, "\u25BA (9.5) Attention, railroad crossing", builder(p).attention("RAILWAY"));
+ addButton(ll, "\u25BA (9.6) Attention, traffic calming", builder(p).attention("TRAFFIC_CALMING"));
+ addButton(ll, "\u25BA (9.7) Attention, toll booth", builder(p).attention("TOLL_BOOTH"));
+ addButton(ll, "\u25BA (9.8) Attention, stop sign", builder(p).attention("STOP"));
+ addButton(ll, "\u25BA (9.9) Attention, pedestrian crosswalk", builder(p).attention("PEDESTRIAN"));
+ addButton(ll, "\u25BA (9.10) Attention, tunnel", builder(p).attention("TUNNEL"));
addButton(ll, "Other prompts:", builder(p));
addButton(ll, "\u25BA (10.1) GPS signal lost", builder(p).gpsLocationLost());
diff --git a/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java b/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java
index 5740edd1a4e..1fa1cf5a756 100644
--- a/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java
+++ b/OsmAnd/src/net/osmand/plus/routing/AlarmInfo.java
@@ -6,6 +6,7 @@
import net.osmand.data.LocationPoint;
import net.osmand.data.PointDescription;
import net.osmand.plus.R;
+import net.osmand.plus.settings.enums.SpeedConstants;
public class AlarmInfo implements LocationPoint {
public enum AlarmInfoType {
@@ -42,7 +43,7 @@ public String getVisualName(Context ctx) {
private final AlarmInfoType type;
protected final int locationIndex;
private int lastLocationIndex = -1;
- private int intValue;
+ private float maxSpeed;
private float floatValue;
private double latitude;
private double longitude;
@@ -64,7 +65,17 @@ public float getFloatValue() {
public void setFloatValue(float floatValue) {
this.floatValue = floatValue;
}
-
+
+ public int getMaxSpeed(SpeedConstants sc) {
+ return sc.imperial
+ ? Math.round(getMaxSpeed() * 3.6f / 1.6f)
+ : Math.round(getMaxSpeed() * 3.6f);
+ }
+
+ public float getMaxSpeed() { return maxSpeed; }
+
+ public void setMaxSpeed(float maxSpeed) { this.maxSpeed = maxSpeed; }
+
@Override
public double getLatitude() {
return latitude;
@@ -75,10 +86,6 @@ public double getLongitude() {
return longitude;
}
- public int getIntValue() {
- return intValue;
- }
-
public int getLocationIndex() {
return locationIndex;
}
@@ -91,14 +98,10 @@ public void setLastLocationIndex(int lastLocationIndex) {
this.lastLocationIndex = lastLocationIndex;
}
- public void setIntValue(int intValue) {
- this.intValue = intValue;
- }
-
- public static AlarmInfo createSpeedLimit(int speed, Location loc){
+ public static AlarmInfo createSpeedLimit(float maxSpeed, Location loc){
AlarmInfo info = new AlarmInfo(AlarmInfoType.SPEED_LIMIT, 0);
info.setLatLon(loc.getLatitude(), loc.getLongitude());
- info.setIntValue(speed);
+ info.setMaxSpeed(maxSpeed);
return info;
}
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
index 14d036b0d94..9b1b455aa79 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
@@ -20,6 +20,7 @@
import net.osmand.plus.R;
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
import net.osmand.plus.settings.backend.ApplicationMode;
+import net.osmand.plus.settings.enums.SpeedConstants;
import net.osmand.router.ExitInfo;
import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingContext;
@@ -276,6 +277,8 @@ private static void attachAlarmInfo(List alarms, RouteSegmentResult r
int[] pointTypes = res.getObject().getPointTypes(intId);
if (pointTypes != null) {
RouteRegion reg = res.getObject().region;
+ float maxSpeed = -1;
+ AlarmInfo speedCameraAlarmInfo = null;
for (int r = 0; r < pointTypes.length; r++) {
RouteTypeRule typeRule = reg.quickGetEncodingRule(pointTypes[r]);
int x31 = res.getObject().getPoint31XTile(intId);
@@ -284,9 +287,28 @@ private static void attachAlarmInfo(List alarms, RouteSegmentResult r
loc.setLatitude(MapUtils.get31LatitudeY(y31));
loc.setLongitude(MapUtils.get31LongitudeX(x31));
AlarmInfo info = AlarmInfo.createAlarmInfo(typeRule, locInd, loc);
+
// For STOP first check if it has directional info
if ((info != null) && !((info.getType() == AlarmInfoType.STOP) && !res.getObject().isStopApplicable(res.isForwardDirection(), intId, res.getStartPointIndex(), res.getEndPointIndex()))) {
alarms.add(info);
+
+ if (info.getType() == AlarmInfoType.SPEED_CAMERA) {
+ speedCameraAlarmInfo = info;
+ }
+ }
+
+ if (maxSpeed <= 0 || maxSpeed == RouteDataObject.NONE_MAX_SPEED) {
+ maxSpeed = typeRule.maxSpeed();
+ }
+ }
+
+ if (speedCameraAlarmInfo != null) {
+ if (maxSpeed <= 0 || maxSpeed == RouteDataObject.NONE_MAX_SPEED) {
+ maxSpeed = res.getObject().getMaximumSpeed(res.isForwardDirection());
+ }
+
+ if (maxSpeed > 0 && maxSpeed != RouteDataObject.NONE_MAX_SPEED) {
+ speedCameraAlarmInfo.setMaxSpeed(maxSpeed);
}
}
}
diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java
index 892a0bc5dc3..b2bf92be91b 100644
--- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java
+++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java
@@ -319,17 +319,21 @@ protected String getText(Location location, List points, d
public void announceAlarm(AlarmInfo info, float speed) {
AlarmInfoType type = info.getType();
+ OsmandSettings settings = router.getSettings();
+
if (type == AlarmInfoType.SPEED_LIMIT) {
- announceSpeedAlarm(info.getIntValue(), speed);
+ announceSpeedAlarm(info.getMaxSpeed(settings.SPEED_SYSTEM.get()), speed);
+ } else if (type == AlarmInfoType.SPEED_CAMERA) {
+ if (settings.SPEAK_SPEED_CAMERA.get()) {
+ announceSpeedCameraAlarm(info.getFloatValue(), info.getMaxSpeed(settings.SPEED_SYSTEM.get()));
+ }
} else {
- OsmandSettings settings = router.getSettings();
boolean speakTrafficWarnings = settings.SPEAK_TRAFFIC_WARNINGS.get();
boolean speakTunnels = type == AlarmInfoType.TUNNEL && settings.SPEAK_TUNNELS.get();
boolean speakPedestrian = type == AlarmInfoType.PEDESTRIAN && settings.SPEAK_PEDESTRIAN.get();
- boolean speakSpeedCamera = type == AlarmInfoType.SPEED_CAMERA && settings.SPEAK_SPEED_CAMERA.get();
- boolean speakPrefType = type == AlarmInfoType.TUNNEL || type == AlarmInfoType.PEDESTRIAN || type == AlarmInfoType.SPEED_CAMERA;
+ boolean speakPrefType = type == AlarmInfoType.TUNNEL || type == AlarmInfoType.PEDESTRIAN;
- if (speakSpeedCamera || speakPedestrian || speakTunnels || speakTrafficWarnings && !speakPrefType) {
+ if (speakPedestrian || speakTunnels || speakTrafficWarnings && !speakPrefType) {
CommandBuilder p = getNewCommandPlayerToPlay();
if (p != null) {
p.attention(String.valueOf(type));
@@ -365,7 +369,19 @@ public void announceSpeedAlarm(int maxSpeed, float speed) {
}
}
}
-
+
+ private void announceSpeedCameraAlarm(double dist, int maxSpeed) {
+ CommandBuilder p = getNewCommandPlayerToPlay();
+ if (p != null) {
+ if (dist > 0 && maxSpeed > 0) {
+ p.speedCameraAlarm(dist, maxSpeed, String.valueOf(AlarmInfoType.SPEED_CAMERA));
+ } else {
+ p.attention(String.valueOf(AlarmInfoType.SPEED_CAMERA));
+ }
+ }
+ play(p);
+ }
+
private boolean isTargetPoint(NextDirectionInfo info) {
boolean in = info != null && info.intermediatePoint;
boolean target = info == null || info.directionInfo == null
diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java
index 1cac61d0bc3..214c93091c4 100644
--- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java
+++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/AlarmWidget.java
@@ -10,7 +10,9 @@
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
+import android.view.Gravity;
import android.view.View;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -43,6 +45,8 @@ public class AlarmWidget {
private static final float WIDGET_BITMAP_TEXT_AMERICAN_SPEED_LIMIT_SHIFT_DP = 12f;
private static final float WIDGET_BITMAP_BOTTOM_TEXT_SIZE = 16f;
private static final float WIDGET_BITMAP_BOTTOM_TEXT_SIZE_SMALL = 12f;
+ private static final float WIDGET_BITMAP_SPEED_CAMERA_SPEED_INFO_SIZE_DP = 36f;
+ private static final float WIDGET_BITMAP_SPEED_CAMERA_SPEED_INFO_TEXT_SIZE = 16f;
@Nullable
private final View layout;
@@ -67,6 +71,7 @@ public class AlarmWidget {
private String cachedText;
private String cachedBottomText;
private DrivingRegion cachedRegion;
+ private AlarmInfo.AlarmInfoType cachedAlarmType;
public static class AlarmWidgetInfo {
public AlarmInfo alarm;
@@ -138,39 +143,18 @@ public boolean updateInfo(DrawSettings drawSettings, boolean drawBitmap) {
icon.setImageResource(info.locImgId);
}
}
- if (!Algorithms.objectEquals(info.text, cachedText) || cachedRegion != info.region) {
+
+ if (!Algorithms.objectEquals(info.text, cachedText) ||
+ !Algorithms.objectEquals(info.bottomText, cachedBottomText) ||
+ cachedRegion != info.region || cachedAlarmType != alarm.getType()) {
changed = true;
cachedText = info.text;
- cachedRegion = info.region;
- if (layout != null && widgetText != null) {
- widgetText.setText(cachedText);
- Resources res = layout.getContext().getResources();
- if (alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT && info.americanType && !info.isCanadianRegion) {
- int topPadding = res.getDimensionPixelSize(R.dimen.map_alarm_text_top_padding);
- widgetText.setPadding(0, topPadding, 0, 0);
- } else {
- widgetText.setPadding(0, 0, 0, 0);
- }
- }
- }
- if (!Algorithms.objectEquals(info.bottomText, cachedBottomText) || cachedRegion != info.region) {
- changed = true;
cachedBottomText = info.bottomText;
cachedRegion = info.region;
- if (layout != null && widgetBottomText != null) {
- widgetBottomText.setText(cachedBottomText);
- Resources res = layout.getContext().getResources();
- if (alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT && info.isCanadianRegion) {
- int bottomPadding = res.getDimensionPixelSize(R.dimen.map_button_margin);
- widgetBottomText.setPadding(0, 0, 0, bottomPadding);
- widgetBottomText.setTextSize(COMPLEX_UNIT_PX, res.getDimensionPixelSize(R.dimen.map_alarm_bottom_si_text_size));
- } else {
- widgetBottomText.setPadding(0, 0, 0, 0);
- widgetBottomText.setTextSize(COMPLEX_UNIT_PX, res.getDimensionPixelSize(R.dimen.map_alarm_bottom_text_size));
- }
- widgetBottomText.setTextColor(ContextCompat.getColor(layout.getContext(),
- info.americanType ? R.color.color_black : R.color.color_white));
- }
+ cachedAlarmType = alarm.getType();
+
+ updateTextWidget(info);
+ updateBottomTextWidget(info);
}
}
}
@@ -198,6 +182,64 @@ public boolean updateInfo(DrawSettings drawSettings, boolean drawBitmap) {
return true;
}
+ private void updateTextWidget(@NonNull AlarmWidgetInfo info) {
+ if (layout == null || widgetText == null) {
+ return;
+ }
+
+ widgetText.setText(info.text);
+ Resources res = layout.getContext().getResources();
+
+ if (info.alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT && info.americanType && !info.isCanadianRegion) {
+ int topPadding = res.getDimensionPixelSize(R.dimen.map_alarm_text_top_padding);
+ widgetText.setPadding(0, topPadding, 0, 0);
+ } else {
+ widgetText.setPadding(0, 0, 0, 0);
+ }
+
+ if (info.alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_CAMERA) {
+ FrameLayout.LayoutParams widgetTextLayoutParams = new FrameLayout.LayoutParams(
+ res.getDimensionPixelSize(R.dimen.map_alarm_speed_camera_speed_info_size),
+ res.getDimensionPixelSize(R.dimen.map_alarm_speed_camera_speed_info_size));
+
+ widgetTextLayoutParams.gravity = Gravity.RIGHT | Gravity.TOP;
+
+ widgetText.setLayoutParams(widgetTextLayoutParams);
+ widgetText.setGravity(Gravity.CENTER);
+ widgetText.setTextSize(COMPLEX_UNIT_PX, res.getDimensionPixelSize(R.dimen.map_alarm_speed_camera_speed_info_text_size));
+ } else {
+ FrameLayout.LayoutParams widgetTextLayoutParams = new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT);
+
+ widgetTextLayoutParams.gravity = Gravity.CENTER;
+
+ widgetText.setLayoutParams(widgetTextLayoutParams);
+ widgetText.setGravity(Gravity.NO_GRAVITY);
+ widgetText.setTextSize(COMPLEX_UNIT_PX, res.getDimensionPixelSize(R.dimen.map_alarm_text_size));
+ }
+ }
+
+ private void updateBottomTextWidget(@NonNull AlarmWidgetInfo info) {
+ if (layout == null || widgetBottomText == null) {
+ return;
+ }
+
+ widgetBottomText.setText(info.bottomText);
+ Resources res = layout.getContext().getResources();
+
+ if (info.alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT && info.isCanadianRegion) {
+ int bottomPadding = res.getDimensionPixelSize(R.dimen.map_button_margin);
+ widgetBottomText.setPadding(0, 0, 0, bottomPadding);
+ widgetBottomText.setTextSize(COMPLEX_UNIT_PX, res.getDimensionPixelSize(R.dimen.map_alarm_bottom_si_text_size));
+ } else {
+ widgetBottomText.setPadding(0, 0, 0, 0);
+ widgetBottomText.setTextSize(COMPLEX_UNIT_PX, res.getDimensionPixelSize(R.dimen.map_alarm_bottom_text_size));
+ }
+ widgetBottomText.setTextColor(ContextCompat.getColor(layout.getContext(),
+ info.americanType ? R.color.color_black : R.color.color_white));
+ }
+
@NonNull
private Bitmap createWidgetBitmap(@NonNull AlarmWidgetInfo info, float density) {
Bitmap bitmap = Bitmap.createBitmap((int) (WIDGET_BITMAP_SIZE_DP * density),
@@ -208,17 +250,28 @@ private Bitmap createWidgetBitmap(@NonNull AlarmWidgetInfo info, float density)
locImg.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
locImg.draw(canvas);
+ boolean isSpeedLimit = info.alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT;
+ boolean isSpeedCamera = info.alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_CAMERA;
+
if (!Algorithms.isEmpty(info.text)) {
TextPaint textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.BLACK);
- textPaint.setTextSize(WIDGET_BITMAP_TEXT_SIZE * density);
+ textPaint.setTextSize((!isSpeedCamera ? WIDGET_BITMAP_TEXT_SIZE : WIDGET_BITMAP_SPEED_CAMERA_SPEED_INFO_TEXT_SIZE) * density);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
textPaint.setTextAlign(Paint.Align.CENTER);
- float x = canvas.getWidth() / 2f;
- float y = canvas.getHeight() / 2f - ((textPaint.descent() + textPaint.ascent()) / 2);
- if (info.alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT && info.americanType && !info.isCanadianRegion) {
+
+ float x = !isSpeedCamera
+ ? canvas.getWidth() / 2f
+ : canvas.getWidth() - WIDGET_BITMAP_SPEED_CAMERA_SPEED_INFO_SIZE_DP * density / 2f;
+
+ float y = (!isSpeedCamera
+ ? canvas.getHeight() / 2f
+ : WIDGET_BITMAP_SPEED_CAMERA_SPEED_INFO_SIZE_DP * density / 2f) -
+ ((textPaint.descent() + textPaint.ascent()) / 2);
+
+ if (isSpeedLimit && info.americanType && !info.isCanadianRegion) {
y += WIDGET_BITMAP_TEXT_AMERICAN_SPEED_LIMIT_SHIFT_DP * density;
}
canvas.drawText(info.text, x, y, textPaint);
@@ -235,7 +288,7 @@ private Bitmap createWidgetBitmap(@NonNull AlarmWidgetInfo info, float density)
textPaint.setTextAlign(Paint.Align.CENTER);
float x = canvas.getWidth() / 2f;
float y = canvas.getHeight() - (textPaint.descent() - textPaint.ascent());
- if (info.alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_LIMIT && info.isCanadianRegion) {
+ if (isSpeedLimit && info.isCanadianRegion) {
textPaint.setTextSize(WIDGET_BITMAP_BOTTOM_TEXT_SIZE_SMALL * density);
}
canvas.drawText(info.bottomText, x, y, textPaint);
@@ -263,9 +316,24 @@ public AlarmWidgetInfo createWidgetInfo(@NonNull AlarmInfo alarm) {
locImgId = R.drawable.warnings_speed_limit_us;
//else case is done by drawing red ring
}
- text = alarm.getIntValue() + "";
+ text = alarm.getMaxSpeed(settings.SPEED_SYSTEM.get()) + "";
} else if (alarm.getType() == AlarmInfo.AlarmInfoType.SPEED_CAMERA) {
- locImgId = R.drawable.warnings_speed_camera;
+ int maxSpeed = alarm.getMaxSpeed(settings.SPEED_SYSTEM.get());
+ if (maxSpeed > 0) {
+ if (americanType) {
+ locImgId = R.drawable.warnings_speed_camera_dist_lim_us;
+ } else {
+ locImgId = R.drawable.warnings_speed_camera_dist_lim;
+ }
+ text = maxSpeed + "";
+ }
+ else if (americanType) {
+ locImgId = R.drawable.warnings_speed_camera_dist_us;
+ }
+ else {
+ locImgId = R.drawable.warnings_speed_camera_dist;
+ }
+ bottomText = OsmAndFormatter.getFormattedAlarmInfoDistance(settings.getContext(), alarm.getFloatValue());
} else if (alarm.getType() == AlarmInfo.AlarmInfoType.BORDER_CONTROL) {
locImgId = R.drawable.warnings_border_control;
} else if (alarm.getType() == AlarmInfo.AlarmInfoType.HAZARD) {
diff --git a/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java b/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java
index 7750c2db880..dc2f33fe50a 100644
--- a/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java
+++ b/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java
@@ -30,6 +30,7 @@ public abstract class CommandBuilder {
protected static final String C_REACHED_POI = "reached_poi";
protected static final String C_THEN = "then";
protected static final String C_SPEAD_ALARM = "speed_alarm";
+ protected static final String C_SPEED_CAMERA_ALARM = "speed_camera_alarm";
protected static final String C_ATTENTION = "attention";
protected static final String C_OFF_ROUTE = "off_route";
protected static final String C_BACK_ON_ROUTE = "back_on_route";
@@ -69,6 +70,8 @@ public List getCommandsList() {
public abstract CommandBuilder speedAlarm(int maxSpeed, float speed);
+ public abstract CommandBuilder speedCameraAlarm(double dist, int maxSpeed, String fallbackAttentionType);
+
public abstract CommandBuilder attention(String type);
public abstract CommandBuilder offRoute(double dist);
diff --git a/OsmAnd/src/net/osmand/plus/voice/JsCommandBuilder.java b/OsmAnd/src/net/osmand/plus/voice/JsCommandBuilder.java
index 0e971cb64c1..02f08c35270 100644
--- a/OsmAnd/src/net/osmand/plus/voice/JsCommandBuilder.java
+++ b/OsmAnd/src/net/osmand/plus/voice/JsCommandBuilder.java
@@ -79,6 +79,13 @@ public CommandBuilder speedAlarm(int maxSpeed, float speed) {
return addCommand(C_SPEAD_ALARM, maxSpeed, speed);
}
+ @Override
+ public CommandBuilder speedCameraAlarm(double dist, int maxSpeed, String fallbackAttentionType) {
+ return isJsCommandExists(C_SPEED_CAMERA_ALARM)
+ ? addCommand(C_SPEED_CAMERA_ALARM, dist, maxSpeed)
+ : attention(fallbackAttentionType);
+ }
+
@Override
public CommandBuilder attention(String type) {
return addCommand(C_ATTENTION, type);