android 自定义地图 路线规划 自定义marker
最近接到了一个新需求 计划做路线导航提示 由于个性化程度很高 与元地图差异较大 我选择了自定义地图和路线规划相机和的方式先看效果图首先要点 基本地图显示 定位蓝点 路线规划 自定义路线规划图层(高德已开源) 自定义marker测距等 功能部分官方网的文档并不是很清晰 我在这里整理一下 我所用的流程第一 先配置高德环境 自己去高德官网看 按文档来就可以了第二 初始化地图 ...
最近接到了一个新需求 计划做路线导航提示 由于个性化程度很高 与元地图差异较大 我选择了自定义地图和路线规划相机和的方式
先看效果图
首先要点 基本地图显示 定位蓝点 路线规划 自定义路线规划图层(高德已开源) 自定义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 ArrayList<BitmapDescriptor>iconList = 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<LatLng>(); tmcs = new ArrayList<TMC>(); List<DriveStep> drivePaths = drivePath.getSteps(); mPolylineOptions.add(startPoint); for (DriveStep step : drivePaths) { List<LatLonPoint> latlonPoints = step.getPolyline(); List<TMC> 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<TMC> tmcSection) { if (mAMap == null) { return; } if (tmcSection == null || tmcSection.size() <= 0) { return; } TMC segmentTrafficStatus; mPolylineOptionscolor = null; mPolylineOptionscolor = new PolylineOptions(); mPolylineOptionscolor.width(getRouteWidth()); List<Integer> colorList = new ArrayList<Integer>(); 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<LatLonPoint> 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 文件
更多推荐
所有评论(0)