高德地圖導航和路徑規劃

1 高德地圖定位

1.1 要使用路徑規劃和導航須要使用3Dmap

在build.gradle文件加入一下包git

api 'com.amap.api:search:6.5.0.1'
api 'com.amap.api:location:4.3.0'
api 'com.amap.api:navi-3dmap:6.4.0_3dmap6.5.0'
複製代碼

1.2 初始化mapView

private void initAMap() {
    if (aMap == null) {
      aMap = mapView.getMap();
      //地圖設置相關
      UiSettings settings = aMap.getUiSettings();
      //去掉自帶的放大縮小按鈕
      settings.setZoomControlsEnabled(false);
      //支持手勢縮放地圖
      settings.setGestureScaleByMapCenter(true);
      //地圖的觸摸事件
      aMap.setOnMapTouchListener(this);
      //地圖加載完的回調事件
      aMap.setOnMapLoadedListener(this);
      //地圖位置變化事件
      aMap.setOnCameraChangeListener(this);
      //地圖點擊事件
      aMap.setOnMapClickListener(this);
      // 綁定 Marker 被點擊事件
      aMap.setOnMarkerClickListener(markerClickListener);
      // 設置自定義InfoWindow樣式
      aMap.setInfoWindowAdapter(this);
      mAMapNavi = AMapNavi.getInstance(getApplicationContext());
      mAMapNavi.addAMapNaviListener(this);
    }
  }
複製代碼

1.3 開啓定位相關

public void startLocate() {
	mLocationClient = new AMapLocationClient(context);
	mLocationClient.setLocationListener(this);
	AMapLocationClientOption option=new AMapLocationClientOption();
	option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
	//屢次定位獲取數據
	option.setOnceLocation(false);
	option.setInterval(8*1000);
	mLocationClient.setLocationOption(option);
	mLocationClient.startLocation();

}
複製代碼

1.4 回調到下面的onLocationChanged方法中,你能夠使用自定義的回調把定位數據監聽回來

@Override
	public void onLocationChanged(AMapLocation amapLocation) {
	if (amapLocation != null && amapLocation.getErrorCode() == 0) {
		PositionEntity entity = new PositionEntity();
		entity.latitue = amapLocation.getLatitude();
		entity.longitude = amapLocation.getLongitude();
		entity.city = amapLocation.getCity();
		if (!TextUtils.isEmpty(amapLocation.getAddress())) {
			entity.address = amapLocation.getAddress();
		}
		mOnLocationGetlisGetListener.onLocationGet(entity);

	}
}
複製代碼

1.4 監聽到對應的onLocationGet方法中,使用一個定位的Marker標識就能夠

@Override
public void onLocationGet(PositionEntity entity) {
mStartPosition = new LatLng(entity.latitue, entity.longitude);
if (mIsFirstShow) {
  CameraUpdate cameraUpate = CameraUpdateFactory.newLatLngZoom(
      mStartPosition, 17);
  aMap.animateCamera(cameraUpate);
  mIsFirstShow = false;
}
mInitialMark.setPosition(mStartPosition);
processSearchTips(entity);
}
複製代碼

這樣就完成對應的定位信息api

2.路徑規劃

2.1獲取路徑規劃起始位置和終點位置的經緯度

起始信息直接使用定位的當前位置信息dom

對應的終點信息,能夠使用隨機數來肯定ide

public static void addEmulateData(AMap amap, LatLng center) {
    if (markers.size() == 0) {
		//終點位置信息的標識
      BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory
          .fromResource(R.drawable.stable_cluster_marker_one_normal);

      for (int i = 0; i < 20; i++) {
        double latitudeDelt;
        double longtitudeDelt;
        if (i % 2 == 0) {
          latitudeDelt = (Math.random() - 0.5) * 0.1;
          longtitudeDelt = (Math.random() - 0.5) * 0.1;
        } else {
          latitudeDelt = (Math.random() - 0.5) * 0.01;
          longtitudeDelt = (Math.random() - 0.5) * 0.01;
        }
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.icon(bitmapDescriptor);
		 markerOptions.position(
            new LatLng(center.latitude + latitudeDelt, center.longitude + longtitudeDelt));
        Marker marker = amap.addMarker(markerOptions);
        markers.add(marker);
      }
    } else {
      for (Marker marker : markers) {
        double latitudeDelt = (Math.random() - 0.5) * 0.1;
        double longtitudeDelt = (Math.random() - 0.5) * 0.1;
        marker.setPosition(
            new LatLng(center.latitude + latitudeDelt, center.longitude + longtitudeDelt));
		}
    }
}
複製代碼

2.2 設置marker的點擊事件,動態計算對應的路線

