换乘方案-百万公交

来源:互联网 发布:如何申请顶级域名 编辑:程序博客网 时间:2024/04/30 08:43

需求:
输入出发位置,目的地位置,得到相应的车辆换乘信息。

需求分析
需求可以实现,有API能够查询到换乘信息,不过需要自己对信息进行再处理。

可能出现的问题

    • 出发位置不存在
    • 目的地位置不存在
    • 出发位置模糊(只知道大概位置)
    • 目的地位置模糊(只知道大概位置)


如何解决
LBS提供了推荐查询功能。对于查询的关键字,有补全信息。

例子: 太**
补全:太湖湿地公园 太仓
诸如此类,方便用户进行位置选择

同时,我们可以对用户的位置进行定位。获得详细的位置情况,直接从当前位置出发。

概要设计

设计两个Activity来完成线路查询的功能

  • LineRouteActivity 这个Activity是主要界面,显示查询的详情,在这个界面定位
  • StationInputActivity 在这个界面中输入出发点和目的地,使用了推荐算法

实现

定位的实现

主要使用了 LocationClient这个类. mLocationClient.start开启定位, mLocationClient.stop结束定位。
由于我仅仅需要定位一次,不需要持续定位,开启后需要Stop。 这个LocationClient对象是放在Application中的

    mMyLocationListener = new MyLocationListener();  //监听类    mLocationClient = new LocationClient(this.getApplicationContext()); //定位类    mLocationClient.registerLocationListener(mMyLocationListener);  //注册监听    //监听类详情。这里我把监听得到的经纬度信息存储到SharedPreferences中,可能之后还会用到    public class MyLocationListener implements BDLocationListener{    @Override    public void onReceiveLocation(BDLocation location) {        // TODO Auto-generated method stub        Log.d("onReceiveLocation", location.getAddrStr());        String resultAddres = location.getAddrStr();        if(mLocationResult!=null){            mLocationResult.setText(resultAddres);            SharedPreferences.Editor editor = getSharedPreferences("LatLong", MODE_PRIVATE).edit();            editor.putString("latitude", location.getLatitude()+"");            editor.putString("longitude", location.getLongitude()+"");            editor.commit();        }        if(mImageView !=null){            mImageView.setImageDrawable(getResources().getDrawable(R.drawable.icon_location));        }        mLocationClient.stop();    }}

上面的就是定位的主要内容,获得经纬度信息和Address的详细信息就好。需要注意的是,线路规划,尽可能使用经纬度信息,这样更加准确,不容易出现查询无结果。

SuggestionInfo,推荐信息实现

主要用到的类 suggestionSearch,就是他了。

 suggestionSearch = SuggestionSearch.newInstance(); //新建对象 suggestionSearch.setOnGetSuggestionResultListener(this); //注册监听方法 //启动suggestionSearch suggestionSearch.requestSuggestion(new SuggestionSearchOption()                    .keyword(s.toString()).city("苏州"));//查询结果public void onGetSuggestionResult(SuggestionResult result) {    // TODO Auto-generated method stub    cityAddressesList.clear();    List<SuggestionInfo> suggestionInfos = new ArrayList<SuggestionResult.SuggestionInfo>();    if(result.error == SearchResult.ERRORNO.NO_ERROR){        suggestionInfos = result.getAllSuggestions();        if((null != suggestionInfos) && (suggestionInfos.size()>0) ){            for (SuggestionInfo suggestionInfo : suggestionInfos) {                CityAddress cityAddress = new CityAddress(suggestionInfo.key, suggestionInfo.city+suggestionInfo.district);                cityAddressesList.add(cityAddress);            }            cityAddressAdapter.notifyDataSetChanged();        }        else {            Toast.makeText(getBaseContext(), "没有合适的地址",Toast.LENGTH_SHORT).show();        }        progressBar.setVisibility(View.GONE);    }    else {        Toast.makeText(this, "没有合适的地址", Toast.LENGTH_SHORT).show();    }}    //Destroy的时候记得释放对象    protected void onDestroy() {    // TODO Auto-generated method stub    super.onDestroy();    suggestionSearch.destroy();}

这一部分可能遇到的问题,就是editText 变化以后,启动建议查询功能。用户选中查询的内容,setText到edtiText后,又edittext又变化了,会引起新的建议查询。

可以设置一个boolean变量。来判断什么时候启用建议查询。编写的过程中可能会出现很多小问题,静下心来慢慢解决。

这部分用了startActivityForResult。给之前的LineRouteActivity返回了查询内容。

线路规划

