Android安卓 自定义高德地图比例尺

来源:互联网 发布:淘宝调整上下架时间 编辑:程序博客网 时间:2024/05/16 19:50

高德地图有提供自带的比例尺,但是不能改变位置,只能固定在屏幕右下角,做项目时,有些需求非要在某个位置,那就只能自定义了。

用高德自带的比例尺测试过,同一缩放等级,不同经纬度,比例尺也可能是不一样的,所以不能根据缩放等级处理。

好在高德地图有提供相应api

比例尺数据:AMap. getScalePerPixel()可以获取当前地图级别下1像素点对应的距离长度(米),然后可自定义比例尺长度(如100像素)。

效果图如下。

这里写图片描述


完整代码:

public class MapScaleView extends View {    private int scaleWidth;    private int scaleHeight;    private int scaleSpaceText;    private int textSize;    private String text;    private Paint mPaint;    private Rect scaleRect;    public MapScaleView(Context context) {        this(context, null);    }    public MapScaleView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MapScaleView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        this.initVariables();    }    private void initVariables() {        scaleWidth = 150;//比例尺宽度        scaleHeight = ResHelper.dipToPx(this.getContext(), 3);//比例尺高度        text = "10km";//比例尺文本        textSize = ResHelper.sp2px(this.getContext(), 11);//比例尺字体        scaleSpaceText = scaleHeight;//比例尺文本与图形的间隔高度        mPaint = new Paint();//画笔        mPaint.setColor(Color.BLACK);        mPaint.setAntiAlias(true);        mPaint.setTextSize(textSize);        scaleRect = new Rect();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int resultWidth;        if (widthMode == MeasureSpec.EXACTLY) {            resultWidth = widthSize;        } else {            resultWidth = scaleWidth;            if (widthMode == MeasureSpec.AT_MOST) {                resultWidth = Math.min(resultWidth, widthSize);            }        }        int heightSize = getHeightSize(heightMeasureSpec);        setMeasuredDimension(resultWidth, heightSize);    }    /**     * 测量ScaleView的高度     */    private int getHeightSize(int heightMeasureSpec) {        int mode = MeasureSpec.getMode(heightMeasureSpec);        int height = 0;        switch (mode) {            case MeasureSpec.AT_MOST:                height = textSize + scaleSpaceText + scaleHeight;                break;            case MeasureSpec.EXACTLY: {                height = MeasureSpec.getSize(heightMeasureSpec);                break;            }            case MeasureSpec.UNSPECIFIED: {                height = Math.max(textSize + scaleSpaceText + scaleHeight, MeasureSpec.getSize(heightMeasureSpec));                break;            }        }        return height;    }    /**     * 绘制上面的文字和下面的比例尺,因为比例尺是.9.png,我们需要利用{@link #drawNinePath(Canvas, int, Rect)}方法绘制比例尺     */    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        float textWidth = mPaint.measureText(text);        canvas.drawText(text, (scaleWidth - textWidth) / 2, textSize, mPaint);        scaleRect.set(0, textSize + scaleSpaceText, scaleWidth, textSize + scaleSpaceText + scaleHeight);        drawNinePath(canvas, R.drawable.blc, scaleRect);    }    private void drawNinePath(Canvas canvas, int resId, Rect rect) {        Bitmap bmp = BitmapFactory.decodeResource(getResources(), resId);        NinePatch patch = new NinePatch(bmp, bmp.getNinePatchChunk(), null);        patch.draw(canvas, rect);    }    /**     * 根据缩放级别更新ScaleView的文字以及比例尺的长度     */    public void refreshScaleView(AMap mapView) {        if (mapView == null) {            return;        }        int max = 100;        double scale = mapView.getScalePerPixel() * max;//结果单位米,表示图上max像素代表*米        if (scale > 0 && scale <= 14) {//换算10米            text = "10m";            scaleWidth = (int) (10 * max / scale);        } else if (scale <= 25) {//换算25米            text = "25m";            scaleWidth = (int) (25 * max / scale);        } else if (scale <= 50) {//换算50米            text = "50m";            scaleWidth = (int) (50 * max / scale);        } else if (scale <= 100) {            text = "100m";            scaleWidth = (int) (100 * max / scale);        } else if (scale <= 200) {            text = "200m";            scaleWidth = (int) (200 * max / scale);        } else if (scale <= 500) {            text = "500m";            scaleWidth = (int) (500 * max / scale);        } else if (scale <= 1000) {            text = "1km";            scaleWidth = (int) (1000 * max / scale);        } else if (scale <= 2000) {            text = "2km";            scaleWidth = (int) (2000 * max / scale);        } else if (scale <= 5000) {            text = "5km";            scaleWidth = (int) (5000 * max / scale);        } else if (scale <= 10000) {            text = "10km";            scaleWidth = (int) (10000 * max / scale);        } else if (scale <= 20000) {            text = "20km";            scaleWidth = (int) (20000 * max / scale);        } else if (scale <= 25000) {            text = "25km";            scaleWidth = (int) (25000 * max / scale);        } else if (scale <= 50000) {            text = "50km";            scaleWidth = (int) (50000 * max / scale);        } else if (scale <= 100000) {            text = "100km";            scaleWidth = (int) (100000 * max / scale);        } else if (scale <= 200000) {            text = "200km";            scaleWidth = (int) (200000 * max / scale);        } else if (scale <= 500000) {            text = "500km";            scaleWidth = (int) (500000 * max / scale);        } else if (scale <= 1000000) {            text = "1000km";            scaleWidth = (int) (1000000 * max / scale);        }        requestLayout();        invalidate();    }}


使用方法:

和正常view一样添加到layout中,注意修改包名

<com.xxx.xxx.view.MapScaleView     android:id="@+id/blc"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_toLeftOf="@id/tv_scale" />

OnCameraChangeListeneronCameraChange中调用比例尺的refreshScaleView()

override fun onCameraChange(p0: CameraPosition?) {    if (p0 == null) return    blc.refreshScaleView(mMap)}


上面用到的单位转换方法:

public static int dipToPx(Context context, int dip) {        float density = context.getResources().getDisplayMetrics().density;        return (int) ((float) dip * density + 0.5F);    }
public static int sp2px(Context context, float spValue) {        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;        return (int) (spValue * fontScale + 0.5F);    }


比例尺点9图 blc.9.png

下面这个黑色的,有点小
这里写图片描述

参考资料:
如何自定义指南针、缩放按钮、比例尺控件、定位按钮?
ArcGIS for Android 自定义地图比例尺

阅读全文
0 0
原创粉丝点击