百度地图 SDK(4)---- 检索功能

不知不觉研究百度地图也已经3,4天了,虽然我们一直停留在MainActivty上,但是也已经取得很不错的成果了(有些图标,UI细节没有在文章上指出)


百度地图 SDK(4)---- 检索功能_第1张图片
演示图片

可以看到我们的演示效果,虽然画质渣渣(压缩gif的缘故)但是也是有点样子的对吧。
这也算我们实现的第一个阶段吧,下一个阶段会实现其他的功能,但是可能更新频率不会很快,我要修养一段时间(开玩笑啦,其实是转Php去了,不能落下任何一个不是嘛。)不过这个我是不会放弃的,我会坚持把他做到我期待的样子,并把我开发的全过程用记录下来。

1.开始今天的旅行

目前百度地图SDK所集成的检索服务包括:POI检索、公交信息查询、线路规划、地理编码、行政区边界数据检索、在线建议查询、短串分享(包括POI搜索结果分享、驾车/公交/骑行/步行路线规划分享、反向地理编码结果分享)

POI(Point of Interest)

中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。
首先我们看一下我们百度提供的说明,
http://lbsyun.baidu.com/index.php?title=androidsdk/guide/retrieval

百度地图 SDK(4)---- 检索功能_第2张图片
BAIDU.PNG

这里的检索主要分为五个步骤,主要有3个类型
下面是百度demo里的一段代码,主要是显示在线搜索结果,那么这都是什么意思呢,这里我详细说一下。

百度地图 SDK(4)---- 检索功能_第3张图片
SUGGESTION.PNG

大家可以拿着百度地图对照,首先我们点击首页的搜索框进入一个单独的页面,输入搜索词,比如说北京大学,这时候下面立马显示一排搜索结果,并显示一些信息,那么本应该就是我们的SuggestionSearch,中文可以译作搜索建议,这个建议包含了很多数据,包括名称,地理位置等
但是百度这里用的是onGetPoiResult,(可以看到他每一条都带有详细的介绍)我们也打算用这个,
那么我们点击搜索按钮的话


百度地图 SDK(4)---- 检索功能_第4张图片
图片发自App

可以看到,这里有一个列表,一个地图,地图上还有标注。
这里就是我们的onGetPoiResult获取的结果。
最后还有一个onGetPoiDetailResult,从名字看当然是详情啦。
梳理结束之后,我们要思考设计一个页面。

……一个非专业的UI正在苦瘪界面……请稍后……

两天之后……
我终于回来了,那么我回来带来了什么呢?


演示效果

个人认为这个界面还是看的过去的,因为毕竟不是专业的UI,所以有些细节还得推敲一下。

当然如果今天我在这里将UI设计的代码那可能就跑偏了,我最多只会说说这个UI界面是怎么实现的。

首先我们回到首页

2.UI分析

点击首页的toolbar进入搜索页面,这里的搜索页面可以看到分为三部分,上方的toolbar,中间的tablayout,下面的viewpager,viewpager中在推荐这个页面是一个fragment,包含一个列表和一个下拉刷新,后期会添加一些历史纪录啥的。

那么我们输入关键字 “天安门广场” 是怎么出来这个列表的呢?
下面直接上代码

    //这是poi搜索的准备,进行一个初始化,在onCreate()里开始调用
        // 初始化搜索模块,注册搜索事件监听
        mPoiSearch = PoiSearch.newInstance();
        mPoiSearch.setOnGetPoiSearchResultListener(this);

然后他会要求activity实现他的接口里的方法,一共3个

  /**
     * 获取POI搜索结果,包括searchInCity,searchNearby,searchInBound返回的搜索结果
     * @param result
     */
    public void onGetPoiResult(PoiResult result) {

    }

    /**
     * 获取POI详情搜索结果,得到searchPoiDetail返回的搜索结果
     * @param result
     */
    public void onGetPoiDetailResult(PoiDetailResult result) {
    
    }
      //暂时先不管这个
    @Override
    public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

    }

最后别忘记销毁释放资源

   @Override
    protected void onDestroy() {
//销毁,释放资源
        mPoiSearch.destroy();
        super.onDestroy();
    }

这样我们的一个搜索框架就搭建好了,有建立,监听和销毁
下面我们来填充一下。
下面是我们的搜索框的TextWatcher

mpoi_se.addTextChangedListener(new TextWatcher() {
             @Override
             public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

             }

             @Override
             public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                 //先清空列表,这个列表是储存着onGetPoiResult结果
                //的列表,也就是说我们一旦改变了输入框内容,那么
                //以前的数据也就没用了,必须清空
                 poi_list.clear();
               
                //这里的判断也就是说如果获取到的内容不为空就开始
                //搜索,为空就直接调用更新UI的方法更新一个空列表。
                 if(!mpoi_se.getText().toString().equals("")){
                     //s_page角色是搜索页码,因为搜索结果很多,
                    //肯定是分页加载,默认是加载第0页
                      s_page = 0;

                       //这里主要控制着,搜附近还是搜城市
                       //假如说我们从主页面进入搜索页,那就是搜城市
                       //从搜城市搜出来的结果item项进入它的附近就是搜
                       //附近,那其实这两个方法都大同小异,一会在下面贴
                     if(getIntent().getStringExtra("KEY")!=null){
                         search_nearby(0);
                         Log.d("SESO", "GetMessage key: 附近");
                     }else{
                         search(0);
                         Log.d("SESO", "GetMessage key: 城市");
                     }
                     //这里我写了一个通知开始刷新的方法,主要是
                    //UI上的,如果要写这个poi搜素,UI可以自己写
                    //我就不贴UI相关的代码了
                     sendRefreshNotify("START");
                 }else{
                     //如果查询空串自动复位,这就是更新UI的方法
                    //同样不贴了
                     LoadSuggestFragment();
                 }

             }

             @Override
             public void afterTextChanged(Editable editable) {

             }
         });