AMap.OnMarkerClickListener markerClickListener = new AMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(final Marker marker) {
  LogUtils.w("點擊的Marker");
  LogUtils.w(marker.getPosition() + "");
  isClickIdentification = true;
  //清除原先的路徑
  clearRoute();
  //增長動畫
  startAnim(marker);
      new Thread(new Runnable() {
        @Override
        public void run() {
          try {
            Thread.sleep(300);
            tempMark = marker;
            mStartPoint = new LatLonPoint(mRecordPositon.latitude, mRecordPositon.longitude);
            startList.add(new NaviLatLng(mRecordPositon.latitude, mRecordPositon.longitude));
            mPositionMark.setPosition(mRecordPositon);
            mEndPoint = new LatLonPoint(marker.getPosition().latitude,
                marker.getPosition().longitude);
            handleEndList(mEndPoint);
			//規劃路徑
            planRoute();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }).start();
      return true;
    }
  };
複製代碼

2.3 路徑規劃路徑選擇

調用如下事件就能夠,在對應的onCalculateRouteSuccess會返回對應的路徑gradle

mAMapNavi.calculateRideRoute(startList.get(0), endList.get(0));
複製代碼

返回的路徑會存在多條,每一個對應進行處理便可動畫

@Override
public void onCalculateRouteSuccess(int[] ints) {
    if (ints.length == 1) {
      onCalculateRouteSuccessOld();
    } else {
      onCalculateMultipleRoutesSuccessOld(ints);
    }
}

private void onCalculateRouteSuccessOld() {
    /**
     * 清空上次計算的路徑列表。
     */
    routeOverlays.clear();
    ways.clear();
    AMapNaviPath path = mAMapNavi.getNaviPath();
    /**
     * 單路徑不須要進行路徑選擇,直接傳入-1便可
     */
    drawRoutes(-1, path);
    showMarkInfo(path);
}


private void onCalculateMultipleRoutesSuccessOld(int[] ints) {
	//清空上次計算的路徑列表。
	routeOverlays.clear();
	ways.clear();
	HashMap<Integer, AMapNaviPath> paths = mAMapNavi.getNaviPaths();
	for (int i = 0; i < ints.length; i++) {
	  AMapNaviPath path = paths.get(ints[i]);
	  if (path != null) {
	    drawRoutes(ints[i], path);
	    ways.add(path);
	  }
	}
	changeRoute();
}
複製代碼

2.4 路徑規劃畫線

畫線其實也就是調用高德的api便可ui

/**
   * 繪製路線
   */
  private void drawRoutes(int routeId, AMapNaviPath path) {
    calculateSuccess = true;
    aMap.moveCamera(CameraUpdateFactory.changeTilt(0));
	//路徑繪製圖層
    RouteOverLay routeOverLay = new RouteOverLay(aMap, path, this);
    routeOverLay.setTrafficLine(false);
    routeOverLay.addToMap();
    routeOverlays.put(routeId, routeOverLay);	
  }
複製代碼

3 實時導航

導航其實只要調用AMapNavi的startNavi便可this

mAMapNaviView.setAMapNaviViewListener(this);
//獲取AMapNavi實例
mAMapNavi = AMapNavi.getInstance(this);
//添加監聽回調,用於處理算路成功
mAMapNavi.addAMapNaviListener(this);

//實例化語音引擎
mTtsManager = TTSController.getInstance(getApplicationContext());
mTtsManager.init();
mAMapNavi.addAMapNaviListener(mTtsManager);
mAMapNavi.startNavi(NaviType.GPS);
複製代碼

3.1 加入訊飛語音導航

須要實現AMapNaviListener接口,通常處理下面幾個接口就能夠了spa

@Override
public void onCalculateRouteFailure(int arg0) {
    if (wordList != null)
        wordList.addLast("路線規劃失敗");
}

@Override
public void onGetNavigationText(int arg0, String arg1) {
	//導航相關的語音播報
    if (wordList != null)
        wordList.addLast(arg1);
    handler.obtainMessage(CHECK_TTS_PLAY).sendToTarget();
}

 @Override
public void onReCalculateRouteForTrafficJam() {
    if (wordList != null)
        wordList.addLast("前方路線擁堵,路線從新規劃");
}

@Override
public void onReCalculateRouteForYaw() {
    if (wordList != null)
        wordList.addLast("路線從新規劃");
}
複製代碼

回調須要是用Handler來處理,主要是播報方式是隊列模式。其原理就是依次將須要播報的語音放入鏈表中,播報過程是從頭開始依次日後播報3d

@Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case TTS_PLAY:
                synchronized (mTts) {
                    if (!isPlaying && mTts != null && wordList.size() > 0) {
                        isPlaying = true;
                        String playtts = wordList.removeFirst();
                        if (mTts == null) {
                            createSynthesizer();
                        }
                        mTts.startSpeaking(playtts, new SynthesizerListener() {
                            @Override
                            public void onCompleted(SpeechError arg0) {
                                isPlaying = false;
                                handler.obtainMessage(1).sendToTarget();
                            }

                            @Override
                            public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
                            }

                            @Override
                            public void onBufferProgress(int arg0, int arg1, int arg2, String arg3) {
                                // 合成進度
                                isPlaying = true;
                            }

                            @Override
                            public void onSpeakBegin() {
                                //開始播放
                                isPlaying = true;
                            }

                            @Override
                            public void onSpeakPaused() {
                            }

                            @Override
                            public void onSpeakProgress(int arg0, int arg1, int arg2) {
                                //播放進度
                                isPlaying = true;
                            }

                            @Override
                            public void onSpeakResumed() {
                                //繼續播放
                                isPlaying = true;
                            }
                        });
                    }
                }
                break;
            case CHECK_TTS_PLAY:
                if (!isPlaying) {
                    handler.obtainMessage(1).sendToTarget();
                }
                break;
        }

    }
複製代碼
相關文章
相關標籤/搜索