Create the second mode of the ruler

This commit is contained in:
Alexander Sytnyk 2017-06-07 18:14:40 +03:00
parent 0c5aa539bf
commit ea8ba0ea99
3 changed files with 143 additions and 29 deletions

View file

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

View file

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

View file

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