A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

android 通过百度地图API查询经纬度来获得地址信息

本文主要讲解如何通过百度地图API根据某个经纬度值(地理坐标)查询对应的地址信息以及该地址周边的POI(Point of Interest,兴趣点)信息。
百度地图移动版API不仅包含构建地图的基本接口,还集成了众多搜索服务,包括:范围检索、位置检索、周边检索、步行检索、公交检索、驾乘检索、地址信息查询等。
百度地图移动版API提供的搜索服务主要是通过初始化MKSearch类,注册搜索结果的监听对象MKSearchListener来实现异步搜索服务。首先需要自定义一个MySearchListener类,它实现MKSearchListener接口,然后通过实现接口中不同的回调方法,来获得对应的搜索结果。MySearchListener类的定义如下:
  1. /**
  2. * 实现MKSearchListener接口,用于实现异步搜索服务,得到搜索结果
  3. *
  4. * @author liufeng
  5. */
  6. public class MySearchListener implements MKSearchListener {
  7.     /**
  8.      * 根据经纬度搜索地址信息结果
  9.      *
  10.      * @param result
  11.      *            搜索结果
  12.      * @param iError
  13.      *            错误号(0表示正确返回)
  14.      */
  15.     @Override
  16.     public void onGetAddrResult(MKAddrInfo result, int iError) {
  17.     }

  18.     /**
  19.      * 驾车路线搜索结果
  20.      *
  21.      * @param result
  22.      *            搜索结果
  23.      * @param iError
  24.      *            错误号(0表示正确返回)
  25.      */
  26.     @Override
  27.     public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
  28.     }

  29.     /**
  30.      * POI搜索结果(范围检索、城市POI检索、周边检索)
  31.      *
  32.      * @param result
  33.      *            搜索结果
  34.      * @param type
  35.      *            返回结果类型(11,12,21:poi列表 7:城市列表)
  36.      * @param iError
  37.      *            错误号(0表示正确返回)
  38.      */
  39.     @Override
  40.     public void onGetPoiResult(MKPoiResult result, int type, int iError) {
  41.     }

  42.     /**
  43.      * 公交换乘路线搜索结果
  44.      *
  45.      * @param result
  46.      *            搜索结果
  47.      * @param iError
  48.      *            错误号(0表示正确返回)
  49.      */
  50.     @Override
  51.     public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) {
  52.     }

  53.     /**
  54.      * 步行路线搜索结果
  55.      *
  56.      * @param result
  57.      *            搜索结果
  58.      * @param iError
  59.      *            错误号(0表示正确返回)
  60.      */
  61.     @Override
  62.     public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {
  63.     }
  64. }
复制代码
说明:上面的类定义只是在说明MKSearchListener类的5个方法的作用,全都是空实现,并未给出具体的实现。根据你要检索的内容,再去具体实现上面对应的方法,就能获取到搜索结果。例如:1)你想通过一个地理坐标(经纬度值)来搜索地址信息,那么只需要具体实现上面的onGetAddrResult()方法就能得到搜索结果;2)如果你想搜索驾车路线信息,只需要具体实现onGetDrivingRouteResult()方法就能得到搜索结果。
紧接着,需要初始化MKSearch类:
  1. // 初始化MKSearch
  2. mMKSearch = new MKSearch();
  3. mMKSearch.init(mapManager, new MySearchListener());
复制代码
经过上面两步之后,就可以通过调用MKSearch所提供的一些检索方法来搜索你想要的信息了。
下面给出一个具体的示例:根据某个经纬度值(地理坐标)查询对应的地址信息以及该地址周边的POI(Point of Interest,兴趣点)信息。

