mapabc地图开发之定位篇(GPS+谷歌基站定位+高德基站定位)

android地图应用的开发,相信大家在网上都看过不少例子

不过基本上都是基于google地图的,有一点不好的是基于google地图开发的应用

不是每部手机都能够装的上去,要求设备系统本身支持google地图库才行

而如果采用高德公司的mapabc地图则摆脱了这种限制

下面本人就以基于mapabc的地图应用来阐述如何在地图上显示自身位置

为了让广大开发者方便将原有的google地图应用移植到mapabc上来

高德公司开发了与google map API相同的类与方法,基本上只要改变导入的包即可完成移植

稍后我会将mapabcAPI相关文档同工程一并上传

废话不多说,先上几张效果图:

mapabc地图开发之定位篇(GPS+谷歌基站定位+高德基站定位)_第1张图片

mapabc地图开发之定位篇(GPS+谷歌基站定位+高德基站定位)_第2张图片

mapabc地图开发之定位篇(GPS+谷歌基站定位+高德基站定位)_第3张图片

 

本例主要是获取自身经纬度,纠偏后在地图上显示图标

同时通过相应接口获取地理位置信息,点击位置图标弹出气泡显示地理位置信息

在获取自身经纬度有多种方式,android API里提供的LocationManager就可以通过GPS 或 网络 获取位置

不过使用该类的前提是设备上相关的设置选项要打开,否则是监听不到位置信息的

除此之外我们还可以获取基站信息然后通过google提供的基站定位接口来获取到经纬度

同时使用mapabc的话还可直接通过其提供的LocationManagerProxy类来监听获取位置

值得注意的是此时得到的位置已经是纠偏后的位置了

本例分别以以上三种定位方式获取位置然后在地图上显示

同时可通过菜单来比对基站定位与实际GPS定位的误差(在室外打开GPS选项来测试)

本人亲测google基站定位要比高德基站定位准一些,一般误差在一两百米以内

google到底是老大,不过纠偏的话当然还是高德准啦,自家的地图自家的算法

下面贴上部分源码稍作分析

且看主ACTIVITY有以下成员变量

public class TestMapABCDemoActivity extends MapActivity{

    /** Called when the activity is first created. */

    private final static String TAG = "TestMapABCDemoActivity";

    

    private MapView mMapView;                                   //地图VIEW

    private MapController mMapController;                       //控制器

    private List<Overlay> mOverlayList;                           //地图图层容器

    private View mPopView;                                      //地图气泡

    private MyLocationManager mLocationManager;                     // LocationManager API获取位置

    private MyLocationListen mListen;                       

    private MyPositionOverlay mGoogleOverlay;

    

    

    private MyStationLocationManager mStationLocationManager;       //google基站接口获取位置

    private MyStationLocationListen mStationLocationListen;

    private MyPositionOverlay mStationOverlay;

    

    

    

    private MyGaodeLocationManager mGaodeLocationManager;           //高德基站接口获取位置

    private MyGaodeListen mGaodeLocationListen;

    private MyPositionOverlay mGaoDeOverlay;

    

    private Handler mHandler;


初始化调以下两个方法

 

    public void initView()

    {

        mMapView = (MapView) findViewById(R.id.main_mapView);

        mMapView.setBuiltInZoomControls(true);              // 设置启用内置的缩放控件

        mMapController = mMapView.getController();          // 得到mMapView的控制权,可以用它控制和驱动平移和缩放

        mOverlayList = mMapView.getOverlays();              // 得到图层容器

        

    

        // 设置气泡位置

        mPopView = getLayoutInflater().inflate(R.layout.map_popup, null);

        mMapView.addView(mPopView,new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, 

                                                            MapView.LayoutParams.WRAP_CONTENT,

                                                            null,

                                                            MapView.LayoutParams.BOTTOM_CENTER));  

        mPopView.setVisibility(View.GONE);

        

        

        // android API定位自身位置图标

        mGoogleOverlay = new MyPositionOverlay(this, getResources().getDrawable(R.drawable.marker_google), mPopView, mMapView); 

        mGoogleOverlay.setColor(Color.argb(50, 0, 119, 192));

        mOverlayList.add(mGoogleOverlay);

        

        // google基站定位自身位置图标

        mStationOverlay = new MyPositionOverlay(this, getResources().getDrawable(R.drawable.marker_station) , mPopView, mMapView);  

        mStationOverlay.setColor(Color.argb(50, 255, 100, 55));

        mOverlayList.add(mStationOverlay);

        

        // 高德基站定位自身位置图标

        mGaoDeOverlay = new MyPositionOverlay(this, getResources().getDrawable(R.drawable.marker_gaode),  mPopView, mMapView);  

