上一篇文章介绍了如何在Android平台上利用百度地图进行定位,接下来就介绍一下在获取的定位功能的基础上采用百度地图来获取周边的公交信息。

这里采用如上文同样的方式,单独写一个类,该类是对周边搜索功能的封装,NearbySearchHelper。该类向外部只暴露一个函数SearchNearby()接口;

实现的主要流程时,根据当前的定位获取周边的公交车的信息,并排除了冗余的公交车线路信息,根据搜索到的公交线路信息,继续搜索该公交车的uid(百度地图的唯一标示符),再根据具体的uid来搜索详细的公交车信息,包括起始站点。具体代码如下:

1、创建周边公交搜索帮助类:NearbySearchHelper

import java.util.ArrayList;
import java.util.List;

import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.busline.BusLineResult;
import com.baidu.mapapi.search.busline.BusLineSearch;
import com.baidu.mapapi.search.busline.OnGetBusLineSearchResultListener;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.utils.DistanceUtil;
import com.busleep.app.CustomApplication;
import com.busleep.bean.MrNearbyBus;
import com.busleep.config.Constant;
import com.busleep.listener.MrNearbySearchListener;
import com.busleep.utils.LogUtils;

/**
 * 周边公交查询帮助类;这里需要实现百度地图的两个接口,一个是Poi搜索监听器,一个是公交路线搜索监听器;
 * @author Render;
 */
