百度地图开发-检索功能

转载请注明作者。
注:本人在找工作,地点在北京。

百度地图SDK开发(三)检索功能

目前百度地图SDK所集成的检索服务包括:POI检索、公交信息查询、线路规划、地理编码、行政区边界数据检索、在线建议查询、短串分享(包括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,看一下官方的文档。
,可以看到就这么几个方法,使用也很容易。

监听器的回调有两个方法,发起请求有两种,参数设置有两个辅助类。就这么多就能实现从地理位置到坐标和坐标到地理位置。

可以看到在效果图中输入地理位置信息就能在地图上标记出来,至于坐标转到地理位置就是调用另一个方法就可以。

总结

关于百度地图的开发就准备写这么多了。不再继续往下写了,因为写一篇博客对于我来说通常需要一天到两天的时间去了解,查资料,自己先写一遍再整理成一篇博客,对于百度地图,通过我的这三篇博客应该就可能够说实现基本的使用了,日常功能完全可以满足,更多的内容我也不怎么会 。那就这样吧。。

注:本人在找工作,地点在北京。

你可能感兴趣的:(百度地图SDK开发)