        mGaoDeOverlay.setColor(Color.argb(50, 0, 136, 25));

        mOverlayList.add(mGaoDeOverlay);

        

        

        GeoPoint point = new GeoPoint((int) (MyConstant.DOUBLE_STUDEN_LAT * 1E6),

                (int) (MyConstant.DOUBLE_STUDEN_LON * 1E6));  //用给定的经纬度构造一个GeoPoint

    

        mMapController.setCenter(point);  //设置地图中心点

        mMapController.setZoom(15);    //设置地图zoom级别

    }

    

    public void initLogic()

    {

        mHandler = new Handler()

        {

            @Override

            public void handleMessage(Message msg) {

                // TODO Auto-generated method stub

            

            }

            

    

        };

        

        

        

        mLocationManager = new MyLocationManager(this);

        mListen = new MyLocationListen(this, mHandler, new UpdateLocationRunnable());

        mStationLocationManager = new MyStationLocationManager(this);

        mStationLocationListen = new MyStationLocationListen(this, mHandler, new UpdateStationLocationRunnable());

        

        mGaodeLocationManager = new MyGaodeLocationManager(this);

        mGaodeLocationListen = new MyGaodeListen(mHandler, new UpdateGaodeLocationRunnable());

        

    }


一个是地图相关控件的初始化,一个是三种定位方式的类对象初始化

resumepause里进行注册监听和反注册监听

@Override

    protected void onPause() {

        // TODO Auto-generated method stub

        super.onPause();

        

        // 取消监听

        mLocationManager.unRegisterListen();

        mStationLocationManager.unRegisterListen();

        mGaodeLocationManager.unRegisterListen();

    }

    @Override

    protected void onResume() {

        // TODO Auto-generated method stub

        super.onResume();

        

        // 注册监听

        mLocationManager.registerListen(mListen);

        mStationLocationManager.registerListen(mStationLocationListen);

        mGaodeLocationManager.registerListen(mGaodeLocationListen);

    }


设置以三十秒的频率更新位置

在刷新位置后进行纠偏(LocationManagerProxy不用纠偏)和获取地理位置信息

由于这两个都要联网获取,所以不能在UI线程里操作

下面看看这三种定位方式的监听器实现

android API location监听器

public class MyLocationListen implements LocationListener

{

    private Handler mHandler;

    private IONSetLocation mRunnable;

    private Context mContext;

    

    public MyLocationListen(Context context, Handler handler, IONSetLocation runnable)

    {

        mHandler = handler;

        mRunnable = runnable;

        mContext = context;

    }

    

    @Override

    public void onLocationChanged(Location location) {

        // TODO Auto-generated method stub

        

        if (mHandler != null)

        {

            Thread thread = new InnerThread(location);

            

            thread.start();

        }

        

        

    

    }

    

    class InnerThread extends Thread

    {

        private Location mLocation;

        

        public InnerThread( Location location)

        {

            mLocation = location;       

            

        }

        @Override

        public void run() {

            // TODO Auto-generated method stub

            Location newLocation = WebManager.correctPosToMap(mLocation, mContext);

            

            mRunnable.setLocation(newLocation);

            

            try {

                mRunnable.setAdress(WebManager.getAddressByGoogle(mLocation));

            } catch (Exception e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

    

            mHandler.post( mRunnable);

        }

        

        

    }

    @Override

    public void onProviderDisabled(String provider) {

        // TODO Auto-generated method stub

        

    }

    @Override

    public void onProviderEnabled(String provider) {

        // TODO Auto-generated method stub

        

    }

    @Override

    public void onStatusChanged(String provider, int status, Bundle extras) {

        // TODO Auto-generated method stub

        

    }

    

}

onLocationChange方法是在UI线程里执行的,所以需要开子线程进行查询操作

google基站 位置监听

public class MyStationLocationListen implements LocationListener

{

    private Handler mHandler;

    private IONSetLocation mRunnable;

    private Context mContext;

    

    public MyStationLocationListen(Context context, Handler handler, IONSetLocation runnable)

    {

        mHandler = handler;

        mRunnable = runnable;

        mContext = context;

    }

    

    @Override

    public void onLocationChanged(Location location) {

        // TODO Auto-generated method stub

        

        if (mHandler != null)

        {

            Location newLocation = WebManager.correctPosToMap(location, mContext);

            

            mRunnable.setLocation(newLocation);

            try {

                mRunnable.setAdress(WebManager.getAddressByGoogle(location));

            } catch (Exception e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

            mHandler.post( mRunnable);

        }

    

    

    }

    @Override

    public void onProviderDisabled(String provider) {

        // TODO Auto-generated method stub

        

    }

    @Override

    public void onProviderEnabled(String provider) {

        // TODO Auto-generated method stub

        

    }

    @Override

    public void onStatusChanged(String provider, int status, Bundle extras) {

        // TODO Auto-generated method stub

        

    }

    

}

这个所谓的位置监听是假的,其实就是开了个定时器每隔三十秒获取基站信息然后在获取位置

看它对应的locationmanager实现

public class MyStationLocationManager {