public class NearbySearchHelper implements OnGetPoiSearchResultListener,

  OnGetBusLineSearchResultListener{

  public static final String TAG = "NearbySearchHelper";

  private final int BUSSTATION=0;          // 先查询周边的公交站点信息;
  private final int BUSLINE=1;              // 站点的公交信息;
  private PoiSearch mSearch = null;         // Poi点搜索模块;
  private BusLineSearch mBusLineSearch = null;  // 公交路线搜索模块;

  private int mType;                  // 查询类型;
  private int nodeIndex=-1;            // 查询的索引;

  private MrNearbySearchListener nearBySearchListener; //查询结束监听对象,该对象是为了封装而重新的一个监听器;

  private List<MrNearbyBus> nearbyBuses=null;     //查询的结果;

  public NearbySearchHelper(){

  }

  public void setNearBySearchListener(MrNearbySearchListener nearBySearchListener) {
    this.nearBySearchListener = nearBySearchListener;
  }

  /**
   * 初始化函数,主要是初始化百度地图的搜索对象以及存放周边公交信息的链表,至于Bean实体对象MrNearbyBus下文继续介绍;
   */
  public void init(){

    if(mSearch==null||mBusLineSearch==null){

      mSearch = PoiSearch.newInstance();
      mSearch.setOnGetPoiSearchResultListener(this);
      mBusLineSearch = BusLineSearch.newInstance();
      mBusLineSearch.setOnGetBusLineSearchResultListener(this);

      nearbyBuses=new ArrayList<MrNearbyBus>();

    }else {
      nearbyBuses.clear();
    }
  }

  /**
   * 销毁函数;
   */
  public void Destory(){

    mSearch.destroy();
    mBusLineSearch.destroy();
  }

   /**
   * 搜索的周边的函数;由外部程序直接调用;
   */

  public void searchNearby(){

    //设置当前的搜索类型是公交站点的搜索;

    mType=BUSSTATION;

    //获取当前位置的经度与纬度,该值是通过上文的定位方式来获取的;

    double latitude=CustomApplication.mLastLocation.getLatitude();
    double longtitude=CustomApplication.mLastLocation.getLongitude();

    //查询周边公交线路;采用百度地图的周边搜索接口,并定义周边点搜索选项,其中Constant.nearbyRadius是周边搜索的半径;
    mSearch.searchNearby(new PoiNearbySearchOption().keyword("公交站")
        .location(new LatLng(latitude,longtitude)).radius(Constant.nearbyRadius));

  }

  @Override
  public void onGetBusLineResult(BusLineResult arg0) {
    // TODO Auto-generated method stub

  }

  @Override
  public void onGetPoiDetailResult(PoiDetailResult arg0) {
    // TODO Auto-generated method stub

  }

  //该函数是百度地图的周边兴趣点搜索回调函数;该函数在两处都进行了回调,所以需要根据当前的搜索类型来进行判断;

  @Override
  public void onGetPoiResult(PoiResult result) {

    switch(mType)
    {
      case BUSSTATION:
      {
        //如果查询失败直接返回;
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR)
        {
          LogUtils.i(TAG, "查询站点失败!");
          nearBySearchListener.onRefreshBusNearby(nearbyBuses);
          return;
        }
        //处理公交站点的搜索结果;
        ProcessBusStation(result);
        break;
      }
      case BUSLINE:
      {
        //如果查询失败直接返回;
        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR)
        {
          LogUtils.i(TAG, "查询线路失败!");
          nearBySearchListener.onRefreshBusNearby(nearbyBuses);
          return;
        }
        //处理公交线路的搜索结果;
        ProcessBusLine(result);
        break;
      }
    }
  }

  /**
   * 主要是寻找该站点中是否存在相同的公交,如果存在则取两趟公交距离当前位置最近的点;
   * 由于是搜索周边的公交站,可能会存在一趟公交车经过周边的两个或者三个公交站,为了排除冗余的信息,
   * 故需要判断同一辆公交车的多个车站那个车站距离当前位置最近。
   * @return
   */

  private boolean FindSameBus(MrNearbyBus nearbyBus){

    String busName=nearbyBus.getBusName();

    LatLng nowLocation=new LatLng(CustomApplication.mLastLocation.getLatitude(),
        CustomApplication.mLastLocation.getLongitude());

    LatLng newLocation=nearbyBus.getStationLaction();

    double newDistance=DistanceUtil.getDistance(nowLocation, newLocation);
    double oldDistance=0.0;

    for(int i=0;i<nearbyBuses.size();i++)
    {
      //如果存在名称相同的公交线路;
      if(nearbyBuses.get(i).getBusName().equals(busName))
      {
        LatLng oldLocation=nearbyBuses.get(i).getStationLaction();

        //DistanceUtil是百度地图提供的计算两个经纬度坐标之间的距离工具类;

        oldDistance=DistanceUtil.getDistance(nowLocation, oldLocation);

        //如果当前的距离小于之前的距离,则更新该公交车的信息;
        if(newDistance<oldDistance)
        {
          nearbyBuses.get(i).setStationLaction(newLocation);
          nearbyBuses.get(i).setStationName(nearbyBus.getStationName());
        }
        return true;
      }
    }
    return false;
  }

  /**
   * 处理查询后的结果是公交站点的情况;
   * @param result
   */
  private void ProcessBusStation(PoiResult result){

    for (PoiInfo poi : result.getAllPoi())
    {
      if (poi.type == PoiInfo.POITYPE.BUS_STATION)
      {
        String busNames []=poi.address.split(";");

        for(int i=0;i<busNames.length;++i){

          MrNearbyBus nearbyBus=new MrNearbyBus();
          nearbyBus.setBusName(busNames[i]);
          nearbyBus.setStationName(poi.name);
          nearbyBus.setStationLaction(poi.location);

          boolean bRes=FindSameBus(nearbyBus);

          if(!bRes)
          {
            nearbyBuses.add(nearbyBus);
          }
        }
      }
    }

    //搜索完了公交站点后则根据公交站点来搜索公交路线,由于搜索时间有可能会挺长,故查询完站点后就调用周边搜索监听器

    //来刷新数据,UI线程实现了该监听器,则可以直接刷新数据。

    searchBusLine();
    nearBySearchListener.onRefreshBusNearby(nearbyBuses);
  }

  /**
   * 查询公交线路;
   */
  private void searchBusLine(){
    //nodeIndex表示当前周边站点的索引;

    nodeIndex++;

    mType=BUSLINE;

    if(nearbyBuses.isEmpty()){
      return;
    }

    //部分刷新;
    if(nodeIndex%5==0){
      nearBySearchListener.onRefreshBusNearby(nearbyBuses);
    }

    //如果此时返回表明查询完毕;
    if(nodeIndex >= nearbyBuses.size()){
      LogUtils.i(TAG, "查询完毕!");
      nearBySearchListener.onRefreshBusNearby(nearbyBuses);
      return;
    }

    //这里还是采用搜索周边的方式,效率会更高;
    double latitude=CustomApplication.mLastLocation.getLatitude();
    double longtitude=CustomApplication.mLastLocation.getLongitude();
    //获取当前节点下的周边公交车的公交名称;

    String busLineName=nearbyBuses.get(nodeIndex).getBusName();
    mSearch.searchNearby(new PoiNearbySearchOption().keyword(busLineName+"公交")
        .location(new LatLng(latitude,longtitude)).radius(Constant.nearbyRadius));
  }

  /**
   * 处理公交路线的信息;
   * @param result
   */
  private void ProcessBusLine(PoiResult result)
  {
    for (PoiInfo poi : result.getAllPoi())
    {
      if (poi.type == PoiInfo.POITYPE.BUS_LINE)
      {
        MrNearbyBus nearbyBus=nearbyBuses.get(nodeIndex);

        //如果是第一次进来;
        if(nearbyBus.getUid()==null){

          nearbyBus.setUid(poi.uid);
          String drection=poi.name;
          int index=drection.indexOf("(");
          int length=drection.length();

          drection=drection.substring(index+1,length-1);
          nearbyBus.setBusDrection(drection);

        }else {  //否则是返程公交车;

          nearbyBus.setReverseUid(poi.uid);;
        }
      }
    }
    searchBusLine();
  }
}