这个部分难度也不大,主要是对API的熟悉,字符串的处理。
得到起点信息,终点信息进行规划就行。规划有参数,公交车,自驾,步行,以及不乘地铁,时间最快,最便捷等等参数。我这里用的是最简单的公交车,没有什么额外参数。时间有限,没有用到所有功能。

主要用的 RoutePlanSearch 这个类。 名字上就看出来是线路规划了。

    routePlanSearch = RoutePlanSearch.newInstance();    routePlanSearch.setOnGetRoutePlanResultListener(new OnGetRoutePlanResultListener() {        //步行结果        @Override        public void onGetWalkingRouteResult(WalkingRouteResult arg0) {            // TODO Auto-generated method stub        }        //公交结果        @Override        public void onGetTransitRouteResult(TransitRouteResult result) {            // TODO Auto-generated method stub            if(result == null || result.error != SearchResult.ERRORNO.NO_ERROR){                Toast.makeText(getBaseContext(),"抱歉,未找到结果" , Toast.LENGTH_SHORT).show();                progressBar.setVisibility(View.GONE);                return;            }            if(result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR ){                progressBar.setVisibility(View.GONE);                return;            }            if(result.error == SearchResult.ERRORNO.NO_ERROR){                progressBar.setVisibility(View.GONE);                listViewInfo.setVisibility(View.VISIBLE);                transitRouteLineInfo.clear();                TransitRouteLineInfo info = null;                List<TransitRouteLine> mRouteLines =  result.getRouteLines();                List<TransitStep> mTransitSteps = null;                Calendar c = Calendar.getInstance();                c.setTime(new Date());                //可能有好几条规划结果                for (TransitRouteLine transitRouteLine : mRouteLines) {                    ArrayList<String> lineRoute = new ArrayList<String>();                    c.add(Calendar.SECOND, transitRouteLine.getDuration());                    String distanceStr = BusUtils.getKm(transitRouteLine.getDistance());                    String durationStr = BusUtils.getHour(transitRouteLine.getDuration());                    Log.d("duration", transitRouteLine.getDuration()+"");                    String arrivedTimeStr = BusUtils.addZeroBeforeTime(c.getTime())+"到达";                    int sumWalkingLength = 0;                    mTransitSteps = transitRouteLine.getAllStep();                    //对每一条结果进行单独处理                    for (TransitStep transitStep : mTransitSteps) {                        Log.d("routeline", transitStep.getInstructions()+transitStep.getStepType().name()+transitStep.getDistance());                        if((transitStep.getStepType() == TransitRouteStepType.BUSLINE)                                 || transitStep.getStepType() == TransitRouteStepType.SUBWAY){                            lineRoute.add(transitStep.getInstructions().split(",经过")[0]);                        }                        //得到步行距离 。这个TransitStep是每段路程的意思。具体查看API说明                        if(transitStep.getStepType() == TransitRouteStepType.WAKLING){                            transitStep.getDistance();                            sumWalkingLength+= transitStep.getDistance();                        }                    }                    //千米转米                    String sumWalkingLengthStr = "步行" + String.valueOf(sumWalkingLength)+"米";                    String transitLineStr = BusUtils.getTransiLine(lineRoute);                    //每条规划线路的对象                    info = new TransitRouteLineInfo(transitLineStr, arrivedTimeStr, durationStr, distanceStr, sumWalkingLengthStr);                    transitRouteLineInfo.add(info);                }                transiRouteAdapter.notifyDataSetChanged();            }        }        //驾车路线        @Override        public void onGetDrivingRouteResult(DrivingRouteResult arg0) {            // TODO Auto-generated method stub        }    });}

代码的话并不复杂,当然我自己写的我肯定这么说,也许你看着会晕。
查询的结果并不是像百度地图上,换乘几路车,步行多少之类的都清楚的有属性的。得到的是字符串,需要自己再处理,好在处理起来并是不很复杂。

无非就是千米转米,秒转小时分钟。根据TransitStep获得步行距离,车辆信息啊等等。得到以后都丢到换乘信息对象里,加入数组,全扔到adapter里,notify下就完事了。

需要注意的地方:

  • 定位的结果作为起点的话,尽量使用经纬度作为线路规划的信息。这样更加准确,当然你可以目的地也用经纬度
  • 根据需要,在onStart,或者onResume进行定位,或者新建Thread啦什么的,随自己折腾。理解这个生命周期还是很重要的
  • 打好java基础,多些代码,多看,多想。

以上就是换乘方案的主要内容,其他的细节自己再实现啦。每个人的水平不同,可能有朋友看的很迷糊..恩,多看几遍,我也是这么过来的。

0 0
原创粉丝点击