Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Android上的MapView中添加地图比例?_Java_Android_Google Maps_Android Mapview - Fatal编程技术网

Java 如何在Android上的MapView中添加地图比例?

Java 如何在Android上的MapView中添加地图比例?,java,android,google-maps,android-mapview,Java,Android,Google Maps,Android Mapview,我正在努力添加一个地图比例,根据当前的缩放级别在屏幕上显示当前长度。我有一种感觉,它可能存在一些预定义的类来使用,但我不知道。。。?我到处找了很多,但什么也没找到 任何我非常感激的帮助=) //Alex据我所知,没有一个预先定义的类可以这样做 一种可能是创建一个覆盖,当当前经度跨度随纬度变化时检查它,然后以正确的大小绘制比例 下面,您可以找到一个关于如何做到这一点的示例: 比例尺覆盖 public class CopyOfScaleBarOverlay extends Overlay {

我正在努力添加一个地图比例,根据当前的缩放级别在屏幕上显示当前长度。我有一种感觉,它可能存在一些预定义的类来使用,但我不知道。。。?我到处找了很多,但什么也没找到

任何我非常感激的帮助=)


//Alex

据我所知,没有一个预先定义的类可以这样做

一种可能是创建一个覆盖,当当前经度跨度随纬度变化时检查它,然后以正确的大小绘制比例

下面,您可以找到一个关于如何做到这一点的示例:

比例尺覆盖

public class CopyOfScaleBarOverlay extends Overlay {    
private static final String STR_M = "m"; 
private static final String STR_KM = "km"; 

//Constants
private static float scaleBarProportion = 0.25f;
private float cMarginLeft=4;
private float cLineTopSize=8;
private float cMarginTop=6;
private float cMarginBottom=2;
private float cTextSize=12;
private float distanceFromBottom=100;


//instantiation
private Context context;

private Paint paintLine, paintText, paintRectangle;
private Location l0;
private Location l1;
private float ds;
private int width, height, pi;
private float marginLeft, marginTop, marginBottom, lineTopSize;
private String unit;



public CopyOfScaleBarOverlay(Context context){
    super();
    this.context=context;

    paintText= new TextPaint();
    paintText.setARGB(180, 0, 0, 0);
    paintText.setAntiAlias(true);
    paintText.setTextAlign(Align.CENTER);

    paintRectangle = new Paint();
    paintRectangle.setARGB(80,255,255,255);
    paintRectangle.setAntiAlias(true);

    paintLine = new Paint();
    paintLine.setARGB(180, 0, 0, 0);
    paintLine.setAntiAlias(true);

    l0 = new Location("none");
    l1 = new Location("none");

    ds=this.context.getApplicationContext().getResources().getDisplayMetrics().density;
    width=this.context.getApplicationContext().getResources().getDisplayMetrics().widthPixels;
    height=this.context.getApplicationContext().getResources().getDisplayMetrics().heightPixels;
    pi = (int) (height - distanceFromBottom *ds);

    marginLeft=cMarginLeft*ds;
    lineTopSize=cLineTopSize*ds;
    marginTop=cMarginTop*ds;
    marginBottom=cMarginBottom*ds;


}

@Override
public void draw(Canvas canvas, MapView mapview, boolean shadow) {
    super.draw(canvas, mapview, shadow);
    if(mapview.getZoomLevel() > 1){

        //Calculate scale bar size and units
        GeoPoint g0 = mapview.getProjection().fromPixels(0, height/2);
        GeoPoint g1 = mapview.getProjection().fromPixels(width, height/2);
        l0.setLatitude(g0.getLatitudeE6()/1E6);
        l0.setLongitude(g0.getLongitudeE6()/1E6);
        l1.setLatitude(g1.getLatitudeE6()/1E6);
        l1.setLongitude(g1.getLongitudeE6()/1E6);
        float d01=l0.distanceTo(l1);
        float d02=d01*scaleBarProportion;
        // multiply d02 by a unit conversion factor if needed
        float cd02;
        if(d02 > 1000){
            unit = STR_KM;
            cd02 = d02 / 1000;
        } else{
            unit = STR_M;
            cd02 = d02;
        }
        int i=1;
        do{
            i *=10;
        }while (i <= cd02);
        i/=10;
        float dcd02=(int)(cd02/i)*i;
        float bs=dcd02*width/d01*d02/cd02;

        String text=String.format("%.0f %s", dcd02, unit);
        paintText.setTextSize(cTextSize * ds);
        float text_x_size=paintText.measureText(text);
        float x_size = bs + text_x_size/2 + 2*marginLeft;

        //Draw rectangle
        canvas.drawRect(0,pi,x_size,pi+marginTop+paintText.getFontSpacing()+marginBottom, paintRectangle);

        //Draw line
        canvas.drawLine(marginLeft, pi+marginTop, marginLeft + bs, pi+marginTop, paintLine);
        //Draw line tops
        canvas.drawLine(marginLeft, pi+marginTop - lineTopSize/2, marginLeft, pi+marginTop + lineTopSize/2, paintLine);
        canvas.drawLine(marginLeft +bs, pi+marginTop - lineTopSize/2, marginLeft+bs, pi+marginTop + lineTopSize/2, paintLine);
        //Draw line midle
        canvas.drawLine(marginLeft + bs/2, pi+marginTop - lineTopSize/3, marginLeft + bs/2, pi+marginTop + lineTopSize/3, paintLine);
        //Draw line quarters
        canvas.drawLine(marginLeft + bs/4, pi+marginTop - lineTopSize/4, marginLeft + bs/4, pi+marginTop + lineTopSize/4, paintLine);
        canvas.drawLine(marginLeft + 3*bs/4, pi+marginTop - lineTopSize/4, marginLeft + 3*bs/4, pi+marginTop + lineTopSize/4, paintLine);

        //Draw text
        canvas.drawText(text, marginLeft +bs, pi+marginTop+paintText.getFontSpacing(), paintText);
    }
}
注意

例如,使用公制单位。若要使用不同的单位系统,请将上述代码中的
d02
乘以单位转换系数,并使用单位名称调整字符串


享受它。

好吧,我现在就拿到了!路易斯的回答帮了我很多忙,还打开了街道地图。以下是我的想法:

<your.own.package.path>;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Picture;
import android.graphics.Rect;
import android.location.Location;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.iqqn.uppgift5.GameMapActivity;

public class ScaleBarOverlay extends Overlay{

