Android百度地图——BaiduMapView(MapView+定位+覆盖物+路线搜索)

根据我对地图的开发经验,MapView+定位+覆盖物+路线搜索,这四个模块基本上已经可以满足开发需求了。百度地图官网下载的BaiduMapsApiDemo使用发杂,移植性又不好。我对这四个模块功能做了一个总的封装,使用起来更加简便。

使用如下:
1、初始化地图
在XML布局中只需要调用


在activity中

BaiduMapView baiduMapView = (BaiduMapView) findViewById(R.id.baidumapview); 

2、定位。定位已经是完全独立的模块了,具体实现参考《Android百度地图——定位》

//定位
        BaiduLocation.getLocation(context);
        BaiduLocation.setMyLocationListener(new BaiduLocation.MyLocationListener(){
            @Override
            public void myLocatin(double mylongitude, double mylatitude, String city, String street) {
                // TODO Auto-generated method stub
                baiduMapView.setCenter(new LatLng(mylatitude,mylongitude) );
            } 
        });

3、覆盖物
添加覆盖物只需一行代码,设置参数view,经纬度,覆盖物的title(用于标识)

baiduMapView.addOverlay(View.inflate(getApplicationContext(), R.layout.view_baidumap, null)
                , new LatLng(BaiduLocation.mylatitude, BaiduLocation.mylongitude), "title");

覆盖物点击事件

baiduMapView.setOnMarkerClickListener(new OnMyMarkerClickListener() {
            @Override
            public void onMarkerClick(Marker arg0) {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), ""+arg0.getTitle(), 0).show();
            }
        });

4、路线搜索。搜索结果会自动在地图上加载

ArrayList pass=new ArrayList();
        pass.add(new LatLng( 23.102603,113.304713));
        baiduMapView.SearchProcess(new LatLng( 23.159499,113.261269)
                , new LatLng(23.15312,113.328859 )
                , pass
                , BaiduSearch.DrivingRoute);

说那么多来看一下效果图


Android百度地图——BaiduMapView(MapView+定位+覆盖物+路线搜索)_第1张图片
Paste_Image.png

下面附上各文件的源代码

Android百度地图——BaiduMapView(MapView+定位+覆盖物+路线搜索)_第2张图片
Paste_Image.png

除了上面几个类,还必须要如下文件,这些都是BaiduMapsApiDemo中的原文件,不需要修改直接copy。

Android百度地图——BaiduMapView(MapView+定位+覆盖物+路线搜索)_第3张图片
Paste_Image.png

再强调使用百度地图需要配置好的几点:
1、权限

 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

2、定位需要的服务


        

3、API_KEY,去百度地图API官网申请该应用的key


4、activity中初始化百度地图,在setContentView前面加入SDKInitializer.initialize(getApplicationContext());

super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_baidumap_test);

5、在测试的时候需要通过Export导出项目app安装包,把程序安装到手机上测试,不能直接通过开发工具debug程序到手机中测试。原因是因为申请的API_KEY是由程序的包名和keystore通过sha1加密生成的,程序必须Export导出项目通过keystone签名加密才能匹配到API_KEY。

BaiduLocation.java:

package baidumap;

import android.content.Context;
import android.util.Log;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
public class BaiduLocation {
    /**经度*/
    public static double mylongitude = -1.0;
    /**纬度*/
    public static double mylatitude = -1.0;
    /**城市*/
    public static String myCity = null;
    /**街道*/
    public static String myCityadd = null;
    /**
     * 回调经纬度方法
     * @param myLocationListener
     */
    public static void setMyLocationListener(MyLocationListener myLocationListener) {
        BaiduLocation.myLocationListener = myLocationListener;
    }
    public static MyLocationListener myLocationListener;
    /**
     * 回调经纬度的接口定义
     * @author Administrator
     */
    public static interface MyLocationListener {
        public void myLocatin(double mylongitude, double mylatitude, String city, String street);
    };

