转载请注明作者。
注:本人在找工作,地点在北京。
目前百度地图SDK所集成的检索服务包括:POI检索、公交信息查询、线路规划、地理编码、行政区边界数据检索、在线建议查询、短串分享(包括POI搜索结果分享、驾车/公交/骑行/步行路线规划分享、反向地理编码结果分享)。 本文将简单的介绍下POI检索,路线查询,地理编码。
POI(Point of Interest),中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。
百度地图SDK提供三种类型的POI检索:周边检索、区域检索和城市内检索。
接下来就是代码时刻,通过不同的代码来展示下三种不同的搜索,其实也就是范围不同,其他的都差不多。还记得上一篇中说过的百度地图中的基本模式吗?创建对象, 创建监听器,设置参数发起请求。在检索的时候也是这个套路。
@Override
public void onClick(View v) {
if(TextUtils.isEmpty(ed_constent.getText().toString())){
return ;
}
//创建搜索对象
PoiSearch search= PoiSearch.newInstance();
//创建监听器
search.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
@Override
public void onGetPoiResult(PoiResult poiResult) {
//普通检索
if (poiResult == null || poiResult.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MainActivity.this, "没有搜索内容", Toast.LENGTH_SHORT).show();
return;
}
List allPoi = poiResult.getAllPoi();
for (PoiInfo info : allPoi) {
MarkerOptions overlay = new MarkerOptions();
overlay.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_locate));
overlay.position(info.location);
Marker marker = (Marker)baiduMap.addOverlay(overlay);
Log.d("tag", "info: " + info.toString());
Bundle bundle = new Bundle();
bundle.putString("arr", info.address);
bundle.putString("phone", info.phoneNum);
bundle.putString("name", info.name);
marker.setExtraInfo(bundle);
}
}
@Override
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
//深度检索
}
});
//设置检索参数,发起检索
PoiNearbySearchOption option=new PoiNearbySearchOption()
.keyword(ed_constent.getText().toString())
.location(mylocation)
.radius(30000);
search.searchNearby(option);
}
上面的代码完全就是按照之前的逻辑去写的,创建对象,设置监听器,设置参数。发起请求,采用的是附近检索,用到的类分别有 PoiSearch POi检索对象,OnGetPoiSearchResultListener检索的监听对象,根据检索方式的不同采用不用的检索参数对象。
经常用的就是City,Bound,Nearby三种检索方式,其他的我也不熟悉。配置好参数之后就可以发起一次检索,并且发起的形式要与检索参数相对应。之后就可以就监听器中对检索的结果进行处理了。
检索监听器的回调函数有两个,分别是普通回调和深度回调,以普通回调为例,先进行检索结果的判断,之后对结果中的信息进行处理,查出每一个POi的PoiInfo对象,之后我做的就是把info中的一些信息封装到了Marker的bundle对象中,好在之后使用。marker对象的获得是通过baidumap的addoverlay方法的返回值强转获取到的。接下来看看对于查询到的信息的使用。
infoView=View.inflate(this,R.layout.infomation,null);
name=(TextView) infoView.findViewById(R.id.name);
phone=(TextView) infoView.findViewById(R.id.phone);
arr=(TextView) infoView.findViewById(R.id.arr);
baiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
Log.d("TAG","marker:"+marker);
Bundle info= marker.getExtraInfo();
Log.d("TAG","info:"+info);
Log.d("TAG","name"+name);
name.setText(info.getString("name"));
phone.setText(info.getString("phone"));
arr.setText(info.getString("arr"));
InfoWindow infoWindow=new InfoWindow(infoView,marker.getPosition(),-30);
baiduMap.showInfoWindow(infoWindow);
return false;
}
});
利用InfoWindow和marker的点击事件,创建一个布局放置三个文本用来显示信息,之后在监听事件中取出之前放在marker对象中的bundle对象,将其中的内容显示在文本中,最后创建一个infowindow显示在地图上。看效果。
布局写的有点Low,各位就将就看吧,不过功能是实现了,对于POI检索就这多,还有就是建议大家以后写的时候别像我上面那样写,很浪费资源的,可以把搜索对象和监听回调都拿出去,在onClick方法中只对检索参数进行设置,发起检索就可以。城市检索和范围检索就是在检索参数上有所不同,其他的都一样,最后别忘了执行search.destroy(),释放资源。
在最新的V3.7.0中支持四种线路分别是,公交,驾车,步行,骑行四种。四种方式的规划模式是一样的,上代码。
public void onClick(View v) {
if(TextUtils.isEmpty(ed_start.getText().toString())|TextUtils.isEmpty(ed_end.getText().toString())){
return ;
}
RoutePlanSearch search=RoutePlanSearch.newInstance();
search.setOnGetRoutePlanResultListener(new OnGetRoutePlanResultListener() {
@Override
public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
//TODO 步行回调
}
@Override
public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
//TODO 公交回调
Log.d("TAG","result_biking:"+transitRouteResult.error);
if (transitRouteResult==null || transitRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MainActivity.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
return ;
}
if (transitRouteResult.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
//起终点或途经点地址有岐义,通过以下接口获取建议查询信息
//result.getSuggestAddrInfo()
return;
}
if (transitRouteResult.error == SearchResult.ERRORNO.NO_ERROR) {
TransitRouteOverlay overlay = new TransitRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(overlay);
overlay.setData(transitRouteResult.getRouteLines().get(0));
overlay.addToMap();
overlay.zoomToSpan();
}
}
@Override
public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
//TODO 驾车回调
Log.d("TAG","result_biking:"+drivingRouteResult.error);
if (drivingRouteResult == null || drivingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MainActivity.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
return ;
}
if (drivingRouteResult.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
//起终点或途经点地址有岐义,通过以下接口获取建议查询信息
//result.getSuggestAddrInfo()
return;
}
if (drivingRouteResult.error == SearchResult.ERRORNO.NO_ERROR) {
DrivingRouteOverlay overlay = new DrivingRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(overlay);
overlay.setData(drivingRouteResult.getRouteLines().get(0));
overlay.addToMap();
overlay.zoomToSpan();
}
}
@Override
public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
//TODO
Log.d("TAG","result_biking:"+bikingRouteResult.error);
if (bikingRouteResult == null || bikingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MainActivity.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
return ;
}
if (bikingRouteResult.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
//起终点或途经点地址有岐义,通过以下接口获取建议查询信息
//result.getSuggestAddrInfo()
return;
}
if (bikingRouteResult.error == SearchResult.ERRORNO.NO_ERROR) {
BikingRouteOverlay overlay = new BikingRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(overlay);
overlay.setData(bikingRouteResult.getRouteLines().get(0));
overlay.addToMap();
overlay.zoomToSpan();
}
}
});
PlanNode start=PlanNode.withCityNameAndPlaceName("北京",ed_start.getText().toString());
PlanNode end=PlanNode.withCityNameAndPlaceName("北京",ed_end.getText().toString());
BikingRoutePlanOption options=new BikingRoutePlanOption()
.from(start)
.to(end);
// TransitRoutePlanOption options=new TransitRoutePlanOption()
// .from(start)
// .to(end)
// .city("北京");
search.bikingSearch(options);
// search.transitSearch(options);
}
上面的代码同样也是根据之前说过的模板去写的。创建一个查询对象RoutePlanSearch,设置监听器setOnGetRoutePlanResultListener,设置查询参数BikingRoutePlanOption,发起查询search.bikingSearch(options)。百度地图中都是这么处理的。接下来仔细看下代码。原谅我的懒惰,我都写onClick方法里了。比较值得注意的就是在监听器的回调中有四个方法,分别对应着四种规划。同样的查询方法也有四种。参数的配置也有四种。在回调函数中可能会有人注意到BikingRouteOverlay类似的这种类,对应着骑车覆盖物,驾车覆盖物等,就是在地图上的显示,这些类在百度地图的类参考中是没有的。而且下载下来的SDK中也没有,最开始还以为得自己根据查询回来的路线,之后经过计算用之前说过的基本的覆盖物去写,后来在官方的demo中发现了这个东西。
,有兴趣的可以去下个demo去看看,专门有个overlayUtils包里面放着已经写好的关于路线的覆盖物。真是的。百度地图也不告诉一声。而且官方的类参考也查不到,有点不负责任啊。
上面的代码并不难。如果你已经了解了百度地图的这种创建模式就很好理解了。上效果。(效果里面显示的是骑行的路线)。
关于这个搜索的地址,可以看到我在搜索东单到西单的时候提示地址是无效的,百度对于路线规划的站点是不支持模糊查询的,必须是准确的。
还有一点就是我一共进行了两次搜索,在进行第二次搜索之后之前的搜索路线没有被清除,这点也很好解决。调用这个方法就可以 overlay.removeFromMap();
如果想要更改路线覆盖物的样式,可以直接重写overlay的两个方法,能够设置起点和终点坐标,如果想把路线改了,可以改BikingRouteOverlay中的代码,可以实现各种样式。
公交,驾车,步行的程序类似,就不多介绍了。
地理编码指的是将地址信息建立空间坐标关系的过程。有可分为正向地图编码和反向地图编码。使用的方式也很简单,跟之前的方式也是相同的,创建对象, 设置监听器,设置参数发起请求就可以。上代码。。
//创建百度地图的地理编码查询对象
GeoCoder coder=GeoCoder.newInstance();
//设置监听器
coder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
@Override
public void onGetGeoCodeResult(GeoCodeResult result) {
//地理位置查经纬度
Log.d("tag", "error_code: "+result.error);
if(result==null||result.error!= SearchResult.ERRORNO.NO_ERROR){
Toast.makeText(GeocodeActivity.this, "该点在地球上不存在",Toast.LENGTH_SHOR# #T).show();
return;
}
LatLng location = result.getLocation();
MarkerOptions overlay=new MarkerOptions();
overlay.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_locate));
overlay.position(location);
baiduMap.addOverlay(overlay);
//移动屏幕中心
MapStatusUpdate msu= MapStatusUpdateFactory.newLatLng(location);
baiduMap.animateMapStatus(msu);
}
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
//经纬度查地址
}
});
GeoCodeOption options=new GeoCodeOption()
.city("北京")
.address(ed_location.getText().toString());
//设置查询参数。发起查询
coder.geocode(options);
//坐标系查地理位置
// coder.reverseGeoCode();
}
可以看到逻辑都是一样的,不同的就是地理编码查询类GeoCoder,看一下官方的文档。
,可以看到就这么几个方法,使用也很容易。
监听器的回调有两个方法,发起请求有两种,参数设置有两个辅助类。就这么多就能实现从地理位置到坐标和坐标到地理位置。
可以看到在效果图中输入地理位置信息就能在地图上标记出来,至于坐标转到地理位置就是调用另一个方法就可以。
关于百度地图的开发就准备写这么多了。不再继续往下写了,因为写一篇博客对于我来说通常需要一天到两天的时间去了解,查资料,自己先写一遍再整理成一篇博客,对于百度地图,通过我的这三篇博客应该就可能够说实现基本的使用了,日常功能完全可以满足,更多的内容我也不怎么会 。那就这样吧。。
注:本人在找工作,地点在北京。