一. 百度地图城市定位和POI搜索知识

      上一篇文章"百度地图开发(一)"中讲述了如何申请百度APIKey及解决显示空白网格的问题.该篇文章主要讲述如何定位城市位置、定位自己的位置和进行城市兴趣点POI(Point of Interest)搜索.那么如何在百度地图上定位某一个位置呢?
      通过类GeoPoint可以定义经纬度,它存放着纬度值和经度值,通过getLastKnownLocation()方法可以获取Location对象,再定位经纬度设置其为地图中心即可显示当前位置.
      其中Geopoint(纬度值,经度值)以微度为单位,需要乘以10的6次方.核心代码如下:

//通过网络获取当前位置String provider = LocationManager.NeTWORK_PROVIDER;Location location = locationManager.getLastKnownLocation(provider);Geopoint point = new Geopoint((int)(location.getLatitude*1E6), (int)(location.getLongitude*1E6));mMapController.setCenter(point);
     同样的道理,如果知道了城市的经纬度就可以设置其为当前地图中心,这样就实现了定位城市位置的功能.那么怎样获取城市的经纬度呢?
      百度Map API提供MKSearch.geocode(String address, String city)方法进行GEO地理编码检索,它的意思就是搜索某个城市具体地址的位置,而如果只搜索城市使用geocode(city, city)即可.同时逆地址解析函数MKSearch.reverseGeocode(new GeoPoint(latitude, longitude))可以实现通过输入经纬度查询具体地址.
     
其中核心代码如下(代码放置位置不同,详见后面实例):
//初始化MKSearchmMKSearch = new MKSearch();mMKSearch.init(mBMapManager, new MySearchListener()); //搜索城市mMKSearch.geocode(city, city);//内部类实现MKSearchListener接口,实现异步搜索服务public class MySearchListener implements MKSearchListener {  @Override      public void onGetAddrResult(MKAddrInfo result, int iError) {     //经纬度与地址搜索    ...    mMapController.setCenter(result.geoPt);    }}
     其中百度地图API搜索主要通过初始化MKSearch类,同时其结果监听对象MKSearchListener类来实现一部搜索服务.在该类中有很多方法实现不同功能,其中onGetAddrResult()方法可以根据经纬度搜索地址信息,而我们需要实现的POI兴趣点搜索是通过onGetPoiResult()实现的,同样公交路线等搜索都可以通过它实现.
      具体核心代码如下:
//内部类实现MKSearchListener接口,实现异步搜索服务public class MySearchListener implements MKSearchListener {      //经纬度与地址搜索结果    public void onGetAddrResult(MKAddrInfo result, int iError) {    }    //POI搜索结果(范围检索、城市POI检索、周边检索)    public void onGetPoiResult(MKPoiResult result, int type, int iError) {      }    //驾车路线搜索结果     public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {    }    //公交换乘路线搜索结果    public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) {  }     //步行路线搜索结果    public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {      }    //获取详细信息    public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {    }    public void onGetPoiDetailSearchResult(int arg0, int arg1) {    }    public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1,int arg2) {    }    public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {    }}
      在android使用百度地图中可以添加地图覆盖物,那么什么是覆盖物呢?
      所有叠加或覆盖到地图的内容,我们统称为地图覆盖物.如标注、矢量图形元素(包括:折线和多边形和圆)、定位图标等.覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的移动.

      地图API提供了如下几种覆盖物:
      1.Overlay 覆盖物的抽象基类,所有的覆盖物均继承此类的方法,实现用户自定义图层显示.
      2.MyLocationOverlay 一个负责显示用户当前位置的Overlay.
      3.ItemizedOverlay 它是Overlay的一个基类,包含了一个OverlayItem列表,相当于一组分条的Overlay,通过继承此类将一组兴趣点显示在地图上.
      4.PoiOverlay 本地搜索图层,提供某一特定地区的位置搜索服务,比如在北京市搜索“公园”,通过此图层将公园显示在地图上.
      5.RouteOverlay 步行驾车导航线路图层,将步行驾车出行方案的路线及关键点显示在地图上.
      6.TransitOverlay 
公交换乘线路图层,将某一特定地区的公交出行方案的路线及换乘位置显示在地图上.
      我们这里可以使用MyLocationOverlay定位自己当前位置添加覆盖物,也可以在POI搜索过程中通过PoiOverlay添加搜索的兴趣点覆盖物.下面讲述代码及实现.

二. 源码实现

      下载地址:http://download.csdn.net/detail/eastmount/8292969
      首先,设置其activity_main.xml布局

                                        

      然后是MainActivity.java源码