    // ===========================================================
    // Fields
    // ===========================================================

    // Defaults

    boolean enabled = true;

    float xOffset = 10;
    float yOffset = 10;
    float lineWidth = 2;
    int textSize = 12;

    boolean imperial = false;
    boolean nautical = false;

    boolean latitudeBar = true;
    boolean longitudeBar = false;

    // Internal

    protected final MapView mapView;
    protected final GameMapActivity master;

    private Context context;

    protected final Picture scaleBarPicture = new Picture();
    private final Matrix scaleBarMatrix = new Matrix();

    private int lastZoomLevel = -1;

    float xdpi;
    float ydpi;
    int screenWidth;
    int screenHeight;

    // ===========================================================
    // Constructors
    // ===========================================================

    public ScaleBarOverlay(Context _context, GameMapActivity master, MapView mapView) {
        super();

        this.master = master;
        this.context = _context;
        this.mapView = mapView;

        xdpi = this.context.getResources().getDisplayMetrics().xdpi;
        ydpi = this.context.getResources().getDisplayMetrics().ydpi;

        screenWidth = this.context.getResources().getDisplayMetrics().widthPixels;
        screenHeight = this.context.getResources().getDisplayMetrics().heightPixels;

    }

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    /**
     * @return the enabled
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * @param enabled the enabled to set
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * @return the lineWidth
     */
    public float getLineWidth() {
        return lineWidth;
    }

    /**
     * @param lineWidth the lineWidth to set
     */
    public void setLineWidth(float lineWidth) {
        this.lineWidth = lineWidth;
    }

    /**
     * @return the imperial
     */
    public boolean isImperial() {
        return imperial;
    }

