如何实现腾讯地图的路径规划功能?

如何实现腾讯地图的路径规划功能?
前⾔
开发者在⾯对配送⾏业场景,诸如外卖,B2C零售,商超等需要路线规划的功能,尤其⽹约车⾏业,还需要⽤到计算路费、动画模拟⼩车在路线上⾏驶等功能,这个腾讯位置服务产品的⼩demo就可以实现定位、规划路线、计算距离和路费,以及模拟⼩车平滑移动等基础功能。
先看下实现效果:
新建个Android项⽬并新建个Activity,命名为DrivingRouteActivity,先来画⼀下UI布局,布局⽐较简单,由⼀个腾讯SDK包下的地图组件MapView,以及两个⽤于输⼊起始位置的输⼊框,两个确认路线规划的Button,⼀个定位当前位置的ImageView,⼀个⽤于显⽰⾏程信息的TextView组成,布局代码只是为了⽅便展⽰实现功能,所以下⾯直接贴出布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="schemas.android/apk/res/android"
xmlns:app="schemas.android/apk/res-auto"
xmlns:tools="schemas.android/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activity.DrivingRouteActivity">
&t.tencentmap.mapsdk.maps.MapView
android:id="@+id/mapview"
棉黑蚜
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="bottom"
android:paddingTop="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/from_et"
android:hint="您在哪⼉上车"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_width="match_parent"
android:layout_height="50dp"></EditText>
<ImageButton
android:id="@+id/location_ib"
android:background="@drawable/sendtocar_balloon"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:layout_width="50dp"
android:layout_height="50dp"></ImageButton>
</LinearLayout>
<EditText
android:id="@+id/to_et"
android:hint="您要去哪⼉"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"></EditText>
<TextView
android:id="@+id/orderdesc_tv"
芜湖月中华情
android:layout_width="match_parent"
android:layout_height="wrap_content"
碱法android:gravity="center"
android:textSize="20sp"></TextView>
<Button
android:id="@+id/confirm_btn"
android:text="确定"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:visibility="gone"></Button>
<Button
android:id="@+id/order_btn"
android:text="预约快车"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"></Button>
</LinearLayout>
</LinearLayout>
1.账号注册与配置
在开发之前,我们需要到腾讯位置服务官⽹注册⼀个账号
注册后进⼊控制台
选择key管理,点击创建新秘钥,按照申请信息提交申请
将上⾯申请的key在application标签下进⾏如下配置(value替换成⾃⼰的key)
<meta-data
android:name="TencentMapSDK"
android:value="XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" />
2.引⼊腾讯Android地图
进⼊Android地图SDK,下载3D版地图SDK压缩包
下载完成后打开压缩包,将libs⽂件夹下的jar包拷贝到app的libs⽬录下,右键该jar包选择add as library添加为依赖,并且在项⽬
app\src\main路径下建⽴名为jniLibs的⽬录,把压缩包libs/jniLibs/strip⽂件夹下的所有包放到jniLibs⽬录下
引⼊后在l⽂件下配置相关权限
<!-- 访问⽹络获取地图服务 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 检查⽹络可⽤性 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 访问WiFi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 需要外部存储写权限⽤于保存地图缓存 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 获取 device id 辨别设备 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
3.
配置完成,现在开始实现我们的逻辑交互,为了让实现逻辑更加清晰,我将业务逻辑代码与视图渲染代码分到了两个包中,除了activity包中的DrivingRouteActivity之外,新建了⼀个present包,并在包下建⽴⼀个DrivingRoutePresent类,分别由DrivingRouteActivity负责对UI组件进⾏视图渲染,由DrivingRoutePresent类负责业务逻辑。这⾥我还新建了⼀个contract包,并创建⼀个DrivingRouteContract接⼝,通过这个接⼝定义的⽅法,实现DrivingRoutePresent与DrivingRouteActivity之间的交互。我们在DrivingRouteContract接⼝中定义两个接⼝,⼀个View接⼝供DrivingRouteActivity实现,⼀个Presenter接⼝供DrivingRoutePresent实现,并定义⼀些初始化的⽅法
public interface DrivingRouteContract {
interface View{
void initView();//初始化View
void initOnClick();//初始化OnClickListener
void setOrderDescTV(String content);//渲染订单⾏程信息
EditText getFromET();
}
interface Presenter{
void attachView(DrivingRouteContract.View view);//绑定View
}
}
接着再让DrivingRouteActivity实现DrivingRouteContract.View接⼝并声明UI中的组件进⾏初始化
public class DrivingRouteActivity extends Activity implements DrivingRouteContract.View, View.OnClickListener {
private MapView mapView;
private TencentMap mMap;
private Button confirmBtn;
private Button orderBtn;
private ImageButton locationIB;
private EditText fromET;
private EditText toET;
private TextView orderDescTV;
private DrivingRoutePresent drivingRoutePresent;
@Override
protected void onCreate(Bundle savedInstanceState) {        Create(savedInstanceState);
setContentView(R.layout.activity_driving_route);
initView();
initOnClick();
}
@Override
public void onClick(View view) {
switch (Id()){
case der_btn:
//实现⾏程路线规划
break;
case firm_btn:
//开启动画移动
break;asmuchas
夏洛的网全文case R.id.location_ib:
//定位当前位置
break;
}
}
/**
* mapview的⽣命周期管理
*/
@Override
protected void onStart() {
}
@Override
protected void onResume() {
}
@Override
protected void onPause() {
}
@Override
protected void onStop() {
}
@Override
protected void onDestroy() {
}
@Override
protected void onRestart() {
}
@Override
嘉善团public void initView() {
mapView = findViewById(R.id.mapview);
confirmBtn = findViewById(firm_btn);
orderBtn = findViewById(der_btn);
locationIB = findViewById(R.id.location_ib);
fromET = findViewById(R.id.from_et);
toET = findViewById(_et);
orderDescTV = findViewById(derdesc_tv);        mMap = Map();
drivingRoutePresent = new DrivingRoutePresent();        drivingRoutePresent.attachView(this);
}
@Override
public void initOnClick() {
orderBtn.setOnClickListener(this);
confirmBtn.setOnClickListener(this);
locationIB.setOnClickListener(this);
}
@Override
public void setOrderDescTV(String content) {
orderDescTV.setText(content);
}
@Override
public EditText getFromET() {
return fromET;
}
}
DrivingRoutePresent实现DrivingRouteContract.Presenter接⼝
public class DrivingRoutePresent implements DrivingRouteContract.Presenter {
private DrivingRouteContract.View drinvingRouteView;
@Override
public void attachView(DrivingRouteContract.View view) {
drinvingRouteView = view;
}
}
因为我们后⾯在多个地⽅都需要⽤到当前应⽤的上下⽂,为了⽅便,需要再编写⼀个全局的应⽤上下⽂⼯具类来帮助我们获取上下⽂,建⽴⼀个util包并创建⼀个GlobalApplication类
public class GlobalApplication extends Application {
private static Context context;
@Override
public void onCreate() {
context = getApplicationContext();
}
public static Context getContext(){
return context;
}
}
同时,在Android类⽂件的application标签中加⼊下⾯属性,让应⽤启动时加载上⾯的GlobalApplication
android:name=".util.GlobalApplication"
到这⾥,我们就完成了界⾯与业务代码的基本设计,运⾏app,可以看到显⽰的基本地图信息。接下来我们来实现⼀下路线规划的功能。腾讯官⽅Android地图SDK开发⽂档对路线规划服务和地址解析都
有较详细的说明。
另外还提供了调⽤⽰例Demo。如果不清楚如何调⽤的话可以参考官⽅Demo或参考下⾯代码。
4.地址解析与路线规划
⾸先我们在DrivingRouteContract.Presenter接⼝申明⼀个⽤于通过地址查经纬度的geocoder⽅法和⼀个⽤于路线规划的routePlan⽅法
public interface DrivingRouteContract {
interface View{
void initView();//初始化View
void initOnClick();//初始化OnClickListener
void setOrderDescTV(String content);//渲染订单⾏程信息
EditText getFromET();
}
interface Presenter{
void attachView(DrivingRouteContract.View view);//绑定View
void geocoder(String address, Integer type);//地址解码,转经纬度
void routePlan();//实现路线规划
}
}
通过腾讯Android地图SDK路线规划服务的开发⽂档,我们了解到要获得规划路线需要先获取起点和终点的经纬度,⽽在⼀般业务场景中,我们⼏乎不会让⽤户⼿动输⼊经纬度,所以我这⾥还需要⽤到地址解析服务,通过输⼊中⽂地址来获取经纬度,再通过经纬度规划路线(不过在实际业务中最好是加上关键词输⼊提⽰这个服务,⽅便⽤户到输⼊的位置)。
在DrivingRoutePresent类中实现这两个⽅法
public static final Integer FROM_TYPE = 0x100; //获取起始位置坐标
public static final Integer TO_TYPE = 0x101; //获取⽬的位置坐标
private LatLng fromLatLng;
private LatLng toLatLng;
/**
* 地址解码
* @param address 传⼊需要解码的地址
* @param type 地址类型,起始位置、⽬的位置
*/
@Override
public void geocoder(String address, final Integer type) {
TencentSearch tencentSearch = new Context());
Address2GeoParam address2GeoParam =
new Address2GeoParam(address);
tencentSearch.address2geo(address2GeoParam, new HttpResponseListener<BaseObject>() {
@Override
public void onSuccess(int arg0, BaseObject arg1) {
if (arg1 == null) {
return;
}
Address2GeoResultObject obj = (Address2GeoResultObject)arg1;
if (sult.latLng != null) {
if (type==FROM_TYPE)
fromLatLng = sult.latLng;
else if (type==TO_TYPE)
toLatLng = sult.latLng;
routePlan();
}
}
@Override
public void onFailure(int arg0, String arg1, Throwable arg2) {
Log.e("test", "error code:" + arg0 + ", msg:" + arg1);
}
});
}
private TencentSearch tencentSearch = new Context());
private StringBuffer lineStringBuilder = new StringBuffer();//路线坐标
private Double taxiFare = 0d;//预估打车费⽤
private Float distance = 0f;//预计全程⾥程
/**
* 路线规划
*/
@Override
public void routePlan() {
if (fromLatLng!=null&&toLatLng!=null){
Toast.Context(), "正在为您规划路线", Toast.LENGTH_SHORT).show();        DrivingParam drivingParam = new DrivingParam(fromLatLng, toLatLng);
drivingParam.policy(DrivingParam.Policy.TRIP);//驾车路线规划策略,⽹约车场景,送乘客
drivingParam.setCarNumber("粤A00001");//填⼊车牌号,在路线规划时会避让车牌限⾏区域
@Override
public void onSuccess(int i, DrivingResultObject drivingResultObject) {
for (DrivingResultObject.Route route : utes){
for (LatLng latLng : route.polyline){
lineStringBuilder.append(latLng.latitude + "," + latLng.longitude);
lineStringBuilder.append(",");
}
distance += route.distance;
taxiFare += route.taxi_fare.fare;
}
drinvingRouteView.setOrderDescTV("⾏程⼤约" + distance + "m,预计¥" + taxiFare + "元");
//清空⾏程路线,⾥程,费⽤信息
lineStringBuilder = new StringBuffer();
distance = 0f;
taxiFare = 0d;
}
@Override
public void onFailure(int i, String s, Throwable throwable) {
Log.d("DrivingRouteActivity", "onSuccess: " + s + i);
}
});
fromLatLng=null;
toLatLng=null;
}
}

本文发布于:2024-09-21 18:46:59,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/487484.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:路线   规划   实现   代码   地图   需要   地址   业务
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议