先看运行后的图吧:
POI(Point of Interest),中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等 详细:http://developer.baidu.com/map/sdkandev-4.htm
主要应用 MKSearch 类:
com.baidu.mapapi.search
类 MKSearch
- java.lang.Object
- com.baidu.mapapi.search.MKSearch
-
public class MKSearch extends java.lang.Object
搜索服务.用于位置检索、周边检索、范围检索、公交检索、驾乘检索、步行检索
-
-
字段概要
限定符和类型 字段和说明 static int
EBUS_NO_SUBWAY
公交检索策略常量:不含地铁static int
EBUS_TIME_FIRST
公交检索策略常量:时间优先static int
EBUS_TRANSFER_FIRST
公交检索策略常量:最少换乘static int
EBUS_WALK_FIRST
公交检索策略常量:最少步行距离static int
ECAR_AVOID_JAM
驾车策略: 躲避拥堵static int
ECAR_DIS_FIRST
驾乘检索策略常量:最短距离static int
ECAR_FEE_FIRST
驾乘检索策略常量:较少费用static int
ECAR_TIME_FIRST
驾乘检索策略常量:时间优先static int
POI_DETAIL_SEARCH
poi详细信息检索页面static int
TYPE_AREA_MULTI_POI_LIST
多关键字范围搜索、周边搜索poi列表static int
TYPE_AREA_POI_LIST
范围搜索、周边搜索poi列表static int
TYPE_CITY_LIST
城市列表static int
TYPE_POI_LIST
城市内搜索poi列表
-
方法概要
限定符和类型 | 方法和说明 |
---|---|
int | busLineSearch(java.lang.String city, java.lang.String busLineUid)
公交路线详细信息搜索 异步函数,返回结果在MKSearchListener里的onGetBusDetailResult方法通知
|
void | destory()
销毁MKSearch 模块 , 当不再使用Search 功能时,需要调用此函数
|
int | drivingSearch(java.lang.String startCity, MKPlanNode start, java.lang.String endCity, MKPlanNode end)
驾乘路线搜索.
|
int | drivingSearch(java.lang.String startCity, MKPlanNode start, java.lang.String endCity, MKPlanNode end, java.util.List<MKWpNode> wpNodes)
驾车路线搜索,可设置途经点 异步函数,返回结果在MKSearchListener里的onGetDrivingRouteResult方法通知
|
int | geocode(java.lang.String strAddr, java.lang.String city)
根据地址名获取地址信息 异步函数,返回结果在MKSearchListener里的onGetAddrResult方法通知
|
int | getPoiPageCapacity()
返回每页容量
|
int | goToPoiPage(int num)
获取指定页的的poi结果.
|
boolean | init(BMapManager bmapMan, MKSearchListener listener)
初使化,使用完成后,请调用 destroy 函数释放资源
|
int | poiDetailSearch(java.lang.String uid)
poi详细信息检索
|
boolean | poiDetailShareURLSearch(java.lang.String poiUid)
获取POI信息共享短url.
|
boolean | poiRGCShareURLSearch(GeoPoint location, java.lang.String name, java.lang.String address)
获取地址信息共享短URL.
|
int | poiSearchInbounds(java.lang.String key, GeoPoint ptLB, GeoPoint ptRT)
根据范围和检索词发起范围检索.
|
int | poiSearchInCity(java.lang.String city, java.lang.String key)
城市poi检索.
|
int | poiSearchNearBy(java.lang.String key, GeoPoint pt, int radius)
根据中心点、半径与检索词发起周边检索.
|
int | reverseGeocode(GeoPoint pt)
根据地理坐标点获取地址信息 异步函数,返回结果在MKSearchListener里的onGetAddrResult方法通知
|
int | setDrivingPolicy(int policy)
设置驾车路线规划策略.
|
void | setPoiPageCapacity(int num)
设置每页容量.
|
int | setTransitPolicy(int policy)
设置路线规划策略.
|
int | suggestionSearch(java.lang.String key, java.lang.String city)
联想词检索,根据模糊的不完备的检索词返回精确的建议搜索词 异步函数,返回结果在MKSearchListener里的onGetSuggestionResult方法通知
|
int | transitSearch(java.lang.String city, MKPlanNode start, MKPlanNode end)
公交路线搜索.
|
int | walkingSearch(java.lang.String startCity, MKPlanNode start, java.lang.String endCity, MKPlanNode end)
步行路线搜索.
|
通过上面的阅读应该有所了解了吧,直接代码了。。
这里的代码和前面(http://blog.csdn.net/majianjie/article/details/27958929)的代码变化不大:
MainActivity.java
package com.majianjie.baidumap;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MKMapViewListener;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.PoiOverlay;
import com.baidu.mapapi.map.PopupClickListener;
import com.baidu.mapapi.map.PopupOverlay;
import com.baidu.mapapi.search.MKAddrInfo;
import com.baidu.mapapi.search.MKBusLineResult;
import com.baidu.mapapi.search.MKDrivingRouteResult;
import com.baidu.mapapi.search.MKPoiInfo;
import com.baidu.mapapi.search.MKPoiResult;
import com.baidu.mapapi.search.MKSearch;
import com.baidu.mapapi.search.MKSearchListener;
import com.baidu.mapapi.search.MKShareUrlResult;
import com.baidu.mapapi.search.MKSuggestionResult;
import com.baidu.mapapi.search.MKTransitRouteResult;
import com.baidu.mapapi.search.MKWalkingRouteResult;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.example.baidumap.R;
public class MainActivity extends Activity {
//声明控件
private Button request;
private static StringBuilder sb = new StringBuilder();
private int i=1;
private Toast mToast=null;
private BMapManager mBMapManager=null;
private MapView mMapView = null; //MapView 是地图主控件
private MapController mMapController = null;//用MapController完成地图控制
private LocationClient mLocClient;
public LocationData mLocData = null;
private LocationOverlay myLocationOverlay = null;//定位图层
private boolean isRequest = false;//是否手动触发请求定位
private boolean isFirstLoc = true;//是否首次定位
private PopupOverlay mPopupOverlay = null;//弹出泡泡图层,浏览节点时使用
private View viewCache=null;
public BDLocation location = new BDLocation();
<span style="color:#ff6666;"> //POI
private MKSearch mMKSearch = null;
private Spinner detail;
private List<String> poi;
private ArrayAdapter< String> adapter;
private String poiName="";</span>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//**使用地图sdk前需先初始化BMapManager,这个必须在setContentView()先初始化
mBMapManager = new BMapManager(this);
//第一个参数是API key, 第二个参数是常用事件监听,用来处理通常的网络错误,授权验证错误等,你也可以不添加这个回调接口
mBMapManager.init("LDtH1sVwr7kygaF0aTqaVwWU", new MKGeneralListener() {
//授权错误的时候调用的回调函数
@Override
public void onGetPermissionState(int iError) {
if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
showToast("API KEY错误, 请检查!");
}
}
//一些网络状态的错误处理回调函数
@Override
public void onGetNetworkState(int iError) {
if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
Toast.makeText(getApplication(), "您的网络出错啦!", Toast.LENGTH_LONG).show();
}
}
});
//初始化
init();
//单击事件
click();
}
//* 显示Toast消息
private void showToast(String msg){
if(mToast == null){
mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
}else{
mToast.setText(msg);
mToast.setDuration(Toast.LENGTH_SHORT);
}
mToast.show();
}
private void click() {
request.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
requestLocation();
}
});
}
@Override
protected void onResume() {
//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
mMapView.onResume();
mBMapManager.start();//重新启动
mMKSearch.init(mBMapManager, new MySearchListener());
super.onResume();
}
@Override
protected void onPause() {
//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
mMapView.onPause();
super.onPause();
}
private void init() {
//使用自定义的title,注意顺序
setContentView(R.layout.activity_main); //activity的布局 //这里是添加自己定义的titlebtn.xml
//通过id找到他们
mMapView = (com.baidu.mapapi.map.MapView) findViewById(R.id.bmapView);
mMapController=mMapView.getController(); //获取地图控制器
mMapController.enableClick(true); //设置地图是否响应点击事件
request=(Button)findViewById(R.id.request);
viewCache = LayoutInflater.from(this).inflate(R.layout.pop_layout, null);
mPopupOverlay= new PopupOverlay(mMapView, new PopupClickListener() {// * 点击弹出窗口图层回调的方法
@Override
public void onClickedPopup(int arg0) {
//隐藏弹出窗口图层
mPopupOverlay.hidePop();
}
});
mMapController.enableClick(true); //* 设置地图是否响应点击事件 .
mMapController.setZoom(12); // * 设置地图缩放级别
mMapView.setBuiltInZoomControls(true); // * 显示内置缩放控件
mMapView.setTraffic(true);
<span style="color:#ff6666;"> //poi
mMKSearch = new MKSearch();
detail=(Spinner)findViewById(R.id.detail);
poi = new ArrayList<String>();
poi.add("请选择");
poi.add("ATM");
poi.add("旅馆");
poi.add("餐厅");
poi.add("公园");
poi.add("药店");
poi.add("图书馆");
poi.add("景点");
poi.add("医院");
poi.add("KFC");
poi.add("学校");
poi.add("超市");
</span>
adapter=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,poi);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
detail.setAdapter(adapter);
detail.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View v,int position, long id) {
poiName=(parent.getSelectedItem().toString());
if(poiName.equals("请选择")){}
else{
mMKSearch.init(mBMapManager, new MySearchListener());//注意,MKSearchListener只支持一个,以最后一次设置为准
mMKSearch.poiSearchNearBy(poiName, new GeoPoint((int) (39.907004 * 1E6), (int) (119.54048 * 1E6)), 5000);
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {}
});
mLocData = new LocationData();
mLocClient = new LocationClient(getApplicationContext()); // 定位SDK的核心类
//实例化定位服务,LocationClient类必须在主线程中声明
mLocClient.registerLocationListener(new BDLocationListenerImpl());//注册定位监听接口
/**
* 设置定位参数
*/
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); //打开GPRS
option.setAddrType("all");//返回的定位结果包含地址信息
option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(5000); //设置发起定位请求的间隔时间为5000ms
option.disableCache(false);//禁止启用缓存定位
//option.setPoiNumber(5); //最多返回POI个数
//option.setPoiDistance(1000); //poi查询距离
//option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息
mLocClient.setLocOption(option);
mLocClient.start(); // 调用此方法开始定位
myLocationOverlay = new LocationOverlay(mMapView);//定位图层初始化
//将定位数据设置到定位图层里
myLocationOverlay.setMarker(getResources().getDrawable(R.drawable.set));
//添加定位图层
mMapView.getOverlays().add(myLocationOverlay);
myLocationOverlay.enableCompass();
//更新图层数据执行刷新后生效
mMapView.refresh();
/*
//准备要添加的Overlay
double mLat1 = 39.910159;
double mLon1 = 119.544697;
// 用给定的经纬度构造GeoPoint,单位是微度 (度 * 1E6)
GeoPoint p1 = new GeoPoint((int) (mLat1 * 1E6), (int) (mLon1 * 1E6));
//准备overlay图像数据,根据实情情况修复
Drawable mark= getResources().getDrawable(R.drawable.set);
//用OverlayItem准备Overlay数据
OverlayItem item1 = new OverlayItem(p1,"item1","item1");
//使用setMarker()方法设置overlay图片,如果不设置则使用构建ItemizedOverlay时的默认设置
//创建IteminizedOverlay
CustomItemizedOverlay itemOverlay = new CustomItemizedOverlay(mark, mMapView);
//将IteminizedOverlay添加到MapView中
mMapView.getOverlays().clear();
mMapView.getOverlays().add(itemOverlay);
//现在所有准备工作已准备好,使用以下方法管理overlay.
//添加overlay, 当批量添加Overlay时使用addItem(List<OverlayItem>)效率更高
itemOverlay.addItem(item1);
//删除overlay .
//itemOverlay.removeItem(itemOverlay.getItem(0));
//mMapView.refresh();
//清除overlay
// itemOverlay.removeAll();
// mMapView.refresh();
mMapView.refresh();
*/
// mMapController.setCenter(p1);
mMapView.regMapViewListener(mBMapManager, new MKMapViewListener() {
// * 地图移动完成时会回调此接口 方法
@Override
public void onMapMoveFinish() {
//showToast("地图移动完毕!");
}
//* 地图加载完毕回调此接口方法
@Override
public void onMapLoadFinish() {
showToast("地图载入完毕!");
}
//* 地图完成带动画的操作(如: animationTo())后,此回调被触发
@Override
public void onMapAnimationFinish() {
}
//当调用过 mMapView.getCurrentMap()后,此回调会被触发 可在此保存截图至存储设备
@Override
public void onGetCurrentMap(Bitmap arg0) {
}
//* 点击地图上被标记的点回调此方法
@Override
public void onClickMapPoi(MapPoi arg0) {
if (arg0 != null){
showToast(arg0.strText);
}
}
});
}
class MySearchListener implements MKSearchListener{
@Override
public void onGetAddrResult(MKAddrInfo arg0, int arg1) {}
@Override
public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {}
@Override
public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {}
@Override
public void onGetPoiDetailSearchResult(int arg0, int arg1) {}
@Override
public void onGetPoiResult(MKPoiResult result, int type, int iError) {
if (result == null) {
return;
}
// 清除地图上已有的所有覆盖物
mMapView.getOverlays().clear();
// PoiOverlay是baidu map api提供的用于显示POI的Overlay
PoiOverlay poioverlay = new PoiOverlay(MainActivity.this, mMapView);
// 设置搜索到的POI数据
poioverlay.setData(result.getAllPoi());
// 在地图上显示PoiOverlay(将搜索到的兴趣点标注在地图上)
mMapView.getOverlays().add(poioverlay);
if(result.getNumPois() > 0) {
// 设置其中一个搜索结果所在地理坐标为地图的中心
MKPoiInfo poiInfo = result.getPoi(0);
mMapController.setCenter(poiInfo.pt);
}
// sb.append("共搜索到").append(result.getNumPois()).append("个POI\n");
sb.append("POI信息:").append("\n");
// 遍历当前页返回的POI(默认只返回10个)
for (MKPoiInfo poiInfo : result.getAllPoi()) {
sb.append(i+" 名称:").append(poiInfo.name).append("\n");
sb.append("地址:").append(poiInfo.address).append("\n");
i++;
}
// 通过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();
sb.delete(0,sb.length());
i=1;
}
}).create().show();
}
@Override
public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1,int arg2) {}
@Override
public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {}
@Override /** * 公交换乘路线搜索结果 * * @param result 搜索结果 * @param iError 错误号(0表示正确返回) */
public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {}
@Override /** * 步行路线搜索结果 * * @param result 搜索结果 * @param iError 错误号(0表示正确返回) */
public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
CreateMenu(menu);
return true;
}
private void CreateMenu(Menu menu){
MenuItem mnu1 =menu.add(0,0,0,"显示卫星地图");
{
mnu1.setAlphabeticShortcut('a');//设置快捷键
//mnu1.serIcon(R.drawable.icon);//设置图片
}
MenuItem mnu2 =menu.add(0,1,1,"显示街道地图");
{
mnu2.setAlphabeticShortcut('b');//设置快捷键
//mnu1.serIcon(R.drawable.icon);//设置图片
}
MenuItem mnu3 =menu.add(0,2,2,"3D地图");
{
mnu3.setAlphabeticShortcut('c');//设置快捷键
//mnu1.serIcon(R.drawable.icon);//设置图片
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == 0){
mMapView.setSatellite(true); //设置显示为卫星地图:
mMapView.setTraffic(false);
}else if(item.getItemId() == 1){
mMapView.setTraffic(true); //显示街道地图
mMapView.setSatellite(false);
}else if(item.getItemId() == 2){
//mMapView.se
}
return true;
}
public class BDLocationListenerImpl implements BDLocationListener {
// * 接收异步返回的定位结果,参数是BDLocation类型参数
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null) {
return;
}
MainActivity.this.location = location;
mLocData.latitude = location.getLatitude();
mLocData.longitude = location.getLongitude();
//如果不显示定位精度圈,将accuracy赋值为0即可
mLocData.accuracy = location.getRadius();
mLocData.direction = location.getDerect();
//将定位数据设置到定位图层里
myLocationOverlay.setData(mLocData);
//更新图层数据执行刷新后生效
mMapView.refresh();
if(isFirstLoc || isRequest){
//将给定的位置点以动画形式移动至地图中心
mMapController.animateTo(new GeoPoint(
(int) (location.getLatitude() * 1e6), (int) (location.getLongitude() * 1e6)));
showPopupOverlay(location); //载入时候就弹出
isRequest = false;
}
isFirstLoc = false;
}
// 接收异步返回的POI查询结果,参数是BDLocation类型参数
@Override
public void onReceivePoi(BDLocation poiLocation) {
}
}
private void requestLocation() {
isRequest = true;
if(mLocClient != null && mLocClient.isStarted()){
showToast("正在定位......");
mLocClient.requestLocation();
}
}
//继承MyLocationOverlay重写dispatchTap方法
private class LocationOverlay extends MyLocationOverlay{
public LocationOverlay(MapView arg0) {
super(arg0);
}
// * 在“我的位置”坐标上处理点击事件。
@Override
protected boolean dispatchTap() {
//点击我的位置显示PopupOverlay
showPopupOverlay(location);
return super.dispatchTap();
}
@Override
public void setMarker(Drawable arg0) {
super.setMarker(arg0);
}
}
@Override
protected void onDestroy() {
//MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()
mMapView.destroy();
//退出应用调用BMapManager的destroy()方法
if(mBMapManager != null){
mBMapManager.destroy();
mBMapManager = null;
}
//退出时销毁定位
if (mLocClient != null){
mLocClient.stop();
}
super.onDestroy();
}
//* 显示弹出窗口图层PopupOverlay
private void showPopupOverlay(BDLocation location){
TextView popText = ((TextView)viewCache.findViewById(R.id.location_tips));
popText.setText("[我的位置]\n" + location.getAddrStr());
mPopupOverlay.showPopup(getBitmapFromView(popText),
new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()*1e6)),
15);
}
// * 将View转换成Bitmap的方法
public static Bitmap getBitmapFromView(View view) {
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
}
有关性能的优化,这里不多讲解,正在学习中。。。/呵呵