android 高德地图 自定义图层 路线规划 自定义marker

最近接到了一个新需求 计划做路线提示 由于个性化程度很高 与原地图差异较大 我选择了自定义地图和路线规划相机和的方式 

先看效果图 


android 高德地图 自定义图层 路线规划 自定义marker_第1张图片
效果图

首先要点 基本地图显示 定位蓝点 路线规划 自定义路线规划图层(高德已开源) 自定义marker 测距等 功能部分官方网的文档并不是很清晰 我在这里整理一下 我所用的流程

第一 先配置高德环境 自己去高德官网看 按文档来就可以了

第二 初始化地图

map_view = (MapView) findViewById(R.id.map_view); 

map_view.onCreate(savedInstanceState); 

if (map_view!=null){ 

aMap = map_view.getMap(); 

}

设置定位蓝点

MyLocationStyle myLocationStyle; 

myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。 

myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。 

aMap.getUiSettings().setMyLocationButtonEnabled(false);//设置默认定位按钮是否显示,非必需设置。 

aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。 

// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。 

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。 

myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.map_ownerlocation_img)); 

myLocationStyle.showMyLocation(true);

    aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style

    aMap.setMapType(AMap.MAP_TYPE_NAVI);

模拟地点 并规划路线

////////////////////路线规划//////////////////////

    start = new LatLonPoint(30.291779,120.040998);

    end = new LatLonPoint(30.406169,120.305117);

    final LatLonPoint way1 = new LatLonPoint(30.270999,120.163277);

    final LatLonPoint way2 = new LatLonPoint(30.291124,120.212892);

    wayPointList.add(way1);

    wayPointList.add(way2);

    routeSearch = new RouteSearch(this);

    routeSearch.setRouteSearchListener(this);

    // fromAndTo包含路径规划的起点和终点,drivingMode表示驾车模式

    // 第三个参数表示途经点(最多支持16个),第四个参数表示避让区域(最多支持32个),第五个参数表示避让道路

    RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(start, end);

    RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault,wayPointList, null, “”); 

routeSearch.calculateDriveRouteAsyn(query);

//////////////////当前位置监听//////////////////

    aMap.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {

        @Override

        public void onMyLocationChange(Location location) {

        }

    })


自定义路线规划图层 高德sdk 5.0版本以后 就不在提供overlay包 但是官方demo 中会有overlay 包 如有需要你可以直接过去拷贝 有一些小地方需要修改 注意下

@Override 

public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) { 

if (i==1000){// 路线规划成功 

if (driveRouteResult!=null&&driveRouteResult.getPaths()!=null&&driveRouteResult.getPaths().size()>0){ 

DrivePath drivePath = driveRouteResult.getPaths().get(0); 

aMap.clear();// 清理地图上的所有覆盖物 

// 定义图层 

DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(MapActivity.this, aMap, drivePath, 

driveRouteResult.getStartPos(), 

driveRouteResult.getTargetPos(),wayPointList); 

drivingRouteOverlay.setNodeIconVisibility(false);//隐藏转弯的节点 

drivingRouteOverlay.addToMap(); 

drivingRouteOverlay.zoomToSpan(); 

aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(new 

LatLngBounds( 

new LatLng(start.getLatitude(),start.getLongitude()), 

new LatLng(end.getLatitude(),end.getLongitude())),50));

        }

    }else {// 路线规划失败

        Toast.makeText(MapActivity.this, "无可用路线", Toast.LENGTH_SHORT).show();

    }

}

自定义图层类

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

import android.content.Context; import android.graphics.Bitmap; import 

android.graphics.BitmapFactory; import android.graphics.Color; import 

android.graphics.drawable.Drawable; import android.os.Parcel; import 

android.util.Log; import android.view.LayoutInflater; import 

android.view.View; import android.widget.LinearLayout;

import com.amap.api.maps.AMap; import 

com.amap.api.maps.model.BitmapDescriptor; import 

com.amap.api.maps.model.BitmapDescriptorFactory; import 

com.amap.api.maps.model.LatLng; import 

com.amap.api.maps.model.LatLngBounds; import 

com.amap.api.maps.model.Marker; import 

com.amap.api.maps.model.MarkerOptions; import 

com.amap.api.maps.model.PolylineOptions; import 

com.amap.api.services.core.LatLonPoint; import 