public class MainActivity extends Activity {//BMapManager 对象管理地图、定位、搜索功能private BMapManager mBMapManager;  private MapView mapView = null;               //地图主控件 private MapController mMapController = null;  //地图控制 MKMapViewListener mMapListener = null;        //处理地图事件回调 private MKSearch mMKSearch;                   //定义搜索服务类//搜索private EditText keyWordEditText;  private EditText cityEditText;private Button queryButton; private static StringBuilder sb;  private MyLocationOverlay myLocationOverlay;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);                /**         * 创建对象BMapManager并初始化操作         * V2.3.1中init(APIKey,null) V2.4.1在AndroidManifest中赋值AK         * 注意 初始化操作在setContentView()前         */        mBMapManager = new BMapManager(getApplication());          mBMapManager.init(null);         setContentView(R.layout.activity_main);          mapView = (MapView) findViewById(R.id.map_view);          cityEditText = (EditText) findViewById(R.id.city_edittext);        keyWordEditText = (EditText) findViewById(R.id.keyword_edittext);        queryButton = (Button) findViewById(R.id.query_button);                mMapController = mapView.getController(); //获取地图控制器        mMapController.enableClick(true);         //设置地图是否响应点击事        mMapController.setZoom(16);               //地图缩放级别(3-19级) 级别越高信息越详细        mapView.setBuiltInZoomControls(true);     //显示内置缩放控件                  /**         * 获取学校经纬度 设置地图中心点         */        GeoPoint point = new GeoPoint((int)(39.96703 * 1E6), (int)(116.323772 * 1E6));          mMapController.setCenter(point);          mapView.regMapViewListener(mBMapManager, new MKMapViewListener() {                            /**              * 地图移动完成时会回调此接口方法              */              @Override              public void onMapMoveFinish() {              //Toast.makeText(MainActivity.this, "地图移动", Toast.LENGTH_SHORT).show();            }                            /**              * 地图加载完毕回调此接口方法              */              @Override              public void onMapLoadFinish() {              Toast.makeText(MainActivity.this, "地图载入", Toast.LENGTH_SHORT).show();            }                            /**              *  地图完成带动画的操作(如: animationTo())后,此回调被触发              */              @Override              public void onMapAnimationFinish() {                                }                            /**              *  当调用过 mMapView.getCurrentMap()后,此回调会被触发              *  可在此保存截图至存储设备              */              @Override              public void onGetCurrentMap(Bitmap arg0) {                               }                            /**              * 点击地图上被标记的点回调此方法             */              @Override              public void onClickMapPoi(MapPoi arg0) {                  if (arg0 != null){                      Toast.makeText(MainActivity.this, arg0.strText, Toast.LENGTH_SHORT).show();                }              }          });                  /**         * 初始化MKSearch 调用城市和POI搜索           */        mMKSearch = new MKSearch();        mMKSearch.init(mBMapManager, new MySearchListener());         queryButton.setOnClickListener(new OnClickListener() {              @Override              public void onClick(View v) {                  mMapController = mapView.getController();            mMapController.setZoom(10);                  sb = new StringBuilder();  //内容清空                  //输入正确城市关键字                String city = cityEditText.getText().toString().trim();                  String keyWord = keyWordEditText.getText().toString().trim();                  if(city.isEmpty()) { //默认城市设置为贵阳                city="贵阳";                }                //如果关键字为空只搜索城市 GEO搜索 geocode(adress,city) 具体地址和城市                if(keyWord.isEmpty()) {                mMKSearch.geocode(city, city);                     }                 else {                //搜索城市+关键字                     mMKSearch.setPoiPageCapacity(10);  //每页返回POI数                    mMKSearch.poiSearchInCity(city, keyWord);                 }            }          });      }        @Overrideprotected void onResume() {mapView.onResume();if (mBMapManager != null) {mBMapManager.start();}super.onResume();}        @Overrideprotected void onDestroy() {mapView.destroy();if (mBMapManager != null) {mBMapManager.destroy();mBMapManager = null;}super.onDestroy();}@Overrideprotected void onPause() {mapView.onPause();if (mBMapManager != null) {mBMapManager.stop();}super.onPause();}/**      * 内部类实现MKSearchListener接口,用于实现异步搜索服务      */      public class MySearchListener implements MKSearchListener {              /**          * 根据经纬度搜索地址信息结果          * 同时mMKSearch.geocode(city, city)搜索城市返回至该函数         *          * @param result 搜索结果          * @param iError 错误号(0表示正确返回)          */          @Override          public void onGetAddrResult(MKAddrInfo result, int iError) {          if (result == null) {                  return;              }              StringBuffer sbcity = new StringBuffer();              sbcity.append(result.strAddr).append("\n"); //经纬度所对应的位置          mapView.getOverlays().clear();          //清除地图上已有的所有覆盖物              mMapController.setCenter(result.geoPt);     //置为地图中心            //添加原点并刷新            LocationData locationData = new LocationData();            locationData.latitude = result.geoPt.getLatitudeE6();            locationData.longitude = result.geoPt.getLongitudeE6();            myLocationOverlay = new MyLocationOverlay(mapView);            myLocationOverlay.setData(locationData);mapView.getOverlays().add(myLocationOverlay);mapView.refresh();            // 通过AlertDialog显示地址信息            new AlertDialog.Builder(MainActivity.this)              .setTitle("显示当前城市地图")              .setMessage(sbcity.toString())              .setPositiveButton("关闭", new DialogInterface.OnClickListener() {                  public void onClick(DialogInterface dialog, int whichButton) {                      dialog.dismiss();                  }              }).create().show();        }            /**          * POI搜索结果(范围检索、城市POI检索、周边检索)          *           * @param result 搜索结果          * @param type 返回结果类型(11,12,21:poi列表 7:城市列表)          * @param iError 错误号(0表示正确返回)          */          @Override          public void onGetPoiResult(MKPoiResult result, int type, int iError) {          if (result == null) {                  return;              }                //获取POI并显示            mapView.getOverlays().clear();             PoiOverlay poioverlay = new PoiOverlay(MainActivity.this, mapView);            poioverlay.setData(result.getAllPoi());  //设置搜索到的POI数据              mapView.getOverlays().add(poioverlay);   //兴趣点标注在地图上            mapView.refresh();             //设置其中一个搜索结果所在地理坐标为地图的中心              if(result.getNumPois() > 0) {                  MKPoiInfo poiInfo = result.getPoi(0);                  mMapController.setCenter(poiInfo.pt);              }              //添加StringBuffer 遍历当前页返回的POI (默认只返回10个)            sb.append("共搜索到").append(result.getNumPois()).append("个POI\n");              for (MKPoiInfo poiInfo : result.getAllPoi()) {                  sb.append("名称:").append(poiInfo.name).append("\n");            }         // 通过AlertDialog显示当前页搜索到的POI              new AlertDialog.Builder(MainActivity.this)              .setTitle("搜索到的POI信息")              .setMessage(sb.toString())              .setPositiveButton("关闭", new DialogInterface.OnClickListener() {                  public void onClick(DialogInterface dialog, int whichButton) {                      dialog.dismiss();                  }              }).create().show();        }            /**          * 驾车路线搜索结果          *           * @param result 搜索结果          * @param iError 错误号(0表示正确返回)          */          @Override          public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {          }                  /**          * 公交换乘路线搜索结果          *           * @param result 搜索结果          * @param iError 错误号(0表示正确返回)          */          @Override          public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) {          }            /**          * 步行路线搜索结果          *           * @param result 搜索结果          * @param iError 错误号(0表示正确返回)          */          @Override          public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {          }@Overridepublic void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {// TODO Auto-generated method stub}@Overridepublic void onGetPoiDetailSearchResult(int arg0, int arg1) {// TODO Auto-generated method stub}@Overridepublic void onGetShareUrlResult(MKShareUrlResult arg0, int arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {// TODO Auto-generated method stub}    }  }
     最后设置AndroidManifest.xml文件,主要是申请网络权限和设置APIKey
<?xml version="1.0" encoding="utf-8"?>                                                                                                                                                                                         
      程序运行结果如下图所示:
      当只输入城市名的时候显示的是城市对应的地图.如下图贵阳.

  
      当输入城市+关键字时显示POI兴趣点,如北京的大学.这里设置只显示10个POI.
    