    /**
     * @param imperial the imperial to set
     */
    public void setImperial() {
        this.imperial = true;
        this.nautical = false;
        createScaleBarPicture();
    }

    /**
     * @return the nautical
     */
    public boolean isNautical() {
        return nautical;
    }

    /**
     * @param nautical the nautical to set
     */
    public void setNautical() {
        this.nautical = true;
        this.imperial = false;
        createScaleBarPicture();
    }

    public void setMetric() {
        this.nautical = false;
        this.imperial = false;
        createScaleBarPicture();
    }

    public void drawLatitudeScale(boolean latitude) {
        this.latitudeBar = latitude;
    }

    public void drawLongitudeScale(boolean longitude) {
        this.longitudeBar = longitude;
    }

    @Override
    public void draw(Canvas canvas, MapView localMapView, boolean shadow) {
        if (this.enabled) {
            // Draw the overlay
            if (shadow == false) {
                final int zoomLevel = localMapView.getZoomLevel();

                if (zoomLevel != lastZoomLevel) {
                    lastZoomLevel = zoomLevel;
                    createScaleBarPicture();
                }

                this.scaleBarMatrix.setTranslate(-1 * (scaleBarPicture.getWidth() / 2 - 0.5f), -1 * (scaleBarPicture.getHeight() / 2 - 0.5f));
                this.scaleBarMatrix.postTranslate(xdpi/2, ydpi/2 + canvas.getHeight()-50);

                canvas.save();
                canvas.setMatrix(scaleBarMatrix);
                canvas.drawPicture(scaleBarPicture);
                canvas.restore();
            }
        }
    }

    // ===========================================================
    // Methods
    // ===========================================================

    public void disableScaleBar() {
        this.enabled = false;
    }

    public boolean enableScaleBar() {
        return this.enabled = true;
    }

    private void createScaleBarPicture() {
        // We want the scale bar to be as long as the closest round-number miles/kilometers
        // to 1-inch at the latitude at the current center of the screen.

        Projection projection = mapView.getProjection();

        if (projection == null) {
            return;
        }

        Location locationP1 = new Location("ScaleBar location p1");
        Location locationP2 = new Location("ScaleBar location p2");

        // Two points, 1-inch apart in x/latitude, centered on screen
        GeoPoint p1 = projection.fromPixels((int) ((screenWidth / 2) - (xdpi / 2)), screenHeight/2);
        GeoPoint p2 = projection.fromPixels((int) ((screenWidth / 2) + (xdpi / 2)), screenHeight/2);

        locationP1.setLatitude(p1.getLatitudeE6()/1E6);
        locationP2.setLatitude(p2.getLatitudeE6()/1E6);
        locationP1.setLongitude(p1.getLongitudeE6()/1E6);
        locationP2.setLongitude(p2.getLongitudeE6()/1E6);

        float xMetersPerInch = locationP1.distanceTo(locationP2);

        p1 = projection.fromPixels(screenWidth/2, (int) ((screenHeight / 2) - (ydpi / 2)));
        p2 = projection.fromPixels(screenWidth/2, (int) ((screenHeight / 2) + (ydpi / 2)));

        locationP1.setLatitude(p1.getLatitudeE6()/1E6);
        locationP2.setLatitude(p2.getLatitudeE6()/1E6);
        locationP1.setLongitude(p1.getLongitudeE6()/1E6);
        locationP2.setLongitude(p2.getLongitudeE6()/1E6);

        float yMetersPerInch =  locationP1.distanceTo(locationP2);

        final Paint barPaint = new Paint();
        barPaint.setColor(Color.BLACK);
        barPaint.setAntiAlias(true);
        barPaint.setStyle(Style.FILL);
        barPaint.setAlpha(255);

        final Paint textPaint = new Paint();
        textPaint.setColor(Color.BLACK);
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Style.FILL);
        textPaint.setAlpha(255);
        textPaint.setTextSize(textSize);

        final Canvas canvas = scaleBarPicture.beginRecording((int)xdpi, (int)ydpi);

