由于项目里用到了百度地图,路线规划的标题(比如“M235/362”)在百度地图API里面没有给出来,网上各种搜索都找不到别人发出来的方案,然后就只能自己组织标题了,相信很多人也遇到和我一样的问题,所以这里我把我的方案拿出来分享一下。先看一下效果图。
请尊重作者劳动成果,转载请标明原文地址:
http://blog.csdn.net/u010053224/article/details/51968653
private List addBusLinesTitle(List busLines){
for(int i=0 ; i steps = busLine.getAllStep();
String title = "";
for(int j=0 ; j 0){
title += ("→"+instructions.substring(2,instructions.indexOf(",经过")));
//下面被屏蔽的一行也可以使用
// title += ( "→"+instructions.split(",经过")[0].substring(2) );
}else {
// title = instructions.split(",经过")[0].substring(2);
title = instructions.substring(2,instructions.indexOf(",经过"));
}
}
}
busLine.setTitle(title);
}
return busLines;
}
上面的代码就是获取公交路线名字的方法,每个步骤的字符串用getInstructions()方法来获取。如果有很多个字符串有“乘坐”两字,代表要换乘多辆公交,然后把公交用连接符"→"连起来。
/**
* 组织路线的名字,(格式:途径xxx和xxx),xxx取最近的两条路
* @param steps
* @param
* @return
*/
private String getRouteTitle(List steps){
if(steps == null || steps.size()==0)
return "";
String title = "";
Method method = null;
try {
method = steps.get(0).getClass().getDeclaredMethod("getInstructions");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
for(T step:steps){
try {
String ss = (String) method.invoke(step);
if(ss.contains("进入")){
if(title.contains("途径")){
title += (" 和 " + ss.substring(ss.indexOf("进入")+2).split(",")[0]);
break;
}else {
title += ("途径 " + ss.substring(ss.indexOf("进入")+2).split(",")[0]);
}
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return title;
}
上面的用法是反射加泛型的方法。因为每个步骤的名字只能在RouteStep的子类才能获取,而且都是从每个子类的
getInstructions()方法来获取步骤名字,所以不用反射的话只能驾车步行骑行都单独去写一个。路线名字只取了最近经过的两条路显示。
/**
* 定位、显示多个商家地址
* Created by HuangYuGuang on 2016/7/11.
*/
public abstract class MapBaseFragment extends ABaseFragment {
//地图相关
private MapView mMapView = null;
protected BaiduMap mBaiduMap;
//定位相关
private BitmapDescriptor mIconMaker;
private LocationService locService;
protected BDLocation myLocation = MapApplication.bdLocation;
@Override
protected int inflateContentView() {
return R.layout.comm_lay_base_map;
}
@Override
protected void layoutInit(LayoutInflater inflater, Bundle savedInstanceSate) {
super.layoutInit(inflater, savedInstanceSate);
mMapView = (MapView) findViewById(R.id.bmapView);
//隐藏缩放按键
mMapView.showZoomControls(false);
mBaiduMap = mMapView.getMap();
mIconMaker = BitmapDescriptorFactory.fromResource(R.drawable.btu_gps_map);
//地图显示的比例范围
mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(15.0f));
mBaiduMap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
onMapLoadFinish();
}
});
if(canShowInfoWindow()){
initMarkerClickEvent();
initMapClickEvent();
}
if(canShowMyLocation()){
initMyLocation();
findViewById(R.id.view_my_location).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showMyLocation();
}
});
}
}
private void initMapClickEvent()
{
mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public boolean onMapPoiClick(MapPoi arg0) {
return false;
}
@Override
public void onMapClick(LatLng arg0) {
mBaiduMap.hideInfoWindow();
}
});
}
private void initMarkerClickEvent()
{
// 对Marker的点击
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(final Marker marker) {
// 获得marker中的数据
final AddrInfo info = (AddrInfo) marker.getExtraInfo().get("markerInfo");
InfoWindow mInfoWindow;
// 将marker所在的经纬度的信息转化成屏幕上的坐标
final LatLng ll = marker.getPosition();
Point p = mBaiduMap.getProjection().toScreenLocation(ll);
p.y -= 47;
LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
mInfoWindow = new InfoWindow(InfoWindowView(info), llInfo,-15);
mBaiduMap.showInfoWindow(mInfoWindow);
return true;
}
});
}
public void addInfoOverlay(AddrInfo info){
addInfosOverlay(Arrays.asList(info));
}
/**
* 在百度地图图层添加热点覆盖物
*/
public void addInfosOverlay(List infos)
{
mBaiduMap.clear();
LatLng latLng = null;
OverlayOptions overlayOptions = null;
Marker marker = null;
for (AddrInfo info : infos)
{
// 位置
latLng = new LatLng(info.getLatitude(), info.getLongitude());
// 图标
overlayOptions = new MarkerOptions().position(latLng)
.icon(mIconMaker).zIndex(5);
marker = (Marker) (mBaiduMap.addOverlay(overlayOptions));
Bundle bundle = new Bundle();
bundle.putSerializable("markerInfo", info);
marker.setExtraInfo(bundle);
}
// 将地图移到到最后一个经纬度位置
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.setMapStatus(u);
}
private void initMyLocation(){
locService = new LocationService(getActivity());
LocationClientOption mOption = locService.getDefaultLocationClientOption();
mOption.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
mOption.setCoorType("bd09ll");
locService.setLocationOption(mOption);
locService.registerListener(listener);
locService.start();
}
/***
* 定位结果回调,在此方法中处理定位结果
*/
BDLocationListener listener = new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || location.getLatitude() == 4.9E-324 || mMapView == null) {
return;
}
myLocation = location;
MapApplication.bdLocation = location;
MyLocationData locData = new MyLocationData.Builder()
//去掉光圈
// .accuracy(location.getRadius())
.accuracy(0)
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
}
};
private void showMyLocation(){
LatLng ll = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(15.0f));
mBaiduMap.animateMapStatus(u);
}
public void useOtherMap(AddrInfo addrInfo){
useOtherMap(addrInfo.getLatitude(), addrInfo.getLongitude(), addrInfo.getName());
}
/**
* 传入的坐标为百度坐标
* @param latitude
* @param longitude
* @param name
*/
public void useOtherMap(double latitude,double longitude,String name){
Gps gps = PositionUtil.bd09_To_Gps84(latitude, longitude);
Uri mUri = Uri.parse(String.format("geo:%s,%s?q=%s",gps.getWgLat(),gps.getWgLon(),name));
Intent mIntent = new Intent(Intent.ACTION_VIEW,mUri);
try {
startActivity(mIntent);
}catch (Exception e){
ToastUtil.showMsg("找不到手机地图软件。");
}
}
/**
* 需要重写InfoWindow的就重写该方法
* @param addrInfo
* @return
*/
protected View InfoWindowView(final AddrInfo addrInfo){
if(addrInfo == null) return null;
// 生成一个TextView用户在地图中显示InfoWindow
TextView textView = new TextView(getActivity());
textView.setBackgroundResource(R.drawable.location_tips);
textView.setPadding(30, 20, 30, 50);
textView.setText(addrInfo.getName());
textView.setTextColor(0xFFFFFFFF);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onInfoWindowClick(addrInfo);
}
});
return textView;
}
/**
* 是否显示我当前的位置
* @return
*/
protected boolean canShowMyLocation(){
return true;
}
/**
* 点击出现标InfoWindow
* @return
*/
protected boolean canShowInfoWindow(){
return false;
}
/**
* 可以重写该方法重写InfoWindow的点击事件
* @param addrInfo
*/
protected void onInfoWindowClick(AddrInfo addrInfo){
useOtherMap(addrInfo.getLatitude(),addrInfo.getLongitude(),addrInfo.getName());
}
/**
* 有些操作必须放在map加载完成后
*/
protected void onMapLoadFinish(){}
@Override
public void onStart()
{
mBaiduMap.setMyLocationEnabled(true);
super.onStart();
}
@Override
public void onStop()
{
mBaiduMap.setMyLocationEnabled(false);
super.onStop();
}
@Override
public void onDestroy()
{
super.onDestroy();
if(locService != null){
locService.unregisterListener(listener);
locService.stop();
}
mMapView.onDestroy();
mIconMaker.recycle();
mMapView = null;
}
@Override
public void onResume()
{
super.onResume();
mMapView.onResume();
}
@Override
public void onPause()
{
super.onPause();
mMapView.onPause();
}
}
/**
* 路线列表
* Created by HuangYuGuang on 2016/7/12.
*/
@SuppressLint("ValidFragment")
public class RouteLinesFragment extends Fragment {
private RoutePlanSearch mSearch = null;
private AddrInfo mAddrInfo;
private BDLocation myLocation = MapApplication.bdLocation;
private PlanNode stNode;
private PlanNode enNode;
private ListView listView;
private ViewGroup rootView;
public enum RoutePlanType{
bus, //公交路线查询
driving, //驾车路线查询
walking //步行路线查询
}
public RouteLinesFragment(AddrInfo addrInfo, RoutePlanType type) {
Bundle bundle = new Bundle();
bundle.putSerializable("whereToGo", addrInfo);
bundle.putSerializable("routeType",type);
setArguments(bundle);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rootView = (ViewGroup) View.inflate(getActivity(), R.layout.hyg_ui_route_lines,null);
listView = (ListView) rootView.findViewById(R.id.listView);
mAddrInfo = (AddrInfo) getArguments().getSerializable("whereToGo");
initPlan();
searchRoutePlan();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
RoutePlanAdapter adapter = (RoutePlanAdapter) listView.getAdapter();
MapRoutePlanFreament.routeLine = adapter.getItem(position);
MapRoutePlanFreament.lunch(getActivity(),null);
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return rootView;
}
/**
* 初始化线路规划
*/
private void initPlan() {
// 初始化搜索模块,注册事件监听
mSearch = RoutePlanSearch.newInstance();
mSearch.setOnGetRoutePlanResultListener(new OnGetRoutePlanResultListener() {
@Override
public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
if (walkingRouteResult == null || walkingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
loadFailAction();
}
if (walkingRouteResult.error == SearchResult.ERRORNO.NO_ERROR) {
loadSuccessAction();
WalkingRouteLine route = walkingRouteResult.getRouteLines().get(0);
String title = getRouteTitle(route.getAllStep());
route.setTitle(title.length()>0?title:"步行");
listView.setAdapter(new RoutePlanAdapter(getActivity(), Arrays.asList(route)));
}else {
loadFailAction();
}
}
@Override
public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
if (transitRouteResult == null || transitRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
loadFailAction();
}
//FIXME
if (transitRouteResult.error == SearchResult.ERRORNO.NO_ERROR) {
loadSuccessAction();
List routeLines = transitRouteResult.getRouteLines();
listView.setAdapter(new RoutePlanAdapter(getActivity(),addBusLinesTitle(routeLines)));
}else {
loadFailAction();
}
}
@Override
public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
if (drivingRouteResult == null || drivingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
loadFailAction();
}
if (drivingRouteResult.error == SearchResult.ERRORNO.NO_ERROR) {
loadSuccessAction();
DrivingRouteLine route = drivingRouteResult.getRouteLines().get(0);
String title = getRouteTitle(route.getAllStep());
route.setTitle(title.length()>0?title:"驾车");
listView.setAdapter(new RoutePlanAdapter(getActivity(), Arrays.asList(route)));
}else {
loadFailAction();
}
}
@Override
public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
}
});
}
/**
* 组织路线的名字,(格式:途径xxx和xxx),xxx取最近的两条路
* @param steps
* @param
* @return
*/
private String getRouteTitle(List steps){
if(steps == null || steps.size()==0)
return "";
String title = "";
Method method = null;
try {
method = steps.get(0).getClass().getDeclaredMethod("getInstructions");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
for(T step:steps){
try {
String ss = (String) method.invoke(step);
if(ss.contains("进入")){
if(title.contains("途径")){
title += (" 和 " + ss.substring(ss.indexOf("进入")+2).split(",")[0]);
break;
}else {
title += ("途径 " + ss.substring(ss.indexOf("进入")+2).split(",")[0]);
}
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return title;
}
/**
* 给公交路线添加名字
*/
private List addBusLinesTitle(List busLines){
for(int i=0 ; i steps = busLine.getAllStep();
String title = "";
for(int j=0 ; j 0){
title += ("→"+instructions.substring(2,instructions.indexOf(",经过")));
//下面被屏蔽的一行也可以使用
// title += ( "→"+instructions.split(",经过")[0].substring(2) );
}else {
// title = instructions.split(",经过")[0].substring(2);
title = instructions.substring(2,instructions.indexOf(",经过"));
}
}
}
busLine.setTitle(title);
}
return busLines;
}
private void searchRoutePlan(){
if(myLocation == null){
loadFailAction("获取不到当前位置!");
return;
}
if(mAddrInfo == null){
loadFailAction("找不到您要去的地址!");
return;
}
stNode = PlanNode.withLocation(new LatLng(myLocation.getLatitude(), myLocation.getLongitude()));
enNode = PlanNode.withLocation(new LatLng(mAddrInfo.getLatitude(), mAddrInfo.getLongitude()));
doingSearch();
}
private void doingSearch(){
loadingAction();
RoutePlanType type = (RoutePlanType) getArguments().getSerializable("routeType");
if(type == RoutePlanType.bus)
mSearch.transitSearch(new TransitRoutePlanOption().city(myLocation.getCity()).from(stNode).to(enNode));
else if(type == RoutePlanType.driving)
mSearch.drivingSearch(new DrivingRoutePlanOption().from(stNode).to(enNode));
else if(type == RoutePlanType.walking)
mSearch.walkingSearch(new WalkingRoutePlanOption().from(stNode).to(enNode));
}
/**
* 交换地点查询
*/
public void exchangeSearch(){
if(stNode == null || enNode == null)
return;
PlanNode node = stNode;
stNode = enNode;
enNode = node;
doingSearch();
}
private void loadingAction(){
listView.setVisibility(View.GONE);
rootView.findViewById(R.id.layoutLoading).setVisibility(View.VISIBLE);
rootView.findViewById(R.id.layoutLoadFailed).setVisibility(View.GONE);
}
private void loadFailAction(){
loadFailAction(null);
}
private void loadFailAction(String msg){
listView.setVisibility(View.GONE);
if(msg != null && msg.length()>0)
((TextView)rootView.findViewById(R.id.tv_fail_msg)).setText(msg);
rootView.findViewById(R.id.layoutLoading).setVisibility(View.GONE);
rootView.findViewById(R.id.layoutLoadFailed).setVisibility(View.VISIBLE);
}
private void loadSuccessAction(){
listView.setVisibility(View.VISIBLE);
rootView.findViewById(R.id.layoutLoading).setVisibility(View.GONE);
rootView.findViewById(R.id.layoutLoadFailed).setVisibility(View.GONE);
}
@Override
public void onDestroy() {
mSearch.destroy();
super.onDestroy();
}
}
/**
* 路线规划
* Created by HuangYuGuang on 2016/7/11.
*/
public class MapRoutePlanFreament extends MapBaseFragment {
public static RouteLine routeLine;
// private OverlayManager routeOverlay = null;
private ListView listView;
private ImageView ivUpDown;
protected List routeSteps;
public static void lunch(Activity from, T route){
Bundle bundle = new Bundle();
bundle.putParcelable("whereToGo",route);
FragmentContainerActivity.getInstance(false).launch(from,MapRoutePlanFreament.class,bundle);
}
@Override
protected int inflateContentView() {
return R.layout.hyg_ui_storemap1;
}
@Override
protected void layoutInit(LayoutInflater inflater, Bundle savedInstanceSate) {
super.layoutInit(inflater, savedInstanceSate);
// 清除路线
// if (routeOverlay != null) {
// routeOverlay.removeFromMap();
// }
}
@Override
protected void onMapLoadFinish() {
// Object o = getArguments().getParcelable("whereToGo");
/**
*RouteLine通过intent传过来会出现异常闪退,可能是RouteLine使用Parcelable序列化的原因(据说比Serializable性能高,内存开销小)。
*把RouteLine设为静态变量保存在内存就能用,但手机内存回收时会有问题。
*/
if(routeLine == null) return;
RouteLine o = routeLine;
if(o instanceof TransitRouteLine){
TransitRouteLine routeLine = (TransitRouteLine) o;
addTransitOverLay(routeLine);
routeSteps = getRouteSteps(routeLine.getAllStep());
}else if(o instanceof DrivingRouteLine){
DrivingRouteLine routeLine = (DrivingRouteLine) o;
addDrivingOverLay(routeLine);
routeSteps = getRouteSteps(routeLine.getAllStep());
}
else if(o instanceof WalkingRouteLine){
WalkingRouteLine routeLine = (WalkingRouteLine) o;
addWalkingOverLay(routeLine);
routeSteps = getRouteSteps(routeLine.getAllStep());
}
setTextView(R.id.tv_name,routeLine.getTitle());
setTextView(R.id.tv_time, RoutePlanAdapter.getRouteTimeStr(routeLine.getDuration()));
setTextView(R.id.tv_distance,RoutePlanAdapter.getDistanceStr(routeLine.getDistance()));
setOnClickListener(R.id.iv_back);
setOnClickListener(R.id.linearLayout);
ivUpDown = (ImageView) findViewById(R.id.iv_up_down);
listView = (ListView) findViewById(R.id.listView);
if(routeSteps != null && routeSteps.size()>0)
listView.setAdapter(new RouteStepAdapter());
}
private void addWalkingOverLay(WalkingRouteLine route){
WalkingRouteOverlay overlay = new WalkingRouteOverlay(mBaiduMap);
overlay.setData(route);
overlay.addToMap();
overlay.zoomToSpan();
}
private void addTransitOverLay(TransitRouteLine route){
TransitRouteOverlay overlay = new TransitRouteOverlay(mBaiduMap);
overlay.setData(route);
overlay.addToMap();
overlay.zoomToSpan();
}
private void addDrivingOverLay(DrivingRouteLine route){
DrivingRouteOverlay overlay = new DrivingRouteOverlay(mBaiduMap);
overlay.setData(route);
overlay.addToMap();
overlay.zoomToSpan();
}
/**
* 获取路线的详细步骤
* @param steps
* @param
* @return
*/
private List getRouteSteps(List steps){
if(steps == null || steps.size()==0)
return null;
Method method = null;
try {
method = steps.get(0).getClass().getDeclaredMethod("getInstructions");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
List stepStrs = new ArrayList<>();
for(T step:steps){
try {
stepStrs.add((String) method.invoke(step));
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return stepStrs;
}
@Override
public void onViewClicked(View view) {
super.onViewClicked(view);
int i = view.getId();
if (i == R.id.iv_back) {
getActivity().finish();
}else if(i == R.id.linearLayout){
if(listView.getVisibility() == View.VISIBLE){
listView.setVisibility(View.GONE);
ivUpDown.setImageResource(R.drawable.icon_map_up);
}else {
listView.setVisibility(View.VISIBLE);
ivUpDown.setImageResource(R.drawable.icon_map_dnow);
}
}
}
class RouteStepAdapter extends BaseAdapter{
@Override
public int getCount() {
return routeSteps.size();
}
@Override
public Object getItem(int position) {
return routeSteps.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null){
convertView = View.inflate(getActivity(),R.layout.hyg_item_route_step,null);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
viewHolder.tvStep = (TextView) convertView.findViewById(R.id.tv_step);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
String step = routeSteps.get(position);
viewHolder.tvStep.setText(step);
if(routeLine instanceof TransitRouteLine){
if(step.contains("步行") )
viewHolder.imageView.setImageResource(R.drawable.btu_pep2);
else
viewHolder.imageView.setImageResource(R.drawable.btu_bus2);
}else if(routeLine instanceof DrivingRouteLine){
viewHolder.imageView.setImageResource(R.drawable.btu_car2);
}else if(routeLine instanceof WalkingRouteLine){
viewHolder.imageView.setImageResource(R.drawable.btu_pep2);
}
return convertView;
}
}
class ViewHolder{
public ImageView imageView;
public TextView tvStep;
}
}