1)布局文件res/layout/query_address.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent">
  5.     <LinearLayout
  6.         android:orientation="vertical"
  7.         android:layout_width="fill_parent"
  8.         android:layout_height="fill_parent">
  9.         <TextView
  10.             android:layout_width="fill_parent"
  11.             android:layout_height="wrap_content"
  12.             android:text="经度:"
  13.             />
  14.         <EditText
  15.             android:id="@+id/longitude_input"
  16.             android:layout_width="fill_parent"
  17.             android:layout_height="wrap_content"
  18.             android:text="106.720397"
  19.             />
  20.         <TextView
  21.             android:layout_width="fill_parent"
  22.             android:layout_height="wrap_content"
  23.             android:text="纬度:"
  24.             />
  25.         <EditText
  26.             android:id="@+id/latitude_input"
  27.             android:layout_width="fill_parent"
  28.             android:layout_height="wrap_content"
  29.             android:text="26.597239"
  30.             />
  31.         <Button
  32.             android:id="@+id/query_button"
  33.             android:layout_width="wrap_content"
  34.             android:layout_height="wrap_content"
  35.             android:layout_gravity="right"
  36.             android:text="地址查询"
  37.             />
  38.         <TextView
  39.             android:id="@+id/address_text"
  40.             android:layout_width="wrap_content"
  41.             android:layout_height="wrap_content"
  42.             />
  43.         <!-- 虽然定义了MapView,但是设置了android:visibility="gone"将其隐藏 因为本示例并不需要显示地图,但不定义又不行(baidu
  44.             map api的要求) -->
  45.         <com.baidu.mapapi.MapView
  46.             android:id="@+id/map_View"
  47.             android:layout_width="fill_parent"
  48.             android:layout_height="fill_parent"
  49.             android:clickable="true"
  50.             android:visibility="gone"
  51.             />
  52.     </LinearLayout>
  53. </ScrollView>