        if (latitudeBar) {
            String xMsg = scaleBarLengthText(xMetersPerInch, imperial, nautical);
            Rect xTextRect = new Rect();
            textPaint.getTextBounds(xMsg, 0, xMsg.length(), xTextRect);

            int textSpacing = (int)(xTextRect.height() / 5.0);

            canvas.drawRect(xOffset, yOffset, xOffset + xdpi, yOffset + lineWidth, barPaint);
            canvas.drawRect(xOffset + xdpi, yOffset, xOffset + xdpi + lineWidth, yOffset + xTextRect.height() + lineWidth + textSpacing, barPaint);

            if (!longitudeBar) {
                canvas.drawRect(xOffset, yOffset, xOffset + lineWidth, yOffset + xTextRect.height() + lineWidth + textSpacing, barPaint);
            }
            canvas.drawText(xMsg, (xOffset + xdpi/2 - xTextRect.width()/2), (yOffset + xTextRect.height() + lineWidth + textSpacing), textPaint);
        }

        if (longitudeBar) {
            String yMsg = scaleBarLengthText(yMetersPerInch, imperial, nautical);
            Rect yTextRect = new Rect();
            textPaint.getTextBounds(yMsg, 0, yMsg.length(), yTextRect);

            int textSpacing = (int)(yTextRect.height() / 5.0);

            canvas.drawRect(xOffset, yOffset, xOffset + lineWidth, yOffset + ydpi, barPaint);
            canvas.drawRect(xOffset, yOffset + ydpi, xOffset + yTextRect.height() + lineWidth + textSpacing, yOffset + ydpi + lineWidth, barPaint);

            if (! latitudeBar) {
                canvas.drawRect(xOffset, yOffset, xOffset + yTextRect.height() + lineWidth + textSpacing, yOffset + lineWidth, barPaint);
            }                       

            float x = xOffset + yTextRect.height() + lineWidth + textSpacing;
            float y = yOffset + ydpi/2 + yTextRect.width()/2;

            canvas.rotate(-90, x, y);
            canvas.drawText(yMsg, x, y + textSpacing, textPaint);

        }

        scaleBarPicture.endRecording();
    }

    private String scaleBarLengthText(float meters, boolean imperial, boolean nautical) {
        if (this.imperial) {
            if (meters >= 1609.344) {
                return (meters / 1609.344) + "mi";
            } else if (meters >= 1609.344/10) {
                return ((meters / 160.9344) / 10.0) + "mi";
            } else {
                return (meters * 3.2808399) + "ft";
            }
        } else if (this.nautical) {
            if (meters >= 1852) {
                return ((meters / 1852)) + "nm";
            } else if (meters >= 1852/10) {
                return (((meters / 185.2)) / 10.0) + "nm";
            } else {
                return ((meters * 3.2808399)) + "ft";
            }
        } else {
            if (meters >= 1000) {
                return ((meters / 1000)) + "km";
            } else if (meters > 100) {
                return ((meters / 100.0) / 10.0) + "km";
            } else {
                return meters + "m";
            }
        }
    }

