高德地图(第二篇)测量距离小工具

实现如下图一样的小工具

操作说明:

1.在地图上长按选点,第一个点添加起点marker,底部导航点为红色表示正在编辑

2.连续选点会弹出气泡计算总距离,底部导航点为红色表示正在编辑

3.点击气泡内垃圾桶会删除当前点,回退到上次内容.

4.点击红色按钮会清除已所有绘制内容

 下面开始准备工作:

 一、配置工作

1.app moudle的build.gradle文件内引入Amap依赖

//3D地图so及jar
implementation 'com.amap.api:3dmap:6.8.0'

2.AndroidManifest添加使用到的权限

   <!-- 网络权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 允许程序获取网络状态 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- 允许程序访问WiFi网络信息 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 允许改变wifi连接状态 -->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

    <!-- 写入权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!--读取权限-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

AndroidManifest的application节点下配置AMap的key

<!-- 配置AMap 的key -->
<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="@string/map_key" />

3.string.xml内容

<resources>
    <string name="app_name">Measure</string>
    <string name="map_key">your key</string>
</resources>

 

二、开始编码工作

1.编写activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!--引入MapView-->
    <com.amap.api.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!--添加清除按钮-->
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="13dp"
        android:layout_marginBottom="100dp"
        android:clickable="true"
        android:focusable="true"
        android:src="@drawable/clear_map"
        app:backgroundTint="#FFFF0000"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</android.support.constraint.ConstraintLayout>

2.custom_info_window.xml   这个是自定义Marker的infowidow的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:gravity="center_vertical"
    android:layout_width="match_parent"
    android:layout_height="40dp">
    <TextView
        android:id="@+id/info_distance"
        android:layout_weight="1"
        android:gravity="center"
        android:text="距离:xxxm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="#FF000000"
        android:layout_width="1dp"
        android:layout_height="30dp" />
    <ImageView
        android:id="@+id/info_delete"
        android:src="@drawable/ic_remove_circle"
        android:padding="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

 

3.java代码 核心绘制工具类 

MeasureHelper.java

package com.ming.measure;

import android.content.Context;
import android.widget.Toast;

import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;

import java.util.ArrayList;
import java.util.List;

public class MeasureHelper {
    //起点marker
    private Marker drawStartMarker = null;
    //记录最后一个marker
    private Marker lastClickMarker = null;
    //所有点的集合
    private List<LatLng> lineLatLngList = new ArrayList<>();
    //线
    private Polyline polyline = null;
    //地图对象
    private AMap mMap;

    private Context ctx;

    public MeasureHelper(Context context, AMap aMap) {
        this.mMap = aMap;
        this.ctx = context;
    }

