commit
d38025474a
17 changed files with 512 additions and 358 deletions
|
@ -12,6 +12,11 @@
|
|||
|
||||
-->
|
||||
|
||||
<string name="map_widget_distance_by_tap">Distance by tap</string>
|
||||
<string name="quick_action_coordinates_widget_descr">A toggle to show or hide the Coordinates widget on the map.</string>
|
||||
<string name="quick_action_coordinates_widget_show">Show Coordinates widget</string>
|
||||
<string name="quick_action_coordinates_widget_hide">Hide Coordinates widget</string>
|
||||
<string name="quick_action_showhide_coordinates_widget">Show/Hide coordinates widget</string>
|
||||
<string name="routing_attr_height_obstacles_description">Routing could avoid strong uphills.</string>
|
||||
<string name="app_restart_required">Application restart required to apply some settings.</string>
|
||||
<string name="on_pause">On pause</string>
|
||||
|
|
|
@ -373,22 +373,30 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
|||
|
||||
public void addLocationListener(@NonNull OsmAndLocationListener listener) {
|
||||
if (!locationListeners.contains(listener)) {
|
||||
locationListeners.add(listener);
|
||||
List<OsmAndLocationListener> listeners = new ArrayList<>(locationListeners);
|
||||
listeners.add(listener);
|
||||
locationListeners = listeners;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLocationListener(@NonNull OsmAndLocationListener listener) {
|
||||
locationListeners.remove(listener);
|
||||
List<OsmAndLocationListener> listeners = new ArrayList<>(locationListeners);
|
||||
listeners.remove(listener);
|
||||
locationListeners = listeners;
|
||||
}
|
||||
|
||||
public void addCompassListener(@NonNull OsmAndCompassListener listener) {
|
||||
if (!compassListeners.contains(listener)) {
|
||||
compassListeners.add(listener);
|
||||
List<OsmAndCompassListener> listeners = new ArrayList<>(compassListeners);
|
||||
listeners.add(listener);
|
||||
compassListeners = listeners;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeCompassListener(@NonNull OsmAndCompassListener listener) {
|
||||
compassListeners.remove(listener);
|
||||
List<OsmAndCompassListener> listeners = new ArrayList<>(compassListeners);
|
||||
listeners.remove(listener);
|
||||
compassListeners = listeners;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -57,7 +57,8 @@ import net.osmand.plus.views.layers.POIMapLayer;
|
|||
import net.osmand.plus.views.layers.PointLocationLayer;
|
||||
import net.osmand.plus.views.layers.PointNavigationLayer;
|
||||
import net.osmand.plus.views.layers.RouteLayer;
|
||||
import net.osmand.plus.views.layers.RulerControlLayer;
|
||||
import net.osmand.plus.views.layers.RadiusRulerControlLayer;
|
||||
import net.osmand.plus.views.layers.DistanceRulerControlLayer;
|
||||
import net.osmand.plus.views.layers.TransportStopsLayer;
|
||||
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry;
|
||||
|
||||
|
@ -82,7 +83,8 @@ public class MapActivityLayers {
|
|||
private FavouritesLayer mFavouritesLayer;
|
||||
private TransportStopsLayer transportStopsLayer;
|
||||
private PointLocationLayer locationLayer;
|
||||
private RulerControlLayer rulerControlLayer;
|
||||
private RadiusRulerControlLayer radiusRulerControlLayer;
|
||||
private DistanceRulerControlLayer distanceRulerControlLayer;
|
||||
private PointNavigationLayer navigationLayer;
|
||||
private MapMarkersLayer mapMarkersLayer;
|
||||
private ImpassableRoadsLayer impassableRoadsLayer;
|
||||
|
@ -168,9 +170,12 @@ public class MapActivityLayers {
|
|||
// 7.5 Impassible roads
|
||||
impassableRoadsLayer = new ImpassableRoadsLayer(activity);
|
||||
mapView.addLayer(impassableRoadsLayer, 7.5f);
|
||||
// 7.8 ruler control layer
|
||||
rulerControlLayer = new RulerControlLayer(activity);
|
||||
mapView.addLayer(rulerControlLayer, 7.8f);
|
||||
// 7.8 radius ruler control layer
|
||||
radiusRulerControlLayer = new RadiusRulerControlLayer(activity);
|
||||
mapView.addLayer(radiusRulerControlLayer, 7.8f);
|
||||
// 7.9 ruler by tap control layer
|
||||
distanceRulerControlLayer = new DistanceRulerControlLayer(activity);
|
||||
mapView.addLayer(distanceRulerControlLayer, 7.9f);
|
||||
// 8. context menu layer
|
||||
// 9. map info layer
|
||||
mapInfoLayer = new MapInfoLayer(activity, routeLayer);
|
||||
|
@ -612,8 +617,12 @@ public class MapActivityLayers {
|
|||
return locationLayer;
|
||||
}
|
||||
|
||||
public RulerControlLayer getRulerControlLayer() {
|
||||
return rulerControlLayer;
|
||||
public RadiusRulerControlLayer getRadiusRulerControlLayer() {
|
||||
return radiusRulerControlLayer;
|
||||
}
|
||||
|
||||
public DistanceRulerControlLayer getDistanceRulerControlLayer() {
|
||||
return distanceRulerControlLayer;
|
||||
}
|
||||
|
||||
public MapInfoLayer getMapInfoLayer() {
|
||||
|
|
|
@ -1002,7 +1002,6 @@ public class MeasurementEditingContext implements IRouteSettingsListener {
|
|||
pts.add(pt);
|
||||
}
|
||||
calculatedPairs++;
|
||||
params.calculationProgressCallback.updateProgress(0);
|
||||
List<RouteSegmentResult> originalRoute = route.getOriginalRoute();
|
||||
if (Algorithms.isEmpty(originalRoute)) {
|
||||
originalRoute = Collections.singletonList(RoutePlannerFrontEnd.generateStraightLineSegment(
|
||||
|
@ -1012,6 +1011,7 @@ public class MeasurementEditingContext implements IRouteSettingsListener {
|
|||
application.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
params.calculationProgressCallback.updateProgress(0);
|
||||
updateSegmentsForSnap(true, false);
|
||||
progressListener.refresh();
|
||||
RouteCalculationParams params = getParams(false);
|
||||
|
|
|
@ -30,6 +30,7 @@ import net.osmand.plus.quickaction.actions.NavReplaceDestinationAction;
|
|||
import net.osmand.plus.quickaction.actions.NavResumePauseAction;
|
||||
import net.osmand.plus.quickaction.actions.NavStartStopAction;
|
||||
import net.osmand.plus.quickaction.actions.NavVoiceAction;
|
||||
import net.osmand.plus.quickaction.actions.ShowHideCoordinatesWidgetAction;
|
||||
import net.osmand.plus.quickaction.actions.ShowHideFavoritesAction;
|
||||
import net.osmand.plus.quickaction.actions.ShowHideGpxTracksAction;
|
||||
import net.osmand.plus.quickaction.actions.ShowHideMapillaryAction;
|
||||
|
@ -214,6 +215,7 @@ public class QuickActionRegistry {
|
|||
quickActionTypes.add(DayNightModeAction.TYPE);
|
||||
quickActionTypes.add(ShowHideTransportLinesAction.TYPE);
|
||||
quickActionTypes.add(ShowHideMapillaryAction.TYPE);
|
||||
quickActionTypes.add(ShowHideCoordinatesWidgetAction.TYPE);
|
||||
// navigation
|
||||
quickActionTypes.add(NavVoiceAction.TYPE);
|
||||
quickActionTypes.add(NavDirectionsFromAction.TYPE);
|
||||
|
@ -313,7 +315,8 @@ public class QuickActionRegistry {
|
|||
}
|
||||
if (obj.has("params")) {
|
||||
qa.setParams((Map<String, String>) context.deserialize(obj.get("params"),
|
||||
new TypeToken<HashMap<String, String>>() {}.getType())
|
||||
new TypeToken<HashMap<String, String>>() {
|
||||
}.getType())
|
||||
);
|
||||
}
|
||||
return qa;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package net.osmand.plus.quickaction.actions;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.quickaction.QuickActionType;
|
||||
|
||||
public class ShowHideCoordinatesWidgetAction extends QuickAction {
|
||||
public static final QuickActionType TYPE = new QuickActionType(35,
|
||||
"coordinates.showhide", ShowHideCoordinatesWidgetAction.class)
|
||||
.nameRes(R.string.quick_action_showhide_coordinates_widget)
|
||||
.iconRes(R.drawable.ic_action_coordinates_widget).nonEditable()
|
||||
.category(QuickActionType.CONFIGURE_MAP);
|
||||
|
||||
public ShowHideCoordinatesWidgetAction() {
|
||||
super(TYPE);
|
||||
}
|
||||
|
||||
public ShowHideCoordinatesWidgetAction(QuickAction quickAction) {
|
||||
super(quickAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(MapActivity activity) {
|
||||
|
||||
activity.getMyApplication().getSettings().SHOW_COORDINATES_WIDGET.set(
|
||||
!activity.getMyApplication().getSettings().SHOW_COORDINATES_WIDGET.get());
|
||||
|
||||
activity.getMapLayers().updateLayers(activity.getMapView());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawUI(ViewGroup parent, MapActivity activity) {
|
||||
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.quick_action_with_text, parent, false);
|
||||
|
||||
((TextView) view.findViewById(R.id.text)).setText(
|
||||
R.string.quick_action_coordinates_widget_descr);
|
||||
|
||||
parent.addView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionText(OsmandApplication application) {
|
||||
|
||||
return application.getSettings().SHOW_COORDINATES_WIDGET.get()
|
||||
? application.getString(R.string.quick_action_coordinates_widget_hide)
|
||||
: application.getString(R.string.quick_action_coordinates_widget_show);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionWithSlash(OsmandApplication application) {
|
||||
return application.getSettings().SHOW_COORDINATES_WIDGET.get();
|
||||
}
|
||||
}
|
|
@ -232,12 +232,18 @@ class RouteRecalculationHelper {
|
|||
}
|
||||
|
||||
void startProgress(final RouteCalculationParams params) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (params.calculationProgressCallback != null) {
|
||||
params.calculationProgressCallback.start();
|
||||
} else if (progressRoute != null) {
|
||||
progressRoute.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void updateProgress(final RouteCalculationParams params) {
|
||||
final RouteCalculationProgressCallback progressRoute;
|
||||
|
|
|
@ -237,8 +237,13 @@ public class TransportRoutingHelper {
|
|||
private void startProgress(final TransportRouteCalculationParams params) {
|
||||
final TransportRouteCalculationProgressCallback progressRoute = this.progressRoute;
|
||||
if (progressRoute != null) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressRoute.start();
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
setCurrentRoute(-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ import net.osmand.plus.profiles.ProfileIconColors;
|
|||
import net.osmand.plus.routing.RouteProvider.RouteService;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -41,7 +43,7 @@ import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_NEXT_NEX
|
|||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_NEXT_TURN;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_NEXT_TURN_SMALL;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_PLAIN_TIME;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_RULER;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_RADIUS_RULER;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_SPEED;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_TIME;
|
||||
|
||||
|
@ -226,7 +228,7 @@ public class ApplicationMode {
|
|||
regWidgetAvailability(WIDGET_GPS_INFO, all);
|
||||
regWidgetAvailability(WIDGET_BATTERY, all);
|
||||
regWidgetAvailability(WIDGET_BEARING, all);
|
||||
regWidgetAvailability(WIDGET_RULER, all);
|
||||
regWidgetAvailability(WIDGET_RADIUS_RULER, all);
|
||||
regWidgetAvailability(WIDGET_PLAIN_TIME, all);
|
||||
|
||||
// top
|
||||
|
@ -330,8 +332,12 @@ public class ApplicationMode {
|
|||
|
||||
public String toHumanString() {
|
||||
String userProfileName = getUserProfileName();
|
||||
if (Algorithms.isEmpty(userProfileName) && keyName != -1) {
|
||||
if (Algorithms.isEmpty(userProfileName)) {
|
||||
if (keyName != -1) {
|
||||
return app.getString(keyName);
|
||||
} else {
|
||||
return StringUtils.capitalize(getStringKey());
|
||||
}
|
||||
} else {
|
||||
return userProfileName;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode;
|
|||
import net.osmand.plus.render.RendererRegistry;
|
||||
import net.osmand.plus.routing.RouteProvider.RouteService;
|
||||
import net.osmand.plus.srtmplugin.TerrainMode;
|
||||
import net.osmand.plus.views.layers.RulerControlLayer.RulerMode;
|
||||
import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode;
|
||||
import net.osmand.plus.voice.CommandPlayer;
|
||||
import net.osmand.plus.wikipedia.WikiArticleShowImages;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
|
@ -700,9 +700,9 @@ public class OsmandSettings {
|
|||
return false;
|
||||
}
|
||||
|
||||
public final CommonPreference<RulerMode> RULER_MODE = new EnumStringPreference<>(this, "ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal().makeShared();
|
||||
|
||||
public final CommonPreference<RadiusRulerMode> RADIUS_RULER_MODE = new EnumStringPreference<>(this, "ruler_mode", RadiusRulerMode.FIRST, RadiusRulerMode.values()).makeGlobal().makeShared();
|
||||
public final OsmandPreference<Boolean> SHOW_COMPASS_CONTROL_RULER = new BooleanPreference(this, "show_compass_ruler", true).makeGlobal().makeShared();
|
||||
public final OsmandPreference<Boolean> SHOW_DISTANCE_RULER = new BooleanPreference(this, "show_distance_ruler", false).makeProfile();
|
||||
|
||||
public final CommonPreference<Boolean> SHOW_LINES_TO_FIRST_MARKERS = new BooleanPreference(this, "show_lines_to_first_markers", false).makeProfile();
|
||||
public final CommonPreference<Boolean> SHOW_ARROWS_TO_FIRST_MARKERS = new BooleanPreference(this, "show_arrows_to_first_markers", false).makeProfile();
|
||||
|
@ -1206,6 +1206,7 @@ public class OsmandSettings {
|
|||
|
||||
// this value string is synchronized with settings_pref.xml preference name
|
||||
public final CommonPreference<Boolean> AUTO_ZOOM_MAP = new BooleanPreference(this, "auto_zoom_map_on_off", false).makeProfile().cache();
|
||||
|
||||
{
|
||||
AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.CAR, true);
|
||||
AUTO_ZOOM_MAP.setModeDefaultValue(ApplicationMode.BICYCLE, false);
|
||||
|
@ -1215,6 +1216,7 @@ public class OsmandSettings {
|
|||
public final CommonPreference<AutoZoomMap> AUTO_ZOOM_MAP_SCALE =
|
||||
new EnumStringPreference<AutoZoomMap>(this, "auto_zoom_map_scale", AutoZoomMap.FAR,
|
||||
AutoZoomMap.values()).makeProfile().cache();
|
||||
|
||||
{
|
||||
AUTO_ZOOM_MAP_SCALE.setModeDefaultValue(ApplicationMode.CAR, AutoZoomMap.FAR);
|
||||
AUTO_ZOOM_MAP_SCALE.setModeDefaultValue(ApplicationMode.BICYCLE, AutoZoomMap.CLOSE);
|
||||
|
@ -1323,6 +1325,7 @@ public class OsmandSettings {
|
|||
|
||||
public final OsmandPreference<Boolean> SPEAK_STREET_NAMES = new BooleanPreference(this, "speak_street_names", true).makeProfile().cache();
|
||||
public final CommonPreference<Boolean> SPEAK_TRAFFIC_WARNINGS = new BooleanPreference(this, "speak_traffic_warnings", true).makeProfile().cache();
|
||||
|
||||
{
|
||||
SPEAK_TRAFFIC_WARNINGS.setModeDefaultValue(ApplicationMode.CAR, true);
|
||||
}
|
||||
|
|
|
@ -465,7 +465,7 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
|
|||
bld.setTitle(R.string.profile_alert_delete_title);
|
||||
bld.setMessage(String
|
||||
.format(getString(R.string.profile_alert_delete_msg),
|
||||
profile.getUserProfileName()));
|
||||
profile.toHumanString()));
|
||||
bld.setPositiveButton(R.string.shared_string_delete,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
package net.osmand.plus.views.layers;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PathMeasure;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.views.OsmandMapLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.layers.geometry.GeometryWay;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DistanceRulerControlLayer extends OsmandMapLayer {
|
||||
|
||||
private static final int VERTICAL_OFFSET = 15;
|
||||
private static final long DRAW_TIME = 2000;
|
||||
private static final long DELAY_BEFORE_DRAW = 500;
|
||||
private static final int DISTANCE_TEXT_SIZE = 16;
|
||||
|
||||
private final MapActivity mapActivity;
|
||||
private OsmandApplication app;
|
||||
private OsmandMapTileView view;
|
||||
|
||||
private boolean showTwoFingersDistance;
|
||||
private boolean showDistBetweenFingerAndLocation;
|
||||
private boolean touchOutside;
|
||||
private int acceptableTouchRadius;
|
||||
|
||||
private long cacheMultiTouchEndTime;
|
||||
private LatLon touchPointLatLon;
|
||||
private PointF touchPoint;
|
||||
private long touchStartTime;
|
||||
private long touchEndTime;
|
||||
private boolean touched;
|
||||
private boolean wasZoom;
|
||||
|
||||
private final List<Float> tx = new ArrayList<>();
|
||||
private final List<Float> ty = new ArrayList<>();
|
||||
private final Path linePath = new Path();
|
||||
|
||||
private Bitmap centerIconDay;
|
||||
private Bitmap centerIconNight;
|
||||
private Paint bitmapPaint;
|
||||
|
||||
private RenderingLineAttributes lineAttrs;
|
||||
private RenderingLineAttributes lineFontAttrs;
|
||||
|
||||
private Handler handler;
|
||||
|
||||
public DistanceRulerControlLayer(MapActivity mapActivity) {
|
||||
this.mapActivity = mapActivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initLayer(final OsmandMapTileView view) {
|
||||
app = mapActivity.getMyApplication();
|
||||
this.view = view;
|
||||
touchPoint = new PointF();
|
||||
acceptableTouchRadius = mapActivity.getResources().getDimensionPixelSize(R.dimen.acceptable_touch_radius);
|
||||
|
||||
centerIconDay = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_day);
|
||||
centerIconNight = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_night);
|
||||
|
||||
bitmapPaint = new Paint();
|
||||
bitmapPaint.setAntiAlias(true);
|
||||
bitmapPaint.setDither(true);
|
||||
bitmapPaint.setFilterBitmap(true);
|
||||
|
||||
lineAttrs = new RenderingLineAttributes("rulerLine");
|
||||
|
||||
float lineTextSize = DISTANCE_TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
|
||||
|
||||
lineFontAttrs = new RenderingLineAttributes("rulerLineFont");
|
||||
lineFontAttrs.paint.setTextSize(lineTextSize);
|
||||
lineFontAttrs.paint2.setTextSize(lineTextSize);
|
||||
|
||||
handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
view.refreshMap();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMapGestureAllowed(MapGestureType type) {
|
||||
return !rulerModeOn() || type != MapGestureType.TWO_POINTERS_ZOOM_OUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event, RotatedTileBox tileBox) {
|
||||
if (rulerModeOn() && !showTwoFingersDistance) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
touched = true;
|
||||
touchOutside = false;
|
||||
touchPoint.set(event.getX(), event.getY());
|
||||
touchPointLatLon = tileBox.getLatLonFromPixel(event.getX(), event.getY());
|
||||
touchStartTime = System.currentTimeMillis();
|
||||
wasZoom = false;
|
||||
} else if (event.getAction() == MotionEvent.ACTION_MOVE && !touchOutside &&
|
||||
!(touched && showDistBetweenFingerAndLocation)) {
|
||||
double d = Math.sqrt(Math.pow(event.getX() - touchPoint.x, 2) + Math.pow(event.getY() - touchPoint.y, 2));
|
||||
if (d > acceptableTouchRadius) {
|
||||
touchOutside = true;
|
||||
}
|
||||
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
touched = false;
|
||||
touchEndTime = System.currentTimeMillis();
|
||||
refreshMapDelayed();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
|
||||
if (rulerModeOn()) {
|
||||
OsmandApplication app = view.getApplication();
|
||||
lineAttrs.updatePaints(app, settings, tb);
|
||||
lineFontAttrs.updatePaints(app, settings, tb);
|
||||
lineFontAttrs.paint.setStyle(Style.FILL);
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
|
||||
if (cacheMultiTouchEndTime != view.getMultiTouchEndTime()) {
|
||||
cacheMultiTouchEndTime = view.getMultiTouchEndTime();
|
||||
refreshMapDelayed();
|
||||
}
|
||||
if (touched && view.isMultiTouch()) {
|
||||
touched = false;
|
||||
touchEndTime = currentTime;
|
||||
}
|
||||
if (tb.isZoomAnimated()) {
|
||||
wasZoom = true;
|
||||
}
|
||||
|
||||
showTwoFingersDistance = !tb.isZoomAnimated() &&
|
||||
!view.isWasZoomInMultiTouch() &&
|
||||
currentTime - view.getMultiTouchStartTime() > DELAY_BEFORE_DRAW &&
|
||||
(view.isMultiTouch() || currentTime - cacheMultiTouchEndTime < DRAW_TIME);
|
||||
|
||||
showDistBetweenFingerAndLocation = !wasZoom &&
|
||||
!showTwoFingersDistance &&
|
||||
!view.isMultiTouch() &&
|
||||
!touchOutside &&
|
||||
touchStartTime - view.getMultiTouchStartTime() > DELAY_BEFORE_DRAW &&
|
||||
currentTime - touchStartTime > DELAY_BEFORE_DRAW &&
|
||||
(touched || currentTime - touchEndTime < DRAW_TIME);
|
||||
|
||||
Location currentLoc = app.getLocationProvider().getLastKnownLocation();
|
||||
if (showDistBetweenFingerAndLocation && currentLoc != null) {
|
||||
drawDistBetweenFingerAndLocation(canvas, tb, currentLoc, settings.isNightMode());
|
||||
} else if (showTwoFingersDistance) {
|
||||
drawTwoFingersDistance(canvas, tb, view.getFirstTouchPointLatLon(),
|
||||
view.getSecondTouchPointLatLon(), settings.isNightMode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean rulerModeOn() {
|
||||
return app.getSettings().SHOW_DISTANCE_RULER.get();
|
||||
}
|
||||
|
||||
private void refreshMapDelayed() {
|
||||
handler.sendEmptyMessageDelayed(0, DRAW_TIME + 50);
|
||||
}
|
||||
|
||||
private void drawTwoFingersDistance(Canvas canvas, RotatedTileBox tb, LatLon firstTouch,
|
||||
LatLon secondTouch, boolean nightMode) {
|
||||
float x1 = tb.getPixXFromLatLon(firstTouch.getLatitude(), firstTouch.getLongitude());
|
||||
float y1 = tb.getPixYFromLatLon(firstTouch.getLatitude(), firstTouch.getLongitude());
|
||||
float x2 = tb.getPixXFromLatLon(secondTouch.getLatitude(), secondTouch.getLongitude());
|
||||
float y2 = tb.getPixYFromLatLon(secondTouch.getLatitude(), secondTouch.getLongitude());
|
||||
|
||||
Path path = new Path();
|
||||
path.moveTo(x1, y1);
|
||||
path.lineTo(x2, y2);
|
||||
|
||||
String text = OsmAndFormatter.getFormattedDistance((float) MapUtils.getDistance(firstTouch, secondTouch), app);
|
||||
|
||||
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
canvas.drawPath(path, lineAttrs.paint);
|
||||
drawFingerTouchIcon(canvas, x1, y1, nightMode);
|
||||
drawFingerTouchIcon(canvas, x2, y2, nightMode);
|
||||
drawTextOnCenterOfPath(canvas, x1, x2, path, text);
|
||||
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
}
|
||||
|
||||
private void drawTextOnCenterOfPath(Canvas canvas, float x1, float x2, Path path, String text) {
|
||||
PathMeasure pm = new PathMeasure(path, false);
|
||||
Rect bounds = new Rect();
|
||||
lineFontAttrs.paint.getTextBounds(text, 0, text.length(), bounds);
|
||||
float hOffset = pm.getLength() / 2 - bounds.width() / 2f;
|
||||
|
||||
if (x1 >= x2) {
|
||||
float[] pos = new float[2];
|
||||
pm.getPosTan(pm.getLength() / 2, pos, null);
|
||||
canvas.rotate(180, pos[0], pos[1]);
|
||||
canvas.drawTextOnPath(text, path, hOffset, bounds.height() + VERTICAL_OFFSET, lineFontAttrs.paint2);
|
||||
canvas.drawTextOnPath(text, path, hOffset, bounds.height() + VERTICAL_OFFSET, lineFontAttrs.paint);
|
||||
canvas.rotate(-180, pos[0], pos[1]);
|
||||
} else {
|
||||
canvas.drawTextOnPath(text, path, hOffset, -VERTICAL_OFFSET, lineFontAttrs.paint2);
|
||||
canvas.drawTextOnPath(text, path, hOffset, -VERTICAL_OFFSET, lineFontAttrs.paint);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawFingerTouchIcon(Canvas canvas, float x, float y, boolean nightMode) {
|
||||
if (nightMode) {
|
||||
canvas.drawBitmap(centerIconNight, x - centerIconNight.getWidth() / 2f,
|
||||
y - centerIconNight.getHeight() / 2f, bitmapPaint);
|
||||
|
||||
} else {
|
||||
canvas.drawBitmap(centerIconDay, x - centerIconDay.getWidth() / 2f,
|
||||
y - centerIconDay.getHeight() / 2f, bitmapPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDistBetweenFingerAndLocation(Canvas canvas, RotatedTileBox tb, Location currLoc, boolean night) {
|
||||
float x = tb.getPixXFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
|
||||
float y = tb.getPixYFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
|
||||
float currX = tb.getPixXFromLatLon(currLoc.getLatitude(), currLoc.getLongitude());
|
||||
float currY = tb.getPixYFromLatLon(currLoc.getLatitude(), currLoc.getLongitude());
|
||||
|
||||
linePath.reset();
|
||||
tx.clear();
|
||||
ty.clear();
|
||||
|
||||
tx.add(x);
|
||||
ty.add(y);
|
||||
tx.add(currX);
|
||||
ty.add(currY);
|
||||
|
||||
GeometryWay.calculatePath(tb, tx, ty, linePath);
|
||||
|
||||
float dist = (float) MapUtils.getDistance(touchPointLatLon, currLoc.getLatitude(), currLoc.getLongitude());
|
||||
String text = OsmAndFormatter.getFormattedDistance(dist, app);
|
||||
|
||||
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
canvas.drawPath(linePath, lineAttrs.paint);
|
||||
drawFingerTouchIcon(canvas, x, y, night);
|
||||
drawTextOnCenterOfPath(canvas, x, currX, linePath, text);
|
||||
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyLayer() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawInScreenPixels() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -780,7 +780,7 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
if (app.getRoutingHelper().isFollowingMode() || app.getRoutingHelper().isPauseNavigation()
|
||||
|| mapActivity.getMeasurementToolFragment() != null
|
||||
|| mapActivity.getPlanRouteFragment() != null
|
||||
|| mapActivity.getMapLayers().getRulerControlLayer().rulerModeOn()) {
|
||||
|| mapActivity.getMapLayers().getDistanceRulerControlLayer().rulerModeOn()) {
|
||||
return;
|
||||
}
|
||||
if (isMapControlsVisible()) {
|
||||
|
|
|
@ -58,7 +58,7 @@ import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_NEXT_NEX
|
|||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_NEXT_TURN;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_NEXT_TURN_SMALL;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_PLAIN_TIME;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_RULER;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_RADIUS_RULER;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_SPEED;
|
||||
import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_TIME;
|
||||
|
||||
|
@ -232,8 +232,8 @@ public class MapInfoLayer extends OsmandMapLayer {
|
|||
registerSideWidget(plainTime, R.drawable.ic_action_time, R.string.map_widget_plain_time, WIDGET_PLAIN_TIME, false, 41);
|
||||
TextInfoWidget battery = ric.createBatteryControl(map);
|
||||
registerSideWidget(battery, R.drawable.ic_action_battery, R.string.map_widget_battery, WIDGET_BATTERY, false, 42);
|
||||
TextInfoWidget ruler = mic.createRulerControl(map);
|
||||
registerSideWidget(ruler, new CompassRulerWidgetState(app), WIDGET_RULER, false, 43);
|
||||
TextInfoWidget radiusRuler = mic.createRadiusRulerControl(map);
|
||||
registerSideWidget(radiusRuler, new CompassRulerWidgetState(app), WIDGET_RADIUS_RULER, false, 43);
|
||||
}
|
||||
|
||||
public void recreateControls() {
|
||||
|
@ -298,6 +298,7 @@ public class MapInfoLayer extends OsmandMapLayer {
|
|||
}
|
||||
|
||||
private int themeId = -1;
|
||||
|
||||
public void updateColorShadowsOfText() {
|
||||
boolean transparent = view.getSettings().TRANSPARENT_MAP_THEME.get();
|
||||
boolean nightMode = drawSettings != null && drawSettings.isNightMode();
|
||||
|
|
|
@ -8,22 +8,16 @@ import android.graphics.LinearGradient;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PathMeasure;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadPoint;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
|
@ -36,19 +30,14 @@ import net.osmand.plus.R;
|
|||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.views.OsmandMapLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.layers.geometry.GeometryWay;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RulerControlLayer extends OsmandMapLayer {
|
||||
public class RadiusRulerControlLayer extends OsmandMapLayer {
|
||||
|
||||
private static final int VERTICAL_OFFSET = 15;
|
||||
private static final long DRAW_TIME = 2000;
|
||||
private static final long DELAY_BEFORE_DRAW = 500;
|
||||
private static final int TEXT_SIZE = 14;
|
||||
private static final int DISTANCE_TEXT_SIZE = 16;
|
||||
private static final float COMPASS_CIRCLE_FITTING_RADIUS_COEF = 1.25f;
|
||||
private static final float CIRCLE_ANGLE_STEP = 5;
|
||||
private static final int SHOW_COMPASS_MIN_ZOOM = 8;
|
||||
|
@ -63,10 +52,6 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
private float maxRadius;
|
||||
private int radius;
|
||||
private double roundedDist;
|
||||
private boolean showTwoFingersDistance;
|
||||
private boolean showDistBetweenFingerAndLocation;
|
||||
private boolean touchOutside;
|
||||
private int acceptableTouchRadius;
|
||||
|
||||
private QuadPoint cacheCenter;
|
||||
private float cacheMapDensity;
|
||||
|
@ -74,18 +59,7 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
private MetricsConstants cacheMetricSystem;
|
||||
private int cacheIntZoom;
|
||||
private LatLon cacheCenterLatLon;
|
||||
private long cacheMultiTouchEndTime;
|
||||
private ArrayList<String> cacheDistances;
|
||||
private LatLon touchPointLatLon;
|
||||
private PointF touchPoint;
|
||||
private long touchStartTime;
|
||||
private long touchEndTime;
|
||||
private boolean touched;
|
||||
private boolean wasZoom;
|
||||
|
||||
private List<Float> tx = new ArrayList<>();
|
||||
private List<Float> ty = new ArrayList<>();
|
||||
private Path linePath = new Path();
|
||||
|
||||
private Bitmap centerIconDay;
|
||||
private Bitmap centerIconNight;
|
||||
|
@ -95,41 +69,25 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
private Paint redLinesPaint;
|
||||
private Paint blueLinesPaint;
|
||||
|
||||
private RenderingLineAttributes lineAttrs;
|
||||
private RenderingLineAttributes lineFontAttrs;
|
||||
private RenderingLineAttributes circleAttrs;
|
||||
private RenderingLineAttributes circleAttrsAlt;
|
||||
|
||||
private Path compass = new Path();
|
||||
private Path arrow = new Path();
|
||||
private Path arrowArc = new Path();
|
||||
private Path redCompassLines = new Path();
|
||||
private final Path compass = new Path();
|
||||
private final Path arrow = new Path();
|
||||
private final Path arrowArc = new Path();
|
||||
private final Path redCompassLines = new Path();
|
||||
|
||||
private double[] degrees = new double[72];
|
||||
private String[] cardinalDirections = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
|
||||
private final double[] degrees = new double[72];
|
||||
private final String[] cardinalDirections = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
|
||||
|
||||
private int[] arcColors = {Color.parseColor("#00237BFF"), Color.parseColor("#237BFF"), Color.parseColor("#00237BFF")};
|
||||
private final int[] arcColors = {Color.parseColor("#00237BFF"), Color.parseColor("#237BFF"), Color.parseColor("#00237BFF")};
|
||||
|
||||
private float cachedHeading = 0;
|
||||
|
||||
private Handler handler;
|
||||
|
||||
public RulerControlLayer(MapActivity mapActivity) {
|
||||
public RadiusRulerControlLayer(MapActivity mapActivity) {
|
||||
this.mapActivity = mapActivity;
|
||||
}
|
||||
|
||||
public boolean isShowTwoFingersDistance() {
|
||||
return showTwoFingersDistance;
|
||||
}
|
||||
|
||||
public boolean isShowDistBetweenFingerAndLocation() {
|
||||
return showDistBetweenFingerAndLocation;
|
||||
}
|
||||
|
||||
public LatLon getTouchPointLatLon() {
|
||||
return touchPointLatLon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initLayer(final OsmandMapTileView view) {
|
||||
app = mapActivity.getMyApplication();
|
||||
|
@ -141,8 +99,6 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
cacheCenter = new QuadPoint();
|
||||
maxRadiusInDp = mapActivity.getResources().getDimensionPixelSize(R.dimen.map_ruler_width);
|
||||
rightWidgetsPanel = mapActivity.findViewById(R.id.map_right_widgets_panel);
|
||||
touchPoint = new PointF();
|
||||
acceptableTouchRadius = mapActivity.getResources().getDimensionPixelSize(R.dimen.acceptable_touch_radius);
|
||||
|
||||
centerIconDay = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_day);
|
||||
centerIconNight = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_night);
|
||||
|
@ -160,14 +116,7 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
redLinesPaint = initPaintWithStyle(Style.STROKE, colorNorthArrow);
|
||||
blueLinesPaint = initPaintWithStyle(Style.STROKE, colorHeadingArrow);
|
||||
|
||||
lineAttrs = new RenderingLineAttributes("rulerLine");
|
||||
|
||||
float circleTextSize = TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
|
||||
float lineTextSize = DISTANCE_TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
|
||||
|
||||
lineFontAttrs = new RenderingLineAttributes("rulerLineFont");
|
||||
lineFontAttrs.paint.setTextSize(lineTextSize);
|
||||
lineFontAttrs.paint2.setTextSize(lineTextSize);
|
||||
|
||||
circleAttrs = new RenderingLineAttributes("rulerCircle");
|
||||
circleAttrs.paint2.setTextSize(circleTextSize);
|
||||
|
@ -177,13 +126,6 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
circleAttrsAlt.paint2.setTextSize(circleTextSize);
|
||||
circleAttrsAlt.paint3.setTextSize(circleTextSize);
|
||||
|
||||
handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
view.refreshMap();
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i < 72; i++) {
|
||||
degrees[i] = Math.toRadians(i * 5);
|
||||
}
|
||||
|
@ -197,95 +139,27 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
return paint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMapGestureAllowed(MapGestureType type) {
|
||||
if (rulerModeOn() && type == MapGestureType.TWO_POINTERS_ZOOM_OUT) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event, RotatedTileBox tileBox) {
|
||||
if (rulerModeOn() && !showTwoFingersDistance) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
touched = true;
|
||||
touchOutside = false;
|
||||
touchPoint.set(event.getX(), event.getY());
|
||||
touchPointLatLon = tileBox.getLatLonFromPixel(event.getX(), event.getY());
|
||||
touchStartTime = System.currentTimeMillis();
|
||||
wasZoom = false;
|
||||
} else if (event.getAction() == MotionEvent.ACTION_MOVE && !touchOutside &&
|
||||
!(touched && showDistBetweenFingerAndLocation)) {
|
||||
double d = Math.sqrt(Math.pow(event.getX() - touchPoint.x, 2) + Math.pow(event.getY() - touchPoint.y, 2));
|
||||
if (d > acceptableTouchRadius) {
|
||||
touchOutside = true;
|
||||
}
|
||||
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
touched = false;
|
||||
touchEndTime = System.currentTimeMillis();
|
||||
refreshMapDelayed();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
|
||||
if (rulerModeOn()) {
|
||||
OsmandApplication app = view.getApplication();
|
||||
lineAttrs.updatePaints(app, settings, tb);
|
||||
lineFontAttrs.updatePaints(app, settings, tb);
|
||||
lineFontAttrs.paint.setStyle(Style.FILL);
|
||||
circleAttrs.updatePaints(app, settings, tb);
|
||||
circleAttrs.paint2.setStyle(Style.FILL);
|
||||
circleAttrsAlt.updatePaints(app, settings, tb);
|
||||
circleAttrsAlt.paint2.setStyle(Style.FILL);
|
||||
final QuadPoint center = tb.getCenterPixelPoint();
|
||||
final RulerMode mode = app.getSettings().RULER_MODE.get();
|
||||
final RadiusRulerMode mode = app.getSettings().RADIUS_RULER_MODE.get();
|
||||
boolean showCompass = app.getSettings().SHOW_COMPASS_CONTROL_RULER.get() && tb.getZoom() >= SHOW_COMPASS_MIN_ZOOM;
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
|
||||
if (cacheMultiTouchEndTime != view.getMultiTouchEndTime()) {
|
||||
cacheMultiTouchEndTime = view.getMultiTouchEndTime();
|
||||
refreshMapDelayed();
|
||||
}
|
||||
if (touched && view.isMultiTouch()) {
|
||||
touched = false;
|
||||
touchEndTime = currentTime;
|
||||
}
|
||||
if (tb.isZoomAnimated()) {
|
||||
wasZoom = true;
|
||||
}
|
||||
|
||||
showTwoFingersDistance = !tb.isZoomAnimated() &&
|
||||
!view.isWasZoomInMultiTouch() &&
|
||||
currentTime - view.getMultiTouchStartTime() > DELAY_BEFORE_DRAW &&
|
||||
(view.isMultiTouch() || currentTime - cacheMultiTouchEndTime < DRAW_TIME);
|
||||
|
||||
showDistBetweenFingerAndLocation = !wasZoom &&
|
||||
!showTwoFingersDistance &&
|
||||
!view.isMultiTouch() &&
|
||||
!touchOutside &&
|
||||
touchStartTime - view.getMultiTouchStartTime() > DELAY_BEFORE_DRAW &&
|
||||
currentTime - touchStartTime > DELAY_BEFORE_DRAW &&
|
||||
(touched || currentTime - touchEndTime < DRAW_TIME);
|
||||
|
||||
drawCenterIcon(canvas, tb, center, settings.isNightMode(), mode);
|
||||
Location currentLoc = app.getLocationProvider().getLastKnownLocation();
|
||||
if (showDistBetweenFingerAndLocation && currentLoc != null) {
|
||||
drawDistBetweenFingerAndLocation(canvas, tb, currentLoc, settings.isNightMode());
|
||||
} else if (showTwoFingersDistance) {
|
||||
drawTwoFingersDistance(canvas, tb, view.getFirstTouchPointLatLon(), view.getSecondTouchPointLatLon(), settings.isNightMode());
|
||||
}
|
||||
if (mode == RulerMode.FIRST || mode == RulerMode.SECOND) {
|
||||
|
||||
if (mode == RadiusRulerMode.FIRST || mode == RadiusRulerMode.SECOND) {
|
||||
updateData(tb, center);
|
||||
if (showCompass) {
|
||||
updateHeading();
|
||||
resetDrawingPaths();
|
||||
}
|
||||
RenderingLineAttributes attrs = mode == RulerMode.FIRST ? circleAttrs : circleAttrsAlt;
|
||||
RenderingLineAttributes attrs = mode == RadiusRulerMode.FIRST ? circleAttrs : circleAttrsAlt;
|
||||
int compassCircleId = getCompassCircleId(tb, center);
|
||||
for (int i = 1; i <= cacheDistances.size(); i++) {
|
||||
if (showCompass && i == compassCircleId) {
|
||||
|
@ -350,99 +224,19 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
arrow.reset();
|
||||
}
|
||||
|
||||
private void refreshMapDelayed() {
|
||||
handler.sendEmptyMessageDelayed(0, DRAW_TIME + 50);
|
||||
}
|
||||
|
||||
private void drawTwoFingersDistance(Canvas canvas, RotatedTileBox tb, LatLon firstTouch, LatLon secondTouch, boolean nightMode) {
|
||||
float x1 = tb.getPixXFromLatLon(firstTouch.getLatitude(), firstTouch.getLongitude());
|
||||
float y1 = tb.getPixYFromLatLon(firstTouch.getLatitude(), firstTouch.getLongitude());
|
||||
float x2 = tb.getPixXFromLatLon(secondTouch.getLatitude(), secondTouch.getLongitude());
|
||||
float y2 = tb.getPixYFromLatLon(secondTouch.getLatitude(), secondTouch.getLongitude());
|
||||
|
||||
Path path = new Path();
|
||||
path.moveTo(x1, y1);
|
||||
path.lineTo(x2, y2);
|
||||
|
||||
String text = OsmAndFormatter.getFormattedDistance((float) MapUtils.getDistance(firstTouch, secondTouch), app);
|
||||
|
||||
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
canvas.drawPath(path, lineAttrs.paint);
|
||||
drawFingerTouchIcon(canvas, x1, y1, nightMode);
|
||||
drawFingerTouchIcon(canvas, x2, y2, nightMode);
|
||||
drawTextOnCenterOfPath(canvas, x1, x2, path, text);
|
||||
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
}
|
||||
|
||||
private void drawTextOnCenterOfPath(Canvas canvas, float x1, float x2, Path path, String text) {
|
||||
PathMeasure pm = new PathMeasure(path, false);
|
||||
Rect bounds = new Rect();
|
||||
lineFontAttrs.paint.getTextBounds(text, 0, text.length(), bounds);
|
||||
float hOffset = pm.getLength() / 2 - bounds.width() / 2;
|
||||
|
||||
if (x1 >= x2) {
|
||||
float[] pos = new float[2];
|
||||
pm.getPosTan(pm.getLength() / 2, pos, null);
|
||||
canvas.rotate(180, pos[0], pos[1]);
|
||||
canvas.drawTextOnPath(text, path, hOffset, bounds.height() + VERTICAL_OFFSET, lineFontAttrs.paint2);
|
||||
canvas.drawTextOnPath(text, path, hOffset, bounds.height() + VERTICAL_OFFSET, lineFontAttrs.paint);
|
||||
canvas.rotate(-180, pos[0], pos[1]);
|
||||
} else {
|
||||
canvas.drawTextOnPath(text, path, hOffset, -VERTICAL_OFFSET, lineFontAttrs.paint2);
|
||||
canvas.drawTextOnPath(text, path, hOffset, -VERTICAL_OFFSET, lineFontAttrs.paint);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawFingerTouchIcon(Canvas canvas, float x, float y, boolean nightMode) {
|
||||
if (nightMode) {
|
||||
canvas.drawBitmap(centerIconNight, x - centerIconNight.getWidth() / 2,
|
||||
y - centerIconNight.getHeight() / 2, bitmapPaint);
|
||||
} else {
|
||||
canvas.drawBitmap(centerIconDay, x - centerIconDay.getWidth() / 2,
|
||||
y - centerIconDay.getHeight() / 2, bitmapPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center, boolean nightMode,
|
||||
RulerMode mode) {
|
||||
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center,
|
||||
boolean nightMode, RadiusRulerMode mode) {
|
||||
canvas.rotate(-tb.getRotate(), center.x, center.y);
|
||||
if (nightMode || mode == RulerMode.SECOND) {
|
||||
canvas.drawBitmap(centerIconNight, center.x - centerIconNight.getWidth() / 2,
|
||||
center.y - centerIconNight.getHeight() / 2, bitmapPaint);
|
||||
if (nightMode || mode == RadiusRulerMode.SECOND) {
|
||||
canvas.drawBitmap(centerIconNight, center.x - centerIconNight.getWidth() / 2f,
|
||||
center.y - centerIconNight.getHeight() / 2f, bitmapPaint);
|
||||
} else {
|
||||
canvas.drawBitmap(centerIconDay, center.x - centerIconDay.getWidth() / 2,
|
||||
center.y - centerIconDay.getHeight() / 2, bitmapPaint);
|
||||
canvas.drawBitmap(centerIconDay, center.x - centerIconDay.getWidth() / 2f,
|
||||
center.y - centerIconDay.getHeight() / 2f, bitmapPaint);
|
||||
}
|
||||
canvas.rotate(tb.getRotate(), center.x, center.y);
|
||||
}
|
||||
|
||||
private void drawDistBetweenFingerAndLocation(Canvas canvas, RotatedTileBox tb, Location currLoc, boolean night) {
|
||||
float x = tb.getPixXFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
|
||||
float y = tb.getPixYFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
|
||||
float currX = tb.getPixXFromLatLon(currLoc.getLatitude(), currLoc.getLongitude());
|
||||
float currY = tb.getPixYFromLatLon(currLoc.getLatitude(), currLoc.getLongitude());
|
||||
|
||||
linePath.reset();
|
||||
tx.clear();
|
||||
ty.clear();
|
||||
|
||||
tx.add(x);
|
||||
ty.add(y);
|
||||
tx.add(currX);
|
||||
ty.add(currY);
|
||||
|
||||
GeometryWay.calculatePath(tb, tx, ty, linePath);
|
||||
|
||||
float dist = (float) MapUtils.getDistance(touchPointLatLon, currLoc.getLatitude(), currLoc.getLongitude());
|
||||
String text = OsmAndFormatter.getFormattedDistance(dist, app);
|
||||
|
||||
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
canvas.drawPath(linePath, lineAttrs.paint);
|
||||
drawFingerTouchIcon(canvas, x, y, night);
|
||||
drawTextOnCenterOfPath(canvas, x, currX, linePath, text);
|
||||
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
}
|
||||
|
||||
private void updateData(RotatedTileBox tb, QuadPoint center) {
|
||||
if (tb.getPixHeight() > 0 && tb.getPixWidth() > 0 && maxRadiusInDp > 0
|
||||
&& !Double.isNaN(tb.getLatitude()) && !Double.isNaN(tb.getLongitude())) {
|
||||
|
@ -472,8 +266,8 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
float bottomDist = tb.getPixHeight() - center.y;
|
||||
float leftDist = center.x;
|
||||
float rightDist = tb.getPixWidth() - center.x;
|
||||
float maxVertical = topDist >= bottomDist ? topDist : bottomDist;
|
||||
float maxHorizontal = rightDist >= leftDist ? rightDist : leftDist;
|
||||
float maxVertical = Math.max(topDist, bottomDist);
|
||||
float maxHorizontal = Math.max(rightDist, leftDist);
|
||||
|
||||
if (maxVertical >= maxHorizontal) {
|
||||
maxRadius = maxVertical;
|
||||
|
@ -631,8 +425,8 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
return new float[]{x1, y1, x2, y2};
|
||||
}
|
||||
|
||||
private void drawCompassCircle(Canvas canvas, RotatedTileBox tileBox,int circleNumber, QuadPoint center,
|
||||
RenderingLineAttributes attrs) {
|
||||
private void drawCompassCircle(Canvas canvas, RotatedTileBox tileBox, int circleNumber,
|
||||
QuadPoint center, RenderingLineAttributes attrs) {
|
||||
if (!tileBox.isZoomAnimated()) {
|
||||
float radiusLength = radius * circleNumber;
|
||||
float innerRadiusLength = radiusLength - attrs.paint.getStrokeWidth() / 2;
|
||||
|
@ -823,7 +617,7 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
return false;
|
||||
}
|
||||
|
||||
public enum RulerMode {
|
||||
public enum RadiusRulerMode {
|
||||
FIRST,
|
||||
SECOND,
|
||||
EMPTY
|
|
@ -68,9 +68,7 @@ import net.osmand.plus.routing.RouteCalculationResult;
|
|||
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.layers.RulerControlLayer;
|
||||
import net.osmand.plus.views.layers.RulerControlLayer.RulerMode;
|
||||
import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode;
|
||||
import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget;
|
||||
import net.osmand.render.RenderingRuleSearchRequest;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
|
@ -162,38 +160,13 @@ public class MapInfoWidgetsFactory {
|
|||
return gpsInfoControl;
|
||||
}
|
||||
|
||||
public TextInfoWidget createRulerControl(final MapActivity map) {
|
||||
public TextInfoWidget createRadiusRulerControl(final MapActivity map) {
|
||||
final String title = "—";
|
||||
final TextInfoWidget rulerControl = new TextInfoWidget(map) {
|
||||
RulerControlLayer rulerLayer = map.getMapLayers().getRulerControlLayer();
|
||||
LatLon cacheFirstTouchPoint = new LatLon(0, 0);
|
||||
LatLon cacheSecondTouchPoint = new LatLon(0, 0);
|
||||
LatLon cacheSingleTouchPoint = new LatLon(0, 0);
|
||||
boolean fingerAndLocDistWasShown;
|
||||
final TextInfoWidget radiusRulerControl = new TextInfoWidget(map) {
|
||||
|
||||
@Override
|
||||
public boolean updateInfo(DrawSettings drawSettings) {
|
||||
OsmandMapTileView view = map.getMapView();
|
||||
Location currentLoc = map.getMyApplication().getLocationProvider().getLastKnownLocation();
|
||||
|
||||
if (rulerLayer.isShowDistBetweenFingerAndLocation() && currentLoc != null) {
|
||||
if (!cacheSingleTouchPoint.equals(rulerLayer.getTouchPointLatLon())) {
|
||||
cacheSingleTouchPoint = rulerLayer.getTouchPointLatLon();
|
||||
setDistanceText(cacheSingleTouchPoint.getLatitude(), cacheSingleTouchPoint.getLongitude(),
|
||||
currentLoc.getLatitude(), currentLoc.getLongitude());
|
||||
fingerAndLocDistWasShown = true;
|
||||
}
|
||||
} else if (rulerLayer.isShowTwoFingersDistance()) {
|
||||
if (!cacheFirstTouchPoint.equals(view.getFirstTouchPointLatLon()) ||
|
||||
!cacheSecondTouchPoint.equals(view.getSecondTouchPointLatLon()) ||
|
||||
fingerAndLocDistWasShown) {
|
||||
cacheFirstTouchPoint = view.getFirstTouchPointLatLon();
|
||||
cacheSecondTouchPoint = view.getSecondTouchPointLatLon();
|
||||
setDistanceText(cacheFirstTouchPoint.getLatitude(), cacheFirstTouchPoint.getLongitude(),
|
||||
cacheSecondTouchPoint.getLatitude(), cacheSecondTouchPoint.getLongitude());
|
||||
fingerAndLocDistWasShown = false;
|
||||
}
|
||||
} else {
|
||||
LatLon centerLoc = map.getMapLocation();
|
||||
|
||||
if (currentLoc != null && centerLoc != null) {
|
||||
|
@ -206,7 +179,6 @@ public class MapInfoWidgetsFactory {
|
|||
} else {
|
||||
setText(title, null);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -226,29 +198,29 @@ public class MapInfoWidgetsFactory {
|
|||
}
|
||||
};
|
||||
|
||||
rulerControl.setText(title, null);
|
||||
setRulerControlIcon(rulerControl, map.getMyApplication().getSettings().RULER_MODE.get());
|
||||
rulerControl.setOnClickListener(new OnClickListener() {
|
||||
radiusRulerControl.setText(title, null);
|
||||
setRulerControlIcon(radiusRulerControl, map.getMyApplication().getSettings().RADIUS_RULER_MODE.get());
|
||||
radiusRulerControl.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
final RulerMode mode = map.getMyApplication().getSettings().RULER_MODE.get();
|
||||
RulerMode newMode = RulerMode.FIRST;
|
||||
if (mode == RulerMode.FIRST) {
|
||||
newMode = RulerMode.SECOND;
|
||||
} else if (mode == RulerMode.SECOND) {
|
||||
newMode = RulerMode.EMPTY;
|
||||
final RadiusRulerMode mode = map.getMyApplication().getSettings().RADIUS_RULER_MODE.get();
|
||||
RadiusRulerMode newMode = RadiusRulerMode.FIRST;
|
||||
if (mode == RadiusRulerMode.FIRST) {
|
||||
newMode = RadiusRulerMode.SECOND;
|
||||
} else if (mode == RadiusRulerMode.SECOND) {
|
||||
newMode = RadiusRulerMode.EMPTY;
|
||||
}
|
||||
setRulerControlIcon(rulerControl, newMode);
|
||||
map.getMyApplication().getSettings().RULER_MODE.set(newMode);
|
||||
setRulerControlIcon(radiusRulerControl, newMode);
|
||||
map.getMyApplication().getSettings().RADIUS_RULER_MODE.set(newMode);
|
||||
map.refreshMap();
|
||||
}
|
||||
});
|
||||
|
||||
return rulerControl;
|
||||
return radiusRulerControl;
|
||||
}
|
||||
|
||||
private void setRulerControlIcon(TextInfoWidget rulerControl, RulerMode mode) {
|
||||
if (mode == RulerMode.FIRST || mode == RulerMode.SECOND) {
|
||||
private void setRulerControlIcon(TextInfoWidget rulerControl, RadiusRulerMode mode) {
|
||||
if (mode == RadiusRulerMode.FIRST || mode == RadiusRulerMode.SECOND) {
|
||||
rulerControl.setIcons(R.drawable.widget_ruler_circle_day, R.drawable.widget_ruler_circle_night);
|
||||
} else {
|
||||
rulerControl.setIcons(R.drawable.widget_hidden_day, R.drawable.widget_hidden_night);
|
||||
|
@ -933,7 +905,6 @@ public class MapInfoWidgetsFactory {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public boolean updateInfo(DrawSettings d) {
|
||||
CurrentStreetName streetName = null;
|
||||
boolean showClosestWaypointFirstInAddress = true;
|
||||
|
@ -1051,6 +1022,7 @@ public class MapInfoWidgetsFactory {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean setRoadShield(ImageView view, RouteDataObject object, String nameTag, String name, StringBuilder additional) {
|
||||
|
||||
Context context = topBar.getContext();
|
||||
|
|
|
@ -66,7 +66,7 @@ public class MapWidgetRegistry {
|
|||
public static String WIDGET_BEARING = "bearing";
|
||||
public static String WIDGET_PLAIN_TIME = "plain_time";
|
||||
public static String WIDGET_BATTERY = "battery";
|
||||
public static String WIDGET_RULER = "ruler";
|
||||
public static String WIDGET_RADIUS_RULER = "ruler";
|
||||
|
||||
public static String WIDGET_STREET_NAME = "street_name";
|
||||
|
||||
|
@ -369,6 +369,13 @@ public class MapWidgetRegistry {
|
|||
.setSelected(settings.SHOW_COORDINATES_WIDGET.get())
|
||||
.setListener(new AppearanceItemClickListener(settings.SHOW_COORDINATES_WIDGET, map))
|
||||
.setLayout(R.layout.list_item_icon_and_switch).createItem());
|
||||
|
||||
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_distance_by_tap, map)
|
||||
.setIcon(R.drawable.ic_action_ruler_line)
|
||||
.setSelected(settings.SHOW_DISTANCE_RULER.get())
|
||||
.setListener(new AppearanceItemClickListener(settings.SHOW_DISTANCE_RULER, map))
|
||||
.setLayout(R.layout.list_item_icon_and_switch).createItem());
|
||||
|
||||
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_markers, map)
|
||||
.setDescription(settings.MAP_MARKERS_MODE.get().toHumanString(map))
|
||||
.setListener(new ContextMenuAdapter.ItemClickListener() {
|
||||
|
|
Loading…
Reference in a new issue