2019-详细Android Studio开发百度地图(4)—百度地图_路线规划的实现

百度地图_路线规划的实现

前言

从小白一步步开始,很多资源是很久以前的,而且没有操作配套截图和资源分享。现在本踩过了很多坑,现在开发完成后决定重新写一份教程,希望能借此帮助到许多其他有这方面需求的人。
精力有限,会尽可能详细。
本文同项目同步完成,已经是做过好几个类似项目工程,但还是出了一些小问题,已经附上解决方法,本文中所用到资源文件已经附上下载链接,也可以自行去百度地图开发者官网去下载,不过由于版本更新很快,若使用本文开发还是强烈推荐使用本文提供链接进行下载,尤其是SDK,如果在构建项目中出一些问题很可能是SDK已经被官方更新导致,本文的操作步骤只在本人开发时保证有效,随着时间推移可能已经不适合,本人也不可能一直维护更新操作步骤
另外,源码已在文末给出下载地址,若导入源码出现问题很大程度上可以考虑是Android Studio(AS)和Gradle版本的问题,请自行百度去解决

还想说的是,若可以编译生成了APK,在虚拟机或实体设备运行中出现问题,给大家分享的一些本人开发百度地图调试的主要思路:
1.首先请自行百度学习一下AS的BUG调试,同其他的IDE程序一样,AS也可以标识代码运行到哪一步出现问题
2.找到出问题的代码,BUG调试里会有报错原因提示,可以直接复制报错原因,百度查找解决方法,大概率会有类似的解决帖子

相信按照本文可以解决绝大数问题,每个人的开发运行环境不同,不可避免会出一些其他问题,若还有其他问题,本人只能提供一些建议,具体措施可能还是需要你自己去解决,若分享链接失效,文末附上了**联系方式(会及时查看好友申请,同时请注明添加理由,否则不通过申请)**或者评论区冒泡。

于2020.3.7 19:16更新了失效链接,重新编辑了前言

注:
本文仅在前文的基础上只新增了步行规划,其实只要搞懂原理,只不过把路线规划其他抽象方法进行实现而已,这里仅举例实现步行规划的抽象方法。下文会具体指出在哪里实现抽象方法。
注:
路线规划的发起不能放到onCreate中,所以做了路线规划按钮。

参考官方文档(步行规划)步骤:
其实参考价值比较小,只提供了所需要的MainActivity部分代码,具体所需要的类方法以及绘制路线的覆盖物资源都没有提供,一路磕磕绊绊找了好多资源最后实现了路线规划,现分享如下(另外也可以去官方平台下载官方Demo点击下载进行参考,下面用到的资源其实也是官方的资源):
布局文件更新:

<Button
        android:id="@+id/but_RoutrPlan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="规划"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="50dp"/>

在这里插入图片描述
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;
private LocationClient mLocationClient;
public BDAbstractLocationListener myListener;
private LatLng mLastLocationData;
private boolean isFirstin = true;

// 路线规划相关
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);
    this.context = this;
    mMapView = (MapView) findViewById(R.id.bmapView);
    //获取地图控件引用
    mBaiduMap = mMapView.getMap();
    initMyLocation();
    initPoutePlan();
    button();
}
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;
    mSearch.destroy();
}
@Override
public void onClick(View v) {
    SDKInitializer.initialize(getApplicationContext());
    switch (v.getId()) {
        case R.id.but_Loc: {
            centerToMyLocation(mLatitude, mLongtitude);
            break;
        }
        case R.id.but_RoutrPlan: {
            StarRoute();
            break;
        }
    }
}

//按钮响应
private void button() {
    //按钮
    Button mbut_Loc = (Button) findViewById(R.id.but_Loc);
    Button mbut_RoutrPlan = (Button) findViewById(R.id.but_RoutrPlan);
    //按钮处理
    mbut_Loc.setOnClickListener(this);
    mbut_RoutrPlan.setOnClickListener(this);
}