2、在UI中 通过该NearbySearchHelper对象可以快速的搜索到周边的公交车信息,代码如下:

public class SearchNearbyActivity extends Activity implements MrNearbySearchListener {

  private NearbySearchHelper mHelper=null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    /**
     * 创建周边搜索帮助类,初始化该帮助类,并设置帮助类的监听器;
     */
    nearbySearchHelper=new NearbySearchHelper();
    nearbySearchHelper.init();
    nearbySearchHelper.setNearBySearchListener(this);

  }

  @Override
  public void onRefreshBusNearby(List<MrNearbyBus> list) {

    for(int i=0;i<list.size();i++){

      LogUtils.i(TAG, list.get(i).getBusName());
    }

    //busNearAdapter 为显示公交信息的适配器;

    if(busNearAdapter==null){
      busNearAdapter=new BusNearAdapter(getActivity(), list);
      mBusNearListView.setAdapter(busNearAdapter);
    }
    else {
      busNearAdapter.updateListView(list);
    }
  }
}

3、对于上文中提到的保存周边公交信息的bean对象,是自定义的数据对象,MrNearbyBus 代码如下:

package com.busleep.bean;

import com.baidu.mapapi.model.LatLng;

/**
 * 周边的公交车信息;
 * @author Render;
 */
public class MrNearbyBus {

  /**
   * 公交车名称;
   */
  private String busName=null;

  /**
   * 该公交线路的uid;
   */
  private String uid=null;

  /**
   * 反向公交的Uid;
   */
  private String reverseUid=null;

  /**
   * 查到周围的站点名称,根据该名称查到的公交线路;
   */
  private String stationName=null;

  /**
   * 站点位置;
   */
  private LatLng stationLaction=null;

  /**
   * 开往的方向;
   */
  private String busDrection=null;

  /**
   * 构造函数;
   */
  public MrNearbyBus(){

  }

  public String getBusName() {
    return busName;
  }

  public String getUid() {
    return uid;
  }

  public void setUid(String uid) {
    this.uid = uid;
  }

  public String getReverseUid() {
    return reverseUid;
  }

  public void setReverseUid(String reverseUid) {
    this.reverseUid = reverseUid;
  }

  public void setBusName(String busName) {
    this.busName = busName;
  }

  public String getStationName() {
    return stationName;
  }

  public void setStationName(String stationName) {
    this.stationName = stationName;
  }

  public LatLng getStationLaction() {
    return stationLaction;
  }

  public void setStationLaction(LatLng stationLaction) {
    this.stationLaction = stationLaction;
  }

  public String getBusDrection() {
    return busDrection;
  }

  public void setBusDrection(String busDrection) {
    this.busDrection = busDrection;
  }
}

4、最后的周边公交查询结果如下图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

02-04 18:50