2020最新超详细的Android 百度地图开发讲解(5)骑行、驾车路线规划讲解

根据之前两篇文章的讲解,以及知道如何实现路线规划,以及输入起始点地址进行路线规划。详情见之前的文章:
百度地图开发 3 :https://blog.csdn.net/Ace_bb/article/details/104458854
百度地图开发 4 :https://blog.csdn.net/Ace_bb/article/details/104461149

实现其他类型路线规划的思路

通过观察之前写的代码,容易发现下面这几个重写的方法:
Android studio百度地图SDK开发 2020最新超详细的Android 百度地图开发讲解(5) 骑行、驾车路线规划讲解_第1张图片
这几个方法就是实现路线规划的核心方法,通过使用不同的方法可以实现不同类型的路线规划。

步行路线规划

之前我们已经实现了步行路线规划,也就是重写了onGetWalkingRouteResult方法。
步行路线规划可以根据步行路线的起终点数据,使用WalkingRouteOverlay画出 步行路线图层,包括起终点和转弯点。支持开发者自定义起终点和转弯点图标。 注:步行路径规划起终点距离不应超过 100 公里。

步行路线规划示例

  1. 创建路线规划检索实例
mSearch = RoutePlanSearch.newInstance();

这个可以写在onCreate中,也可以新建一个方法

//路线规划初始化    private void initRoutePlan() {        mSearch = RoutePlanSearch.newInstance();        mSearch.setOnGetRoutePlanResultListener(listener);    }
  1. 创建路线规划检索结果监听器
