POI检索
POI~~~ Point of Interest,翻译过来就是“兴趣点”。我们在使用地图的时候,搜索周边的ktv,饭店,或者宾馆的时候,输入关键字,然后地图展示给我们很多个点, 这些点就是我需要的信息。这就是所谓的兴趣点,也就是一个普通的查询,然后结果的反馈罢了。
百度地图SDK提供了三种类型的POI检索:周边检索、区域检索和城市内检索。
还是从API看起。找到com.baidu.mapapi.search.poi程序包:
看到这个包中有一个回调接口,用于接收检索结果;PoiSearch类用于检索请求;PoiResult类表示搜索结果,相比它应该在OnGetPoiSearchResultListener这个接口的某个函数中最为参数~~
最后还有4个xxxOption参数类,分别对应周边检索、城市内检索、区域检索、poi详情检索。
PoiSearch :POI检索接口,是我们应该重点关注的类。
从api中可以看出,此类是一个静态类,构造方法被私有化处理,只能通过newInstance()获得实例。看到它的方法,就发现正好有4个方法对应上面四个检索参数类。
名称 | 方法 | 参数 |
范围检索 | searchInBound() | PoiBoundSearchOption |
城市内检索 | searchInCity() | PoiCitySearchOption |
周边检索 | searchInNearby() | PoiNearbySearchOption |
详情检索 | searchPoiDetail() | PoiDetailSearchOption |
实际上,详情检索与其他三种类型不算一类,它是在通过其他三种检索类型得到的结果在去查询得到详细的信息。
通过这几个类可以对不同的类型设置检索参数,下面看一下监听接口:
该接口有两个回调函数,一个用于接收返回的poi查询结果,一个用于接收返回的详情查询结果。而结果分别封装在PoiResult和PoiDetailResult这两个类中了。
PoiResult:
从这里可以看出,百度对检索结果进行了分页处理。所以在设置参数的时候,需要设置单页容量和页号。
- // 实例化PoiSearch对象
- poiSearch = PoiSearch.newInstance();
- // 设置检索监听器
- poiSearch.setOnGetPoiSearchResultListener(poiSearchListener);
- /**
- * POI检索监听器
- */
- OnGetPoiSearchResultListener poiSearchListener = new OnGetPoiSearchResultListener() {
- @Override
- public void onGetPoiResult(PoiResult poiResult) {
- if (poiResult == null
- || poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {// 没有找到检索结果
- Toast.makeText(PoiSearchActivity.this, "未找到结果",
- Toast.LENGTH_LONG).show();
- return;
- }
- if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {// 检索结果正常返回
- bdMap.clear();
- MyPoiOverlay poiOverlay = new MyPoiOverlay(bdMap);
- poiOverlay.setData(poiResult);// 设置POI数据
- bdMap.setOnMarkerClickListener(poiOverlay);
- poiOverlay.addToMap();// 将所有的overlay添加到地图上
- poiOverlay.zoomToSpan();
- //
- totalPage = poiResult.getTotalPageNum();// 获取总分页数
- Toast.makeText(
- PoiSearchActivity.this,
- "总共查到" + poiResult.getTotalPoiNum() + "个兴趣点, 分为"
- + totalPage + "页", Toast.LENGTH_SHORT).show();
- }
- }
- /**
- * 城市内搜索
- */
- private void citySearch(int page) {
- // 设置检索参数
- PoiCitySearchOption citySearchOption = new PoiCitySearchOption();
- citySearchOption.city(editCityEt.getText().toString());// 城市
- citySearchOption.keyword(editSearchKeyEt.getText().toString());// 关键字
- citySearchOption.pageCapacity(15);// 默认每页10条
- citySearchOption.pageNum(page);// 分页编号
- // 发起检索请求
- poiSearch.searchInCity(citySearchOption);
- }
- /**
- * 范围检索
- */
- private void boundSearch(int page) {
- PoiBoundSearchOption boundSearchOption = new PoiBoundSearchOption();
- LatLng southwest = new LatLng(latitude - 0.01, longitude - 0.012);// 西南
- LatLng northeast = new LatLng(latitude + 0.01, longitude + 0.012);// 东北
- LatLngBounds bounds = new LatLngBounds.Builder().include(southwest)
- .include(northeast).build();// 得到一个地理范围对象
- boundSearchOption.bound(bounds);// 设置poi检索范围
- boundSearchOption.keyword(editSearchKeyEt.getText().toString());// 检索关键字
- boundSearchOption.pageNum(page);
- poiSearch.searchInBound(boundSearchOption);// 发起poi范围检索请求
- }
- /**
- * 附近检索
- */
- private void nearbySearch(int page) {
- PoiNearbySearchOption nearbySearchOption = new PoiNearbySearchOption();
- nearbySearchOption.location(new LatLng(latitude, longitude));
- nearbySearchOption.keyword(editSearchKeyEt.getText().toString());
- nearbySearchOption.radius(1000);// 检索半径,单位是米
- nearbySearchOption.pageNum(page);
- poiSearch.searchNearby(nearbySearchOption);// 发起附近检索请求
- }
通过以上代码,就可以完成三种类型的检索,分组的时候只不过是改一下pageNum()参数。
查询出这一组组的结果之后,可以通过添加覆盖物的方式显示在地图上。但是如果按照之前的添加覆盖物的方式进行添加的话,需要在得到的List<PoiInfo>中得到经纬度数据,然后循环构造出覆盖物对象,添加到地图上。
这样做未尝不可,但是百度提供了更简便的方式给我们。
打开com.baidu.mapapi.overlayutil这个包,看到有一个类用于显示poi的overlay。
从api中得知,该类已经实现了marker点击事件的接口了。我们在接口的毁掉函数onGetPoiResult()中得到了PoiResult对象,然后可以通过setData(PoiResult poiResult)这个方法设置poi数据显示在地图上。
API中说明onPoiClick(int i)可以覆写,这样我们可覆写此方法,当点击底图上覆盖物的时候查询POI详细信息。
- class MyPoiOverlay extends PoiOverlay {
- public MyPoiOverlay(BaiduMap arg0) {
- super(arg0);
- }
- @Override
- public boolean onPoiClick(int arg0) {
- super.onPoiClick(arg0);
- PoiInfo poiInfo = getPoiResult().getAllPoi().get(arg0);
- // 检索poi详细信息
- poiSearch.searchPoiDetail(new PoiDetailSearchOption()
- .poiUid(poiInfo.uid));
- return true;
- }
- }
PoiOverlay从OverlayManager这个类中继承了:
1. addToMap() -- 将所有overlay添加到地图上
2. removeFromMap() -- 将所有overlay从地图上移除
3. zoomToSpan() -- 缩放地图,使所有overlay都在合适的视野内
这样可以在返回poi结果的时候,把poi标注在地图上了:
- if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {// 检索结果正常返回
- bdMap.clear();
- MyPoiOverlay poiOverlay = new MyPoiOverlay(bdMap);
- poiOverlay.setData(poiResult);// 设置POI数据
- bdMap.setOnMarkerClickListener(poiOverlay);
- poiOverlay.addToMap();// 将所有的overlay添加到地图上
- poiOverlay.zoomToSpan();
- //
- totalPage = poiResult.getTotalPageNum();// 获取总分页数
- Toast.makeText(
- PoiSearchActivity.this,
- "总共查到" + poiResult.getTotalPoiNum() + "个兴趣点, 分为"
- + totalPage + "页", Toast.LENGTH_SHORT).show();
- }
当我们点击一个覆盖物的时候,去查询详细信息:
- @Override
- public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
- if (poiDetailResult.error != SearchResult.ERRORNO.NO_ERROR) {
- Toast.makeText(PoiSearchActivity.this, "抱歉,未找到结果",
- Toast.LENGTH_SHORT).show();
- } else {// 正常返回结果的时候,此处可以获得很多相关信息
- Toast.makeText(
- PoiSearchActivity.this,
- poiDetailResult.getName() + ": "
- + poiDetailResult.getAddress(),
- Toast.LENGTH_LONG).show();
- }
- }
短串分享
短串分享时指:用户查询得到的地理位置对应到一个url链接地址,百度将这种地址做短了,就俗称短串。我们可以把这个短传通过短信、邮箱或者第三方分享给其他用户,当其他用户可以点击短串可以打开手机上的百度地图客户端或者手机浏览器进行查看。
目前短串分享开放了【poi搜索结果分享】和【反向地理编码结果分享】。
打开com.baidu.mapapi.search.share这个包:
我们看到这个包结构与POI的包结构非常相似。按照之前的经验,可以猜想:ShareUrlSearch是用来发起短串检索请求的;2个
xxxOption()方法用来对不同的请求类型设置参数的;onGetShareUrlResultListener是用来监听返回结果
的;ShareUrlShare就是返回结果的包装类。
- // 实例化共享URL查询接口对象
- shareUrlSearch = ShareUrlSearch.newInstance();
- // 设置共享URL结果监听函数
- shareUrlSearch.setOnGetShareUrlResultListener(shareUrlResultListener);
- /**
- * 短串检索监听器
- */
- OnGetShareUrlResultListener shareUrlResultListener = new OnGetShareUrlResultListener() {
- @Override
- public void onGetPoiDetailShareUrlResult(ShareUrlResult shareUrlResult) {
- if (shareUrlResult.error != SearchResult.ERRORNO.NO_ERROR) {
- Toast.makeText(PoiSearchActivity.this, "抱歉,未搜索到短串",
- Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(PoiSearchActivity.this, "poi详情分享url:" + shareUrlResult.getUrl(),
- Toast.LENGTH_LONG).show();
- }
- }
- @Override
- public void onGetLocationShareUrlResult(ShareUrlResult shareUrlResult) {
- if (shareUrlResult.error != SearchResult.ERRORNO.NO_ERROR) {
- Toast.makeText(PoiSearchActivity.this, "抱歉,未搜索到短串",
- Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(PoiSearchActivity.this, "请求位置信息分享url:" + shareUrlResult.getUrl(),
- Toast.LENGTH_LONG).show();
- }
- }
- };
发起请求:
- // 请求位置信息分享URL
- shareUrlSearch.requestLocationShareUrl(new LocationShareURLOption()
- .location(poiInfo.location).name("共享点名称").snippet("123"));
- // 共享点位置 --- 共享点名称 --- 通过短URL调起客户端时作为附加信息显示在名称下面
- //请求poi详情分享URL的时候参数xxxOption中只有一个uid
- shareUrlSearch
- .requestPoiDetailShareUrl(new PoiDetailShareURLOption()
- .poiUid(poiInfo.uid));
在线建议查询
指根据关键词查询在线建议词。
实现方式与短串分享大同小异。代码就略了吧~~~