    /**
     * 获取当前经纬度
     * @param activity
     */
    public static void getLocation(Context context) {
        final LocationClient locationClient = new LocationClient(context);
        // 设置定位条件
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 是否打开GPS
        option.setCoorType("bd09ll"); // 设置返回值的坐标类型。
        option.setPriority(LocationClientOption.NetWorkFirst); // 设置定位优先级
        option.setProdName("zhongchengbus"); // 设置产品线名称。强烈建议您使用自定义的产品线名称,方便我们以后为您提供更高效准确的定位服务。
        option.setScanSpan(5000); // 设置定时定位的时间间隔。单位毫秒
        option.setAddrType("all");// 显示所有信息,街道
        locationClient.setLocOption(option);
        // 注册位置监听器
        locationClient.registerLocationListener(new BDLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation location) {
                // TODO Auto-generated method stub
                if (location == null) {
                    return;
                }
                Log.d("baidulocation", "baidulocation1");
                // sb.append("Time : ");
                // sb.append(location.getTime());
                // sb.append("\nError code : ");
                // sb.append(location.getLocType());
                // sb.append("\nLatitude : ");
                // sb.append(location.getLatitude());
                // sb.append("\nLontitude : ");
                // sb.append(location.getLongitude());
                // sb.append("\nRadius : ");
                // sb.append(location.getRadius());
                // if (location.getLocType() == BDLocation.TypeGpsLocation){
                // sb.append("\nSpeed : ");
                // sb.append(location.getSpeed());
                // sb.append("\nSatellite : ");
                // sb.append(location.getSatelliteNumber());
                // } else
                if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
                    // sb.append("\nAddress : ");
                    // sb.append(location.getAddrStr());
                    String district = location.getAddress().district;
                    myCityadd = location.getAddrStr();
                    myCity = location.getCity();
                    mylongitude = location.getLongitude();
                    mylatitude = location.getLatitude();
                    Log.d("baidulocation", mylongitude+"\n"+mylatitude+"\n"+ myCity+"\n"+district);
                    // 经纬度
                    if (myLocationListener != null) {
                        myLocationListener.myLocatin(mylongitude, mylatitude, myCity, district);
                        locationClient.stop();
                    }
                }
            }

        });
        locationClient.start();
        /*
         * 当所设的整数值大于等于1000(ms)时,定位SDK内部使用定时定位模式。调用requestLocation(
         * )后,每隔设定的时间,定位SDK就会进行一次定位。如果定位SDK根据定位依据发现位置没有发生变化,就不会发起网络请求,
         * 返回上一次定位的结果;如果发现位置改变,就进行网络请求进行定位,得到新的定位结果。
         * 定时定位时,调用一次requestLocation,会定时监听到定位结果。
         */
        locationClient.requestLocation();
        Log.d("baidulocation", "baidulocation");
    }
}

BaiduMapView.java

package baidumap;

import java.util.ArrayList;
import java.util.HashMap;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.MarkerOptions.MarkerAnimateType;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.overlayutil.DrivingRouteOverlay;
import com.baidu.mapapi.overlayutil.TransitRouteOverlay;
import com.baidu.mapapi.overlayutil.WalkingRouteOverlay;
import com.baidu.mapapi.search.route.BikingRouteResult;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRouteResult;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import baidumap.BaiduSearch.OnMyGetRoutePlanResultListener;

public class BaiduMapView extends LinearLayout implements BaiduMap.OnMapClickListener{
    private Context context;

    //地图相关,使用继承MapView的MyRouteMapView目的是重写touch事件实现泡泡处理
    //如果不处理touch事件,则无需继承,直接使用MapView即可
    /**地图View */
    private  MapView mMapView = null; 
    private BaiduMap mBaidumap = null;
    
    //覆盖物相关
    private HashMap markers=new HashMap();//保存覆盖物
    /** 覆盖物点击接口  */
    public interface OnMyMarkerClickListener{
        public void onMarkerClick(Marker arg0);
    }
    private OnMyMarkerClickListener listener=null;
    public void setOnMarkerClickListener(OnMyMarkerClickListener listener){
        this.listener=listener;
    }
    