复制代码
2)继承com.baidu.mapapi.MapActivity的Activity类
  1. package com.liufeng.baidumap;

  2. import android.os.Bundle;
  3. import android.view.View;
  4. import android.view.View.OnClickListener;
  5. import android.widget.Button;
  6. import android.widget.EditText;
  7. import android.widget.TextView;

  8. import com.baidu.mapapi.BMapManager;
  9. import com.baidu.mapapi.GeoPoint;
  10. import com.baidu.mapapi.MKAddrInfo;
  11. import com.baidu.mapapi.MKDrivingRouteResult;
  12. import com.baidu.mapapi.MKPoiInfo;
  13. import com.baidu.mapapi.MKPoiResult;
  14. import com.baidu.mapapi.MKSearch;
  15. import com.baidu.mapapi.MKSearchListener;
  16. import com.baidu.mapapi.MKTransitRouteResult;
  17. import com.baidu.mapapi.MKWalkingRouteResult;
  18. import com.baidu.mapapi.MapActivity;

  19. /**
  20. * 根据经纬度查询地址信息
  21. *
  22. * @author liufeng
  23. * @date 2011-05-03
  24. */
  25. public class QueryAddressActivity extends MapActivity {
  26.     // 定义地图引擎管理类
  27.     private BMapManager mapManager;
  28.     // 定义搜索服务类
  29.     private MKSearch mMKSearch;

  30.     private EditText longitudeEditText;
  31.     private EditText latitudeEditText;
  32.     private TextView addressTextView;
  33.     private Button queryButton;

  34.     @Override
  35.     public void onCreate(Bundle savedInstanceState) {
  36.         super.onCreate(savedInstanceState);
  37.         setContentView(R.layout.query_address);

  38.         // 初始化MapActivity
  39.         mapManager = new BMapManager(getApplication());
  40.         // init方法的第一个参数需填入申请的API Key
  41.         mapManager.init("285B415EBAB2A92293E85502150ADA7F03C777C4", null);
  42.         super.initMapActivity(mapManager);

  43.         // 初始化MKSearch
  44.         mMKSearch = new MKSearch();
  45.         mMKSearch.init(mapManager, new MySearchListener());

  46.         // 通过id查询在布局文件中定义的控件
  47.         longitudeEditText = (EditText) findViewById(R.id.longitude_input);
  48.         latitudeEditText = (EditText) findViewById(R.id.latitude_input);
  49.         addressTextView = (TextView) findViewById(R.id.address_text);
  50.         queryButton = (Button) findViewById(R.id.query_button);

  51.         // 给地址查询按钮设置单击事件监听器
  52.         queryButton.setOnClickListener(new OnClickListener() {
  53.             @Override
  54.             public void onClick(View v) {
  55.                 // 用户输入的经度值
  56.                 String longitudeStr = longitudeEditText.getText().toString();
  57.                 // 用户输入的纬度值
  58.                 String latitudeStr = latitudeEditText.getText().toString();

  59.                 try {
  60.                     // 将用户输入的经纬度值转换成int类型
  61.                     int longitude = (int) (1000000 * Double
  62.                             .parseDouble(longitudeStr));
  63.                     int latitude = (int) (1000000 * Double
  64.                             .parseDouble(latitudeStr));

  65.                     // 查询该经纬度值所对应的地址位置信息
  66.                     mMKSearch.reverseGeocode(new GeoPoint(latitude, longitude));
  67.                 } catch (Exception e) {
  68.                     addressTextView.setText("查询出错,请检查您输入的经纬度值!");
  69.                 }
  70.             }
  71.         });
  72.     }

  73.     @Override
  74.     protected boolean isRouteDisplayed() {
  75.         return false;
  76.     }

  77.     @Override
  78.     protected void onDestroy() {
  79.         if (mapManager != null) {
  80.             // 程序退出前需调用此方法
  81.             mapManager.destroy();
  82.             mapManager = null;
  83.         }
  84.         super.onDestroy();
  85.     }

  86.     @Override
  87.     protected void onPause() {
  88.         if (mapManager != null) {
  89.             // 终止百度地图 API
  90.             mapManager.stop();
  91.         }
  92.         super.onPause();
  93.     }

  94.     @Override
  95.     protected void onResume() {
  96.         if (mapManager != null) {
  97.             // 开启百度地图 API
  98.             mapManager.start();
  99.         }
  100.         super.onResume();
  101.     }

  102.     /**
  103.      * 内部类实现MKSearchListener接口,用于实现异步搜索服务
  104.      *
  105.      * @author liufeng
  106.      */
  107.     public class MySearchListener implements MKSearchListener {
  108.         /**
  109.          * 根据经纬度搜索地址信息结果
  110.          *
  111.          * @param result
  112.          *            搜索结果
  113.          * @param iError
  114.          *            错误号(0表示正确返回)
  115.          */
  116.         @Override
  117.         public void onGetAddrResult(MKAddrInfo result, int iError) {
  118.             if (result == null) {
  119.                 return;
  120.             }
  121.             StringBuffer sb = new StringBuffer();
  122.             // 经纬度所对应的位置
  123.             sb.append(result.strAddr).append("/n");

  124.             // 判断该地址附近是否有POI(Point of Interest,即兴趣点)
  125.             if (null != result.poiList) {
  126.                 // 遍历所有的兴趣点信息
  127.                 for (MKPoiInfo poiInfo : result.poiList) {
  128.                     sb.append("----------------------------------------")
  129.                             .append("/n");
  130.                     sb.append("名称:").append(poiInfo.name).append("/n");
  131.                     sb.append("地址:").append(poiInfo.address).append("/n");
  132.                     sb.append("经度:")
  133.                             .append(poiInfo.pt.getLongitudeE6() / 1000000.0f)
  134.                             .append("/n");
  135.                     sb.append("纬度:")
  136.                             .append(poiInfo.pt.getLatitudeE6() / 1000000.0f)
  137.                             .append("/n");
  138.                     sb.append("电话:").append(poiInfo.phoneNum).append("/n");
  139.                     sb.append("邮编:").append(poiInfo.postCode).append("/n");
  140.                     // poi类型,0:普通点,1:公交站,2:公交线路,3:地铁站,4:地铁线路
  141.                     sb.append("类型:").append(poiInfo.ePoiType).append("/n");
  142.                 }
  143.             }
  144.             // 将地址信息、兴趣点信息显示在TextView上
  145.             addressTextView.setText(sb.toString());
  146.         }

  147.         /**
  148.          * 驾车路线搜索结果
  149.          *
  150.          * @param result
  151.          *            搜索结果
  152.          * @param iError
  153.          *            错误号(0表示正确返回)
  154.          */
  155.         @Override
  156.         public void onGetDrivingRouteResult(MKDrivingRouteResult result,
  157.                 int iError) {
  158.         }

  159.         /**
  160.          * POI搜索结果(范围检索、城市POI检索、周边检索)
  161.          *
  162.          * @param result
  163.          *            搜索结果
  164.          * @param type
  165.          *            返回结果类型(11,12,21:poi列表 7:城市列表)
  166.          * @param iError
  167.          *            错误号(0表示正确返回)
  168.          */
  169.         @Override
  170.         public void onGetPoiResult(MKPoiResult result, int type, int iError) {
  171.         }

  172.         /**
  173.          * 公交换乘路线搜索结果
  174.          *
  175.          * @param result
  176.          *            搜索结果
  177.          * @param iError
  178.          *            错误号(0表示正确返回)
  179.          */
  180.         @Override
  181.         public void onGetTransitRouteResult(MKTransitRouteResult result,
  182.                 int iError) {
  183.         }

  184.         /**
  185.          * 步行路线搜索结果
  186.          *
  187.          * @param result
  188.          *            搜索结果
  189.          * @param iError
  190.          *            错误号(0表示正确返回)
  191.          */
  192.         @Override
  193.         public void onGetWalkingRouteResult(MKWalkingRouteResult result,
  194.                 int iError) {
  195.         }
  196.     }
  197. }