    /**
     * 划marker与线
     */
    public void drawMarkerLine(LatLng addLatLng) {
        //1.绘制此次Marker
        Marker addMarker = mMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).position(addLatLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.red_point)));
        //2.判断划线
        if (lastClickMarker != null) {
            if (drawStartMarker == null) {
                drawStartMarker = mMap.addMarker(new MarkerOptions().position(lastClickMarker.getPosition()).icon(BitmapDescriptorFactory.fromResource(R.drawable.start)));
            }
            //显示距离
            addMarker.showInfoWindow();
            //红点变蓝点
            lastClickMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.blue_point));
        }
        //划线
        drawLine(addLatLng);

        //3.本次为最新Marker
        lastClickMarker = addMarker;
    }

    /**
     * 划线
     */
    private void drawLine(LatLng addLatLng) {
        lineLatLngList.add(addLatLng);
        if (lineLatLngList.size() > 1) {
            if (polyline == null) {
                polyline = mMap.addPolyline(
                        new PolylineOptions()
                                .addAll(lineLatLngList)
                                .width(30)
                                .setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.grasp_trace_line)));
            } else {
                polyline.setPoints(lineLatLngList);
            }
        } else {
            Toast.makeText(ctx, "Go On!!!", Toast.LENGTH_SHORT).show();
        }
    }

    public void clearMap() {
        lineLatLngList.clear();
        lastClickMarker = null;
        drawStartMarker = null;
        polyline = null;
        if (mMap != null) {
            mMap.clear();
            Toast.makeText(ctx, "Cleared!!!", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 获取距离
     *
     * @return
     */
    public int getDistance() {
        int distance = 0;
        if (lineLatLngList != null) {
            int listSize = lineLatLngList.size();
            if (listSize > 1) {
                LatLng lastLatLng = lineLatLngList.get(0);
                for (int i = 1; i < listSize; i++) {
                    LatLng indexLatLng = lineLatLngList.get(i);
                    distance = (int) (distance + AMapUtils.calculateLineDistance(lastLatLng, indexLatLng));
                    lastLatLng = indexLatLng;
                }
            }
        }
        return distance;
    }

    /**
     * 回退删除一步
     *
     * @param marker
     */
    public void removeCurrent(Marker marker) {
        try {
            //移除点
            int deleteIndex = lineLatLngList.size() - 1;
            lineLatLngList.remove(deleteIndex);
            //更新图形
            polyline.setPoints(lineLatLngList);
            //移除这个Marker
            marker.remove();
            //找到上一个点,改为红色,赋值lastMarker,显示InfoWindow(注:只剩一个点删除掉起点)
            LatLng lastLatLng = lineLatLngList.get(deleteIndex - 1);
            if (deleteIndex == 1) {
                //起点删除
                drawStartMarker.remove();
                drawStartMarker = null;
                //赋值
                Marker findedMarker = findMarker(lastLatLng);
                if (findedMarker != null) {
                    //蓝变红
                    findedMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.red_point));
                    //赋值上一个
                    lastClickMarker = findedMarker;
                }
            } else {
                //赋值
                Marker findedMarker = findMarker(lastLatLng);
                if (findedMarker != null) {
                    // 显示气泡
                    findedMarker.showInfoWindow();
                    //蓝变红
                    findedMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.red_point));
                    //赋值上一个
                    lastClickMarker = findedMarker;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Marker findMarker(LatLng position) {
        List<Marker> markerList = mMap.getMapScreenMarkers();
        for (Marker mk : markerList) {
            if (mk.getPosition().equals(position)) {
                return mk;
            }
        }
        return null;
    }
}

 

4.MainActivity.java 具体实现的代码

package com.ming.measure;

import android.content.Intent;
import android.os.PersistableBundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;

public class MainActivity extends AppCompatActivity implements CheckPermissionUtil.PermissionCallBack, AMap.InfoWindowAdapter, AMap.OnMapLoadedListener, AMap.OnMapLongClickListener, AMap.OnMarkerClickListener {
    //地图ui
    private MapView mapView;
    private AMap aMap;
    private MeasureHelper drawLineHelper;
    //按钮
    private FloatingActionButton fab_clear;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //地图
        mapView = findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);
        aMap = mapView.getMap();
        //按钮
        fab_clear = findViewById(R.id.fab_clear);
        initUiSettings();
        initMapListener();
        fab_clear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (drawLineHelper != null) {
                    drawLineHelper.clearMap();
                }
            }
        });
    }

    //region 地图初始化参数
    private void initUiSettings() {
        //显示地图文字
        aMap.showMapText(true);

        UiSettings uiSettings = aMap.getUiSettings();
        uiSettings.setMyLocationButtonEnabled(false);
        //显示指南针
        uiSettings.setCompassEnabled(true);
        //显示缩放比例尺
        uiSettings.setScaleControlsEnabled(true);
    }

    private void initMapListener() {
        aMap.setInfoWindowAdapter(this);
        aMap.setOnMapLoadedListener(this);
        aMap.setOnMapLongClickListener(this);
        aMap.setOnMarkerClickListener(this);
    }

    //endregion

    //region 生命周期
    @Override
    protected void onResume() {
        super.onResume();
        if (mapView != null) {
            mapView.onResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mapView != null) {
            mapView.onPause();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        if (mapView != null) {
            mapView.onSaveInstanceState(outState);
        }
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        if (mapView != null) {
            mapView.onLowMemory();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mapView != null) {
            mapView.onDestroy();
        }
    }
//endregion

    //region 权限处理
    private void checkAllPermission() {
        if (getCheckPermissionUtil().checkWriteExternalStorage(MainActivity.this)) {
            if (getCheckPermissionUtil().checkReadExternalStorage(MainActivity.this)) {

            }
        }
    }

    private CheckPermissionUtil checkPermissionUtil = null;

    private CheckPermissionUtil getCheckPermissionUtil() {
        if (null == checkPermissionUtil) {
            checkPermissionUtil = new CheckPermissionUtil(this);
        }
        return checkPermissionUtil;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        checkAllPermission();
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        getCheckPermissionUtil().onRequestPermissionsResult(MainActivity.this, requestCode, permissions, grantResults);
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void onAllow(int permissionCode) {
        checkAllPermission();
    }

    @Override
    public void onDeny(int permissionCode) {
        checkAllPermission();
    }
//endregion

    //region 地图监听
     /**
     * 自定义InfoWindow实现的方法1
     */
    @Override
    public View getInfoWindow(final Marker marker) {
        View view = View.inflate(this, R.layout.custom_info_window, null);
        TextView info_tv_distance = view.findViewById(R.id.info_distance);
        String distanceDes = "";
        if (drawLineHelper != null) {
            int distance = drawLineHelper.getDistance();
            distanceDes = "距离:" + distance + "m";
        }
        info_tv_distance.setText(distanceDes);

        ImageView info_iv_delete = view.findViewById(R.id.info_delete);
        info_iv_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (drawLineHelper != null) {
                    drawLineHelper.removeCurrent(marker);
                }
            }
        });
        return view;
    }

     /**
     * 自定义InfoWindow实现的方法2
     */
    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }

     /**
     *amap 加载完成回调
     */
    @Override
    public void onMapLoaded() {
        drawLineHelper = new MeasureHelper(MainActivity.this.getApplicationContext(), aMap);
        checkAllPermission();
    }

   /**
     *marker长按监听
     */
    @Override
    public void onMapLongClick(LatLng latLng) {
        if (drawLineHelper != null) {
            drawLineHelper.drawMarkerLine(latLng);
        }
    }

    /**
     *marker点击监听
     */
    @Override
    public boolean onMarkerClick(Marker marker) {
        marker.showInfoWindow();
        return true;
    }
    //endregion
}

核心内容都已经贴出来了,也可以去我的资源里下载源码,运行起来体验一下

https://download.csdn.net/download/mr_thesun/11331965

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值