    private final static int CHECK_POSITION_INTERVAL = 30 * 1000;

    

    

    private Context mContext;

    

    private Timer mTimer;

    

    private MyTimeTask mTimeTask;

    private LocationListener mListener;

    

    public MyStationLocationManager(Context context)

    {

        mContext = context;

        

        mTimer = new Timer();

        

    }

    

    public void registerListen(LocationListener listener)

    {

        

    

        if (mListener == null)

        {

            mListener = listener;

    

            startTimer();

        }

    

    }

    

    public void unRegisterListen()

    {

        stopTimer();

                    

        mListener = null;       

    }

    

    

    

    

    private void startTimer( )

    {

        if (mTimeTask == null)

        {

            mTimeTask = new MyTimeTask();

            mTimer.schedule(mTimeTask, 0, CHECK_POSITION_INTERVAL);

        }

    }

    

    private void stopTimer()

    {

        if (mTimeTask != null)

        {

            mTimeTask.cancel();

            mTimeTask = null;

        }

    }

    

    

    

    

    class MyTimeTask extends TimerTask

    {

        @Override

        public void run() {

            // TODO Auto-generated method stub

            //Toast.makeText(mContext, "run", Toast.LENGTH_SHORT).show();

            

            List<CellIDInfo> list = null;

            Location location = null;

            

            try {

                list = CellIDInfoManager.getCellIDInfo(mContext);

                location = WebManager.callGear(list);

            } catch (Exception e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

            

            

            if (mListener != null)

            {

                mListener.onLocationChanged(location);

            }

        }

        

    }

    

    

    

    

    

}

看到木有

再看高德的

public class MyGaodeListen implements LocationListener 

{

    private Handler mHandler;

    private IONSetLocation mRunnable;

    

    public MyGaodeListen(Handler handler, IONSetLocation runnable)

    {

        mHandler = handler;

        mRunnable = runnable;

    }

    

    @Override

    public void onLocationChanged(Location location) {

        // TODO Auto-generated method stub

    

        

        if (mHandler != null)

        {

            mRunnable.setLocation(location);

            try {

                mRunnable.setAdress(WebManager.getAddressByGoogle(location));

            } catch (Exception e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

            mHandler.post( mRunnable);

            

        }

        

    

    }

    @Override

    public void onProviderDisabled(String provider) {

        // TODO Auto-generated method stub

        

    }

    @Override

    public void onProviderEnabled(String provider) {

        // TODO Auto-generated method stub

        

    }

    @Override

    public void onStatusChanged(String provider, int status, Bundle extras) {

        // TODO Auto-generated method stub

        

    }

    

}

public class MyGaodeLocationManager {

    private final static int CHECK_POSITION_INTERVAL = 30 * 1000;

    

    private LocationManagerProxy mLocationManagerProxy;

    

    private Context mContext;

    

    private LocationListener mListener;

    

    public MyGaodeLocationManager(Context context)

    {

        mContext = context;

        

        mLocationManagerProxy = LocationManagerProxy.getInstance(context, context.getString(R.string.maps_api_key));

    }

    

    public void clear()

    {

        mLocationManagerProxy.destory();

    }

    

    public void registerListen(LocationListener listener)

    {

        if (mListener == null)

        {

            mListener = listener;

            mLocationManagerProxy.requestLocationUpdates(LocationProviderProxy.MapABCNetwork, CHECK_POSITION_INTERVAL, 0, listener);

        }

        

    }

    

    public void unRegisterListen()

    {

        if (mListener != null)

        {

            mLocationManagerProxy.removeUpdates(mListener);

        }

        

    }

}

 


 


 

采用自家的LocationManagerProxy 调用 requestLocationUpdates(LocationProviderProxy.MapABCNetwork, CHECK_POSITION_INTERVAL, 0, listener);

MapABCNetwork的值是lbs,得到的位置无需纠偏即可显示

地图气泡的知识在此就不多做解释了,网上搜搜吧

代码分析到此为止,附属工程链接:

http://download.csdn.net/detail/geniuseoe2012/4345880

还有mapabc官方文档(很齐全哦)

http://download.csdn.net/detail/geniuseoe2012/4345909

 

 

 

 

 

你可能感兴趣的:(list,Google,null,文档,代码分析,地图相关)