天天看點

264.高德地圖的使用---駕車出行路線規劃(4)駕車出行路線規劃

駕車出行路線規劃

駕車路徑規劃可以根據起終點和駕車路線的資料,使用 DrivingRouteOverlay 畫出駕車路線圖層,包括起終點和轉彎點。另外也可以自定義起終點和駕車轉彎點的圖示。

第 1 步,初始化 RouteSearch 對象

routeSearch = new RouteSearch(this);
           

第 2 步,設定資料回調監聽器

routeSearch.setRouteSearchListener(this);
           

第 3 步,設定搜尋參數

通過 DriveRouteQuery(RouteSearch.FromAndTo fromAndTo, int mode, List<LatLonPoint> passedByPoints, List<List<LatLonPoint>> avoidpolygons, String avoidRoad) 設定搜尋條件,方法對應的參數說明如下:

  • fromAndTo,路徑的起點終點;
  • mode,路徑規劃的政策,可選,預設為0-速度優先;詳細政策請見駕車政策說明;
  • passedByPoints,途經點,可選;
  • avoidpolygons,避讓區域,可選,支援32個避讓區域,每個區域最多可有16個頂點。如果是四邊形則有4個坐标點,如果是五邊形則有5個坐标點。
  • avoidRoad,避讓道路,隻支援一條避讓道路,避讓區域和避讓道路同時設定,隻有避讓道路生效。
// fromAndTo包含路徑規劃的起點和終點,drivingMode表示駕車模式
// 第三個參數表示途經點(最多支援16個),第四個參數表示避讓區域(最多支援32個),第五個參數表示避讓道路
DriveRouteQuery query = new DriveRouteQuery(fromAndTo, drivingMode, null, null, "");
           

第 4 步,發送請求

使用類 RouteSearch 的 calculateRideRouteAsyn(RideRouteQuery query) 方法進行騎行規劃路徑計算。

routeSearch.calculateDriveRouteAsyn(query);
           

第 5 步,接收資料

在 RouteSearch.OnRouteSearchListener 接口回調方法 void onDriveRouteSearched(DriveRouteResult result, int rCode) 處理駕車規劃路徑結果。傳回的資訊中包括:路線的距離、高速費用(僅針對7座以下轎車)、路況情況等等。

說明:

1)可以在回調中解析 result,擷取駕車的路徑。

2)result.getPaths()可以擷取到 DrivePath 清單,駕車路徑的詳細資訊可參考 DrivePath 類。

3)傳回結果成功或者失敗的響應碼。1000為成功,其他為失敗(詳細資訊參見網站開發指南-實用工具-錯誤碼對照表)

public void onDriveRouteSearched(DriveRouteResult result, int rCode) {  
   //解析result擷取算路結果,可參考官方demo
}  
           

範例

package com.ldw.hello;

import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.overlay.DrivingRouteOverlay;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.WalkRouteResult;

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

public class PassengerActivity extends AppCompatActivity {


    private MapView _mapView = null;
    private AMap _amap = null;
    private AMapLocationClient _amapLocationClient = null;
    private AMapLocationClientOption _amapLocationOption = null;
    private Button _bt_startOrder = null;
    private TextView _tv_srcAddr = null;
    private AutoCompleteTextView _attv_dstAddr = null;

    private Marker _selfMarker = null;
    private boolean isAddSelfMarker = false;
    private String _city = null;//目前定位所在的城市

    private LatLonPoint _startPoint = null;
    private LatLonPoint _endPoint = null;



    protected  void initUI() {
        _mapView = (MapView)findViewById(R.id.PassengerMap);
        _bt_startOrder = (Button)findViewById(R.id.bt_startOrder);
        _tv_srcAddr = (TextView)findViewById(R.id.tv_passenger_srcAddr);
        _attv_dstAddr = (AutoCompleteTextView)findViewById(R.id.attv_passenger_dstAddr);

    }

    //以某個經緯度為中心來展示地圖
    protected void moveMap(double latitude, double longtiude)
    {
        LatLng lagLng = new LatLng(latitude, longtiude);

        //移動amap地圖 以之前的縮放比例展示
        _amap.animateCamera(CameraUpdateFactory.newLatLngZoom(lagLng, _amap.getCameraPosition().zoom));
    }