OnGetRoutePlanResultListener listener = new OnGetRoutePlanResultListener() {    @Override    public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {        //创建WalkingRouteOverlay实例        WalkingRouteOverlay overlay = new WalkingRouteOverlay(mBaiduMap);        if (walkingRouteResult.getRouteLines().size() > 0) {            //获取路径规划数据,(以返回的第一条数据为例)            //为WalkingRouteOverlay实例设置路径数据            overlay.setData(walkingRouteResult.getRouteLines().get(0));            //在地图上绘制WalkingRouteOverlay            overlay.addToMap();        }    }    ......};

这个在我们之前的代码中已经写过,并且有一定的更改。

  1. 设置路线规划检索监听器
mSearch.setOnGetRoutePlanResultListener(listener);

这在initRoutePlan方法中已经写出。

  1. 准备起终点信息
PlanNode stNode = PlanNode.withCityNameAndPlaceName("北京", "西二旗地铁站");PlanNode enNode = PlanNode.withCityNameAndPlaceName("北京", "百度科技园");
  1. 发起检索
mSearch.walkingSearch((new WalkingRoutePlanOption())      .from(stNode)      .to(enNode));
  1. 释放检索实例
mSearch.destroy();

综合代码:

//开始规划,这里实现多种不同的路线规划方式。    private void StarRoute(int id,ArrayList list) {        SDKInitializer.initialize(getApplicationContext());        //经纬度规划路线和动态输入规划路线二选一        // 设置起、终点信息 动态输入规划路线        PlanNode stNode = PlanNode.withCityNameAndPlaceName(list.get(0).toString(), list.get(1).toString());        PlanNode enNode = PlanNode.withCityNameAndPlaceName(list.get(2).toString(), list.get(3).toString());        switch (id){            case 1:                mSearch.walkingSearch((new WalkingRoutePlanOption())                        .from(stNode)                        .to(enNode));                break;            case 2:                if(list.get(0).toString() == list.get(2).toString()){                    mSearch.transitSearch((new TransitRoutePlanOption()).from(stNode).to(enNode));                }else{                    mSearch.masstransitSearch((new MassTransitRoutePlanOption()).from(stNode).to(enNode));                }                break;            default:break;        }    }

骑行路线规划

步骤与步行路线规划完全一样,只是调用的方法不一样。
参看官方文档:http://lbsyun.baidu.com/index.php?title=androidsdk/guide/route/bike
骑行调用的方法:

OnGetRoutePlanResultListener listener = new OnGetRoutePlanResultListener() {    ......    @Override    public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {        //创建BikingRouteOverlay实例        BikingRouteOverlay overlay = new BikingRouteOverlay(mBaiduMap);        if (bikingRouteResult.getRouteLines().size() > 0) {            //获取路径规划数据,(以返回的第一条路线为例)            //为BikingRouteOverlay实例设置数据            overlay.setData(bikingRouteResult.getRouteLines().get(0));            //在地图上绘制BikingRouteOverlay            overlay.addToMap();        }    }};
mSearch.bikingSearch((new BikingRoutePlanOption())        .from(stNode)        .to(enNode)        // ridingType  0 普通骑行,1 电动车骑行        // 默认普通骑行        .ridingType(0));

驾车规划

步骤也与步行规划完全一致。
参看官方文档:
http://lbsyun.baidu.com/index.php?title=androidsdk/guide/route/drive

OnGetRoutePlanResultListener listener = new OnGetRoutePlanResultListener() {    ......    @Override    public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {        //创建DrivingRouteOverlay实例        DrivingRouteOverlay overlay = new DrivingRouteOverlay(mBaiduMap);        if (drivingRouteResult.getRouteLines().size() > 0) {            //获取路径规划数据,(以返回的第一条路线为例)            //为DrivingRouteOverlay实例设置数据            overlay.setData(drivingRouteResult.getRouteLines().get(0));            //在地图上绘制DrivingRouteOverlay            overlay.addToMap();        }    }    ......};
mSearch.drivingSearch((new DrivingRoutePlanOption())    .from(stNode)    .to(enNode));

完整代码

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private MapView mMapView = null;    private BaiduMap mBaiduMap = null;    private Context context;    /* 设置定位代码*/    //定位相关    private double mLatitude;    private double mLongtitude;    //方向传感器    private MyOrientationListener mMyOrientationListener;    private float mCurrentX;    //自定义图标    private BitmapDescriptor mIconLocation;    //定义SDK核心类    private LocationClient mLocationClient;    public BDAbstractLocationListener myListener;    private LatLng mLastLocationData;    //判断是否是首次定位    private boolean isFirstin = true;    /* 设置定位代码 */    //设置变量target,表示默认定位的地方 默认地点华理    protected LatLng target = new LatLng(30.83673,121.510342);    //路线规划相关    private RoutePlanSearch mSearch = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        SDKInitializer.initialize(getApplicationContext());        setContentView(R.layout.activity_main);        SDKInitializer.setCoordType(CoordType.BD09LL);        //没有这个HTTP申请无法实现路线规划        SDKInitializer.setHttpsEnable(true);        /* 设置定位代码 */        this.context = this;        //获取百度地图控件        mMapView = (MapView) findViewById(R.id.bmapView);        //获取地图控件对象        mBaiduMap = mMapView.getMap();        initMyLocation(); //定位方法        /* 设置定位代码 */        //设置地图默认定位位置,地图中心位target的经纬度        MapStatusUpdate mapStatusUpdate= MapStatusUpdateFactory.newLatLng(target);        mBaiduMap.setMapStatus(mapStatusUpdate);        //设置地图缩放比例为15        mapStatusUpdate = MapStatusUpdateFactory.zoomTo(18);        mBaiduMap.setMapStatus(mapStatusUpdate);        //路线规划方法        initRoutePlan();        button();    }    private void button() {        //按钮        ImageView mImage_Loc = (ImageView) findViewById(R.id.image_loc);        Button mbut_RoutrPlan = (Button) findViewById(R.id.but_RoutrPlan);        mImage_Loc.setOnClickListener(this);        mbut_RoutrPlan.setOnClickListener(this);    }    public void onClick(View v){        SDKInitializer.initialize(getApplicationContext());        switch (v.getId()){            case R.id.image_loc:{                centerToMyLocation(mLatitude,mLongtitude);                break;            }            case R.id.but_RoutrPlan:{                Intent intent = new Intent(MainActivity.this,InputSEAddressActivity.class);                startActivityForResult(intent,0x11);                break;            }        }    }    protected void onStart() {        super.onStart();        //开启定位图层        mBaiduMap.setMyLocationEnabled(true);        if (!mLocationClient.isStarted())            mLocationClient.start();        //开启方向传感器        mMyOrientationListener.start();    }    @Override    protected void onResume() {        super.onResume();        mMapView.onResume();    }    @Override    protected void onPause() {        super.onPause();        mMapView.onPause();    }    @Override    protected void onStop() {        super.onStop();        //停止定位        mBaiduMap.setMyLocationEnabled(false);        mLocationClient.stop();        //停止方向传感器        mMyOrientationListener.stop();    }    @Override    protected void onDestroy() {        super.onDestroy();        //关闭定位图层        mBaiduMap.setMyLocationEnabled(false);        mMapView.onDestroy();        mMapView = null;    }    //定位  通过继承抽象类BDAbstractListener并重写其onReceieveLocation方法来获取定位数据,并将其传给MapView。 1    private class MyLocationListener extends BDAbstractLocationListener {        @Override        public void onReceiveLocation(BDLocation location) {            //mapView 销毁后不在处理新接收的位置            if (location == null || mMapView == null) {                return;            }            MyLocationData locData = new MyLocationData.Builder()                    .accuracy(location.getRadius())                    // 此处设置开发者获取到的方向信息,顺时针0-360                    .direction(mCurrentX).latitude(location.getLatitude())                    .longitude(location.getLongitude()).build();            mBaiduMap.setMyLocationData(locData);            //设置自定义图标            MyLocationConfiguration config = new MyLocationConfiguration(                    MyLocationConfiguration.LocationMode.NORMAL, true, mIconLocation);            mBaiduMap.setMyLocationConfiguration(config);            //更新经纬度            mLatitude = location.getLatitude();            mLongtitude = location.getLongitude();            //设置起点            mLastLocationData = new LatLng(mLatitude, mLongtitude);            if (isFirstin) {                centerToMyLocation(location.getLatitude(), location.getLongitude());                if (location.getLocType() == BDLocation.TypeGpsLocation) {                    // GPS定位结果                    Toast.makeText(context, "定位:" + location.getAddrStr(), Toast.LENGTH_SHORT).show();                } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {                    // 网络定位结果                    Toast.makeText(context, "定位:" + location.getAddrStr(), Toast.LENGTH_SHORT).show();                } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {                    // 离线定位结果                    Toast.makeText(context, "定位:" + location.getAddrStr(), Toast.LENGTH_SHORT).show();                } else if (location.getLocType() == BDLocation.TypeServerError) {                    Toast.makeText(context, "定位:服务器错误", Toast.LENGTH_SHORT).show();                } else if (location.getLocType() == BDLocation.TypeNetWorkException) {                    Toast.makeText(context, "定位:网络错误", Toast.LENGTH_SHORT).show();                } else if (location.getLocType() == BDLocation.TypeCriteriaException) {                    Toast.makeText(context, "定位:手机模式错误,请检查是否飞行", Toast.LENGTH_SHORT).show();                }                isFirstin = false;            }        }    }    //初始化定位,实现当前位置的定位 发起定位 2    private void initMyLocation() {        //缩放地图        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);        mBaiduMap.setMapStatus(msu);        //开启定位图层        mBaiduMap.setMyLocationEnabled(true);        //声明LocationClient类 LocationClient类必须在主线程中声明。需要Context类型的参数        mLocationClient = new LocationClient(getApplicationContext());        /**         * 设置定位参数包括:定位模式(高精度定位模式,低功耗定位模式和仅用设备定位模式),         * 返回坐标类型,是否打开GPS,是否返回地址信息、位置语义化信息、POI信息等等。         * 高精度定位模式:这种定位模式下,会同时使用网络定位和GPS定位,优先返回最高精度的定位结果;         * 低功耗定位模式:这种定位模式下,不会使用GPS,只会使用网络定位(Wi-Fi和基站定位);         * 仅用设备定位模式:这种定位模式下,不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位。         */        //通过LocationClientOption设置LocationClient相关参数        LocationClientOption option = new LocationClientOption();        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy        );//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备        option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系        int span = 10000;        option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要        option.setOpenGps(true);//可选,默认false,设置是否使用gps        option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到        option.setIgnoreKillProcess(false);//可选,默认false,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要        //设置locationClientOption        mLocationClient.setLocOption(option);        myListener = new MyLocationListener();        //注册监听函数 获取到位置信息时会回调该定位监听器        mLocationClient.registerLocationListener(myListener);        //解决定位到几内亚湾的问题        List<String> permissionList = new ArrayList<>();        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);        }        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {            permissionList.add(Manifest.permission.READ_PHONE_STATE);        }        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);        }        if (!permissionList.isEmpty()) {            String[] permissions = permissionList.toArray(new String[permissionList.size()]);            ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);        } else {            requestLocation();        }//        requestWindowFeature(Window.FEATURE_NO_TITLE);        //初始化图标        mIconLocation = BitmapDescriptorFactory.fromResource(R.drawable.navi_map_gps);        initOrientation();        //开始定位        mLocationClient.start();    }    //回到当前位置的方法 3    private void centerToMyLocation(double latitude, double longtitude) {        mBaiduMap.clear();        mLastLocationData = new LatLng(latitude, longtitude);        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(mLastLocationData);        mBaiduMap.animateMapStatus(msu);    }    //传感器 4    private void initOrientation() {        //传感器        mMyOrientationListener = new MyOrientationListener(context);        mMyOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {            @Override            public void onOrientationChanged(float x) {                mCurrentX = x;            }        });    }    //initMyLocation 中调用的方法,同样用于定位。 5    private void requestLocation() {        //开始定位,定位结果会回调到前面注册的监听器中        mLocationClient.start();    }    //路线规划初始化    private void initRoutePlan() {        mSearch = RoutePlanSearch.newInstance();        mSearch.setOnGetRoutePlanResultListener(listener);    }    // 路线规划模块    public OnGetRoutePlanResultListener listener = new OnGetRoutePlanResultListener() {        @Override        public void onGetWalkingRouteResult(WalkingRouteResult result) {            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {                Toast.makeText(MainActivity.this, "路线规划:未找到结果,检查输入", Toast.LENGTH_SHORT).show();                //禁止定位                isFirstin = false;            }            assert result != null;            if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {                // 起终点或途经点地址有岐义,通过以下接口获取建议查询信息                result.getSuggestAddrInfo();                return;            }            if (result.error == SearchResult.ERRORNO.NO_ERROR) {                mBaiduMap.clear();                Toast.makeText(MainActivity.this, "路线规划:搜索完成", Toast.LENGTH_SHORT).show();                WalkingRouteOverlay overlay = new WalkingRouteOverlay(mBaiduMap);                overlay.setData(result.getRouteLines().get(0));                overlay.addToMap();                overlay.zoomToSpan();            }            //禁止定位            isFirstin = false;        }        @Override        public void onGetBikingRouteResult(BikingRouteResult result) {            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {                Toast.makeText(MainActivity.this, "路线规划:未找到结果,检查输入", Toast.LENGTH_SHORT).show();                //禁止定位                isFirstin = false;            }            assert result != null;            if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {                // 起终点或途经点地址有岐义,通过以下接口获取建议查询信息                result.getSuggestAddrInfo();                return;            }            if (result.error == SearchResult.ERRORNO.NO_ERROR) {                mBaiduMap.clear();                Toast.makeText(MainActivity.this, "路线规划:搜索完成", Toast.LENGTH_SHORT).show();                BikingRouteOverlay overlay = new BikingRouteOverlay(mBaiduMap);                overlay.setData(result.getRouteLines().get(0));                overlay.addToMap();                overlay.zoomToSpan();            }            //禁止定位            isFirstin = false;        }        @Override        public void onGetDrivingRouteResult(DrivingRouteResult result) {            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {                Toast.makeText(MainActivity.this, "路线规划:未找到结果,检查输入", Toast.LENGTH_SHORT).show();                //禁止定位                isFirstin = false;            }            assert result != null;            if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {                // 起终点或途经点地址有岐义,通过以下接口获取建议查询信息                result.getSuggestAddrInfo();                return;            }            if (result.error == SearchResult.ERRORNO.NO_ERROR) {                mBaiduMap.clear();                Toast.makeText(MainActivity.this, "路线规划:搜索完成", Toast.LENGTH_SHORT).show();                DrivingRouteOverlay overlay = new DrivingRouteOverlay(mBaiduMap);                overlay.setData(result.getRouteLines().get(0));                overlay.addToMap();                overlay.zoomToSpan();            }            //禁止定位            isFirstin = false;        }        @Override        public void onGetTransitRouteResult(TransitRouteResult var1) {        }        @Override        public void onGetMassTransitRouteResult(MassTransitRouteResult var1) {        }        @Override        public void onGetIndoorRouteResult(IndoorRouteResult var1) {        }    };    //开始规划,这里实现多种不同的路线规划方式。    private void StarRoute(int id,ArrayList list) {        SDKInitializer.initialize(getApplicationContext());        //经纬度规划路线和动态输入规划路线二选一        // 设置起、终点信息 动态输入规划路线        PlanNode stNode = PlanNode.withCityNameAndPlaceName(list.get(0).toString(), list.get(1).toString());        PlanNode enNode = PlanNode.withCityNameAndPlaceName(list.get(2).toString(), list.get(3).toString());        switch (id){            case 1: {                mSearch.walkingSearch((new WalkingRoutePlanOption()) //步行规划                        .from(stNode)                        .to(enNode));                break;            }            case 2:{                mSearch.bikingSearch((new BikingRoutePlanOption()) //骑行规划                        .from(stNode)                        .to(enNode));                break;            }            case 3: {                mSearch.drivingSearch((new DrivingRoutePlanOption()) //驾车规划                        .from(stNode)                        .to(enNode));                break;            }            default:break;        }    }    @Override    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(requestCode == 0x11){            ArrayList address = data.getCharSequenceArrayListExtra("address");            StarRoute(resultCode,address);        }    }}

InputSEAddressActivity

public class InputSEAddressActivity extends AppCompatActivity implements View.OnClickListener{    private Button btnWalk, btnBike,btnDrive;    private EditText start_edt_city, start_edt_address, end_edt_city, end_edt_address;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_input_address);        button();    }    private void button() {        btnWalk = findViewById(R.id.btn_walk);        btnBike = findViewById(R.id.btn_bike);        btnDrive = findViewById(R.id.btn_drive);//                start_edt_city = findViewById(R.id.Start_Edt_City_school);        start_edt_address = findViewById(R.id.Start_Edt_Address_school);//       end_edt_city = findViewById(R.id.End_Edt_City_school);        end_edt_address = findViewById(R.id.End_Edt_Address_school);        //按钮事件处理        btnWalk.setOnClickListener(this);        btnBike.setOnClickListener(this);        btnDrive.setOnClickListener(this);    }    @Override    public void onClick(View v) {        SDKInitializer.initialize(getApplicationContext());        Intent intentaddress=getIntent();        String startCity = "上海";        String startAddress = start_edt_address.getText().toString();        String endCity = "上海";        String endAddress = end_edt_address.getText().toString();        ArrayList<String> addressList = new ArrayList<>();        addressList.add(startCity);        addressList.add(startAddress);        addressList.add(endCity);        addressList.add(endAddress);        //先判断起始点地址框输入是否为空        if (startCity.isEmpty() || startAddress.isEmpty() || endCity.isEmpty() || endAddress.isEmpty()) {            Toast.makeText(this, "起点和终点不能为空", Toast.LENGTH_SHORT).show();        } else {            Intent intent = new Intent();//新建意图            intent.putStringArrayListExtra("address", addressList);            switch (v.getId()) {                case R.id.btn_walk: {                    setResult(1, intent);  //1是resultCode,相当于回传给MainActivity的暗号                    break;                             //用来将意图区分开,以实现不同的路线规划                }                case R.id.btn_bike: {                    setResult(2, intent);                    break;                }                case R.id.btn_drive:{                    setResult(3, intent);                    break;                }            }            finish();        }    }}

运行调试结果

路线规划结果以 从上海博物馆到上海大剧院为例

骑行路线规划结果

驾车路线规划结果

到此基本路线规划就全部完毕。 MainActivity代码的完整代码比较多。关于骑行和驾车规划的部分在代码最后面。

——————————————————————————
版权所有,转载请说明出处。 觉得有用请点赞哦!

更多相关文章

  1. Android 虚化图片的方法
  2. android完全退出程序的方法
  3. android常用方法汇总-更新中
  4. Android结束进程的方法
  5. Android 比Timer更好方法
  6. Android中AppWidget使用方法
  7. Android 官方 Lambda支持方法
  8. android BroadcastReceiver遇到 java.lang.IllegalAccessExcepti
  9. Android 调用系统相机拍照保存以及调用系统相册的方法

随机推荐

  1. Android(安卓)Fragment 详细翻译
  2. Android(安卓)中的MVP模式
  3. 五大手机操作系统
  4. Android自定义ViewPager(一)——自定义Scro
  5. Android(安卓)ImageLoader(Android-Univer
  6. Android(安卓)studio 安装 环境搭建
  7. Android(安卓)判断程序是否是第一次启动
  8. android studio 现有项目集成Phonegap
  9. FFmpeg编程开发笔记 —— Android(安卓)F
  10. 如何实现 Android(安卓)ListView『上拉加