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();           for (int j = 1; j <

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,new

LatLng(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,new

LatLng(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开发,java开发)