//定位
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;
        }
    }
}
//初始化定位
private void initMyLocation() {
    //缩放地图
    MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
    mBaiduMap.setMapStatus(msu);
    //开启定位
    mBaiduMap.setMyLocationEnabled(true);
    //声明LocationClient类
    mLocationClient = new LocationClient(this);
    //通过LocationClientOption设置LocationClient相关参数
    LocationClientOption option = new LocationClientOption();
    option.setOpenGps(true); // 打开gps
    option.setCoorType("bd09ll"); // 设置坐标类型
    option.setIsNeedAddress(true);//设置是否需要地址信息
    option.setScanSpan(1000);
    //设置locationClientOption
    mLocationClient.setLocOption(option);
    myListener = new MyLocationListener();
    //注册监听函数
    mLocationClient.registerLocationListener(myListener);
    //初始化图标
    mIconLocation = BitmapDescriptorFactory.fromResource(R.drawable.navi_map_gps);
    initOrientation();
    //开始定位
    mLocationClient.start();
}
//回到定位中心
private void centerToMyLocation(double latitude, double longtitude) {
    mBaiduMap.clear();
    mLastLocationData = new LatLng(latitude, longtitude);
    MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(mLastLocationData);
    mBaiduMap.animateMapStatus(msu);
}
//传感器
private void initOrientation() {
    //传感器
    mMyOrientationListener = new MyOrientationListener(context);
    mMyOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
        @Override
        public void onOrientationChanged(float x) {
            mCurrentX = x;
        }
    });
}

//路线规划初始化
private void initPoutePlan() {
    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 onGetTransitRouteResult(TransitRouteResult var1) {
    }
    @Override
    public void onGetMassTransitRouteResult(MassTransitRouteResult var1) {
    }
    @Override
    public void onGetDrivingRouteResult(DrivingRouteResult result) {
    }
    @Override
    public void onGetIndoorRouteResult(IndoorRouteResult var1) {
    }
    @Override
    public void onGetBikingRouteResult(BikingRouteResult var1) {
    }
};
//开始规划
private void StarRoute() {
    SDKInitializer.initialize(getApplicationContext());
    // 设置起、终点信息
    PlanNode stNode = PlanNode.withCityNameAndPlaceName("北京", "西二旗地铁站");
    PlanNode enNode = PlanNode.withCityNameAndPlaceName("北京", "百度科技园");
    mSearch.walkingSearch((new WalkingRoutePlanOption())
            .from(stNode)
            .to(enNode));
}

}

更新完代码会有如下报错提示:
在这里插入图片描述
这就是因为缺乏相应的类包:
在这里插入图片描述
这里附上百度网盘链接: 规划资源包提取码:b73i
选中com包,复制到工程java目录下,会自动展开为如下结构:
在这里插入图片描述
报错处理:
R报错(有几处改几处,改成自己的包名的R):
在这里插入图片描述
直接删除,一般会自动引入正确的R:
在这里插入图片描述
R下的资源报错(资源在上边的链接):
(1)layout报错:
在这里插入图片描述
需要在上图路径下添加对应文件:
在这里插入图片描述
添加后:
在这里插入图片描述
(2)Style报错:
在这里插入图片描述
用下面文件进行替换:
在这里插入图片描述
替换前:
在这里插入图片描述
替换后:
在这里插入图片描述
以上报错解决完成后:
在以下assets目录下添加资源:
在这里插入图片描述
资源文件:
在这里插入图片描述
添加后:
在这里插入图片描述
至此,路线规划完成了引入,效果如下:
在这里插入图片描述
点击按钮后:
在这里插入图片描述
附加:
其他类型规划的实现,需要在如下代码处进行实现:
已经实现的步行规划:
在这里插入图片描述
还需要实现的部分:
在这里插入图片描述
在实现了上述抽象方法以后,在下图代码处进行做对应修改即可实现相应类型的路线规划:
在这里插入图片描述

工程按照步骤是能自己建好自己工程项目的
工程开发,文章撰写耗费不少精力,很多资源收集不易。若需要源码,给出源码下载链接(按需下载,前一节功能被后一节包含,需要全部功能的朋友直接下载最后一节【导航和TTS】的源码即可):
源码
生成的可运行apk:app-debug.apk 提取码:dy7h

  • 18
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值