    @Override
    public boolean onTap(GeoPoint point, MapView mapView) {
        // Do not react to screen taps.
        return false;
    }
}
;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Matrix;
导入android.graphics.Paint;
导入android.graphics.Paint.Style;
导入android.graphics.Picture;
导入android.graphics.Rect;
导入android.location.location;
导入android.util.Log;
导入com.google.android.maps.GeoPoint;
导入com.google.android.maps.MapView;
导入com.google.android.maps.Overlay;
导入com.google.android.maps.Projection;
导入com.iqqn.uppgit5.GameMapActivity;
公共类ScaleBarroverLay扩展覆盖{
// ===========================================================
//田地
// ===========================================================
//默认值
布尔启用=真;
浮动xOffset=10;
浮动Y偏移=10;
浮动线宽=2;
int textSize=12;
布尔值=假;
布尔值=假;
布尔纬度巴=真;
布尔longitudeBar=false;
//内部的
受保护的最终地图视图地图视图;
受保护的最终游戏地图活动主机;
私人语境;
受保护的最终图片缩放图片=新图片();
私有最终矩阵ScaleBaratrix=新矩阵();
private int lastZoomLevel=-1;
浮动xdpi;
浮动ydpi;
int屏幕宽度;
屏幕高度;
// ===========================================================
//建设者
// ===========================================================
公共ScaleBarOverlay(上下文_上下文,GameMapActivity master,MapView MapView){
超级();
this.master=master;
this.context=\u context;
this.mapView=mapView;
xdpi=this.context.getResources().getDisplayMetrics().xdpi;
ydpi=this.context.getResources().getDisplayMetrics().ydpi;
screenWidth=this.context.getResources().getDisplayMetrics().widthPixels;
screenHeight=this.context.getResources().getDisplayMetrics().heightPixels;
}
// ===========================================================
//吸气剂和塞特
// ===========================================================
/**
*@返回已启用的
*/
公共布尔值isEnabled(){
返回启用;
}
/**
*@param启用了已启用的设置
*/
已启用公共void集(已启用布尔值){
this.enabled=已启用;
}
/**
*@返回线宽
*/
公共浮点getLineWidth(){
返回线宽;
}
/**
*@param lineWidth要设置的线宽
*/
公共空白设置线宽(浮动线宽){
this.lineWidth=线宽;
}
/**
*@returntheimperial
*/
公共布尔值是材料(){
回归帝国;
}
/**
*@param-imperial将由帝国设置
*/
公共空间{
这是真的;
这是假的;
创建ScaleBarPicture();
}
/**
*@还船
*/
公共布尔值(){
返航;
}
/**
*@param-searical要设置的海员
*/
公共空间{
这是真的;
this.imperial=false;
创建ScaleBarPicture();
}
公共void setMetric(){
这是假的;
this.imperial=false;
创建ScaleBarPicture();
}
公共void drawLatitudeScale(布尔纬度){
这个。纬度巴=纬度;
}
公共空白drawLongitudeScale(布尔经度){
this.longitudeBar=经度;
}
@凌驾
公共空白绘制(画布画布、地图视图、局部地图视图、布尔阴影){
如果(此.enabled){
//绘制覆盖图
if(shadow==false){
final int zoomLevel=localMapView.getZoomLevel();
如果(zoomLevel!=lastZoomLevel){
lastZoomLevel=zoomLevel;
创建ScaleBarPicture();
}
这个.scaleBarMatrix.setTranslate(-1*(scaleBarPicture.getWidth()/2-0.5f)、-1*(scaleBarPicture.getHeight()/2-0.5f));
postTranslate(xdpi/2,ydpi/2+canvas.getHeight()-50);
canvas.save();
canvas.setMatrix(ScaleBaratrix);
帆布画(比例画);
canvas.restore();
}
}
}
// ===========================================================
//方法
// ===========================================================
public void disableScaleBar(){
this.enabled=false;
}
公共布尔使能ScaleBar(){
返回this.enabled=true;
}
私有void createScaleBarPicture(){
//我们希望比例尺与最近的圆数英里/公里一样长
//在屏幕当前中心的纬度为1英寸。
<your.own.package.path>;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Picture;
import android.graphics.Rect;
import android.location.Location;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.iqqn.uppgift5.GameMapActivity;

public class ScaleBarOverlay extends Overlay{

    // ===========================================================
    // Fields
    // ===========================================================

    // Defaults

    boolean enabled = true;

    float xOffset = 10;
    float yOffset = 10;
    float lineWidth = 2;
    int textSize = 12;

    boolean imperial = false;
    boolean nautical = false;

    boolean latitudeBar = true;
    boolean longitudeBar = false;

    // Internal

    protected final MapView mapView;
    protected final GameMapActivity master;

    private Context context;

    protected final Picture scaleBarPicture = new Picture();
    private final Matrix scaleBarMatrix = new Matrix();

    private int lastZoomLevel = -1;

    float xdpi;
    float ydpi;
    int screenWidth;
    int screenHeight;

    // ===========================================================
    // Constructors
    // ===========================================================

    public ScaleBarOverlay(Context _context, GameMapActivity master, MapView mapView) {
        super();

        this.master = master;
        this.context = _context;
        this.mapView = mapView;

        xdpi = this.context.getResources().getDisplayMetrics().xdpi;
        ydpi = this.context.getResources().getDisplayMetrics().ydpi;

        screenWidth = this.context.getResources().getDisplayMetrics().widthPixels;
        screenHeight = this.context.getResources().getDisplayMetrics().heightPixels;

    }

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    /**
     * @return the enabled
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * @param enabled the enabled to set
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * @return the lineWidth
     */
    public float getLineWidth() {
        return lineWidth;
    }

    /**
     * @param lineWidth the lineWidth to set
     */
    public void setLineWidth(float lineWidth) {
        this.lineWidth = lineWidth;
    }

    /**
     * @return the imperial
     */
    public boolean isImperial() {
        return imperial;
    }

    /**
     * @param imperial the imperial to set
     */
    public void setImperial() {
        this.imperial = true;
        this.nautical = false;
        createScaleBarPicture();
    }

    /**
     * @return the nautical
     */
    public boolean isNautical() {
        return nautical;
    }

    /**
     * @param nautical the nautical to set
     */
    public void setNautical() {
        this.nautical = true;
        this.imperial = false;
        createScaleBarPicture();
    }

    public void setMetric() {
        this.nautical = false;
        this.imperial = false;
        createScaleBarPicture();
    }

    public void drawLatitudeScale(boolean latitude) {
        this.latitudeBar = latitude;
    }

    public void drawLongitudeScale(boolean longitude) {
        this.longitudeBar = longitude;
    }

    @Override
    public void draw(Canvas canvas, MapView localMapView, boolean shadow) {
        if (this.enabled) {
            // Draw the overlay
            if (shadow == false) {
                final int zoomLevel = localMapView.getZoomLevel();

                if (zoomLevel != lastZoomLevel) {
                    lastZoomLevel = zoomLevel;
                    createScaleBarPicture();
                }

                this.scaleBarMatrix.setTranslate(-1 * (scaleBarPicture.getWidth() / 2 - 0.5f), -1 * (scaleBarPicture.getHeight() / 2 - 0.5f));
                this.scaleBarMatrix.postTranslate(xdpi/2, ydpi/2 + canvas.getHeight()-50);

                canvas.save();
                canvas.setMatrix(scaleBarMatrix);
                canvas.drawPicture(scaleBarPicture);
                canvas.restore();
            }
        }
    }

    // ===========================================================
    // Methods
    // ===========================================================

    public void disableScaleBar() {
        this.enabled = false;
    }

    public boolean enableScaleBar() {
        return this.enabled = true;
    }

    private void createScaleBarPicture() {
        // We want the scale bar to be as long as the closest round-number miles/kilometers
        // to 1-inch at the latitude at the current center of the screen.

        Projection projection = mapView.getProjection();

        if (projection == null) {
            return;
        }

        Location locationP1 = new Location("ScaleBar location p1");
        Location locationP2 = new Location("ScaleBar location p2");

        // Two points, 1-inch apart in x/latitude, centered on screen
        GeoPoint p1 = projection.fromPixels((int) ((screenWidth / 2) - (xdpi / 2)), screenHeight/2);
        GeoPoint p2 = projection.fromPixels((int) ((screenWidth / 2) + (xdpi / 2)), screenHeight/2);

        locationP1.setLatitude(p1.getLatitudeE6()/1E6);
        locationP2.setLatitude(p2.getLatitudeE6()/1E6);
        locationP1.setLongitude(p1.getLongitudeE6()/1E6);
        locationP2.setLongitude(p2.getLongitudeE6()/1E6);

        float xMetersPerInch = locationP1.distanceTo(locationP2);

        p1 = projection.fromPixels(screenWidth/2, (int) ((screenHeight / 2) - (ydpi / 2)));
        p2 = projection.fromPixels(screenWidth/2, (int) ((screenHeight / 2) + (ydpi / 2)));

        locationP1.setLatitude(p1.getLatitudeE6()/1E6);
        locationP2.setLatitude(p2.getLatitudeE6()/1E6);
        locationP1.setLongitude(p1.getLongitudeE6()/1E6);
        locationP2.setLongitude(p2.getLongitudeE6()/1E6);

        float yMetersPerInch =  locationP1.distanceTo(locationP2);

        final Paint barPaint = new Paint();
        barPaint.setColor(Color.BLACK);
        barPaint.setAntiAlias(true);
        barPaint.setStyle(Style.FILL);
        barPaint.setAlpha(255);

        final Paint textPaint = new Paint();
        textPaint.setColor(Color.BLACK);
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Style.FILL);
        textPaint.setAlpha(255);
        textPaint.setTextSize(textSize);

        final Canvas canvas = scaleBarPicture.beginRecording((int)xdpi, (int)ydpi);

        if (latitudeBar) {
            String xMsg = scaleBarLengthText(xMetersPerInch, imperial, nautical);
            Rect xTextRect = new Rect();
            textPaint.getTextBounds(xMsg, 0, xMsg.length(), xTextRect);

            int textSpacing = (int)(xTextRect.height() / 5.0);

            canvas.drawRect(xOffset, yOffset, xOffset + xdpi, yOffset + lineWidth, barPaint);
            canvas.drawRect(xOffset + xdpi, yOffset, xOffset + xdpi + lineWidth, yOffset + xTextRect.height() + lineWidth + textSpacing, barPaint);

            if (!longitudeBar) {
                canvas.drawRect(xOffset, yOffset, xOffset + lineWidth, yOffset + xTextRect.height() + lineWidth + textSpacing, barPaint);
            }
            canvas.drawText(xMsg, (xOffset + xdpi/2 - xTextRect.width()/2), (yOffset + xTextRect.height() + lineWidth + textSpacing), textPaint);
        }

        if (longitudeBar) {
            String yMsg = scaleBarLengthText(yMetersPerInch, imperial, nautical);
            Rect yTextRect = new Rect();
            textPaint.getTextBounds(yMsg, 0, yMsg.length(), yTextRect);

            int textSpacing = (int)(yTextRect.height() / 5.0);

            canvas.drawRect(xOffset, yOffset, xOffset + lineWidth, yOffset + ydpi, barPaint);
            canvas.drawRect(xOffset, yOffset + ydpi, xOffset + yTextRect.height() + lineWidth + textSpacing, yOffset + ydpi + lineWidth, barPaint);

            if (! latitudeBar) {
                canvas.drawRect(xOffset, yOffset, xOffset + yTextRect.height() + lineWidth + textSpacing, yOffset + lineWidth, barPaint);
            }                       

            float x = xOffset + yTextRect.height() + lineWidth + textSpacing;
            float y = yOffset + ydpi/2 + yTextRect.width()/2;

            canvas.rotate(-90, x, y);
            canvas.drawText(yMsg, x, y + textSpacing, textPaint);

        }

        scaleBarPicture.endRecording();
    }

    private String scaleBarLengthText(float meters, boolean imperial, boolean nautical) {
        if (this.imperial) {
            if (meters >= 1609.344) {
                return (meters / 1609.344) + "mi";
            } else if (meters >= 1609.344/10) {
                return ((meters / 160.9344) / 10.0) + "mi";
            } else {
                return (meters * 3.2808399) + "ft";
            }
        } else if (this.nautical) {
            if (meters >= 1852) {
                return ((meters / 1852)) + "nm";
            } else if (meters >= 1852/10) {
                return (((meters / 185.2)) / 10.0) + "nm";
            } else {
                return ((meters * 3.2808399)) + "ft";
            }
        } else {
            if (meters >= 1000) {
                return ((meters / 1000)) + "km";
            } else if (meters > 100) {
                return ((meters / 100.0) / 10.0) + "km";
            } else {
                return meters + "m";
            }
        }
    }

    @Override
    public boolean onTap(GeoPoint point, MapView mapView) {
        // Do not react to screen taps.
        return false;
    }
}
...
scaleBarOverlay = new ScaleBarOverlay(this.getBaseContext(), this, myMapView);
List<Overlay> overlays = myMapView.getOverlays();
// Add scale bar overlay
scaleBarOverlay.setMetric();
overlays.add(scaleBarOverlay);
...