    public BaiduMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        this.context=context;
        initBaiduMap();
    }
    
    /**初始化百度地图
     * 
     */
    private void initBaiduMap(){
        Log.v("BaiduMapView", "initBaiduMap");
        //初始化地图
        mMapView =new MapView(context);
        mMapView.showZoomControls(false);//缩放按钮
    
        mBaidumap = mMapView.getMap();
        //地图点击事件处理
        mBaidumap.setOnMapClickListener(this);
        
//        mBaidumap.setOnMapLoadedCallback(new OnMapLoadedCallback() {
//          
//          @Override
//          public void onMapLoaded() {
//              // TODO Auto-generated method stub
//              ToastUtils.showTextToast(SelectStationActivity.this, "地图加载完成");
//              
//              //SearchButtonProcess();
//          }
//      });
        
        //定位
        BaiduLocation.getLocation(context);
        BaiduLocation.setMyLocationListener(new BaiduLocation.MyLocationListener(){
            @Override
            public void myLocatin(double mylongitude, double mylatitude, String city, String street) {
                // TODO Auto-generated method stub
                setCenter(new LatLng(mylatitude,mylongitude) );
            } 
        });
        
        addView(mMapView);
    }
    
    /**设置中心点
     * @param latLng
     */
    public void setCenter(LatLng latLng){
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
        mBaidumap.animateMapStatus(u);
    }

    @Override
    public void onMapClick(LatLng arg0) {
        // TODO Auto-generated method stub
        mBaidumap.hideInfoWindow();
    }

    @Override
    public boolean onMapPoiClick(MapPoi arg0) {
        // TODO Auto-generated method stub
        return false;
    }
    
    /**添加覆盖物
     * @param view 
     * @param ll 经纬度坐标
     * @param title 覆盖物title,用于标识
     */
    public void addOverlay(View view,LatLng ll,String title) {
        // add marker overlay
        BitmapDescriptor bdC = BitmapDescriptorFactory.fromView(view);
        MarkerOptions ooC = new MarkerOptions().title(title).position(ll).icon(bdC).perspective(false).anchor(0.5f, 1f);
        ooC.animateType(MarkerAnimateType.grow);//生长动画
        markers.put(title,(Marker)(mBaidumap.addOverlay(ooC)));//此处可以强转成Marker,控制覆盖物移动
        
        mBaidumap.setOnMarkerClickListener(new OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker arg0) {
                // TODO Auto-generated method stub
                if (listener!=null) {
                    listener.onMarkerClick(arg0);
                }
                return true;
            }
        });
    }
    /**设置覆盖物位置
     * @param ll 经纬度坐标
     */
    public void setOverlayLatLng(String title,LatLng ll){
        if (markers!=null) {
            Marker marker = markers.get(title);
            if (marker!=null) {
                marker.setPosition(ll);
            }
        }
    }
    
    /**发起路线规划搜索示例
     * @param start 起点
     * @param end 终点
     * @param passBy 途经点,仅在drivingSearch有效
     * @param state 选择搜索方式
     */
    public void SearchProcess(LatLng start,LatLng end,ArrayList passBy,int state) {
        BaiduSearch search = new BaiduSearch(context);
        search.setOnMyGetRoutePlanResultListener(new OnMyGetRoutePlanResultListener() {
            @Override
            public void onGetWalkingRouteResult(WalkingRouteResult arg0) {
                // TODO Auto-generated method stub
                WalkingRouteOverlay overlay = new WalkingRouteOverlay(mBaidumap);
//              mBaidumap.setOnMarkerClickListener(overlay);
                overlay.setData(arg0.getRouteLines().get(0));
                overlay.addToMap();
                overlay.zoomToSpan();
            }
            @Override
            public void onGetTransitRouteResult(TransitRouteResult arg0) {
                // TODO Auto-generated method stub
                TransitRouteOverlay overlay = new TransitRouteOverlay(mBaidumap);
//              mBaidumap.setOnMarkerClickListener(overlay);
                overlay.setData(arg0.getRouteLines().get(0));
                overlay.addToMap();
                overlay.zoomToSpan();
            }
            @Override
            public void onGetDrivingRouteResult(DrivingRouteResult arg0) {
                // TODO Auto-generated method stub
                DrivingRouteOverlay overlay = new MyDrivingRouteOverlay(mBaidumap);
//              mBaidumap.setOnMarkerClickListener(overlay);
                overlay.setData(arg0.getRouteLines().get(0));
                overlay.addToMap();
                overlay.zoomToSpan();
            }
            @Override
            public void onGetBikingRouteResult(BikingRouteResult arg0) {
                // TODO Auto-generated method stub
                
            }
        });
        search.SearchProcess(start, end, passBy, state);
    }
    
    /**
     * 设置底图显示模式
     *
     * @param state 0:普通图 1:卫星图
     */
    public void setMapMode(int state) {
        switch (state) {
            case 0:
                    mBaidumap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
                break;
            case 1:
                    mBaidumap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
                break;
            default:
                break;
        }
    }

    /**
     * 设置是否显示交通图
     * 
     * @param isTraffic
     */
    public void setTraffic(boolean isTraffic) {
        mBaidumap.setTrafficEnabled(isTraffic);
    }

    /**
     * 设置是否显示百度热力图
     * 
     * @param isHeatMap
     */
    public void setBaiduHeatMap(boolean isHeatMap) {
        mBaidumap.setBaiduHeatMapEnabled(isHeatMap);
    }
}