com.amap.api.services.route.DrivePath; import 

com.amap.api.services.route.DriveStep; import 

com.amap.api.services.route.TMC; import com.free_ride.yiwei.R; import 

com.free_ride.yiwei.mvputils.HttpUtils; import 

com.free_ride.yiwei.personal.AppManager; import 

com.free_ride.yiwei.pinchexin.MapActivity; import 

com.free_ride.yiwei.utils.InternetAddressUtis; import 

com.free_ride.yiwei.views.RoundImageView; import 

com.squareup.picasso.Picasso;

import org.xutils.common.Callback; import org.xutils.x;

/导航路线图层类。 */

public class DrivingRouteOverlay extends RouteOverlay{

private DrivePath drivePath; 

private List throughPointList; 

private List throughPointMarkerList = new ArrayList(); 

private boolean throughPointMarkerVisible = true; 

private List tmcs; 

private PolylineOptions mPolylineOptions; 

private PolylineOptions mPolylineOptionscolor; 

private Context mContext; 

private boolean isColorfulline = true; 

private float mWidth = 25; 

private List mLatLngsOfPath;

private ArrayListiconList = new ArrayList();

public void setIsColorfulline(boolean iscolorfulline) { 

this.isColorfulline = iscolorfulline; }

/** 

* 根据给定的参数,构造一个导航路线图层类对象。 

* @param amap 地图对象。 

* @param path 导航路线规划方案。 

* @param context 当前的activity对象。 

*/ 

public DrivingRouteOverlay(Context context, AMap amap, DrivePath path, 

LatLonPoint start, LatLonPoint end, List throughPointList) { 

super(context); 

mContext = context; 

mAMap = amap; 

this.drivePath = path; 

startPoint = toLatLon(start); 

endPoint = toLatLon(end); 

this.throughPointList = throughPointList; 

}

public float getRouteWidth() {

    return mWidth;

}

/**

* 设置路线宽度

*

* @param mWidth 路线宽度,取值范围:大于0

*/

public void setRouteWidth(float mWidth) {

    this.mWidth = mWidth;

}

/**

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

*/  public void addToMap() {        initPolylineOptions();

    try {

        if (mAMap == null) {

            return;

        }

        if (mWidth == 0 || drivePath == null) {

            return;

        }

        mLatLngsOfPath = new ArrayList();

        tmcs = new ArrayList();

        List drivePaths = drivePath.getSteps();

        mPolylineOptions.add(startPoint);

        for (DriveStep step : drivePaths) {

            List latlonPoints = step.getPolyline();

            List tmclist = step.getTMCs();

            tmcs.addAll(tmclist);

            addDrivingStationMarkers(step, convertToLatLng(latlonPoints.get(0)));

            for (LatLonPoint latlonpoint : latlonPoints) {

              mPolylineOptions.add(convertToLatLng(latlonpoint));

              mLatLngsOfPath.add(convertToLatLng(latlonpoint));

          }

        }

        mPolylineOptions.add(endPoint);

        if (startMarker != null) {

            startMarker.remove();

            startMarker = null;

        }

        if (endMarker != null) {

            endMarker.remove();

            endMarker = null;

        }

        addStartAndEndMarker();

        addThroughPointMarker();

        if (isColorfulline && tmcs.size()>0 ) {

          colorWayUpdate(tmcs);

          showcolorPolyline();            }else {

          showPolyline();            }           

    } catch (Throwable e) {

      e.printStackTrace();

    }

}


/** 

* 初始化线段属性 

*/ 

private void initPolylineOptions() { 

mPolylineOptions = null; 

mPolylineOptions = new PolylineOptions(); 

mPolylineOptions.color(getDriveColor()).width(getRouteWidth()); 

}

private void showPolyline() {

    addPolyLine(mPolylineOptions);

}

private void showcolorPolyline() {

  addPolyLine(mPolylineOptionscolor);

      }

/**

* 根据不同的路段拥堵情况展示不同的颜色

*

* @param tmcSection

*/

private void colorWayUpdate(List tmcSection) {

    if (mAMap == null) {

        return;

    }

    if (tmcSection == null || tmcSection.size() <= 0) {

        return;

    }

    TMC segmentTrafficStatus;

    mPolylineOptionscolor = null;

    mPolylineOptionscolor = new PolylineOptions();

    mPolylineOptionscolor.width(getRouteWidth());

    List colorList = new ArrayList();

    mPolylineOptionscolor.add(startPoint);

    mPolylineOptionscolor.add(toLatLon(tmcSection.get(0).getPolyline().get(0)));

    colorList.add(getDriveColor());

    for (int i = 0; i < tmcSection.size(); i++) {

      segmentTrafficStatus = tmcSection.get(i);

      int color = getcolor(segmentTrafficStatus.getStatus());

      List mployline = segmentTrafficStatus.getPolyline(); 

mployline.size(); j++) { 

mPolylineOptionscolor.add(toLatLon(mployline.get(j))); 

colorList.add(color); } } 

mPolylineOptionscolor.add(endPoint); 

colorList.add(getDriveColor()); 

mPolylineOptionscolor.colorValues(colorList); 

}