可以看到我们的逻辑还是相当简单的

1.清空上次搜索的旧数据
2.搜索页面s_page置为0
3.根据从某个页面来的intent携带的值来判断是搜城市还是搜附近

那么搜城市的代码是这样的

 private void search(int i) {
        try {
//1.city方法当然填入你现在所在的城市,从主页面可以获取到,通
//过Intent传过来就好
//2.keyword是你的搜索关键字也就是输入框里打的内容
//3.isReturnAddr返回地址为真
//4.pagenum是请求第几页啦
            mPoiSearch.searchInCity((new PoiCitySearchOption())
                    .city(getIntent().getStringExtra("CITY")).keyword(mpoi_se.getText().toString())
                    .isReturnAddr(true)
                    .pageNum(i));
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.d("SE", "onClick: 开始搜索");
    }

搜附近也类似

 private void search_nearby(int i) {
        Double lati_ = getIntent().getDoubleExtra("LOCATION_latitude",39.92235);
        Double long_ = getIntent().getDoubleExtra("LOCATION_longitude",116.380338);
       //搜索附近
       //keyword不啰嗦
       //sortType是一个排序规则,从我们传递的参数来看,这个一
      //个由近到远的排序规则
      //location是一个坐标点,也就是从谁附近搜这个location就是谁
      //radius是一个搜索半径,单位是m
      //pagenum不啰嗦
        LatLng latLng = new LatLng(lati_,long_);
                    PoiNearbySearchOption nearbySearchOption = new PoiNearbySearchOption().keyword(mpoi_se.getText()
                    .toString()).sortType(PoiSortType.distance_from_near_to_far).location(latLng)
                    .radius(10000).pageNum(i);
            mPoiSearch.searchNearby(nearbySearchOption);
    }

这是两种搜索方法,搜区域我就不说了,如果有人需要的话可以参考百度demo

那么我们的搜索结果在三个重写的方法里接受,这里主要是第一个方法,其余的都没有用到

 public void onGetPoiResult(PoiResult result) {

        //得到结果后,通知停止刷新
        sendRefreshNotify("STOP");

        //搜索结果,为空或者空错误
        if (result == null || result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            Toast.makeText(SeActivity.this, "未找到结果", Toast.LENGTH_LONG)
                    .show();
            return;
        }

        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
              //用一个foreach语句将结果传递给我们的列表
                for (PoiInfo poiInfo : result.getAllPoi()) {
                    poi_list.add(0,poiInfo);
                }
       
            //有了数据,当然是通知ui,加载列表
           LoadSuggestFragment();
        }
    }

那么其实我们的PoiInfo已经包含了这个地方的名字,地址,电话,位置坐标等等,如果你想计算他到某个点的位置还可以通过下面的语法来计算

 dis = DistanceUtil.getDistance(latLng, poiInfo.location);

其实一个简单的poi搜索就这么点东西,初始化,搜索,接收数据,销毁。

那可能有朋友就会问了,我们重写的三个方法,只用了一个方法,另外两个呢?
其实第二个onGetPoiDetailResult是获取详情结果,第三个是onGetPoiIndoorResult是获取室内的结果(我们这里没考虑室内的情况),我们来看看第二种情况。

首先还是我们的初始化,销毁,重写的方法还是那些,只不过我们的搜索变成了这个样子,这里的poiUid接受一个uid参数,这个参数是onGetPoiResult获取的结果里的PoiInfo的一个属性,也就是说我们只要得到onGetPoiResult结果才能使用onGetPoiDetailResult

 //查看详情
                mPoiSearch.searchPoiDetail((new PoiDetailSearchOption())
                        .poiUid(getIntent().getStringExtra("UID")));

那么我们来看一下搜索结果
这里我们直接将搜索结果的detailUrl属性传出去了,其实这里还有很多属性,包括店铺评价啥的,这里我们就不一一展示了。

  @Override
    public void onGetPoiDetailResult(PoiDetailResult result) {
        if (result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(PoiInfoActivity.this, "抱歉,未找到详情结果", Toast.LENGTH_SHORT)
                    .show();
        } else {
            startActivity(new Intent(PoiInfoActivity.this,PoiDetailActivity.class).putExtra("URL",result.detailUrl));
        }
    }

那么poi检索到这里也就算结束了

总结

百度地图检索功能包含的内容还是很多的,这里我只拿poi举个栗子,当然还有更多的我也不会丢下的,可能在以后的学习过程中会补充上去。

你可能感兴趣的:(百度地图 SDK(4)---- 检索功能)