基于百度地图API的轨迹重现

原创
2014/04/29 23:53
阅读数 2.4K

前不久写android应用需要用到轨迹记录,网上找了好多,结合自己看的文档,把这些写出来,给更多人看到,虽然很简单,但还是挺有用的。

主要思路

    百度地图显示地图需要使用一个View来显示地图,地图上有一个图层用来显示轨迹,叫 com.baidu.mapapi.map.RouteOverlay在RouteOverlay上添加路径信息,然后绘制在图层上,再显示出来就好鸟~

  1. 使用百度api首先需要申请百度api的key

    这里申请下载百度的sdk  

  2.  然后就是代码啦

新建一个工程 就叫baduTraceDemo吧  工程配置

把下载的sdk文件里的jar和so库文件解压粗来,把百度定位需要的jar文件放在工程的libs文件夹下,然后在libs文件夹下新建一个文件夹叫 armeabi 把so文件放在这,就像这样


MainActivity里就放一个Button就好了,

MainActivity.java

public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}	
	public void OnClick(View v){
		switch(v.getId()){
		case R.id.startBtn :
			Intent intent = new Intent(MainActivity.this,LocationOverlay.class);
			startActivity(intent);
			break;
		default :
			break;
		}
	}
}

把BaiduMapsApiDemo里面的DemoApplication直接复制过来,把里面的key 改成我们自己申请的

再定义地图显示图层,

public class LocationOverlay extends Activity {

	/**
	 * 定位间隔  单位毫秒
	 */
	private int seconds = 1000 * 20;
	/**
	 *  经纬度数组
	 */
	private geoPointArray gpArray ;
	
	/**
	 *  定位开始点
	 */
	private GeoPoint start;
	
	/**
	 *  定位结束点
	 */
	private GeoPoint end;
	
	/**
	 *  定位点的集合 即路径
	 */
	private MKRoute mkRoute;
	
	/**
	 *  定位图层
	 */
	private RouteOverlay routeOverlay;
	// 定位相关
	LocationClient mLocClient;
	LocationData locData = null;
	public MyLocationListenner myListener = new MyLocationListenner();
	
	MapView mMapView = null;	// 地图View
	
	/**
	 *  地图控制器
	 */
	private MapController mMapController = null; 
	boolean isFirstLoc = true;//是否首次定位
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /**
         * 使用地图sdk前需先初始化BMapManager.
         * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,
         * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁
         */
        DemoApplication app = (DemoApplication)this.getApplication();
        if (app.mBMapManager == null) {
            app.mBMapManager = new BMapManager(getApplicationContext());
            /**
             * 如果BMapManager没有初始化则初始化BMapManager
             */
            app.mBMapManager.init(DemoApplication.strKey,new DemoApplication.MyGeneralListener());
        }
        setContentView(R.layout.activity_locationoverlay);
        CharSequence titleLable="记录轨迹";
        setTitle(titleLable);

        
		//地图初始化
        mMapView = (MapView)findViewById(R.id.bmapView);
        mMapController = mMapView.getController();
        mMapView.getController().setZoom(14);
        mMapView.getController().enableClick(true);
        mMapView.setBuiltInZoomControls(true);
        
        //定位初始化
        mLocClient = new LocationClient( this );
        locData = new LocationData();
        mLocClient.registerLocationListener( myListener );
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true);//打开gps
        option.setCoorType("bd09ll");     //设置坐标类型
        option.setScanSpan(seconds);	// 定位间隔时间  单位毫秒
        option.setIsNeedAddress(true); // 需要街道名称信息
        option.setNeedDeviceDirect(false); // 不需要方向信息
        mLocClient.setLocOption(option);
        mLocClient.start();
        
        mkRoute = new MKRoute();  
        routeOverlay = new RouteOverlay(LocationOverlay.this, mMapView);
       
        routeOverlay.setData(mkRoute);
	    //添加定位图层
		mMapView.getOverlays().add(routeOverlay);
	
		//修改定位数据后刷新图层生效
		mMapView.refresh();
		
    }
    /**
     * 修改位置图标
     * @param marker
     */
    public void modifyLocationOverlayIcon(Drawable marker){
    	//当传入marker为null时,使用默认图标绘制
    	routeOverlay.setEnMarker(marker);
    	//修改图层,需要刷新MapView生效
    	mMapView.refresh();
    }       
    /**
     * 定位SDK监听函数
     */
    public class MyLocationListenner implements BDLocationListener {    	
        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null)
                return ;   
            locData.latitude = location.getLatitude();
            locData.longitude = location.getLongitude();            
            //如果不显示定位精度圈,将accuracy赋值为0即可
            locData.accuracy = 0;
            // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
            locData.direction = location.getDerect();            
            // 是手动触发请求或首次定位时
            if (isFirstLoc){
            	gpArray = new geoPointArray();
            	start = new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6));
            	end = new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6));
            	// 把开始点放在路径中
            	gpArray.addGeoPoint(start);
            	// 构造路径
            	mkRoute.customizeRoute(start, end, gpArray.getGeoPointArray());
            	// 定位图层设置路径
            	routeOverlay.setData(mkRoute);
            	// 更新图层数据执行刷新后生效
            	mMapView.refresh();
            	// 移动地图到定位点
                mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)));
                isFirstLoc = false;
            }else{
            	Log.i("test:LocationOverlay","loc:"+location.getLatitude()+","+location.getLongitude()+","+location.getAddrStr());
            	end = new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6));
            	// 把当前点放在路径中
            	gpArray.addGeoPoint(end);
            	// 构造路径
            	mkRoute.customizeRoute(start, end, gpArray.getGeoPointArray());
            	// 定位图层设置路径
            	routeOverlay.setData(mkRoute); 
            	// 移动地图到定位点
            	mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)));
            	// 刷新图层
            	mMapView.refresh();

            }
        }
		@Override
		public void onReceivePoi(BDLocation arg0) {
			// TODO Auto-generated method stub
			
		}
    } 

    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }
    
    @Override
    protected void onResume() {
        mMapView.onResume();
        super.onResume();
    }
    
    @Override
    protected void onDestroy() {
    	//退出时销毁定位
        if (mLocClient != null)
            mLocClient.stop();
        mMapView.destroy();
        super.onDestroy();
    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
    	super.onSaveInstanceState(outState);
    	mMapView.onSaveInstanceState(outState);    	
    }
    
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
    	super.onRestoreInstanceState(savedInstanceState);
    	mMapView.onRestoreInstanceState(savedInstanceState);
    } 
}
/**
 *  经纬度数组类
 */
class geoPointArray{
	
	private ArrayList <GeoPoint> mlist;
	geoPointArray(){
		mlist = new ArrayList<GeoPoint>();
	}
	
	public void addGeoPoint(GeoPoint point){
		mlist.add(point);
	}
	
	/**
	 * @return 返回包含经纬度点的一纬数组
	 */
	public GeoPoint[] getGeoPointArray(){
		GeoPoint []gp = new GeoPoint[mlist.size()];
		for(int i=0; i<mlist.size(); i++){
			gp[i] = mlist.get(i);
		}
		return  gp;
	}
}

地图图层的路径信息参数是 com.baidu.mapapi.search.MKRoute,而MKRoute里面还要构造一系列的点来组成路径customizeRoute(GeoPoint st, GeoPoint en, GeoPoint[] passby)   我们就自己写一个类来构造GeoPoint[] passby ,就是上面的geoPointArray,卧槽我研究这个研究了好久的说,当然还要重写监听器 MyLocationListenner,在这个监听器里面没定一次位就把得到的经纬度点添加我geoPointArray里面,

gpArray.addGeoPoint(currentPoint);

重新构造一次路径,再把路径添加到图层上

mkRoute.customizeRoute(start, end, gpArray.getGeoPointArray());

routeOverlay.setData(mkRoute);

最后是ManiFest.xml的填写,把百度需要的权限啊,服务啊,还有key添加上 

添加百度的各种权限 ,百度真流氓,给的demo里面还要打电话的权限,这里用不到,就去掉了

   <!--使用网络功能所需权限  -->  
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">  
	</uses-permission>  
	<uses-permission android:name="android.permission.INTERNET">  
	</uses-permission>  
	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE">  
	</uses-permission>  
	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE">  
	</uses-permission>  
	<!-- SDK离线地图和cache功能需要读写外部存储器 -->  
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">  
	</uses-permission>  
	<uses-permission android:name="android.permission.WRITE_SETTINGS">  
	</uses-permission>  
	<!-- 使用定位功能所需权限,demo已集成百度定位SDK,不使用定位功能可去掉以下6项 -->  
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">  
	</uses-permission>  
	<permission android:name="android.permission.BAIDU_LOCATION_SERVICE">  
	</permission>  
	<uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE">  
	</uses-permission>  
	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">  
	</uses-permission>  
	<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION">  
	</uses-permission>

在<application>里面添加这两行,服务权限,和key,自己用的话,记得把里面的key值换掉哦

<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="yRLtRhhaGdHuuLXeulWCtjSu"/>
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" />

3. 差不多完成了,可以编译试试了

当然这里写的太简略了,一会把工程放下面,完成之后出去转一圈试试

4.终于写完鸟

  卧槽,终于写完鸟,第一次写博客,感觉写博客好难,比写代码麻烦,不知道从哪里开始写,有东西讲不粗来的感觉,看来要好好练练了(OSC肿么没有预览),以后多写博客^_^

代码,还没用osc的git,就先用网盘吧 baiduTraceDemo.zip

展开阅读全文
加载中
点击加入讨论🔥(6) 发布并加入讨论🔥
打赏
6 评论
5 收藏
1
分享
返回顶部
顶部