Merge pull request #4147 from osmandapp/ruler_improvements
Ruler improvements
This commit is contained in:
commit
ea15c68527
3 changed files with 328 additions and 297 deletions
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<dimen name="acceptable_touch_radius">48dp</dimen>
|
||||||
|
|
||||||
<dimen name="dialog_button_height">36dp</dimen>
|
<dimen name="dialog_button_height">36dp</dimen>
|
||||||
<dimen name="undo_bottom_offset">15dp</dimen>
|
<dimen name="undo_bottom_offset">15dp</dimen>
|
||||||
<dimen name="touch_slop">32dp</dimen>
|
<dimen name="touch_slop">32dp</dimen>
|
||||||
|
@ -10,7 +12,7 @@
|
||||||
<dimen name="dashboard_land_width">360dp</dimen>
|
<dimen name="dashboard_land_width">360dp</dimen>
|
||||||
<dimen name="dashboard_map_toolbar">56dp</dimen>
|
<dimen name="dashboard_map_toolbar">56dp</dimen>
|
||||||
<dimen name="dash_parking_height">78dp</dimen>
|
<dimen name="dash_parking_height">78dp</dimen>
|
||||||
|
|
||||||
<dimen name="subHeaderPadding">2dp</dimen>
|
<dimen name="subHeaderPadding">2dp</dimen>
|
||||||
<dimen name="subHeaderMarginLeft">15dp</dimen>
|
<dimen name="subHeaderMarginLeft">15dp</dimen>
|
||||||
<dimen name="showAllButtonMarginRight">14dp</dimen>
|
<dimen name="showAllButtonMarginRight">14dp</dimen>
|
||||||
|
@ -30,15 +32,15 @@
|
||||||
<dimen name="dashCardMargin">4dp</dimen>
|
<dimen name="dashCardMargin">4dp</dimen>
|
||||||
<dimen name="abp__shadow_height">4dp</dimen>
|
<dimen name="abp__shadow_height">4dp</dimen>
|
||||||
<dimen name="dashFABMargin">0dp</dimen>
|
<dimen name="dashFABMargin">0dp</dimen>
|
||||||
|
|
||||||
<dimen name="list_content_padding">16dp</dimen>
|
<dimen name="list_content_padding">16dp</dimen>
|
||||||
<dimen name="list_header_padding">8dp</dimen>
|
<dimen name="list_header_padding">8dp</dimen>
|
||||||
|
|
||||||
<dimen name="list_header_top_margin">16dp</dimen>
|
<dimen name="list_header_top_margin">16dp</dimen>
|
||||||
<dimen name="list_header_settings_top_margin">10dp</dimen>
|
<dimen name="list_header_settings_top_margin">10dp</dimen>
|
||||||
<dimen name="list_header_text_left_margin">12dp</dimen>
|
<dimen name="list_header_text_left_margin">12dp</dimen>
|
||||||
<dimen name="list_header_bottom_margin">8dp</dimen>
|
<dimen name="list_header_bottom_margin">8dp</dimen>
|
||||||
|
|
||||||
<dimen name="favorites_icon_right_margin">24dp</dimen>
|
<dimen name="favorites_icon_right_margin">24dp</dimen>
|
||||||
<dimen name="local_index_check_right_margin">10dp</dimen>
|
<dimen name="local_index_check_right_margin">10dp</dimen>
|
||||||
<dimen name="favorites_icon_top_margin">13dp</dimen>
|
<dimen name="favorites_icon_top_margin">13dp</dimen>
|
||||||
|
@ -50,8 +52,8 @@
|
||||||
<dimen name="gpx_small_icon_margin">3dp</dimen>
|
<dimen name="gpx_small_icon_margin">3dp</dimen>
|
||||||
<dimen name="gpx_small_text_margin">14dp</dimen>
|
<dimen name="gpx_small_text_margin">14dp</dimen>
|
||||||
<dimen name="gpx_text_top_margin">6dp</dimen>
|
<dimen name="gpx_text_top_margin">6dp</dimen>
|
||||||
|
|
||||||
|
|
||||||
<dimen name="dashboard_parking_left_margin">16dp</dimen>
|
<dimen name="dashboard_parking_left_margin">16dp</dimen>
|
||||||
<dimen name="dashboard_parking_icon_size">48dp</dimen>
|
<dimen name="dashboard_parking_icon_size">48dp</dimen>
|
||||||
<!-- map buttons -->
|
<!-- map buttons -->
|
||||||
|
@ -69,8 +71,8 @@
|
||||||
<dimen name="map_ruler_width">120dp</dimen>
|
<dimen name="map_ruler_width">120dp</dimen>
|
||||||
<dimen name="map_ruler_bottom_margin">9dp</dimen>
|
<dimen name="map_ruler_bottom_margin">9dp</dimen>
|
||||||
<dimen name="map_alarm_size">78dp</dimen>
|
<dimen name="map_alarm_size">78dp</dimen>
|
||||||
|
|
||||||
|
|
||||||
<dimen name="map_alarm_bottom_margin">87dp</dimen>
|
<dimen name="map_alarm_bottom_margin">87dp</dimen>
|
||||||
<dimen name="map_alarm_bottom_margin_land">57dp</dimen>
|
<dimen name="map_alarm_bottom_margin_land">57dp</dimen>
|
||||||
<dimen name="map_button_shadow_height">85dp</dimen>
|
<dimen name="map_button_shadow_height">85dp</dimen>
|
||||||
|
@ -83,8 +85,8 @@
|
||||||
<dimen name="map_button_spacing_land">6dp</dimen>
|
<dimen name="map_button_spacing_land">6dp</dimen>
|
||||||
<dimen name="map_button_margin">6dp</dimen>
|
<dimen name="map_button_margin">6dp</dimen>
|
||||||
<dimen name="map_routing_progress_width">100dp</dimen>
|
<dimen name="map_routing_progress_width">100dp</dimen>
|
||||||
|
|
||||||
|
|
||||||
<dimen name="map_button_inset_shadow">2dp</dimen>
|
<dimen name="map_button_inset_shadow">2dp</dimen>
|
||||||
<dimen name="map_button_inset">2dp</dimen>
|
<dimen name="map_button_inset">2dp</dimen>
|
||||||
<dimen name="map_button_rect_rad">3dp</dimen>
|
<dimen name="map_button_rect_rad">3dp</dimen>
|
||||||
|
@ -94,9 +96,9 @@
|
||||||
<dimen name="map_route_planning_land_width_minus_shadow">306dp</dimen>
|
<dimen name="map_route_planning_land_width_minus_shadow">306dp</dimen>
|
||||||
<dimen name="map_route_planning_max_height">330dp</dimen>
|
<dimen name="map_route_planning_max_height">330dp</dimen>
|
||||||
<dimen name="map_minwidth_widget">100dp</dimen>
|
<dimen name="map_minwidth_widget">100dp</dimen>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<dimen name="map_widget_text_size">23sp</dimen>
|
<dimen name="map_widget_text_size">23sp</dimen>
|
||||||
<dimen name="map_widget_text_size_small">15sp</dimen>
|
<dimen name="map_widget_text_size_small">15sp</dimen>
|
||||||
<dimen name="map_button_text_size">18sp</dimen>
|
<dimen name="map_button_text_size">18sp</dimen>
|
||||||
|
@ -104,7 +106,7 @@
|
||||||
<dimen name="map_widget_text_bottom_margin">1sp</dimen>
|
<dimen name="map_widget_text_bottom_margin">1sp</dimen>
|
||||||
<dimen name="map_widget_text_small_bottom_margin">3sp</dimen>
|
<dimen name="map_widget_text_small_bottom_margin">3sp</dimen>
|
||||||
<dimen name="map_widget_icon_margin">2dp</dimen>
|
<dimen name="map_widget_icon_margin">2dp</dimen>
|
||||||
|
|
||||||
<dimen name="dash_margin">2dp</dimen>
|
<dimen name="dash_margin">2dp</dimen>
|
||||||
<dimen name="dash_margin_h">6dp</dimen>
|
<dimen name="dash_margin_h">6dp</dimen>
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Paint.Style;
|
import android.graphics.Paint.Style;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
@ -28,330 +29,358 @@ import gnu.trove.list.array.TIntArrayList;
|
||||||
|
|
||||||
public class RulerControlLayer extends OsmandMapLayer {
|
public class RulerControlLayer extends OsmandMapLayer {
|
||||||
|
|
||||||
public static final long DELAY = 2000;
|
private static final long DRAW_TIME = 2000;
|
||||||
private static final int TEXT_SIZE = 14;
|
private static final long DELAY_BEFORE_DRAW = 500;
|
||||||
|
private static final int TEXT_SIZE = 14;
|
||||||
|
|
||||||
private final MapActivity mapActivity;
|
private final MapActivity mapActivity;
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
private OsmandMapTileView view;
|
private OsmandMapTileView view;
|
||||||
private View rightWidgetsPanel;
|
private View rightWidgetsPanel;
|
||||||
|
|
||||||
private TextSide textSide;
|
private TextSide textSide;
|
||||||
private int maxRadiusInDp;
|
private int maxRadiusInDp;
|
||||||
private float maxRadius;
|
private float maxRadius;
|
||||||
private int radius;
|
private int radius;
|
||||||
private double roundedDist;
|
private double roundedDist;
|
||||||
private boolean showTwoFingersDistance;
|
private boolean showTwoFingersDistance;
|
||||||
private boolean showDistBetweenFingerAndLocation;
|
private boolean showDistBetweenFingerAndLocation;
|
||||||
|
private boolean touchOutside;
|
||||||
|
private int acceptableTouchRadius;
|
||||||
|
|
||||||
private QuadPoint cacheCenter;
|
private QuadPoint cacheCenter;
|
||||||
private int cacheIntZoom;
|
private int cacheIntZoom;
|
||||||
private double cacheTileX;
|
private double cacheTileX;
|
||||||
private double cacheTileY;
|
private double cacheTileY;
|
||||||
private long cacheMultiTouchEndTime;
|
private long cacheMultiTouchEndTime;
|
||||||
private ArrayList<String> cacheDistances;
|
private ArrayList<String> cacheDistances;
|
||||||
private Path distancePath;
|
private Path distancePath;
|
||||||
private TIntArrayList tx;
|
private TIntArrayList tx;
|
||||||
private TIntArrayList ty;
|
private TIntArrayList ty;
|
||||||
private LatLon singleTouchPointLatLon;
|
private LatLon touchPointLatLon;
|
||||||
|
private PointF touchPoint;
|
||||||
|
private PointF firstTouchPoint;
|
||||||
|
private long touchTime;
|
||||||
|
|
||||||
private Bitmap centerIconDay;
|
private Bitmap centerIconDay;
|
||||||
private Bitmap centerIconNight;
|
private Bitmap centerIconNight;
|
||||||
private Paint bitmapPaint;
|
private Paint bitmapPaint;
|
||||||
private RenderingLineAttributes lineAttrs;
|
private RenderingLineAttributes lineAttrs;
|
||||||
private RenderingLineAttributes circleAttrs;
|
private RenderingLineAttributes circleAttrs;
|
||||||
private RenderingLineAttributes circleAttrsAlt;
|
private RenderingLineAttributes circleAttrsAlt;
|
||||||
|
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
|
|
||||||
public RulerControlLayer(MapActivity mapActivity) {
|
public RulerControlLayer(MapActivity mapActivity) {
|
||||||
this.mapActivity = mapActivity;
|
this.mapActivity = mapActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShowTwoFingersDistance() {
|
public boolean isShowTwoFingersDistance() {
|
||||||
return showTwoFingersDistance;
|
return showTwoFingersDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShowDistBetweenFingerAndLocation() {
|
public boolean isShowDistBetweenFingerAndLocation() {
|
||||||
return showDistBetweenFingerAndLocation;
|
return showDistBetweenFingerAndLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LatLon getSingleTouchPointLatLon() {
|
public LatLon getTouchPointLatLon() {
|
||||||
return singleTouchPointLatLon;
|
return touchPointLatLon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initLayer(final OsmandMapTileView view) {
|
public void initLayer(final OsmandMapTileView view) {
|
||||||
app = mapActivity.getMyApplication();
|
app = mapActivity.getMyApplication();
|
||||||
this.view = view;
|
this.view = view;
|
||||||
cacheDistances = new ArrayList<>();
|
cacheDistances = new ArrayList<>();
|
||||||
cacheCenter = new QuadPoint();
|
cacheCenter = new QuadPoint();
|
||||||
maxRadiusInDp = mapActivity.getResources().getDimensionPixelSize(R.dimen.map_ruler_width);
|
maxRadiusInDp = mapActivity.getResources().getDimensionPixelSize(R.dimen.map_ruler_width);
|
||||||
rightWidgetsPanel = mapActivity.findViewById(R.id.map_right_widgets_panel);
|
rightWidgetsPanel = mapActivity.findViewById(R.id.map_right_widgets_panel);
|
||||||
distancePath = new Path();
|
distancePath = new Path();
|
||||||
tx = new TIntArrayList();
|
tx = new TIntArrayList();
|
||||||
ty = new TIntArrayList();
|
ty = new TIntArrayList();
|
||||||
|
firstTouchPoint = new PointF();
|
||||||
|
touchPoint = new PointF();
|
||||||
|
acceptableTouchRadius = mapActivity.getResources().getDimensionPixelSize(R.dimen.acceptable_touch_radius);
|
||||||
|
|
||||||
centerIconDay = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_day);
|
centerIconDay = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_day);
|
||||||
centerIconNight = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_night);
|
centerIconNight = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_night);
|
||||||
|
|
||||||
bitmapPaint = new Paint();
|
bitmapPaint = new Paint();
|
||||||
bitmapPaint.setAntiAlias(true);
|
bitmapPaint.setAntiAlias(true);
|
||||||
bitmapPaint.setDither(true);
|
bitmapPaint.setDither(true);
|
||||||
bitmapPaint.setFilterBitmap(true);
|
bitmapPaint.setFilterBitmap(true);
|
||||||
|
|
||||||
lineAttrs = new RenderingLineAttributes("rulerLine");
|
lineAttrs = new RenderingLineAttributes("rulerLine");
|
||||||
|
|
||||||
float textSize = TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
|
float textSize = TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
|
||||||
|
|
||||||
circleAttrs = new RenderingLineAttributes("rulerCircle");
|
circleAttrs = new RenderingLineAttributes("rulerCircle");
|
||||||
circleAttrs.paint2.setTextSize(textSize);
|
circleAttrs.paint2.setTextSize(textSize);
|
||||||
circleAttrs.paint3.setTextSize(textSize);
|
circleAttrs.paint3.setTextSize(textSize);
|
||||||
|
|
||||||
circleAttrsAlt = new RenderingLineAttributes("rulerCircleAlt");
|
circleAttrsAlt = new RenderingLineAttributes("rulerCircleAlt");
|
||||||
circleAttrsAlt.paint2.setTextSize(textSize);
|
circleAttrsAlt.paint2.setTextSize(textSize);
|
||||||
circleAttrsAlt.paint3.setTextSize(textSize);
|
circleAttrsAlt.paint3.setTextSize(textSize);
|
||||||
|
|
||||||
handler = new Handler() {
|
handler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
view.refreshMap();
|
view.refreshMap();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMapGestureAllowed(MapGestureType type) {
|
public boolean isMapGestureAllowed(MapGestureType type) {
|
||||||
if (rulerModeOn() && type == MapGestureType.TWO_POINTERS_ZOOM_OUT) {
|
if (rulerModeOn() && type == MapGestureType.TWO_POINTERS_ZOOM_OUT) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event, RotatedTileBox tileBox) {
|
public boolean onTouchEvent(MotionEvent event, RotatedTileBox tileBox) {
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
if (rulerModeOn()) {
|
||||||
showDistBetweenFingerAndLocation = true;
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
singleTouchPointLatLon = tileBox.getLatLonFromPixel(event.getX(), event.getY());
|
touchOutside = false;
|
||||||
} else if (event.getAction() == MotionEvent.ACTION_UP) {
|
firstTouchPoint.set(event.getX(), event.getY());
|
||||||
showDistBetweenFingerAndLocation = false;
|
setSingleTouch(event.getX(), event.getY(), tileBox);
|
||||||
}
|
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||||
return false;
|
double d = Math.sqrt(Math.pow(event.getX() - firstTouchPoint.x, 2) + Math.pow(event.getY() - firstTouchPoint.y, 2));
|
||||||
}
|
if (d < acceptableTouchRadius) {
|
||||||
|
setSingleTouch(event.getX(), event.getY(), tileBox);
|
||||||
|
touchOutside = false;
|
||||||
|
} else {
|
||||||
|
touchOutside = true;
|
||||||
|
}
|
||||||
|
} else if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
|
refreshMapDelayed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
private void setSingleTouch(float x, float y, RotatedTileBox tb) {
|
||||||
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
|
touchTime = System.currentTimeMillis();
|
||||||
if (rulerModeOn()) {
|
touchPoint.set(x, y);
|
||||||
lineAttrs.updatePaints(view, settings, tb);
|
touchPointLatLon = tb.getLatLonFromPixel(x, y);
|
||||||
circleAttrs.updatePaints(view, settings, tb);
|
}
|
||||||
circleAttrs.paint2.setStyle(Style.FILL);
|
|
||||||
circleAttrsAlt.updatePaints(view, settings, tb);
|
|
||||||
circleAttrsAlt.paint2.setStyle(Style.FILL);
|
|
||||||
final QuadPoint center = tb.getCenterPixelPoint();
|
|
||||||
final RulerMode mode = app.getSettings().RULER_MODE.get();
|
|
||||||
|
|
||||||
if (view.isMultiTouch()) {
|
@Override
|
||||||
showDistBetweenFingerAndLocation = false;
|
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
|
||||||
} else if (cacheMultiTouchEndTime != view.getMultiTouchEndTime()) {
|
if (rulerModeOn()) {
|
||||||
cacheMultiTouchEndTime = view.getMultiTouchEndTime();
|
lineAttrs.updatePaints(view, settings, tb);
|
||||||
refreshMapDelayed();
|
circleAttrs.updatePaints(view, settings, tb);
|
||||||
}
|
circleAttrs.paint2.setStyle(Style.FILL);
|
||||||
showTwoFingersDistance = !view.isWasZoomInMultiTouch() && !tb.isZoomAnimated() &&
|
circleAttrsAlt.updatePaints(view, settings, tb);
|
||||||
(view.isMultiTouch() || System.currentTimeMillis() - cacheMultiTouchEndTime < DELAY);
|
circleAttrsAlt.paint2.setStyle(Style.FILL);
|
||||||
|
final QuadPoint center = tb.getCenterPixelPoint();
|
||||||
|
final RulerMode mode = app.getSettings().RULER_MODE.get();
|
||||||
|
|
||||||
drawCenterIcon(canvas, tb, center, settings.isNightMode(), mode);
|
if (cacheMultiTouchEndTime != view.getMultiTouchEndTime()) {
|
||||||
Location currentLoc = app.getLocationProvider().getLastKnownLocation();
|
cacheMultiTouchEndTime = view.getMultiTouchEndTime();
|
||||||
if (showDistBetweenFingerAndLocation && currentLoc != null) {
|
refreshMapDelayed();
|
||||||
float x = tb.getPixXFromLonNoRot(singleTouchPointLatLon.getLongitude());
|
}
|
||||||
float y = tb.getPixYFromLatNoRot(singleTouchPointLatLon.getLatitude());
|
boolean wasNotZoom = !view.isWasZoomInMultiTouch() && !tb.isZoomAnimated();
|
||||||
drawDistBetweenFingerAndLocation(canvas, tb, x, y, currentLoc, settings.isNightMode());
|
showTwoFingersDistance = wasNotZoom &&
|
||||||
} else if (showTwoFingersDistance) {
|
(view.isMultiTouch() || System.currentTimeMillis() - cacheMultiTouchEndTime < DRAW_TIME);
|
||||||
LatLon firstTouchPoint = view.getFirstTouchPointLatLon();
|
showDistBetweenFingerAndLocation = !showTwoFingersDistance && wasNotZoom && !view.isMultiTouch() &&
|
||||||
LatLon secondTouchPoint = view.getSecondTouchPointLatLon();
|
!touchOutside && System.currentTimeMillis() - touchTime > DELAY_BEFORE_DRAW &&
|
||||||
float x1 = tb.getPixXFromLonNoRot(firstTouchPoint.getLongitude());
|
System.currentTimeMillis() - touchTime < DRAW_TIME;
|
||||||
float y1 = tb.getPixYFromLatNoRot(firstTouchPoint.getLatitude());
|
|
||||||
float x2 = tb.getPixXFromLonNoRot(secondTouchPoint.getLongitude());
|
|
||||||
float y2 = tb.getPixYFromLatNoRot(secondTouchPoint.getLatitude());
|
|
||||||
drawFingerDistance(canvas, x1, y1, x2, y2, settings.isNightMode());
|
|
||||||
}
|
|
||||||
if (mode == RulerMode.FIRST || mode == RulerMode.SECOND) {
|
|
||||||
updateData(tb, center);
|
|
||||||
RenderingLineAttributes attrs;
|
|
||||||
if (mode == RulerMode.FIRST) {
|
|
||||||
attrs = circleAttrs;
|
|
||||||
} else {
|
|
||||||
attrs = circleAttrsAlt;
|
|
||||||
}
|
|
||||||
for (int i = 1; i <= cacheDistances.size(); i++) {
|
|
||||||
drawCircle(canvas, tb, i, center, attrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean rulerModeOn() {
|
drawCenterIcon(canvas, tb, center, settings.isNightMode(), mode);
|
||||||
return mapActivity.getMapLayers().getMapWidgetRegistry().isVisible("ruler") &&
|
Location currentLoc = app.getLocationProvider().getLastKnownLocation();
|
||||||
rightWidgetsPanel.getVisibility() == View.VISIBLE;
|
if (showDistBetweenFingerAndLocation && currentLoc != null) {
|
||||||
}
|
float x = tb.getPixXFromLonNoRot(touchPointLatLon.getLongitude());
|
||||||
|
float y = tb.getPixYFromLatNoRot(touchPointLatLon.getLatitude());
|
||||||
|
drawDistBetweenFingerAndLocation(canvas, tb, x, y, currentLoc, settings.isNightMode());
|
||||||
|
} else if (showTwoFingersDistance) {
|
||||||
|
LatLon firstTouchPoint = view.getFirstTouchPointLatLon();
|
||||||
|
LatLon secondTouchPoint = view.getSecondTouchPointLatLon();
|
||||||
|
float x1 = tb.getPixXFromLonNoRot(firstTouchPoint.getLongitude());
|
||||||
|
float y1 = tb.getPixYFromLatNoRot(firstTouchPoint.getLatitude());
|
||||||
|
float x2 = tb.getPixXFromLonNoRot(secondTouchPoint.getLongitude());
|
||||||
|
float y2 = tb.getPixYFromLatNoRot(secondTouchPoint.getLatitude());
|
||||||
|
drawFingerDistance(canvas, x1, y1, x2, y2, settings.isNightMode());
|
||||||
|
}
|
||||||
|
if (mode == RulerMode.FIRST || mode == RulerMode.SECOND) {
|
||||||
|
updateData(tb, center);
|
||||||
|
RenderingLineAttributes attrs;
|
||||||
|
if (mode == RulerMode.FIRST) {
|
||||||
|
attrs = circleAttrs;
|
||||||
|
} else {
|
||||||
|
attrs = circleAttrsAlt;
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= cacheDistances.size(); i++) {
|
||||||
|
drawCircle(canvas, tb, i, center, attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void refreshMapDelayed() {
|
private boolean rulerModeOn() {
|
||||||
handler.sendEmptyMessageDelayed(0, DELAY + 50);
|
return mapActivity.getMapLayers().getMapWidgetRegistry().isVisible("ruler") &&
|
||||||
}
|
rightWidgetsPanel.getVisibility() == View.VISIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
private void drawFingerDistance(Canvas canvas, float x1, float y1, float x2, float y2, boolean nightMode) {
|
private void refreshMapDelayed() {
|
||||||
canvas.drawLine(x1, y1, x2, y2, lineAttrs.paint);
|
handler.sendEmptyMessageDelayed(0, DRAW_TIME + 50);
|
||||||
drawFingerTouchIcon(canvas, x1, y1, nightMode);
|
}
|
||||||
drawFingerTouchIcon(canvas, x2, y2, nightMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawFingerTouchIcon(Canvas canvas, float x, float y, boolean nightMode) {
|
private void drawFingerDistance(Canvas canvas, float x1, float y1, float x2, float y2, boolean nightMode) {
|
||||||
if (nightMode) {
|
canvas.drawLine(x1, y1, x2, y2, lineAttrs.paint);
|
||||||
canvas.drawBitmap(centerIconNight, x - centerIconNight.getWidth() / 2,
|
drawFingerTouchIcon(canvas, x1, y1, nightMode);
|
||||||
y - centerIconNight.getHeight() / 2, bitmapPaint);
|
drawFingerTouchIcon(canvas, x2, y2, nightMode);
|
||||||
} else {
|
}
|
||||||
canvas.drawBitmap(centerIconDay, x - centerIconDay.getWidth() / 2,
|
|
||||||
y - centerIconDay.getHeight() / 2, bitmapPaint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center, boolean nightMode,
|
private void drawFingerTouchIcon(Canvas canvas, float x, float y, boolean nightMode) {
|
||||||
RulerMode mode) {
|
if (nightMode) {
|
||||||
canvas.rotate(-tb.getRotate(), center.x, center.y);
|
canvas.drawBitmap(centerIconNight, x - centerIconNight.getWidth() / 2,
|
||||||
if (nightMode || mode == RulerMode.SECOND) {
|
y - centerIconNight.getHeight() / 2, bitmapPaint);
|
||||||
canvas.drawBitmap(centerIconNight, center.x - centerIconNight.getWidth() / 2,
|
} else {
|
||||||
center.y - centerIconNight.getHeight() / 2, bitmapPaint);
|
canvas.drawBitmap(centerIconDay, x - centerIconDay.getWidth() / 2,
|
||||||
} else {
|
y - centerIconDay.getHeight() / 2, bitmapPaint);
|
||||||
canvas.drawBitmap(centerIconDay, center.x - centerIconDay.getWidth() / 2,
|
}
|
||||||
center.y - centerIconDay.getHeight() / 2, bitmapPaint);
|
}
|
||||||
}
|
|
||||||
canvas.rotate(tb.getRotate(), center.x, center.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawDistBetweenFingerAndLocation(Canvas canvas, RotatedTileBox tb, float x, float y,
|
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center, boolean nightMode,
|
||||||
Location currentLoc, boolean nightMode) {
|
RulerMode mode) {
|
||||||
int currX = tb.getPixXFromLonNoRot(currentLoc.getLongitude());
|
canvas.rotate(-tb.getRotate(), center.x, center.y);
|
||||||
int currY = tb.getPixYFromLatNoRot(currentLoc.getLatitude());
|
if (nightMode || mode == RulerMode.SECOND) {
|
||||||
distancePath.reset();
|
canvas.drawBitmap(centerIconNight, center.x - centerIconNight.getWidth() / 2,
|
||||||
tx.clear();
|
center.y - centerIconNight.getHeight() / 2, bitmapPaint);
|
||||||
ty.clear();
|
} else {
|
||||||
|
canvas.drawBitmap(centerIconDay, center.x - centerIconDay.getWidth() / 2,
|
||||||
|
center.y - centerIconDay.getHeight() / 2, bitmapPaint);
|
||||||
|
}
|
||||||
|
canvas.rotate(tb.getRotate(), center.x, center.y);
|
||||||
|
}
|
||||||
|
|
||||||
tx.add(currX);
|
private void drawDistBetweenFingerAndLocation(Canvas canvas, RotatedTileBox tb, float x, float y,
|
||||||
ty.add(currY);
|
Location currentLoc, boolean nightMode) {
|
||||||
tx.add((int) x);
|
int currX = tb.getPixXFromLonNoRot(currentLoc.getLongitude());
|
||||||
ty.add((int) y);
|
int currY = tb.getPixYFromLatNoRot(currentLoc.getLatitude());
|
||||||
|
distancePath.reset();
|
||||||
|
tx.clear();
|
||||||
|
ty.clear();
|
||||||
|
|
||||||
calculatePath(tb, tx, ty, distancePath);
|
tx.add(currX);
|
||||||
canvas.drawPath(distancePath, lineAttrs.paint);
|
ty.add(currY);
|
||||||
drawFingerTouchIcon(canvas, x, y, nightMode);
|
tx.add((int) x);
|
||||||
}
|
ty.add((int) y);
|
||||||
|
|
||||||
private void updateData(RotatedTileBox tb, QuadPoint center) {
|
calculatePath(tb, tx, ty, distancePath);
|
||||||
if (tb.getPixHeight() > 0 && tb.getPixWidth() > 0 && maxRadiusInDp > 0) {
|
canvas.drawPath(distancePath, lineAttrs.paint);
|
||||||
if (cacheCenter.y != center.y || cacheCenter.x != center.x) {
|
drawFingerTouchIcon(canvas, x, y, nightMode);
|
||||||
cacheCenter = center;
|
}
|
||||||
updateCenter(tb, center);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean move = tb.getZoom() != cacheIntZoom || Math.abs(tb.getCenterTileX() - cacheTileX) > 1 ||
|
private void updateData(RotatedTileBox tb, QuadPoint center) {
|
||||||
Math.abs(tb.getCenterTileY() - cacheTileY) > 1;
|
if (tb.getPixHeight() > 0 && tb.getPixWidth() > 0 && maxRadiusInDp > 0) {
|
||||||
|
if (cacheCenter.y != center.y || cacheCenter.x != center.x) {
|
||||||
|
cacheCenter = center;
|
||||||
|
updateCenter(tb, center);
|
||||||
|
}
|
||||||
|
|
||||||
if (!tb.isZoomAnimated() && move) {
|
boolean move = tb.getZoom() != cacheIntZoom || Math.abs(tb.getCenterTileX() - cacheTileX) > 1 ||
|
||||||
cacheIntZoom = tb.getZoom();
|
Math.abs(tb.getCenterTileY() - cacheTileY) > 1;
|
||||||
cacheTileX = tb.getCenterTileX();
|
|
||||||
cacheTileY = tb.getCenterTileY();
|
|
||||||
cacheDistances.clear();
|
|
||||||
updateDistance(tb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCenter(RotatedTileBox tb, QuadPoint center) {
|
if (!tb.isZoomAnimated() && move) {
|
||||||
float topDist = center.y;
|
cacheIntZoom = tb.getZoom();
|
||||||
float bottomDist = tb.getPixHeight() - center.y;
|
cacheTileX = tb.getCenterTileX();
|
||||||
float leftDist = center.x;
|
cacheTileY = tb.getCenterTileY();
|
||||||
float rightDist = tb.getPixWidth() - center.x;
|
cacheDistances.clear();
|
||||||
float maxVertical = topDist >= bottomDist ? topDist : bottomDist;
|
updateDistance(tb);
|
||||||
float maxHorizontal = rightDist >= leftDist ? rightDist : leftDist;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (maxVertical >= maxHorizontal) {
|
private void updateCenter(RotatedTileBox tb, QuadPoint center) {
|
||||||
maxRadius = maxVertical;
|
float topDist = center.y;
|
||||||
textSide = TextSide.VERTICAL;
|
float bottomDist = tb.getPixHeight() - center.y;
|
||||||
} else {
|
float leftDist = center.x;
|
||||||
maxRadius = maxHorizontal;
|
float rightDist = tb.getPixWidth() - center.x;
|
||||||
textSide = TextSide.HORIZONTAL;
|
float maxVertical = topDist >= bottomDist ? topDist : bottomDist;
|
||||||
}
|
float maxHorizontal = rightDist >= leftDist ? rightDist : leftDist;
|
||||||
if (radius != 0) {
|
|
||||||
updateText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDistance(RotatedTileBox tb) {
|
if (maxVertical >= maxHorizontal) {
|
||||||
final double dist = tb.getDistance(0, tb.getPixHeight() / 2, tb.getPixWidth(), tb.getPixHeight() / 2);
|
maxRadius = maxVertical;
|
||||||
double pixDensity = tb.getPixWidth() / dist;
|
textSide = TextSide.VERTICAL;
|
||||||
roundedDist = OsmAndFormatter.calculateRoundedDist(maxRadiusInDp / pixDensity, app);
|
} else {
|
||||||
radius = (int) (pixDensity * roundedDist);
|
maxRadius = maxHorizontal;
|
||||||
updateText();
|
textSide = TextSide.HORIZONTAL;
|
||||||
}
|
}
|
||||||
|
if (radius != 0) {
|
||||||
|
updateText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateText() {
|
private void updateDistance(RotatedTileBox tb) {
|
||||||
double maxCircleRadius = maxRadius;
|
final double dist = tb.getDistance(0, tb.getPixHeight() / 2, tb.getPixWidth(), tb.getPixHeight() / 2);
|
||||||
int i = 1;
|
double pixDensity = tb.getPixWidth() / dist;
|
||||||
while ((maxCircleRadius -= radius) > 0) {
|
roundedDist = OsmAndFormatter.calculateRoundedDist(maxRadiusInDp / pixDensity, app);
|
||||||
cacheDistances.add(OsmAndFormatter
|
radius = (int) (pixDensity * roundedDist);
|
||||||
.getFormattedDistance((float) roundedDist * i++, app, false).replaceAll(" ", ""));
|
updateText();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void drawCircle(Canvas canvas, RotatedTileBox tb, int circleNumber, QuadPoint center,
|
private void updateText() {
|
||||||
RenderingLineAttributes attrs) {
|
double maxCircleRadius = maxRadius;
|
||||||
if (!tb.isZoomAnimated()) {
|
int i = 1;
|
||||||
Rect bounds = new Rect();
|
while ((maxCircleRadius -= radius) > 0) {
|
||||||
String text = cacheDistances.get(circleNumber - 1);
|
cacheDistances.add(OsmAndFormatter
|
||||||
attrs.paint2.getTextBounds(text, 0, text.length(), bounds);
|
.getFormattedDistance((float) roundedDist * i++, app, false).replaceAll(" ", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// coords of left or top text
|
private void drawCircle(Canvas canvas, RotatedTileBox tb, int circleNumber, QuadPoint center,
|
||||||
float x1 = 0;
|
RenderingLineAttributes attrs) {
|
||||||
float y1 = 0;
|
if (!tb.isZoomAnimated()) {
|
||||||
// coords of right or bottom text
|
Rect bounds = new Rect();
|
||||||
float x2 = 0;
|
String text = cacheDistances.get(circleNumber - 1);
|
||||||
float y2 = 0;
|
attrs.paint2.getTextBounds(text, 0, text.length(), bounds);
|
||||||
|
|
||||||
if (textSide == TextSide.VERTICAL) {
|
// coords of left or top text
|
||||||
x1 = center.x - bounds.width() / 2;
|
float x1 = 0;
|
||||||
y1 = center.y - radius * circleNumber + bounds.height() / 2;
|
float y1 = 0;
|
||||||
x2 = center.x - bounds.width() / 2;
|
// coords of right or bottom text
|
||||||
y2 = center.y + radius * circleNumber + bounds.height() / 2;
|
float x2 = 0;
|
||||||
} else if (textSide == TextSide.HORIZONTAL) {
|
float y2 = 0;
|
||||||
x1 = center.x - radius * circleNumber - bounds.width() / 2;
|
|
||||||
y1 = center.y + bounds.height() / 2;
|
|
||||||
x2 = center.x + radius * circleNumber - bounds.width() / 2;
|
|
||||||
y2 = center.y + bounds.height() / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.rotate(-tb.getRotate(), center.x, center.y);
|
if (textSide == TextSide.VERTICAL) {
|
||||||
canvas.drawCircle(center.x, center.y, radius * circleNumber, attrs.shadowPaint);
|
x1 = center.x - bounds.width() / 2;
|
||||||
canvas.drawCircle(center.x, center.y, radius * circleNumber, attrs.paint);
|
y1 = center.y - radius * circleNumber + bounds.height() / 2;
|
||||||
canvas.drawText(text, x1, y1, attrs.paint3);
|
x2 = center.x - bounds.width() / 2;
|
||||||
canvas.drawText(text, x1, y1, attrs.paint2);
|
y2 = center.y + radius * circleNumber + bounds.height() / 2;
|
||||||
canvas.drawText(text, x2, y2, attrs.paint3);
|
} else if (textSide == TextSide.HORIZONTAL) {
|
||||||
canvas.drawText(text, x2, y2, attrs.paint2);
|
x1 = center.x - radius * circleNumber - bounds.width() / 2;
|
||||||
canvas.rotate(tb.getRotate(), center.x, center.y);
|
y1 = center.y + bounds.height() / 2;
|
||||||
}
|
x2 = center.x + radius * circleNumber - bounds.width() / 2;
|
||||||
}
|
y2 = center.y + bounds.height() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
private enum TextSide {
|
canvas.rotate(-tb.getRotate(), center.x, center.y);
|
||||||
VERTICAL,
|
canvas.drawCircle(center.x, center.y, radius * circleNumber, attrs.shadowPaint);
|
||||||
HORIZONTAL
|
canvas.drawCircle(center.x, center.y, radius * circleNumber, attrs.paint);
|
||||||
}
|
canvas.drawText(text, x1, y1, attrs.paint3);
|
||||||
|
canvas.drawText(text, x1, y1, attrs.paint2);
|
||||||
|
canvas.drawText(text, x2, y2, attrs.paint3);
|
||||||
|
canvas.drawText(text, x2, y2, attrs.paint2);
|
||||||
|
canvas.rotate(tb.getRotate(), center.x, center.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
private enum TextSide {
|
||||||
public void destroyLayer() {
|
VERTICAL,
|
||||||
|
HORIZONTAL
|
||||||
|
}
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public void destroyLayer() {
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public boolean drawInScreenPixels() {
|
|
||||||
return false;
|
@Override
|
||||||
}
|
public boolean drawInScreenPixels() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,8 +127,8 @@ public class MapInfoWidgetsFactory {
|
||||||
Location currentLoc = map.getMyApplication().getLocationProvider().getLastKnownLocation();
|
Location currentLoc = map.getMyApplication().getLocationProvider().getLastKnownLocation();
|
||||||
|
|
||||||
if (rulerLayer.isShowDistBetweenFingerAndLocation() && currentLoc != null) {
|
if (rulerLayer.isShowDistBetweenFingerAndLocation() && currentLoc != null) {
|
||||||
if (!cacheSingleTouchPoint.equals(rulerLayer.getSingleTouchPointLatLon())) {
|
if (!cacheSingleTouchPoint.equals(rulerLayer.getTouchPointLatLon())) {
|
||||||
cacheSingleTouchPoint = rulerLayer.getSingleTouchPointLatLon();
|
cacheSingleTouchPoint = rulerLayer.getTouchPointLatLon();
|
||||||
setDistanceText(cacheSingleTouchPoint.getLatitude(), cacheSingleTouchPoint.getLongitude(),
|
setDistanceText(cacheSingleTouchPoint.getLatitude(), cacheSingleTouchPoint.getLongitude(),
|
||||||
currentLoc.getLatitude(), currentLoc.getLongitude());
|
currentLoc.getLatitude(), currentLoc.getLongitude());
|
||||||
fingerAndLocDistWasShown = true;
|
fingerAndLocDistWasShown = true;
|
||||||
|
|
Loading…
Reference in a new issue