实现如下图一样的小工具

操作说明:

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-dataandroid: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.ConstraintLayoutxmlns: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.MapViewandroid:id="@+id/map"android:layout_width="match_parent"android:layout_height="match_parent" /><!--添加清除按钮--><android.support.design.widget.FloatingActionButtonandroid: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"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:gravity="center_vertical"android:layout_width="match_parent"android:layout_height="40dp"><TextViewandroid:id="@+id/info_distance"android:layout_weight="1"android:gravity="center"android:text="距离:xxxm"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextViewandroid:layout_marginLeft="5dp"android:layout_marginRight="5dp"android:background="#FF000000"android:layout_width="1dp"android:layout_height="30dp" /><ImageViewandroid: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 {//起点markerprivate Marker drawStartMarker = null;//记录最后一个markerprivate 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.绘制此次MarkerMarker 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.本次为最新MarkerlastClickMarker = 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);//移除这个Markermarker.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 {//地图uiprivate MapView mapView;private AMap aMap;private MeasureHelper drawLineHelper;//按钮private FloatingActionButton fab_clear;@Overrideprotected 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() {@Overridepublic 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 生命周期@Overrideprotected void onResume() {super.onResume();if (mapView != null) {mapView.onResume();}}@Overrideprotected void onPause() {super.onPause();if (mapView != null) {mapView.onPause();}}@Overridepublic void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {super.onSaveInstanceState(outState, outPersistentState);if (mapView != null) {mapView.onSaveInstanceState(outState);}}@Overridepublic void onLowMemory() {super.onLowMemory();if (mapView != null) {mapView.onLowMemory();}}@Overrideprotected 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;}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {checkAllPermission();super.onActivityResult(requestCode, resultCode, data);}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {getCheckPermissionUtil().onRequestPermissionsResult(MainActivity.this, requestCode, permissions, grantResults);super.onRequestPermissionsResult(requestCode, permissions, grantResults);}@Overridepublic void onAllow(int permissionCode) {checkAllPermission();}@Overridepublic void onDeny(int permissionCode) {checkAllPermission();}
//endregion//region 地图监听/*** 自定义InfoWindow实现的方法1*/@Overridepublic 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() {@Overridepublic void onClick(View v) {if (drawLineHelper != null) {drawLineHelper.removeCurrent(marker);}}});return view;}/*** 自定义InfoWindow实现的方法2*/@Overridepublic View getInfoContents(Marker marker) {return null;}/***amap 加载完成回调*/@Overridepublic void onMapLoaded() {drawLineHelper = new MeasureHelper(MainActivity.this.getApplicationContext(), aMap);checkAllPermission();}/***marker长按监听*/@Overridepublic void onMapLongClick(LatLng latLng) {if (drawLineHelper != null) {drawLineHelper.drawMarkerLine(latLng);}}/***marker点击监听*/@Overridepublic boolean onMarkerClick(Marker marker) {marker.showInfoWindow();return true;}//endregion
}

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

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

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

  1. 前端工程师技能之photoshop巧用系列第二篇——测量篇

    前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇--测量篇 测量信息 在网页制作中需要使用photoshop测量的信息分为两类,分别是尺寸信息和颜色信 ...

  2. 高德地图上线全国最全小客车、货车限行提醒功能

    近年来,各大城市为了治理交通拥堵问题,都纷纷开始实施各类限行措施,不仅限路段.限时间.限区域,货车还要限高限重,这就让很多开车的朋友们特别烦恼,限行措施不断出新,哪里记得住,一不小心就得吃到罚单,增加 ...

  3. 距测试软件,两步路怎么测量距离 测距工具使用方法介绍

    两步路户外助手是专门为户外运动爱好者打造的一款手机户外运动助手软件,用户通过它可以记录自己的每一条轨迹以及出行方式,这样可以很好的为大家记录各种户外出行的数据,还能参加各种活动和比赛.此外软件自带的地 ...

  4. android开发之高德地图API篇:1、高德地图API之实时定位+轨迹可视化

    TIME:2020年7月6日 高德地图API之实时定位+轨迹可视化 前言: step1.工程的配置 step2.显示地图 step2.实现静态定位: step3.实时定位 step4.实现轨迹可视化: ...

  5. 高德地图计算两坐标之间距离

    转载自:http://blog.csdn.net/jianggujin/article/details/72833711 如要转载请写明原创地址 Java实现 Javascript实现 MySQL实现 ...

  6. php高德地图计算距离接口,高德地图计算两坐标之间距离

    最近在做与地图相关的应用,使用了高德地图,研究了下高德地图计算两坐标距离的方法,官网上提供的开发包中有相关的方法,但是我的产品中比较特殊,无法直接使用提供的方法,所以就自己封装了相关计算方法,供大家参 ...

  7. 【饥荒mod制作吧第二篇】mod制作工具下载资源!

    谢谢大家阅读 饥荒mod制作吧相关博客第二篇 ! Welcome to Don't Starve mod making bar ! [MOD制作工具] 由本人从正版mod tools中提取以及&quo ...

  8. 高德地图api调用demo_微信小程序----高德地图API实现的DEMO

    [实例简介] 微信小程序----高德地图API实现的周边,天气,路线规划,地址详情等的DEMO.简单的效果,问一下官方能不能不要乱涨积分,你们涨积分,作者被骂!我真的很失望,再这样,我就不上传资源了! ...

  9. 高德地图POI信息获取——爬虫小实验

    写在前面:不详尽支出,各位看官可在留言区留言说明,我会尽快补充回复! 上传一个之前数据爬取过程中,编写的一个小程序,代码如下 # -*- coding: utf-8 -*- import json i ...

最新文章

  1. SpringBoot之事务管理Transactional
  2. 一幅画十六芒星盾---程序员or艺术家
  3. 你以为A10 Networks只做应用交付?
  4. Linux期末复习编程题
  5. STM32之SDIO例程
  6. nodejs websocket server
  7. SQLi LABS Less 17 报错注入
  8. 数据分析:星巴克店铺分布有何规律?
  9. JMeter脚本录制-快速上手篇
  10. PC端打开微信公众号文章 图片加载慢的解决方法
  11. 观察者研报 | Moon的崛起
  12. 如何创建您自己的I爱纽约T恤
  13. 2016最新的旅游网站程序CMS系统优点和缺点对比分析
  14. vdsm:vdsm-client 命令行使用演示
  15. HSV颜色分割,RGB与HSV颜色空间的关系
  16. html的基础网页代码源(超基础)
  17. oracle导出报错04063,导出报错:ORA-04063:packagebody“DMSYS.DBMS_DM_MODEL_EXP”hase
  18. 英雄联盟服务器维护裁决之地,杜绝演员!LOL裁决之地开启审判天使系统
  19. html不支持utf8,html UTF-8在IE中不能自动选择编码的解决办法
  20. 数据中台为什么不好搞?

热门文章

  1. PTA:输出较大或较小值(c++,函数模板)
  2. windows 系统安装苹果操作系统
  3. 31:几何算法--点集的凸包
  4. windows 无法更新计算机的配置,[修复] Windows无法更新计算机引导配置。安装无法继续。 | MOS86...
  5. 微信小程序:升级版手机检测微信工具小程序源码
  6. 愿大家永远用不到的手机自带功能!记得要开启,能救命但别乱用
  7. 古月居 ROS 入门21讲--PA18 tf坐标系广播与监听的编程实现笔记
  8. 相机标定(Camera calibration)原理、步骤
  9. 浅谈Mediator仲裁者模式
  10. sqlsever2008 函数