private int getcolor(String status) {

  if (status.equals("畅通")) {

      return Color.GREEN;        } else if (status.equals("缓行")) {

      return Color.YELLOW;      } else if (status.equals("拥堵")) {          return Color.RED;      } else if (status.equals("严重拥堵")) {            return Color.parseColor(“#990033”); } else { return 

Color.parseColor(“#537edc”); } }

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() {

    if (this.throughPointList != null && this.throughPointList.size() > 0) {

        LatLonPoint latLonPoint = null;

        iconList.add(BitmapDescriptorFactory.fromResource(R.mipmap.map_end_img));

        for (int i = 0; i < this.throughPointList.size(); i++) {

            latLonPoint = this.throughPointList.get(i);

            if (latLonPoint != null) {

                throughPointMarkerList.add(mAMap.addMarker(initMarkerObject(latLonPoint,i)));

            }

        }

    }

}

    // 初始化marker  自定义marker 样式 下main会给出map_custom_marker_img  xml 文件

private MarkerOptions initMarkerObject(LatLonPoint latLonPoint, int i) {

    View inflate = LayoutInflater.from(AppManager.getAppManager().currentActivity()).inflate(R.layout.map_custom_marker_img,null); 

RoundImageView roundImg = (RoundImageView) inflate.findViewById(R.id.map_custom_marker); 

roundImg.setImageBitmap(BitmapFactory.decodeResource(AppManager.getAppManager().currentActivity().getResources(),R.mipmap.map_passheand_one)); 

MarkerOptions options = null;

if (i%2==0){

        options = new MarkerOptions();

        options.position(new LatLng(latLonPoint.getLatitude(),latLonPoint.getLongitude()))

                .visible(throughPointMarkerVisible)

                .icon(BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(inflate)))

                .autoOverturnInfoWindow(true)

                .title("距离"+(i+1)+"还有"+(calculateDistance(this.startPoint,newLatLng(throughPointList.get(i).getLatitude(),throughPointList.get(i).getLongitude())))+”米”); 

}else { options = new MarkerOptions();

        options.position(new LatLng(latLonPoint.getLatitude(),latLonPoint.getLongitude()))

                .visible(throughPointMarkerVisible)

                .icon(BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(inflate)))

                .autoOverturnInfoWindow(true)

                .title("距离"+(i+1)+"还有"+(calculateDistance(this.startPoint,newLatLng(throughPointList.get(i).getLatitude(),throughPointList.get(i).getLongitude())))+”米”); 

} return options;

}

/**

* view 转为 bitmap 对象

* @param view

* @return

*/

public static Bitmap convertViewToBitmap(View view) {

    view.destroyDrawingCache();

    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),

            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

    view.setDrawingCacheEnabled(true);

    return view.getDrawingCache(true);

}

private BitmapDescriptor getThroughPointBitDes() {

  return BitmapDescriptorFactory.fromResource(R.mipmap.pass_head);

}

/**

* 获取两点间距离

*

* @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(); 

}

/**

* 把LatLonPoint对象转化为LatLon对象

*/

public static LatLng toLatLon(LatLonPoint lonPoint){

    return new LatLng(lonPoint.getLatitude(),lonPoint.getLongitude());

} }

我的需求是水滴型内嵌套圆形头像的marker 

map_custom_marker_img 文件

到此就完结了 如有疑问 欢迎留言和私信



android 高德地图 自定义图层 路线规划 自定义marker_第2张图片
加群交流

你可能感兴趣的:(android 高德地图 自定义图层 路线规划 自定义marker)