Android使用百度地圖API實現GPS步行軌跡

百度地圖Android SDK下載:http://developer.baidu.com/map/sdkandev-download.htmjava

下面是效果:git

QQ截圖20121129135007

採樣點取得太頻繁因此看起來像是一個個點。。。   能夠本身設計算法只取有用的點。算法

 

爲了方便,我直接修改百度提供的示例代碼。網絡

QQ截圖20121129135408

要修改的是BMapApiDemoApp.java,LocationOverlay.java還有自定義一個繼承自Overlay的RunLineOverlay。app

 

 

BMapApiDemoApp:ide

public class BMapApiDemoApp extends Application {
    
    static BMapApiDemoApp mDemoApp;
    
    //百度MapAPI的管理類
    BMapManager mBMapMan = null;
    
    // 受權Key
    // TODO: 請輸入您的Key,
    // 申請地址:http://dev.baidu.com/wiki/static/imap/key/
    String mStrKey = "你的Key";
    boolean m_bKeyRight = true;    // 受權Key正確,驗證經過
    
    // 經常使用事件監聽,用來處理一般的網絡錯誤,受權驗證錯誤等
    static class MyGeneralListener implements MKGeneralListener {
        @Override
        public void onGetNetworkState(int iError) {
            Log.d("MyGeneralListener", "onGetNetworkState error is "+ iError);
            Toast.makeText(BMapApiDemoApp.mDemoApp.getApplicationContext(), "您的網絡出錯啦!",
                    Toast.LENGTH_LONG).show();
        }

        @Override
        public void onGetPermissionState(int iError) {
            Log.d("MyGeneralListener", "onGetPermissionState error is "+ iError);
            if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) {
                // 受權Key錯誤:
                Toast.makeText(BMapApiDemoApp.mDemoApp.getApplicationContext(), 
                        "請在BMapApiDemoApp.java文件輸入正確的受權Key!",
                        Toast.LENGTH_LONG).show();
                BMapApiDemoApp.mDemoApp.m_bKeyRight = false;
            }
        }
    }

    @Override
    public void onCreate() {
        Log.v("BMapApiDemoApp", "onCreate");
        mDemoApp = this;
        mBMapMan = new BMapManager(this);
        boolean isSuccess = mBMapMan.init(this.mStrKey, new MyGeneralListener());
        // 初始化地圖sdk成功,設置定位監聽時間
        if (isSuccess) {
             mBMapMan.getLocationManager().enableProvider(MKLocationManager.MK_GPS_PROVIDER);
            mBMapMan.getLocationManager().setNotifyInternal(10, 5);
        }
        else {
            // 地圖sdk初始化失敗,不能使用sdk
        }
        
        super.onCreate();
    }

    @Override
    //建議在您app的退出以前調用mapadpi的destroy()函數,避免重複初始化帶來的時間消耗
    public void onTerminate() {
        // TODO Auto-generated method stub
        if (mBMapMan != null) {
            mBMapMan.destroy();
            mBMapMan = null;
        }
        super.onTerminate();
    }

}

mStrKey的值是你申請來的Key,申請地址上面有。函數

onCreate里加了句mBMapMan.getLocationManager().enableProvider(MKLocationManager.MK_GPS_PROVIDER);用來打開GPS位置。動畫

 

 

RunLineOverlay:ui

public class RunLineOverlay extends Overlay {
    
    private List<GeoPoint> mList;
    
    public RunLineOverlay() {
        // TODO Auto-generated constructor stub
        super();
        mList=new ArrayList<GeoPoint>();
    }
    
    @Override
    public void draw(Canvas arg0, MapView arg1, boolean arg2) {
        // TODO Auto-generated method stub
        super.draw(arg0, arg1, arg2);
        Projection projection = arg1.getProjection();        
        Paint paint=new Paint();
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5.0f);
        
        
        Point p1=projection.toPixels(mList.get(0), null);
        Point p2=projection.toPixels(mList.get(0), null);
        for (GeoPoint item : mList) {
            p1.x=p2.x;
            p1.y=p2.y;
            p2=projection.toPixels(item, null);
            arg0.drawLine(p1.x, p1.y, p2.x, p2.y, paint);
        }
        
        
        
    }

    public List<GeoPoint> getmList() {
        return mList;
    }

    public void setmList(List<GeoPoint> mList) {
        this.mList = mList;
    }
    
    public void addGeoPoint(GeoPoint point){
        
            mList.add(point);
    }

}

