- 一简要描述
- 二地图中已标记POI点
- 1接口
- 2MapPoi 类
- 3获取POI
- 三搜索关键词获取POI点
- 描述
- 1combaidumapapisearchpoi
- 接口OnGetPoiSearchResultListener
- PoiResult类
- PoiInfo类
- 搜索POI
- 2combaidumapapisearchsug
- 接口
- SuggestionResultseggestionInfo
- 联想搜索
- 四搜索效果
- 1联想搜索效果
- 2直接搜索效果
- 3选择一条联想搜索结果
- 五总结
一.简要描述
百度地图的POI点可以分有两种:地图中已经标记的点和通过关键词搜索得到的POI点。对于这两种POI点,百度封装成了不同的类和接口来实现监听,下面简单讲一点。
二.地图中已标记POI点
首先遇到的第一个问题就时如何获取已标记点的信息,在百度地图点击已标记的点会有信息的,那么在自己的地图上如何产生点击事件呢?
(1)接口
百度提供了一个POI点击事件的接口 BaiduMap.OnMapClickListener,该接口提供了两个方法,如下表。
(测试下CSDN的MarkDown编辑器画表格的功能,不会把首行的标题居中呀)
返回类型 | 方法 | 说明 |
---|---|---|
boolean | onMapClick(LatLng point) | 地图单击事件回调函数 |
boolean | onMapPoiClick(MapPoi poi) | 地图内 Poi 单击事件回调函数 |
(2)MapPoi 类
返回类型 | 方法 | 说明 |
---|---|---|
java.lang.String | getName() | 获取该兴趣点的名称 |
LatLng | getPosition() | 获取该兴趣点的地理坐标 |
(3)获取POI
我们只需要重写onMapPoiClick()就可以了。
代码如下:
baiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
}
@Override
public boolean onMapPoiClick(MapPoi mapPoi)
{
String POIName = mapPoi.getName();//POI点名称
LatLng POIPosition = mapPoi.getPosition();//POI点坐标
//下面就是自己随便应用了
//根据POI点坐标反向地理编码
//reverseSearch(POIPosition);
//添加图层显示POI点
/*baiduMap.clear();
baiduMap.addOverlay(
new MarkerOptions()
.position(POIPosition) //坐标位置
.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_marka))
.title(POIName) //标题
);
//将该POI点设置为地图中心
baiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(POIPosition));*/
return true;
}
});
其次,为了获得该POI点的其他详细信息,因为MapPoi没有uid,我尝试通过对position进行反向地理编码,结果还是不太满意,百度地图上直接点击已标记的POI点,是可以获得该点的很多信息的(可见下面的第三部分中PoiInfo),关于这一点,暂时还没找到更好的方式解决。
三.搜索关键词获取POI点
1.描述
该功能就是百度地图首页的顶端,输入想要去的地方或者食物、店铺等名词进行POI搜索,但是这部分分两种查询结果:
(1)根据关键词直接搜索到的相关POI,对应包为com.baidu.mapapi.search.poi;
(2)根据关键词进行联想得到的POI,对应包为com.baidu.mapapi.search.sug。
所谓联想搜索得到的POI,比如我们输入上海的时候,百度会联想搜索将结果提示给你:上海菜、上海大众汽车等等,如下图
2.两种POI有用不同的接口、回调函数、数据类型,如下表:
(1)com.baidu.mapapi.search.poi
接口:OnGetPoiSearchResultListener
类型 | 方法 | 说明 |
---|---|---|
void | onGetPoiDetailResult(PoiDetailResult result) | poi详情查询结果回调 |
void | onGetPoiResult(PoiResult result) | poi 查询结果回调 |
然后主要需要了解的是
PoiResult类
PoiInfo类
搜索POI
private AutoCompleteTextView keyWorldsView;//输入搜索文字的AutoCompleteTextView
private PoiSearch mPoiSearch;//POI搜索模块
mPoiSearch = PoiSearch.newInstance();//实例化
PoiSearch.setOnGetPoiSearchResultListener(this);//监听接口
//*****
//比如在onclick事件里添加:搜索->进入回调函数:onGetPoiResult(PoiResult result)
mPoiSearch.searchInCity((new PoiCitySearchOption())//
.city(currentLoction.getCity())//定位的城市为搜索city
.keyword(keyWorldsView.getText().toString())//关键词
.pageNum(loadIndex));//第几页:默认从0开始,分页为10,所以如果搜索结果大于10,要显示多余10的部分就需要进行loadIndex=页码,或者loadIndex++等来更改loadIndex显示下一页数据
接下来就是onGetPoiResult(PoiResult result)
public void onGetPoiResult(PoiResult result) {
if (result == null
|| result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
Toast.makeText(PoiSearchDemo.this, "未找到结果", Toast.LENGTH_LONG)
.show();
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
//成功在传入的搜索city中搜索到POI
//对result进行一些应用
//一般都是添加到地图中,然后绑定一些点击事件
//官方Demo的处理如下:
mBaiduMap.clear();
PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);
mBaiduMap.setOnMarkerClickListener(overlay);
//MyPoiOverlayextends PoiOverlay;PoiOverlay extends OverlayManager
//看了这三个class之间的关系后瞬间明白咱自己也可以写overlay,重写OverlayManager中的一些方法就可以了
//比如重写了点击事件,这个方法真的太好,对不同类型的图层可能有不同的点击事件,百度地图3.4.0之后就支持设置多个监听对象了,只是本人还没把这个方法彻底掌握...
overlay.setData(result);//图层数据
overlay.addToMap();//添加到地图中(添加的都是marker)
overlay.zoomToSpan();//保证能显示所有marker
return;
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_KEYWORD) {
// 当输入关键字在本市没有找到,但在其他城市找到时,返回包含该关键字信息的城市列表
String strInfo = "在";
for (CityInfo cityInfo : result.getSuggestCityList()) {
strInfo += cityInfo.city;
strInfo += ",";
}
strInfo += "找到结果";
Toast.makeText(PoiSearchDemo.this, strInfo, Toast.LENGTH_LONG)
.show();
}
}
(2)com.baidu.mapapi.search.sug
接口
该包就一个void onGetSuggestionResult(SuggestionResult result)
SuggestionResult.seggestionInfo
从字段说明中可以看到,联想搜索的结果都是已经标记的POI点,拥有uid
联想搜索
@Override
public void onGetSuggestionResult(SuggestionResult res) {
if (res == null || res.getAllSuggestions() == null) {
return;
}
suggest = new ArrayList<String>();//获取联想搜索结果
for (SuggestionResult.SuggestionInfo info : res.getAllSuggestions()) {
if (info.key != null) {
suggest.add(info.key);
}
}
sugAdapter = new ArrayAdapter<String>(PoiSearchDemo.this, android.R.layout.simple_dropdown_item_1line, suggest);//适配器,当然可以给加上item的click事件进行处理
keyWorldsView.setAdapter(sugAdapter);
keyWorldsView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SuggestionResult.SuggestionInfo info = res.getAllSuggestions().get(position);
//String uid = info.uid;
mPoiSearch.searchPoiDetail((new PoiDetailSearchOption())//去搜索该POI的详情->onGetPoiDetailResult(PoiDetailResult result)
.poiUid(info.uid));
}
});
sugAdapter.notifyDataSetChanged();
}
四.搜索效果
(1)联想搜索效果
(2)直接搜索效果
搜索餐厅的结果:其实这里还可以个性化处理,比如在定位的附近搜索等等
(3)选择一条联想搜索结果
选在一条联想搜索结果的显示:
五.总结
就如前面所说,OverlayManager的重写,可以让我们对图层进行一些个性化的处理是非常容易的,只是自己的前期做的时候并没有发现这一点,而且有对图层的一些操作,所以现在想重构图层相关的代码真的一时半会还完成不了。