BaiduSearch.java

package baidumap;

import java.util.ArrayList;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.route.BikingRoutePlanOption;
import com.baidu.mapapi.search.route.BikingRouteResult;
import com.baidu.mapapi.search.route.DrivingRoutePlanOption;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRoutePlanOption;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRoutePlanOption;
import com.baidu.mapapi.search.route.WalkingRouteResult;
import android.content.Context;
import android.widget.Toast;

/**
 * @author 王家宇
 *
 */
public class BaiduSearch implements OnGetRoutePlanResultListener{
    private Context context;
    private RoutePlanSearch mSearch = null;    // 搜索模块,也可去掉地图模块独立使用
    
    /** 路径规划接口  */
    public interface OnMyGetRoutePlanResultListener{
        public void onGetBikingRouteResult(BikingRouteResult arg0);
        public void onGetDrivingRouteResult(DrivingRouteResult arg0);
        public void onGetTransitRouteResult(TransitRouteResult arg0) ;
        public void onGetWalkingRouteResult(WalkingRouteResult arg0);
    }
    private OnMyGetRoutePlanResultListener listener=null;
    public void setOnMyGetRoutePlanResultListener(OnMyGetRoutePlanResultListener listener){
        this.listener=listener;
    }
    
    /** 自行车 */
    public static final int BikingRoute=0;
    /** 驾车 */
    public static final int DrivingRoute=1;
    /** 公交 */
    public static final int TransitRoute=2;
    /** 步行 */
    public static final int WalkingRoute=3;
    