這是一個自定義的用於在底圖上根據點畫出軌跡的覆蓋物。Projection用於經緯度和屏幕像素點的轉換。大概功能就是取出經緯度點而後轉成屏幕像素點而後連成軌跡。this

 

 

LocationOverlay:

public class LocationOverlay extends MapActivity {

    MapView mMapView = null;
    LocationListener mLocationListener = null;//onResume時註冊此listener,onPause時須要Remove
    MyLocationOverlay mLocationOverlay = null;    //定位圖層
    RunLineOverlay mRunLine=null;
    
    protected void onCreate(Bundle savedInstanceState) {
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mapviewdemo);
        
        BMapApiDemoApp app = (BMapApiDemoApp)this.getApplication();
        if (app.mBMapMan == null) {
            app.mBMapMan = new BMapManager(getApplication());
            app.mBMapMan.init(app.mStrKey, new BMapApiDemoApp.MyGeneralListener());
        }
        app.mBMapMan.start();
        // 若是使用地圖SDK,請初始化地圖Activity
        super.initMapActivity(app.mBMapMan);
        
        mMapView = (MapView)findViewById(R.id.bmapView);
        mMapView.setBuiltInZoomControls(true);
        //設置在縮放動畫過程當中也顯示overlay,默認爲不繪製
        mMapView.setDrawOverlayWhenZooming(true);
        
        // 添加定位圖層
        mLocationOverlay = new MyLocationOverlay(this, mMapView);
        mMapView.getOverlays().add(mLocationOverlay);
        
        // 註冊定位事件
        mLocationListener = new LocationListener(){

            @Override
            public void onLocationChanged(Location location) {
                if (location != null){
                    GeoPoint pt = new GeoPoint((int)(location.getLatitude()*1e6),
                            (int)(location.getLongitude()*1e6));
                    if(mRunLine==null)
                    {mRunLine=new RunLineOverlay();
                    mRunLine.addGeoPoint(pt);
                    mMapView.getOverlays().add(mRunLine);}else
                        mRunLine.addGeoPoint(pt);
                    mMapView.getController().animateTo(pt);
                }
            }
        };
    }

    @Override
    protected void onPause() {
        BMapApiDemoApp app = (BMapApiDemoApp)this.getApplication();
        app.mBMapMan.getLocationManager().removeUpdates(mLocationListener);
        mLocationOverlay.disableMyLocation();
        mLocationOverlay.disableCompass(); // 關閉指南針
        app.mBMapMan.stop();
        super.onPause();
    }
    @Override
    protected void onResume() {
        BMapApiDemoApp app = (BMapApiDemoApp)this.getApplication();
        // 註冊定位事件,定位後將地圖移動到定位點
        app.mBMapMan.getLocationManager().requestLocationUpdates(mLocationListener);
        mLocationOverlay.enableMyLocation();
        mLocationOverlay.enableCompass(); // 打開指南針
        app.mBMapMan.start();
        super.onResume();
    }

    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

}

主要修改的代碼是

public void onLocationChanged(Location location) {
                if (location != null){
                    GeoPoint pt = new GeoPoint((int)(location.getLatitude()*1e6),
                            (int)(location.getLongitude()*1e6));
                    if(mRunLine==null)
                    {mRunLine=new RunLineOverlay();
                    mRunLine.addGeoPoint(pt);
                    mMapView.getOverlays().add(mRunLine);}else
                        mRunLine.addGeoPoint(pt);
                    mMapView.getController().animateTo(pt);
                }

 

當位置改變是這個方法會被調用。功能就是把新位置放入mRunLine。固然第一次要mMapView.getOverlays().add(mRunLine);把mRunLine放進mMapView的覆蓋物列表,這樣當mMapView被重繪時mRunLine的draw方法就會被調用。

 

改好後運行程序,列表點擊Overlaytest,而後出去轉一圈。

QQ截圖20121129135007

相關文章
相關標籤/搜索