    //向固定的經緯度添加一個标記
    protected void addMarkerToMap(double latitude, double longitude)
    {
        _selfMarker = _amap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude))
                .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.location_marker))));
    }


    protected void createMap(Bundle savedInstanceState) {
        //展示地圖容器
        _mapView.onCreate(savedInstanceState);


        //得到amap對象
        _amap = _mapView.getMap();

        //預設顯示實時交通資訊
        _amap.setTrafficEnabled(true);

    }

    //啟動定位伺服器
    protected  void doLocation()
    {
        //1 建立一個用戶端定位句柄
        _amapLocationClient = new AMapLocationClient(getApplicationContext());

        //1.5 給定位用戶端設定一些屬性
        _amapLocationOption = new AMapLocationClientOption();
        //每個5s定位一次
        _amapLocationOption.setInterval(3000);
        //_amapLocationOption.setOnceLocation(true);

        //将option設定給client對象
        _amapLocationClient.setLocationOption(_amapLocationOption);

        //2 給用戶端句柄設定一個listenner來處理伺服器傳回的定位資料
        _amapLocationClient.setLocationListener(new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {
                //onLocationChanged 就是如果伺服器給用戶端傳回資料,調用的回調函數
                //aMapLocation 就是伺服器給用戶端傳回的定位資料

                if (aMapLocation != null) {
                    //伺服器是有響應的

                    if(aMapLocation.getErrorCode() == 0) {
                        //定位成功,aMapLocation擷取資料
                        Log.e("Amap", "location succ address = "+ aMapLocation.getAddress());
                        Log.e("Amap", "city = "+ aMapLocation.getCity());
                        Log.e("Amap", "longtitude = " + aMapLocation.getLongitude());
                        Log.e("Amap", "latitude = " + aMapLocation.getLatitude());

                        if (isAddSelfMarker == false) {
                            //在此位置添加一個标記
                            addMarkerToMap(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                            isAddSelfMarker = true;

                            //以自我為中心展示地圖
                            moveMap(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                        }

                        if (_startPoint == null) {
                            //得到乘客的起始坐标點
                            _startPoint = new LatLonPoint(aMapLocation.getLatitude(),aMapLocation.getLongitude());
                        }


                        //設定乘客源位址資訊
                        _tv_srcAddr.setText(aMapLocation.getAddress());

                        _city = aMapLocation.getCity();

                    }
                    else {
                        //定位失敗,

                        Log.e("Amap", "location error, code = "+ aMapLocation.getErrorCode()+
                                ", info = "+ aMapLocation.getErrorInfo());
                    }
                }
            }
        });

        //3 開啟定位服務
        _amapLocationClient.startLocation();
    }


    //繪制駕駛交通路徑
    protected  void drawRouteLine()
    {
          //1 建立路徑的繪制的句柄 routeSearch
        RouteSearch routeSearch = new RouteSearch(getApplicationContext());

        RouteSearch.FromAndTo ft = new RouteSearch.FromAndTo(_startPoint,_endPoint);

          // 2 設定一個路徑搜尋的query
        RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(ft, RouteSearch.DrivingDefault,
                                                                            null, null, "");

        // 3 給繪制路徑的句柄設定一個callback函數
        routeSearch.setRouteSearchListener(new RouteSearch.OnRouteSearchListener() {
            @Override
            public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {
                //公交處理業務
            }

            @Override
            public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
                //駕駛的理業務

                //判斷是否請求成功
                if (i != 1000) {
                    Log.e("Amap", "搜尋駕駛路徑失敗");
                    return ;
                }


                //畫出駕駛路徑

                //1 拿到得到的路徑  (預設以第一個方案為優選方案)
                DrivePath path = driveRouteResult.getPaths().get(0);


                //駕駛路徑一個覆寫物
                DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(
                        getApplicationContext(),
                        _amap,
                        path,
                        _startPoint,
                        _endPoint
                );

                //先把之前的路徑删除掉
                _amap.clear();

                //以适當的縮放顯示路徑
                drivingRouteOverlay.zoomToSpan();

                //去掉中間轉彎的一些圖示提示
                drivingRouteOverlay.setNodeIconVisibility(false);
                drivingRouteOverlay.setThroughPointIconVisibility(false);



                //将路徑添加到地圖
                drivingRouteOverlay.addToMap();


            }

            @Override
            public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {
                //步行的理業務

            }

            @Override
            public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {
                //騎行的理業務

            }
        });

        //3 啟動路徑所有 将query穿進去 向伺服器發送請求
        routeSearch.calculateDriveRouteAsyn(query);
    }

//開啟POI興趣點搜尋
    protected  void doSerarchPOI() {
        _bt_startOrder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //開始搜尋POI興趣點

                Log.e("Amap", "button onclick");

                //拿到使用者搜尋位址的關鍵字
                String dstAddr = _attv_dstAddr.getText().toString();

                //開始POI搜尋
                // 1 建立一個搜尋的條件對象 query
                PoiSearch.Query query = new PoiSearch.Query(dstAddr, "", _city);

                // 2 建立一個POISearch句柄和query關聯
                PoiSearch poiSearch = new PoiSearch(getApplicationContext(), query);

                // 3 給search綁定一個回調函數
                poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
                    @Override
                    public void onPoiSearched(PoiResult poiResult, int i) {
                        //處理得到的POI興趣點集合 poiResult

                        if (i != 1000)  {
                            Log.e("Amap", "poi Search error code = "+ i);
                            return ;
                        }


                        //搜尋成功
                        List<PoiItem> poiList = poiResult.getPois();

                        for (int index = 0; index < poiList.size(); index++) {
                            //此時 表示處理每個已經搜尋到的興趣點

                            Log.e("Amap", "搜尋到的興趣點有");
                            PoiItem item = poiList.get(index);

                            Log.e("Amap", "poi title =" + item.getTitle()+
                            "latitude = " +item.getLatLonPoint().getLatitude()+
                            "longitude = "+ item.getLatLonPoint().getLongitude());

                            //給每個搜尋到的标記點畫一個标記
                            addMarkerToMap(item.getLatLonPoint().getLatitude(),
                                          item.getLatLonPoint().getLongitude());


                            //預設以第一個興趣點為我們坐标點
                            _endPoint = new LatLonPoint(item.getLatLonPoint().getLatitude(),
                                                      item.getLatLonPoint().getLongitude());


                            drawRouteLine();

                            if (index == 0) {
                                break;
                            }

                        }


                    }

                    @Override
                    public void onPoiItemSearched(PoiItem poiItem, int i) {

                    }
                });

                // 4 啟動搜尋
                poiSearch.searchPOIAsyn();
            }
        });
    }

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

        initUI();
        createMap(savedInstanceState);
        doLocation();


    }
}
           

參考:https://lbs.amap.com/api/android-sdk/guide/route-plan/drive