    public BaiduSearch(Context context){
        this.context=context;
        // 初始化搜索模块,注册事件监听
        mSearch = RoutePlanSearch.newInstance();
        mSearch.setOnGetRoutePlanResultListener(this);
    }
    /**发起路线规划搜索示例
     * @param start 起点
     * @param end 终点
     * @param passBy 途经点,仅在drivingSearch有效
     * @param state 选择搜索方式
     */
    public void SearchProcess(LatLng start,LatLng end,ArrayList passBy,int state) {
        ArrayList arg0 =new ArrayList();
        //设置起终点信息,对于tranistsearch 来说,城市名无意义
        PlanNode stNode = PlanNode.withLocation(start);
        PlanNode enNode = PlanNode.withLocation(end);
        if (passBy!=null) {
            for (int i = 0; i < passBy.size(); i++) {
                PlanNode node = PlanNode.withLocation(passBy.get(i));
                arg0.add(node);
            }
        }
        // 实际使用中请对起点终点城市进行正确的设定
        switch (state) {
        case BikingRoute:
            mSearch.bikingSearch((new BikingRoutePlanOption())
                    .from(stNode)
                    .to(enNode));
            break;
        case DrivingRoute:
            mSearch.drivingSearch((new DrivingRoutePlanOption())
                       .from(stNode)
                       .passBy(arg0)
                       .to(enNode));
            break;
        case TransitRoute:
            mSearch.transitSearch((new TransitRoutePlanOption())
                    .from(stNode)
                     .to(enNode));
            break;
        case WalkingRoute:
            mSearch.walkingSearch((new WalkingRoutePlanOption())
                    .from(stNode)
                    .to(enNode));
            break;
        default:
            break;
        }
    }
    @Override
    public void onGetDrivingRouteResult(DrivingRouteResult result) {
        // TODO Auto-generated method stub
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
        }
        if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
            //起终点或途经点地址有岐义,通过以下接口获取建议查询信息
            //result.getSuggestAddrInfo()
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
            return;
        }
        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            if (listener!=null) {
                listener.onGetDrivingRouteResult(result);
            }
        }
    }

    @Override
    public void onGetBikingRouteResult(BikingRouteResult result) {
        // TODO Auto-generated method stub
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
        }
        if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
            //起终点或途经点地址有岐义,通过以下接口获取建议查询信息
            //result.getSuggestAddrInfo()
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
            return;
        }
        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            if (listener!=null) {
                listener.onGetBikingRouteResult(result);
            }
        }
    }

    @Override
    public void onGetTransitRouteResult(TransitRouteResult result) {
        // TODO Auto-generated method stub
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
        }
        if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
            //起终点或途经点地址有岐义,通过以下接口获取建议查询信息
            //result.getSuggestAddrInfo()
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
            return;
        }
        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            if (listener!=null) {
                listener.onGetTransitRouteResult(result);
            }
        }
    }

    @Override
    public void onGetWalkingRouteResult(WalkingRouteResult result) {
        // TODO Auto-generated method stub
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
        }
        if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
            //起终点或途经点地址有岐义,通过以下接口获取建议查询信息
            //result.getSuggestAddrInfo()
            Toast.makeText(context, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
            return;
        }
        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            if (listener!=null) {
                listener.onGetWalkingRouteResult(result);
            }
        }
    }
    
}

MyDrivingRouteOverlay.java

package baidumap;

import java.util.ArrayList;
import java.util.List;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.overlayutil.DrivingRouteOverlay;
import android.view.View;

public class MyDrivingRouteOverlay extends DrivingRouteOverlay {
    private boolean useDefaultIcon = false;//自定义图标
    private View startView;
    private View endView;
    private ArrayList passView;
    
    public MyDrivingRouteOverlay(BaiduMap baiduMap) {
        super(baiduMap);
    }
    
    public MyDrivingRouteOverlay(BaiduMap baiduMap,View startView,View endView,ArrayList passView) {
        super(baiduMap);
        useDefaultIcon = true;
        this.startView=startView;
        this.endView=endView;
        this.passView=passView;
    }

    @Override
    public BitmapDescriptor getStartMarker() {
        if (useDefaultIcon) {
            if (startView==null) {
                return null;
            }
            BitmapDescriptor bd = BitmapDescriptorFactory.fromView(startView);
            return bd;
        }
        return null;
    }
    
    @Override
    public List getCustomTextureList() {
        // TODO Auto-generated method stub
        if (useDefaultIcon) {
            if (passView==null) {
                return null;
            }
            ArrayList list = new ArrayList();
            for (int i = 0; i < passView.size(); i++) {
                list.add(BitmapDescriptorFactory.fromView(passView.get(i)));
            }
            return list;
        }
        return null;
    }
    
    @Override
    public int getLineColor() {
        // TODO Auto-generated method stub
        //覆写此方法以改变默认绘制颜色
        //Returns:
        //线颜色
        return super.getLineColor();
    }
    @Override
    public BitmapDescriptor getTerminalMarker() {
        if (useDefaultIcon) {
            if (endView==null) {
                return null;
            }
            BitmapDescriptor bd = BitmapDescriptorFactory.fromView(endView);
            return bd;
        }
        return null;
    }
    
    @Override
    public boolean onRouteNodeClick(int i) {
        // TODO Auto-generated method stub
        System.out.println(""+i);
        return true;
    }
}

你可能感兴趣的:(Android百度地图——BaiduMapView(MapView+定位+覆盖物+路线搜索))