1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
package cgeo.geocaching.maps;
import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Units;
import cgeo.geocaching.maps.interfaces.GeoPointImpl;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import org.apache.commons.lang3.tuple.ImmutablePair;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.DisplayMetrics;
import android.view.WindowManager;
public class ScaleDrawer {
private static final double SCALE_WIDTH_FACTOR = 1.0 / 2.5;
private Paint scale = null;
private Paint scaleShadow = null;
private BlurMaskFilter blur = null;
private float pixelDensity = 0;
public ScaleDrawer() {
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) CgeoApplication.getInstance().getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
pixelDensity = metrics.density;
}
static private double keepSignificantDigit(final double distance) {
final double scale = Math.pow(10, Math.floor(Math.log10(distance)));
return scale * Math.floor(distance / scale);
}
void drawScale(Canvas canvas, MapViewImpl mapView) {
final double span = mapView.getLongitudeSpan() / 1e6;
final GeoPointImpl center = mapView.getMapViewCenter();
final int bottom = mapView.getHeight() - 14; // pixels from bottom side of screen
final Geopoint leftCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 - span / 2);
final Geopoint rightCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 + span / 2);
final ImmutablePair<Double, String> scaled = Units.scaleDistance(leftCoords.distanceTo(rightCoords) * SCALE_WIDTH_FACTOR);
final double distanceRound = keepSignificantDigit(scaled.left);
final double pixels = Math.round((mapView.getWidth() * SCALE_WIDTH_FACTOR / scaled.left) * distanceRound);
if (blur == null) {
blur = new BlurMaskFilter(3, BlurMaskFilter.Blur.NORMAL);
}
if (scaleShadow == null) {
scaleShadow = new Paint();
scaleShadow.setAntiAlias(true);
scaleShadow.setStrokeWidth(4 * pixelDensity);
scaleShadow.setMaskFilter(blur);
scaleShadow.setTextSize(14 * pixelDensity);
scaleShadow.setTypeface(Typeface.DEFAULT_BOLD);
}
if (scale == null) {
scale = new Paint();
scale.setAntiAlias(true);
scale.setStrokeWidth(2 * pixelDensity);
scale.setTextSize(14 * pixelDensity);
scale.setTypeface(Typeface.DEFAULT_BOLD);
}
if (mapView.needsInvertedColors()) {
scaleShadow.setColor(0xFF000000);
scale.setColor(0xFFFFFFFF);
} else {
scaleShadow.setColor(0xFFFFFFFF);
scale.setColor(0xFF000000);
}
final String formatString = distanceRound >= 1 ? "%.0f" : "%.1f";
canvas.drawLine(10, bottom, 10, (bottom - (8 * pixelDensity)), scaleShadow);
canvas.drawLine((int) (pixels + 10), bottom, (int) (pixels + 10), (bottom - (8 * pixelDensity)), scaleShadow);
canvas.drawLine(8, bottom, (int) (pixels + 12), bottom, scaleShadow);
canvas.drawText(String.format(formatString, distanceRound) + " " + scaled.right, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scaleShadow);
canvas.drawLine(11, bottom, 11, (bottom - (6 * pixelDensity)), scale);
canvas.drawLine((int) (pixels + 9), bottom, (int) (pixels + 9), (bottom - (6 * pixelDensity)), scale);
canvas.drawLine(10, bottom, (int) (pixels + 10), bottom, scale);
canvas.drawText(String.format(formatString, distanceRound) + " " + scaled.right, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scale);
}
}
|