复制代码
3)AndroidManifest.xml中的配置

[backcolor=white !important]<?xml version="1.0" encoding="utf-8"?>
[backcolor=white !important]<manifest xmlns:android="[color=blue !important][size=1em]http://schemas.android.com/apk/res/android"
[backcolor=white !important]    package="com.liufeng.baidumap" android:versionCode="1"
[backcolor=white !important]    android:versionName="1.0">
[backcolor=white !important]    <application android:icon="@drawable/icon" android:label="@string/app_name">
[backcolor=white !important]        <activity android:name=".QueryAddressActivity"android:label="@string/app_name">
[backcolor=white !important]            <intent-filter>
[backcolor=white !important]                <action android:name="android.intent.action.MAIN" />
[backcolor=white !important]                <category android:name="android.intent.category.LAUNCHER" />
[backcolor=white !important]            </intent-filter>
[backcolor=white !important]        </activity>
[backcolor=white !important]    </application>
[backcolor=white !important]    <uses-sdk android:minSdkVersion="4" />

[backcolor=white !important]    <!-- 访问网络的权限 -->
[backcolor=white !important]    <uses-permission android:name="android.permission.INTERNET" />
[backcolor=white !important]    <!-- 访问精确位置的权限 -->
[backcolor=white !important]    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
[backcolor=white !important]    <!-- 访问网络状态的权限 -->
[backcolor=white !important]    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
[backcolor=white !important]    <!-- 访问WIFI网络状态的权限 -->
[backcolor=white !important]    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
[backcolor=white !important]    <!-- 改变WIFI网络状态的权限 -->
[backcolor=white !important]    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
[backcolor=white !important]    <!-- 读写存储卡的权限 -->
[backcolor=white !important]    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
[backcolor=white !important]    <!-- 读取电话状态的权限 -->
[backcolor=white !important]    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
[backcolor=white !important]</manifest>


4)运行结果截图及说明



程序在模拟器上运行的初始效果如上图所示。可以看出,地图并没有显示出来,这和我们在设计时布局时所设想的一样;另外两个输入框中也分别显示了默认给出的经纬度值。
点击“地址查询”按钮后,将看到如下图所示包含了查询结果的界面:




说明:图上的“贵州省贵阳市云岩区普陀路”正是我们要查询的地理坐标(经度:106.720397,纬度:26.597239)所对应的地址信息;同时该地址信息下方还显示出了该地址附近的10个兴趣点(POI),每个兴趣点分别包含了“名称”、“地址”、“经纬度”、“电话”、“邮编”和“兴趣点类型”信息。
备注:如果本文的示例继续做下去,就应该将MapView显示出来,然后将地址信息和兴趣点标注在地图上。我想这两方面应该并不是什么难事,看文章的你就动动手来完成它吧!

3 个回复

倒序浏览
收藏一下,
回复 使用道具 举报
值得下载
回复 使用道具 举报
厉害!学习了!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马