Create the second mode of the ruler
This commit is contained in:
parent
0c5aa539bf
commit
ea8ba0ea99
3 changed files with 143 additions and 29 deletions
|
@ -703,6 +703,8 @@ public class OsmandSettings {
|
|||
return p;
|
||||
}
|
||||
|
||||
public final CommonPreference<Integer> RULER_MODE = new IntPreference("ruler_mode", 0).makeGlobal();
|
||||
|
||||
public final CommonPreference<Boolean> USE_FAST_RECALCULATION = new BooleanPreference("use_fast_recalculation", true).makeGlobal().cache();
|
||||
public final CommonPreference<Boolean> FORCE_PRIVATE_ACCESS_ROUTING_ASKED = new BooleanPreference("force_private_access_routing", false).makeProfile().cache();
|
||||
|
||||
|
|
|
@ -3,22 +3,40 @@ package net.osmand.plus.views;
|
|||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Rect;
|
||||
import android.text.TextPaint;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.QuadPoint;
|
||||
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 static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
|
||||
public class RulerControlLayer extends OsmandMapLayer {
|
||||
|
||||
private final MapActivity mapActivity;
|
||||
private OsmandApplication app;
|
||||
private int maxRadius;
|
||||
private int radius;
|
||||
private int cacheZoom;
|
||||
private double cacheTileX;
|
||||
private double cacheTileY;
|
||||
private String[] cacheDistances;
|
||||
private Bitmap centerIcon;
|
||||
private Paint bitmapPaint;
|
||||
private Paint linePaint;
|
||||
private MapActivity mapActivity;
|
||||
private Paint distancePaint;
|
||||
private Paint circlePaint;
|
||||
private Paint shadowPaint;
|
||||
private TextPaint textPaint;
|
||||
|
||||
public RulerControlLayer(MapActivity mapActivity) {
|
||||
this.mapActivity = mapActivity;
|
||||
|
@ -26,6 +44,10 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
|
||||
@Override
|
||||
public void initLayer(OsmandMapTileView view) {
|
||||
app = mapActivity.getMyApplication();
|
||||
cacheDistances = new String[3];
|
||||
maxRadius = mapActivity.getResources().getDimensionPixelSize(R.dimen.map_ruler_width);
|
||||
|
||||
centerIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center);
|
||||
|
||||
bitmapPaint = new Paint();
|
||||
|
@ -33,26 +55,110 @@ public class RulerControlLayer extends OsmandMapLayer {
|
|||
bitmapPaint.setDither(true);
|
||||
bitmapPaint.setFilterBitmap(true);
|
||||
|
||||
linePaint = new Paint();
|
||||
linePaint.setAntiAlias(true);
|
||||
linePaint.setStyle(Style.STROKE);
|
||||
linePaint.setStrokeWidth(10);
|
||||
linePaint.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0));
|
||||
distancePaint = new Paint();
|
||||
distancePaint.setAntiAlias(true);
|
||||
distancePaint.setStyle(Style.STROKE);
|
||||
distancePaint.setStrokeWidth(10);
|
||||
distancePaint.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0));
|
||||
|
||||
circlePaint = new Paint();
|
||||
circlePaint.setAntiAlias(true);
|
||||
circlePaint.setStyle(Style.STROKE);
|
||||
circlePaint.setStrokeWidth(2);
|
||||
|
||||
shadowPaint = new Paint();
|
||||
shadowPaint.setAntiAlias(true);
|
||||
shadowPaint.setColor(Color.WHITE);
|
||||
|
||||
textPaint = new TextPaint();
|
||||
textPaint.setAntiAlias(true);
|
||||
textPaint.setTextSize(14 * mapActivity.getResources().getDisplayMetrics().density);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
|
||||
if (mapActivity.getMapLayers().getMapWidgetRegistry().isVisible("ruler")) {
|
||||
final QuadPoint centerPos = tileBox.getCenterPixelPoint();
|
||||
canvas.rotate(-tileBox.getRotate(), centerPos.x, centerPos.y);
|
||||
canvas.drawBitmap(centerIcon, centerPos.x - centerIcon.getWidth() / 2,
|
||||
centerPos.y - centerIcon.getHeight() / 2, bitmapPaint);
|
||||
canvas.rotate(tileBox.getRotate(), centerPos.x, centerPos.y);
|
||||
Location currentLoc = mapActivity.getMyApplication().getLocationProvider().getLastKnownLocation();
|
||||
if (currentLoc != null) {
|
||||
int currentLocX = tileBox.getPixXFromLonNoRot(currentLoc.getLongitude());
|
||||
int currentLocY = tileBox.getPixYFromLatNoRot(currentLoc.getLatitude());
|
||||
canvas.drawLine(currentLocX, currentLocY, centerPos.x, centerPos.y, linePaint);
|
||||
final QuadPoint center = tb.getCenterPixelPoint();
|
||||
final int mode = app.getSettings().RULER_MODE.get();
|
||||
|
||||
drawCenterIcon(canvas, tb, center);
|
||||
if (mode == 0) {
|
||||
Location currentLoc = app.getLocationProvider().getLastKnownLocation();
|
||||
if (currentLoc != null) {
|
||||
drawDistance(canvas, tb, center, currentLoc);
|
||||
}
|
||||
} else if (mode == 1) {
|
||||
for (int i = 1; i < 4; i++) {
|
||||
drawCircle(canvas, tb, i, center);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center) {
|
||||
canvas.rotate(-tb.getRotate(), center.x, center.y);
|
||||
canvas.drawBitmap(centerIcon, center.x - centerIcon.getWidth() / 2,
|
||||
center.y - centerIcon.getHeight() / 2, bitmapPaint);
|
||||
canvas.rotate(tb.getRotate(), center.x, center.y);
|
||||
}
|
||||
|
||||
private void drawDistance(Canvas canvas, RotatedTileBox tb, QuadPoint center, Location currentLoc) {
|
||||
int currentLocX = tb.getPixXFromLonNoRot(currentLoc.getLongitude());
|
||||
int currentLocY = tb.getPixYFromLatNoRot(currentLoc.getLatitude());
|
||||
canvas.drawLine(currentLocX, currentLocY, center.x, center.y, distancePaint);
|
||||
}
|
||||
|
||||
private void drawCircle(Canvas canvas, RotatedTileBox tb, int circleNumber, QuadPoint center) {
|
||||
updateData(tb);
|
||||
|
||||
Rect bounds = new Rect();
|
||||
String text = cacheDistances[circleNumber - 1];
|
||||
textPaint.getTextBounds(text, 0, text.length(), bounds);
|
||||
|
||||
float left = 0;
|
||||
float right = 0;
|
||||
float top = 0;
|
||||
float bottom = 0;
|
||||
|
||||
if (mapActivity.getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT) {
|
||||
left = center.x - bounds.width() / 2;
|
||||
right = center.x + bounds.width() / 1.8f;
|
||||
top = center.y - radius * circleNumber - bounds.height() / 2;
|
||||
bottom = center.y - radius * circleNumber + bounds.height() / 2;
|
||||
} else if (mapActivity.getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
|
||||
left = center.x + radius * circleNumber - bounds.width() / 2;
|
||||
right = center.x + radius * circleNumber + bounds.width() / 1.8f;
|
||||
top = center.y - bounds.height() / 2;
|
||||
bottom = center.y + bounds.height() / 2;
|
||||
}
|
||||
|
||||
if (!mapActivity.getMapView().isZooming()) {
|
||||
canvas.rotate(-tb.getRotate(), center.x, center.y);
|
||||
canvas.drawCircle(center.x, center.y, radius * circleNumber, circlePaint);
|
||||
canvas.drawRect(left, top, right, bottom, shadowPaint);
|
||||
canvas.drawText(text, left, bottom, textPaint);
|
||||
canvas.rotate(tb.getRotate(), center.x, center.y);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateData(RotatedTileBox tb) {
|
||||
boolean move = tb.getZoom() != cacheZoom || Math.abs(tb.getCenterTileX() - cacheTileX) > 1 ||
|
||||
Math.abs(tb.getCenterTileY() - cacheTileY) > 1;
|
||||
|
||||
if (!mapActivity.getMapView().isZooming() && move && tb.getPixWidth() > 0 && maxRadius > 0) {
|
||||
cacheZoom = tb.getZoom();
|
||||
cacheTileX = tb.getCenterTileX();
|
||||
cacheTileY = tb.getCenterTileY();
|
||||
|
||||
final double dist = tb.getDistance(0, tb.getPixHeight() / 2, tb.getPixWidth(), tb.getPixHeight() / 2);
|
||||
double pixDensity = tb.getPixWidth() / dist;
|
||||
double roundedDist =
|
||||
OsmAndFormatter.calculateRoundedDist(maxRadius / pixDensity, app);
|
||||
radius = (int) (pixDensity * roundedDist);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
cacheDistances[i] = OsmAndFormatter.getFormattedDistance((float) roundedDist * (i + 1),
|
||||
app, false).replaceAll(" ", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,26 +114,32 @@ public class MapInfoWidgetsFactory {
|
|||
final TextInfoWidget rulerControl = new TextInfoWidget(map) {
|
||||
@Override
|
||||
public boolean updateInfo(DrawSettings drawSettings) {
|
||||
Location currentLoc = map.getMyApplication().getLocationProvider().getLastKnownLocation();
|
||||
LatLon centerLoc = map.getMapLocation();
|
||||
if (currentLoc != null && centerLoc != null) {
|
||||
float dist = (float) MapUtils.getDistance(currentLoc.getLatitude(), currentLoc.getLongitude(),
|
||||
centerLoc.getLatitude(), centerLoc.getLongitude());
|
||||
String distance = OsmAndFormatter.getFormattedDistance(dist, map.getMyApplication());
|
||||
int ls = distance.lastIndexOf(' ');
|
||||
setText(distance.substring(0, ls), distance.substring(ls + 1));
|
||||
} else {
|
||||
setText(title, null);
|
||||
if (map.getMyApplication().getSettings().RULER_MODE.get() == 0) {
|
||||
Location currentLoc = map.getMyApplication().getLocationProvider().getLastKnownLocation();
|
||||
LatLon centerLoc = map.getMapLocation();
|
||||
if (currentLoc != null && centerLoc != null) {
|
||||
float dist = (float) MapUtils.getDistance(currentLoc.getLatitude(), currentLoc.getLongitude(),
|
||||
centerLoc.getLatitude(), centerLoc.getLongitude());
|
||||
String distance = OsmAndFormatter.getFormattedDistance(dist, map.getMyApplication());
|
||||
int ls = distance.lastIndexOf(' ');
|
||||
setText(distance.substring(0, ls), distance.substring(ls + 1));
|
||||
} else {
|
||||
setText(title, null);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
rulerControl.setText(title, null);
|
||||
rulerControl.setIcons(R.drawable.widget_distance_day, R.drawable.widget_distance_night);
|
||||
rulerControl.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
rulerControl.setText(title, null);
|
||||
int mode = map.getMyApplication().getSettings().RULER_MODE.get();
|
||||
map.getMyApplication().getSettings().RULER_MODE.set(mode == 0 ? 1 : 0);
|
||||
map.refreshMap();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue