高德地图之拖动定位、多点路线规划给路段设置不同颜色

又有新需求 所以继续地图开发 这里记录两点 一是拖动定位 二是对多点路线规划不同路段设置颜色 下面给出效果图看一下 再上干货
先推荐一个拾取经纬度工具 http://www.gpsspg.com/bs.htm

拖动定位效果

拖动

设置不同路段的颜色

颜色

先说第一种效果 拖动定位 这个效果还是很简单的实现的
说一下思路
1 首先进入地图页要获得当前位置并显示在地图上
2 通过拖动地图 并获取地图中间点的位置 进行逆运算
3 将选中的点设置成地图中心点 并且显示具体的地址

下面上代码

(首先布局文件就不写了 有兴趣的可以根据效果图自己写一个 )
// 请求定位权限
requestPermissions();
// 添加地图变化监听
map.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {

        }

        @Override
        public void onCameraChangeFinish(CameraPosition cameraPosition) {
            setMyLocationMapCenter(cameraPosition.target);
            boundsSearchPoi(cameraPosition.target,null);
        }
    });

// 定位回调
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (null != aMapLocation){
if (aMapLocation.getErrorInfo().equals("success")) {
city = aMapLocation.getCity();
setMyLocationMapCenter(new LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude()));
start = new LocationBean();
start.setAddress(aMapLocation.getAddress());
start.setCity(TextUtils.isEmpty(city) ? "" : city);
start.setLat(aMapLocation.getLatitude());
start.setLon(aMapLocation.getLongitude());
start_tv.setText((TextUtils.isEmpty(city) ? "" :city)+aMapLocation.getAddress());
}
}
}

// 将latlng 设置为地图中心点
private void setMyLocationMapCenter(LatLng latlng){
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(latlng, 17, 30, 0));
map.moveCamera(cameraUpdate);

}
// 检索  可检索周边 也可检索具体的key
private void boundsSearchPoi(@Nullable LatLng target ,@Nullable String key) {
    PoiSearch.Query query = new PoiSearch.Query(TextUtils.isEmpty(key) ? "" : key, "01|02|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|99", TextUtils.isEmpty(city) ? "" : city);
    query.setPageSize(10);
    query.setDistanceSort(true);
    PoiSearch search = new PoiSearch(this, query);
    if (target != null){
        PoiSearch.SearchBound bound = new PoiSearch.SearchBound(new LatLonPoint(target.latitude, target.longitude), 100);
        search.setBound(bound);
    }
    search.setOnPoiSearchListener(this);
    search.searchPOIAsyn();
}

// 搜索回调
@Override
public void onPoiSearched(PoiResult poiResult, int i) {
if (i == 1000) {
if (poiResult != null && poiResult.getPois() != null && poiResult.getPois().size() > 0) {
setMyLocationMapCenter(new LatLng(poiResult.getPois().get(0).getLatLonPoint().getLatitude(),poiResult.getPois().get(0).getLatLonPoint().getLongitude()));
show(poiResult.getPois().get(0));
}
}
}

好了 剩下的就是显示了 方法已经给出

下面说第二个效果 不同路段设置颜色
首先做好路线规划并显示在地图上 我会给出两个自定义图层和一个acitivity 实现逻辑

由于并没有给出这个方法 我是根据导航的源码受到启发 得到实现的 有兴趣你可以看一下navi 的源码 RouteOvelay 这个类里有介绍 说不定你能得到过更好的实现方式

说说效果 可以设置不同路段不同颜色 自定义marker 视图 多点规划 重点是DrivingRouteOverlay图层类
艰苦历程就不说了 直接干货

// 路线规划UI
public class NadeNaviActivity extends Activity implements RouteSearch.OnRouteSearchListener {

private MapView navi_map;
private AMap map;
private List wayPoints;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_nade_navi);
    initNaviView();
    navi_map.onCreate(savedInstanceState);
    map = navi_map.getMap();
    Bundle bundle = getIntent().getExtras();

    planRoute();
}

/**
 * 路线规划
 *
 */
private void planRoute() {
    wayPoints = new ArrayList<>(); // 经途点集合
    wayPoints.add(new LatLonPoint(30.2762654235,120.0383377075));
    wayPoints.add(new LatLonPoint(30.2833069287,120.0756740570));
    wayPoints.add(new LatLonPoint(30.2921266276,120.1679420471));

    //腾讯高德:30.2903479286,120.0114727020
    LatLonPoint startPoint = new LatLonPoint(30.2903479286, 120.0114727020);
    //腾讯高德:30.2891621114,120.2158355713
    LatLonPoint endPoint = new LatLonPoint(30.2891621114, 120.2158355713);
    RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(startPoint, endPoint);
    RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, wayPoints, null, "");
    RouteSearch routeSearch = new RouteSearch(this);
    routeSearch.setRouteSearchListener(this);
    routeSearch.calculateDriveRouteAsyn(query);

}

private void initNaviView() {
    navi_map = findViewById(R.id.navi_map);
}

@Override
protected void onResume() {
    super.onResume();
    navi_map.onResume();

}

@Override
protected void onDestroy() {
    super.onDestroy();
    navi_map.onDestroy();

}

@Override
protected void onPause() {
    super.onPause();
    navi_map.onPause();

}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    navi_map.onSaveInstanceState(outState);

}

@Override
public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

}

@Override
public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
    if (i == 1000) {
        if (map != null) {
            map.clear();
        }
        if (driveRouteResult != null && driveRouteResult.getPaths() != null && driveRouteResult.getPaths().size() > 0) {

            List colors = new ArrayList<>(); // 色值集合
            colors.add(Color.parseColor("#0471b1"));
            colors.add(Color.parseColor("#78ccfd"));
            colors.add(Color.parseColor("#ff0000"));
            DrivingRouteOverlay routeOverlay = new DrivingRouteOverlay(this,
                    map, driveRouteResult.getPaths().get(0),
                    driveRouteResult.getStartPos(),
                    driveRouteResult.getTargetPos(),
                    wayPoints,colors,null);
            routeOverlay.setNodeIconVisibility(false);
            routeOverlay.setIsColorfulline(false);
            routeOverlay.setThroughPointIconVisibility(true);
            routeOverlay.removeFromMap();

            routeOverlay.addToMap(R.mipmap.start_img,R.mipmap.end_img, "");
            routeOverlay.zoomToSpan();
        }

    }
}

@Override
public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

}

@Override
public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

}

}

/**

  • 导航路线图层类。
    */
    public class DrivingRouteOverlay extends RouteOverlay {

    private DrivePath drivePath;
    private List throughPointList;
    private List throughPointMarkerList = new ArrayList();
    private boolean throughPointMarkerVisible = true;
    private PolylineOptions mPolylineOptions;
    private boolean isColorfulline = true;
    private float mWidth = 25;
    private DriveStep startStep;
    private DriveStep currentStep;
    private List colors;
    private List throughViews;

    public void setIsColorfulline(boolean iscolorfulline) {
    this.isColorfulline = iscolorfulline;
    }

    /**

    • 根据给定的参数,构造一个导航路线图层类对象。
    • @param amap 地图对象。
    • @param path 导航路线规划方案。
    • @param context 当前的activity对象。
    • @param throughPointList 途经点 ## 途经点集合
    • @param colors 色值集 ## 长度必须和色值集合途经点集合长度一致
    • @param throughViews 途径点marker视图 ## 途径点marker视图长度必须和途经点集合长度一致

    */
    public DrivingRouteOverlay(Context context, AMap amap, DrivePath path,
    LatLonPoint start, LatLonPoint end,
    List throughPointList,
    List colors,
    List throughViews) {
    super(context);
    mAMap = amap;
    this.drivePath = path;
    startPoint = AMapUtil.convertToLatLng(start);
    endPoint = AMapUtil.convertToLatLng(end);
    this.throughPointList = throughPointList;
    this.colors = colors;
    this.throughViews = throughViews;
    }

    public float getRouteWidth() {
    return mWidth;
    }

    /**

    • 设置路线宽度
    • @param mWidth 路线宽度,取值范围:大于0
      */
      public void setRouteWidth(float mWidth) {
      this.mWidth = mWidth;
      }

    /**

    • 添加驾车路线添加到地图上显示。

    • @param startRes

    • @param endRes

    • @param color 色值
      */
      public void addToMap(int startRes,int endRes,String color) {
      int index = 0;
      initPolylineOptions(color);
      try {
      if (mAMap == null) {
      return;
      }
      if (mWidth == 0 || drivePath == null) {
      return;
      }
      List drivePaths = drivePath.getSteps();
      List colorList = new ArrayList<>();
      mPolylineOptions.add(startPoint);
      if (colors.size()!=0) {
      colorList.add(colors.get(0));
      }

       boolean isadd = false;
       for (DriveStep step : drivePaths){
           List latlonPoints = step.getPolyline();
           for (LatLonPoint point:latlonPoints){
               mPolylineOptions.add(convertToLatLng(point));
               if (step.getAssistantAction().equals("到达途经地") && isadd == false) { // 到达第一个途径点
                   if (startStep == null) {
                       startStep = step;
                       isadd = true; // 设置为开始添加
                       index++;
                   }
               }else if (step.getAssistantAction().equals("到达途经地") && isadd == true) { // 到达第二个途径点
                   if (startStep != null && startStep != step){
                       isadd = false; // 设置为开始恢复
                       startStep = null;
                   }
               }
               int size = colors.size();
               if (index < size){
                   colorList.add(colors.get(index));
               }
           }
       }
       mPolylineOptions.add(endPoint);
       if (colors.size()!=0) {
           colorList.add(colors.get(0));
       }
       mPolylineOptions.colorValues(colorList);
       if (startMarker != null) {
           startMarker.remove();
           startMarker = null;
       }
       if (endMarker != null) {
           endMarker.remove();
           endMarker = null;
       }
       addStartAndEndMarker(startRes,endRes);
       //addThroughPointMarker(throughViews);
       showPolyline();
      

      } catch (Throwable e) {
      e.printStackTrace();
      }

    }

    /**

    • 初始化线段属性
      */
      private void initPolylineOptions(String color) {
      mPolylineOptions = null;
      mPolylineOptions = new PolylineOptions();

      mPolylineOptions.width(getRouteWidth());
      if (colors.size() == 0){
      mPolylineOptions.color(getDriveColor(color));
      }
      }

    private void showPolyline() {
    addPolyLine(mPolylineOptions);
    }

public LatLng convertToLatLng(LatLonPoint point) {
    return new LatLng(point.getLatitude(),point.getLongitude());

}

/**
 * @param driveStep
 * @param latLng
 */
private void addDrivingStationMarkers(DriveStep driveStep, LatLng latLng) {
    addStationMarker(new MarkerOptions()
            .position(latLng)
            .title("\u65B9\u5411:" + driveStep.getAction()
                    + "\n\u9053\u8DEF:" + driveStep.getRoad())
            .snippet(driveStep.getInstruction()).visible(nodeIconVisible)
            .anchor(0.5f, 0.5f).icon(getDriveBitmapDescriptor()));
}

@Override
protected LatLngBounds getLatLngBounds() {
    LatLngBounds.Builder b = LatLngBounds.builder();
    b.include(new LatLng(startPoint.latitude, startPoint.longitude));
    b.include(new LatLng(endPoint.latitude, endPoint.longitude));
    if (this.throughPointList != null && this.throughPointList.size() > 0) {
        for (int i = 0; i < this.throughPointList.size(); i++) {
            b.include(new LatLng(
                    this.throughPointList.get(i).getLatitude(),
                    this.throughPointList.get(i).getLongitude()));
        }
    }
    return b.build();
}

public void setThroughPointIconVisibility(boolean visible) {
    try {
        throughPointMarkerVisible = visible;
        if (this.throughPointMarkerList != null
                && this.throughPointMarkerList.size() > 0) {
            for (int i = 0; i < this.throughPointMarkerList.size(); i++) {
                this.throughPointMarkerList.get(i).setVisible(visible);
            }
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
}
 // 设置途径点marker视图
private void addThroughPointMarker(List views) {
    if (this.throughPointList != null && this.throughPointList.size() > 0) {
        LatLonPoint latLonPoint = null;
        for (int i = 0; i < this.throughPointList.size(); i++) {
            latLonPoint = this.throughPointList.get(i);
            if (latLonPoint != null) {
                Marker marker = mAMap
                        .addMarker((new MarkerOptions())
                                .position(
                                        new LatLng(latLonPoint
                                                .getLatitude(), latLonPoint
                                                .getLongitude()))
                                .visible(throughPointMarkerVisible)
                                .title(""));
                marker.setIcon(BitmapDescriptorFactory.fromView(views.get(i)));
                throughPointMarkerList.add(marker);
            }
        }
    }
}

private BitmapDescriptor getThroughPointBitDes() {
    //return BitmapDescriptorFactory.fromResource(R.mipmap.amap_through);
    return BitmapDescriptorFactory.fromResource(R.mipmap.app_maplocation);

}

/**
 * 获取两点间距离
 *
 * @param start
 * @param end
 * @return
 */
public static int calculateDistance(LatLng start, LatLng end) {
    double x1 = start.longitude;
    double y1 = start.latitude;
    double x2 = end.longitude;
    double y2 = end.latitude;
    return calculateDistance(x1, y1, x2, y2);
}

public static int calculateDistance(double x1, double y1, double x2, double y2) {
    final double NF_pi = 0.01745329251994329; // 弧度 PI/180
    x1 *= NF_pi;
    y1 *= NF_pi;
    x2 *= NF_pi;
    y2 *= NF_pi;
    double sinx1 = Math.sin(x1);
    double siny1 = Math.sin(y1);
    double cosx1 = Math.cos(x1);
    double cosy1 = Math.cos(y1);
    double sinx2 = Math.sin(x2);
    double siny2 = Math.sin(y2);
    double cosx2 = Math.cos(x2);
    double cosy2 = Math.cos(y2);
    double[] v1 = new double[3];
    v1[0] = cosy1 * cosx1 - cosy2 * cosx2;
    v1[1] = cosy1 * sinx1 - cosy2 * sinx2;
    v1[2] = siny1 - siny2;
    double dist = Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);

    return (int) (Math.asin(dist / 2) * 12742001.5798544);
}


//获取指定两点之间固定距离点
public static LatLng getPointForDis(LatLng sPt, LatLng ePt, double dis) {
    double lSegLength = calculateDistance(sPt, ePt);
    double preResult = dis / lSegLength;
    return new LatLng((ePt.latitude - sPt.latitude) * preResult + sPt.latitude, (ePt.longitude - sPt.longitude) * preResult + sPt.longitude);
}
/**
 * 去掉DriveLineOverlay上的线段和标记。
 */
@Override
public void removeFromMap() {
    try {
        super.removeFromMap();
        if (this.throughPointMarkerList != null
                && this.throughPointMarkerList.size() > 0) {
            for (int i = 0; i < this.throughPointMarkerList.size(); i++) {
                this.throughPointMarkerList.get(i).remove();
            }
            this.throughPointMarkerList.clear();
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

}

public class RouteOverlay {
protected List stationMarkers = new ArrayList();
protected List allPolyLines = new ArrayList();
protected Marker startMarker;
protected Marker endMarker;
protected LatLng startPoint;
protected LatLng endPoint;
protected AMap mAMap;
private Context mContext;
private Bitmap startBit, endBit, busBit, walkBit, driveBit;
protected boolean nodeIconVisible = true;

public RouteOverlay(Context context) {
    mContext = context;
}

/**
 * 去掉BusRouteOverlay上所有的Marker。
 * @since V2.1.0
 */
public void removeFromMap() {
    if (startMarker != null) {
        startMarker.remove();

    }
    if (endMarker != null) {
        endMarker.remove();
    }
    for (Marker marker : stationMarkers) {
        marker.remove();
    }
    for (Polyline line : allPolyLines) {
        line.remove();
    }
    destroyBit();
}

private void destroyBit() {
    if (startBit != null) {
        startBit.recycle();
        startBit = null;
    }
    if (endBit != null) {
        endBit.recycle();
        endBit = null;
    }
    if (busBit != null) {
        busBit.recycle();
        busBit = null;
    }
    if (walkBit != null) {
        walkBit.recycle();
        walkBit = null;
    }
    if (driveBit != null) {
        driveBit.recycle();
        driveBit = null;
    }
}
/**
 * 给起点Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
 * @return 更换的Marker图片。
 * @since V2.1.0
 */
protected BitmapDescriptor getStartBitmapDescriptor(int startRes) {
    return BitmapDescriptorFactory.fromResource(startRes);
}
/**
 * 给终点Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
 * @return 更换的Marker图片。
 * @since V2.1.0
 */
protected BitmapDescriptor getEndBitmapDescriptor(int endRes) {
    return BitmapDescriptorFactory.fromResource(endRes);
}
/**
 * 给公交Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
 * @return 更换的Marker图片。
 * @since V2.1.0
 */
protected BitmapDescriptor getBusBitmapDescriptor() {
    return BitmapDescriptorFactory.fromResource(R.mipmap.amap_bus);
}
/**
 * 给步行Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
 * @return 更换的Marker图片。
 * @since V2.1.0
 */
protected BitmapDescriptor getWalkBitmapDescriptor() {
    return BitmapDescriptorFactory.fromResource(R.mipmap.amap_man);
}

protected BitmapDescriptor getDriveBitmapDescriptor() {
    return BitmapDescriptorFactory.fromResource(R.mipmap.end_img);
}

protected void addStartAndEndMarker(int startRes,int endRes) {
    startMarker = mAMap.addMarker((new MarkerOptions())
            .position(startPoint).icon(getStartBitmapDescriptor(startRes))
            .title(""));

    endMarker = mAMap.addMarker((new MarkerOptions()).position(endPoint)
            .icon(getEndBitmapDescriptor(endRes)).title(""));
     mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(startPoint,
     getShowRouteZoom()));
}
/**
 * 移动镜头到当前的视角。
 * @since V2.1.0
 */
public void zoomToSpan() {
    if (startPoint != null) {
        if (mAMap == null) {
            return;
        }
        try {
            LatLngBounds bounds = getLatLngBounds();
            mAMap.animateCamera(CameraUpdateFactory
                    .newLatLngBounds(bounds, 100));
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

protected LatLngBounds getLatLngBounds() {
    LatLngBounds.Builder b = LatLngBounds.builder();
    b.include(new LatLng(startPoint.latitude, startPoint.longitude));
    b.include(new LatLng(endPoint.latitude, endPoint.longitude));
    return b.build();
}
/**
 * 路段节点图标控制显示接口。
 * @param visible true为显示节点图标,false为不显示。
 * @since V2.3.1
 */
public void setNodeIconVisibility(boolean visible) {
    try {
        nodeIconVisible = visible;
        if (this.stationMarkers != null && this.stationMarkers.size() > 0) {
            for (int i = 0; i < this.stationMarkers.size(); i++) {
                this.stationMarkers.get(i).setVisible(visible);
            }
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

protected void addStationMarker(MarkerOptions options) {
    if(options == null) {
        return;
    }
    Marker marker = mAMap.addMarker(options);
    if(marker != null) {
        stationMarkers.add(marker);
    }
    
}

protected void addPolyLine(PolylineOptions options) {
    if(options == null) {
        return;
    }
    Polyline polyline = mAMap.addPolyline(options);
    if(polyline != null) {
        allPolyLines.add(polyline);
    }
}

protected float getRouteWidth() {
    return 18f;
}

protected int getWalkColor() {
    return Color.parseColor("#6db74d");
}

/**
 * 自定义路线颜色。
 * return 自定义路线颜色。
 * @since V2.2.1
 */
protected int getBusColor() {
    return Color.parseColor("#0471b1");
}

protected int getDriveColor() {
    return Color.parseColor("#78ccfd");
}
protected int getDriveDarkColor() {
    return Color.parseColor("#0471b1");
}
protected int getDriveColor(String color) {
    return Color.parseColor(color);
}

 protected int getShowRouteZoom() {
 return 15;
 }

}

好了 就这样么多 有疑问可以私信我 或者加我qq

你可能感兴趣的:(高德地图之拖动定位、多点路线规划给路段设置不同颜色)