本文主要讲解如何通过百度地图API根据某个经纬度值(地理坐标)查询对应的地址信息以及该地址周边的POI(Point of Interest,兴趣点)信息。 百度地图移动版API不仅包含构建地图的基本接口,还集成了众多搜索服务,包括:位置检索、周边检索、范围检索、公交检索、驾乘检索、步行检索、地址信息查询等。 百度地图移动版API提供的搜索服务主要是通过初始化MKSearch类,注册搜索结果的监听对象MKSearchListener来实现异步搜索服务。首先需要自定义一个MySearchListener类,它实现MKSearchListener接口,然后通过实现接口中不同的回调方法,来获得对应的搜索结果。MySearchListener类的定义如下:
- /**
- * 实现MKSearchListener接口,用于实现异步搜索服务,得到搜索结果
- *
- * @author liufeng
- */
- publicclass MySearchListener implements MKSearchListener {
- /**
- * 根据经纬度搜索地址信息结果
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetAddrResult(MKAddrInfo result, int iError) {
- }
- /**
- * 驾车路线搜索结果
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
- }
- /**
- * POI搜索结果(范围检索、城市POI检索、周边检索)
- * @param result 搜索结果
- * @param type 返回结果类型(11,12,21:poi列表 7:城市列表)
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetPoiResult(MKPoiResult result, int type, int iError) {
- }
- /**
- * 公交换乘路线搜索结果
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetTransitRouteResult(MKTransitRouteResult result, int iError) {
- }
- /**
- * 步行路线搜索结果
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {
- }
- }
/** * 实现MKSearchListener接口,用于实现异步搜索服务,得到搜索结果 * * @author liufeng */ public class MySearchListener implements MKSearchListener { /** * 根据经纬度搜索地址信息结果 * @param result 搜索结果 * @param iError 错误号(0表示正确返回) */ @Override public void onGetAddrResult(MKAddrInfo result, int iError) { } /** * 驾车路线搜索结果 * @param result 搜索结果 * @param iError 错误号(0表示正确返回) */ @Override public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) { } /** * POI搜索结果(范围检索、城市POI检索、周边检索) * @param result 搜索结果 * @param type 返回结果类型(11,12,21:poi列表 7:城市列表) * @param iError 错误号(0表示正确返回) */ @Override public void onGetPoiResult(MKPoiResult result, int type, 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) { } }说明:上面的类定义只是在说明MKSearchListener类的5个方法的作用,全都是空实现,并未给出具体的实现。根据你要检索的内容,再去具体实现上面对应的方法,就能获取到搜索结果。例如:1)你想通过一个地理坐标(经纬度值)来搜索地址信息,那么只需要具体实现上面的onGetAddrResult()方法就能得到搜索结果;2)如果你想搜索驾车路线信息,只需要具体实现onGetDrivingRouteResult()方法就能得到搜索结果。
紧接着,需要初始化MKSearch类:
- // 初始化MKSearch
- mMKSearch = new MKSearch();
- mMKSearch.init(mapManager, new MySearchListener());
// 初始化MKSearch mMKSearch = new MKSearch(); mMKSearch.init(mapManager, new MySearchListener()); 经过上面两步之后,就可以通过调用MKSearch所提供的一些检索方法来搜索你想要的信息了。 下面给出一个具体的示例:根据某个经纬度值(地理坐标)查询对应的地址信息以及该地址周边的POI(Point of Interest,兴趣点)信息。 1)布局文件res/layout/query_address.xml
- <?xmlversion=“1.0”encoding=“utf-8”?>
- <ScrollViewxmlns:android=“http://schemas.android.com/apk/res/android”
- android:layout_width=“fill_parent”
- android:layout_height=“fill_parent”>
- <LinearLayout
- android:orientation=“vertical”
- android:layout_width=“fill_parent”
- android:layout_height=“fill_parent”
- >
- <TextView
- android:layout_width=“fill_parent”
- android:layout_height=“wrap_content”
- android:text=“经度:”
- />
- <EditTextandroid:id=“@+id/longitude_input”
- android:layout_width=“fill_parent”
- android:layout_height=“wrap_content”
- android:text=“106.720397”
- />
- <TextView
- android:layout_width=“fill_parent”
- android:layout_height=“wrap_content”
- android:text=“纬度:”
- />
- <EditTextandroid:id=“@+id/latitude_input”
- android:layout_width=“fill_parent”
- android:layout_height=“wrap_content”
- android:text=“26.597239”
- />
- <Buttonandroid:id=“@+id/query_button”
- android:layout_width=“wrap_content”
- android:layout_height=“wrap_content”
- android:layout_gravity=“right”
- android:text=“地址查询”
- />
- <TextViewandroid:id=“@+id/address_text”
- android:layout_width=“wrap_content”
- android:layout_height=“wrap_content”
- />
- <!–
- 虽然定义了MapView,但是设置了android:visibility=“gone”将其隐藏
- 因为本示例并不需要显示地图,但不定义又不行(baidu map api的要求)
- —>
- <com.baidu.mapapi.MapViewandroid:id=“@+id/map_View”
- android:layout_width=“fill_parent”
- android:layout_height=“fill_parent”
- android:clickable=“true”
- android:visibility=“gone”
- />
- </LinearLayout>
- </ScrollView>
<?xml version=”1.0″ encoding=”utf-8″?> <ScrollView xmlns:android=”http://schemas.android.com/apk/res/android” android:layout_width=”fill_parent” android:layout_height=”fill_parent”> <LinearLayout android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent” > <TextView android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:text=”经度:” /> <EditText android:id=”@+id/longitude_input” android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:text=”106.720397″ /> <TextView android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:text=”纬度:” /> <EditText android:id=”@+id/latitude_input” android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:text=”26.597239″ /> <Button android:id=”@+id/query_button” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:layout_gravity=”right” android:text=”地址查询” /> <TextView android:id=”@+id/address_text” android:layout_width=”wrap_content” android:layout_height=”wrap_content” /> <!– 虽然定义了MapView,但是设置了android:visibility=”gone”将其隐藏 因为本示例并不需要显示地图,但不定义又不行(baidu map api的要求) –> <com.baidu.mapapi.MapView android:id=”@+id/map_View” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:clickable=”true” android:visibility=”gone” /> </LinearLayout> </ScrollView>2)继承com.baidu.mapapi.MapActivity的Activity类
- package com.liufeng.baidumap;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import com.baidu.mapapi.BMapManager;
- import com.baidu.mapapi.GeoPoint;
- import com.baidu.mapapi.MKAddrInfo;
- import com.baidu.mapapi.MKDrivingRouteResult;
- import com.baidu.mapapi.MKPoiInfo;
- import com.baidu.mapapi.MKPoiResult;
- import com.baidu.mapapi.MKSearch;
- import com.baidu.mapapi.MKSearchListener;
- import com.baidu.mapapi.MKTransitRouteResult;
- import com.baidu.mapapi.MKWalkingRouteResult;
- import com.baidu.mapapi.MapActivity;
- /**
- * 根据经纬度查询地址信息
- *
- * @author liufeng
- * @date 2011-05-03
- */
- publicclass QueryAddressActivity extends MapActivity {
- // 定义地图引擎管理类
- private BMapManager mapManager;
- // 定义搜索服务类
- private MKSearch mMKSearch;
- private EditText longitudeEditText;
- private EditText latitudeEditText;
- private TextView addressTextView;
- private Button queryButton;
- @Override
- publicvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.query_address);
- // 初始化MapActivity
- mapManager = new BMapManager(getApplication());
- // init方法的第一个参数需填入申请的API Key
- mapManager.init(“285B415EBAB2A92293E85502150ADA7F03C777C4”, null);
- super.initMapActivity(mapManager);
- // 初始化MKSearch
- mMKSearch = new MKSearch();
- mMKSearch.init(mapManager, new MySearchListener());
- // 通过id查询在布局文件中定义的控件
- longitudeEditText = (EditText) findViewById(R.id.longitude_input);
- latitudeEditText = (EditText) findViewById(R.id.latitude_input);
- addressTextView = (TextView) findViewById(R.id.address_text);
- queryButton = (Button) findViewById(R.id.query_button);
- // 给地址查询按钮设置单击事件监听器
- queryButton.setOnClickListener(new OnClickListener() {
- @Override
- publicvoid onClick(View v) {
- // 用户输入的经度值
- String longitudeStr = longitudeEditText.getText().toString();
- // 用户输入的纬度值
- String latitudeStr = latitudeEditText.getText().toString();
- try {
- // 将用户输入的经纬度值转换成int类型
- int longitude = (int) (1000000 * Double.parseDouble(longitudeStr));
- int latitude = (int) (1000000 * Double.parseDouble(latitudeStr));
- // 查询该经纬度值所对应的地址位置信息
- mMKSearch.reverseGeocode(new GeoPoint(latitude, longitude));
- } catch (Exception e) {
- addressTextView.setText(“查询出错,请检查您输入的经纬度值!”);
- }
- }
- });
- }
- @Override
- protectedboolean isRouteDisplayed() {
- returnfalse;
- }
- @Override
- protectedvoid onDestroy() {
- if (mapManager != null) {
- // 程序退出前需调用此方法
- mapManager.destroy();
- mapManager = null;
- }
- super.onDestroy();
- }
- @Override
- protectedvoid onPause() {
- if (mapManager != null) {
- // 终止百度地图API
- mapManager.stop();
- }
- super.onPause();
- }
- @Override
- protectedvoid onResume() {
- if (mapManager != null) {
- // 开启百度地图API
- mapManager.start();
- }
- super.onResume();
- }
- /**
- * 内部类实现MKSearchListener接口,用于实现异步搜索服务
- *
- * @author liufeng
- */
- publicclass MySearchListener implements MKSearchListener {
- /**
- * 根据经纬度搜索地址信息结果
- *
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetAddrResult(MKAddrInfo result, int iError) {
- if (result == null) {
- return;
- }
- StringBuffer sb = new StringBuffer();
- // 经纬度所对应的位置
- sb.append(result.strAddr).append(“/n”);
- // 判断该地址附近是否有POI(Point of Interest,即兴趣点)
- if (null != result.poiList) {
- // 遍历所有的兴趣点信息
- for (MKPoiInfo poiInfo : result.poiList) {
- sb.append(“—————————————-“).append(“/n”);
- sb.append(“名称:”).append(poiInfo.name).append(“/n”);
- sb.append(“地址:”).append(poiInfo.address).append(“/n”);
- sb.append(“经度:”).append(poiInfo.pt.getLongitudeE6() / 1000000.0f).append(“/n”);
- sb.append(“纬度:”).append(poiInfo.pt.getLatitudeE6() / 1000000.0f).append(“/n”);
- sb.append(“电话:”).append(poiInfo.phoneNum).append(“/n”);
- sb.append(“邮编:”).append(poiInfo.postCode).append(“/n”);
- // poi类型,0:普通点,1:公交站,2:公交线路,3:地铁站,4:地铁线路
- sb.append(“类型:”).append(poiInfo.ePoiType).append(“/n”);
- }
- }
- // 将地址信息、兴趣点信息显示在TextView上
- addressTextView.setText(sb.toString());
- }
- /**
- * 驾车路线搜索结果
- *
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
- }
- /**
- * POI搜索结果(范围检索、城市POI检索、周边检索)
- *
- * @param result 搜索结果
- * @param type 返回结果类型(11,12,21:poi列表 7:城市列表)
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetPoiResult(MKPoiResult result, int type, int iError) {
- }
- /**
- * 公交换乘路线搜索结果
- *
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetTransitRouteResult(MKTransitRouteResult result, int iError) {
- }
- /**
- * 步行路线搜索结果
- *
- * @param result 搜索结果
- * @param iError 错误号(0表示正确返回)
- */
- @Override
- publicvoid onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {
- }
- }
- }
package com.liufeng.baidumap; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.GeoPoint; import com.baidu.mapapi.MKAddrInfo; import com.baidu.mapapi.MKDrivingRouteResult; import com.baidu.mapapi.MKPoiInfo; import com.baidu.mapapi.MKPoiResult; import com.baidu.mapapi.MKSearch; import com.baidu.mapapi.MKSearchListener; import com.baidu.mapapi.MKTransitRouteResult; import com.baidu.mapapi.MKWalkingRouteResult; import com.baidu.mapapi.MapActivity; /** * 根据经纬度查询地址信息 * * @author liufeng * @date 2011-05-03 */ public class QueryAddressActivity extends MapActivity { // 定义地图引擎管理类 private BMapManager mapManager; // 定义搜索服务类 private MKSearch mMKSearch; private EditText longitudeEditText; private EditText latitudeEditText; private TextView addressTextView; private Button queryButton; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.query_address); // 初始化MapActivity mapManager = new BMapManager(getApplication()); // init方法的第一个参数需填入申请的API Key mapManager.init(“285B415EBAB2A92293E85502150ADA7F03C777C4”, null); super.initMapActivity(mapManager); // 初始化MKSearch mMKSearch = new MKSearch(); mMKSearch.init(mapManager, new MySearchListener()); // 通过id查询在布局文件中定义的控件 longitudeEditText = (EditText) findViewById(R.id.longitude_input); latitudeEditText = (EditText) findViewById(R.id.latitude_input); addressTextView = (TextView) findViewById(R.id.address_text); queryButton = (Button) findViewById(R.id.query_button); // 给地址查询按钮设置单击事件监听器 queryButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 用户输入的经度值 String longitudeStr = longitudeEditText.getText().toString(); // 用户输入的纬度值 String latitudeStr = latitudeEditText.getText().toString(); try { // 将用户输入的经纬度值转换成int类型 int longitude = (int) (1000000 * Double.parseDouble(longitudeStr)); int latitude = (int) (1000000 * Double.parseDouble(latitudeStr)); // 查询该经纬度值所对应的地址位置信息 mMKSearch.reverseGeocode(new GeoPoint(latitude, longitude)); } catch (Exception e) { addressTextView.setText(“查询出错,请检查您输入的经纬度值!”); } } }); } @Override protected boolean isRouteDisplayed() { return false; } @Override protected void onDestroy() { if (mapManager != null) { // 程序退出前需调用此方法 mapManager.destroy(); mapManager = null; } super.onDestroy(); } @Override protected void onPause() { if (mapManager != null) { // 终止百度地图API mapManager.stop(); } super.onPause(); } @Override protected void onResume() { if (mapManager != null) { // 开启百度地图API mapManager.start(); } super.onResume(); } /** * 内部类实现MKSearchListener接口,用于实现异步搜索服务 * * @author liufeng */ public class MySearchListener implements MKSearchListener { /** * 根据经纬度搜索地址信息结果 * * @param result 搜索结果 * @param iError 错误号(0表示正确返回) */ @Override public void onGetAddrResult(MKAddrInfo result, int iError) { if (result == null) { return; } StringBuffer sb = new StringBuffer(); // 经纬度所对应的位置 sb.append(result.strAddr).append(“/n”); // 判断该地址附近是否有POI(Point of Interest,即兴趣点) if (null != result.poiList) { // 遍历所有的兴趣点信息 for (MKPoiInfo poiInfo : result.poiList) { sb.append(“—————————————-“).append(“/n”); sb.append(“名称:”).append(poiInfo.name).append(“/n”); sb.append(“地址:”).append(poiInfo.address).append(“/n”); sb.append(“经度:”).append(poiInfo.pt.getLongitudeE6() / 1000000.0f).append(“/n”); sb.append(“纬度:”).append(poiInfo.pt.getLatitudeE6() / 1000000.0f).append(“/n”); sb.append(“电话:”).append(poiInfo.phoneNum).append(“/n”); sb.append(“邮编:”).append(poiInfo.postCode).append(“/n”); // poi类型,0:普通点,1:公交站,2:公交线路,3:地铁站,4:地铁线路 sb.append(“类型:”).append(poiInfo.ePoiType).append(“/n”); } } // 将地址信息、兴趣点信息显示在TextView上 addressTextView.setText(sb.toString()); } /** * 驾车路线搜索结果 * * @param result 搜索结果 * @param iError 错误号(0表示正确返回) */ @Override public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) { } /** * POI搜索结果(范围检索、城市POI检索、周边检索) * * @param result 搜索结果 * @param type 返回结果类型(11,12,21:poi列表 7:城市列表) * @param iError 错误号(0表示正确返回) */ @Override public void onGetPoiResult(MKPoiResult result, int type, 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) { } } } 3)AndroidManifest.xml中的配置
- <?xmlversion=“1.0”encoding=“utf-8”?>
- <manifestxmlns:android=“http://schemas.android.com/apk/res/android”
- package=“com.liufeng.baidumap”
- android:versionCode=“1”
- android:versionName=“1.0”>
- <applicationandroid:icon=“@drawable/icon”android:label=“@string/app_name”>
- <activityandroid:name=“.QueryAddressActivity”android:label=“@string/app_name”>
- <intent-filter>
- <actionandroid:name=“android.intent.action.MAIN”/>
- <categoryandroid:name=“android.intent.category.LAUNCHER”/>
- </intent-filter>
- </activity>
- </application>
- <uses-sdkandroid:minSdkVersion=“4”/>
- <!– 访问网络的权限 –>
- <uses-permissionandroid:name=“android.permission.INTERNET”/>
- <!– 访问精确位置的权限 –>
- <uses-permissionandroid:name=“android.permission.ACCESS_FINE_LOCATION”/>
- <!– 访问网络状态的权限 –>
- <uses-permissionandroid:name=“android.permission.ACCESS_NETWORK_STATE”/>
- <!– 访问WIFI网络状态的权限 –>
- <uses-permissionandroid:name=“android.permission.ACCESS_WIFI_STATE”/>
- <!– 改变WIFI网络状态的权限 –>
- <uses-permissionandroid:name=“android.permission.CHANGE_WIFI_STATE”/>
- <!– 读写存储卡的权限 –>
- <uses-permissionandroid:name=“android.permission.WRITE_EXTERNAL_STORAGE”/>
- <!– 读取电话状态的权限 –>
- <uses-permissionandroid:name=“android.permission.READ_PHONE_STATE”/>
- </manifest>
<?xml version=”1.0″ encoding=”utf-8″?> <manifest xmlns:android=”http://schemas.android.com/apk/res/android” package=”com.liufeng.baidumap” android:versionCode=”1″ android:versionName=”1.0″> <application android:icon=”@drawable/icon” android:label=”@string/app_name”> <activity android:name=”.QueryAddressActivity” android:label=”@string/app_name”> <intent-filter> <action android:name=”android.intent.action.MAIN” /> <category android:name=”android.intent.category.LAUNCHER” /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion=”4″ /> <!– 访问网络的权限 –> <uses-permission android:name=”android.permission.INTERNET” /> <!– 访问精确位置的权限 –> <uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” /> <!– 访问网络状态的权限 –> <uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” /> <!– 访问WIFI网络状态的权限 –> <uses-permission android:name=”android.permission.ACCESS_WIFI_STATE” /> <!– 改变WIFI网络状态的权限 –> <uses-permission android:name=”android.permission.CHANGE_WIFI_STATE” /> <!– 读写存储卡的权限 –> <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” /> <!– 读取电话状态的权限 –> <uses-permission android:name=”android.permission.READ_PHONE_STATE” /> </manifest> 4)运行结果截图及说明 程序在模拟器上运行的初始效果如上图所示。可以看出,地图并没有显示出来,这和我们在设计时布局时所设想的一样;另外两个输入框中也分别显示了默认给出的经纬度值。 点击“地址查询”按钮后,将看到如下图所示包含了查询结果的界面: 说明:图上的“贵州省贵阳市云岩区普陀路”正是我们要查询的地理坐标(经度:106.720397,纬度:26.597239)所对应的地址信息;同时该地址信息下方还显示出了该地址附近的10个兴趣点(POI),每个兴趣点分别包含了“名称”、“地址”、“经纬度”、“电话”、“邮编”和“兴趣点类型”信息。
备注:如果本文的示例继续做下去,就应该将MapView显示出来,同时结合第8篇文章“[008] 百度地图API之ItemizedOverlay的使用(Android)”所介绍的内容将地址信息和兴趣点标注在地图上。我想这两方面的内容都已做过详细讲解并给出了示例,再来实现这个应该并不是什么难事,看文章的你就动动手来完成它吧!
转载于:https://www.cnblogs.com/feiyue528/archive/2013/05/29/3106082.html