     最后我测试了下县份同样可以显示,但是城市名错误处理我没做,如施秉县.说明百度地图的API还是非常强大的,希望后面接着学习吧!
           最后希望文章对大家有所帮助,刚刚接触android开发百度地图,而且还是使用V2.4.1版本,同时搜索城市时没有显示覆盖物不知道其原因.如果有错误或不足之处,还请海涵!建议大家看看官方文档和百度提供的Demo.文章主要参考百度官方文档、柳峰大神博客和《Android第一行代码》.
     下载地址:http://download.csdn.net/detail/eastmount/8292969
      (By:Eastmount 2014-12-24 半夜3点
http://blog.csdn.net/eastmount/
参考资料及在线笔记:
      百度官方文档   http://developer.baidu.com/map/sdkandev-4.htm
      百度官方文档  Android SDK开发指南之覆盖物
      百度地图相关Demo下载  Demo v3.2.0 
      柳峰博客  [010]百度地图API之根据经纬度查询地址信息(Android
     柳峰博客 [013] 百度地图API之城市POI搜索-获取所有结果(Android)

更多相关文章

  1. Android(安卓)百度地图—反地理编码—获取当前位置附近的大厦楼
  2. android 获取经纬度
  3. Android(安卓)studio 百度地图开发(6)Marker绑定事件、计算两点距
  4. Android使用高德地图地理围栏定位自动发送短信
  5. Android(安卓)号码, 来电归属地 Jni 使用C++对二进制文件查询(二
  6. Android原生GPS和网络定位工具类
  7. Android(安卓)获取全国城市列表类似于联系人排序(二)
  8. Android百度地图开发(二)地图覆盖物
  9. 百度地图开发的两个应用源码共享(android版)

随机推荐

  1. Android中关于Audio库的知识
  2. 如何制作Jar包并在android中调用jar包
  3. Android布局详解
  4. android 开发随笔 - 开发环境搭建
  5. Android的内存管理机制
  6. Android(安卓)ADV 虚拟卡常见错误Failed
  7. Android中屏幕密度和图片大小的关系分析
  8. Android系统权限和root权限
  9. 【android】解决设置ImageView的scaletyp
  10. Android(安卓)Java basic knowledge ---A