高德地图导航和路径规划

1 高德地图定位

1.1 要使用路径规划和导航需要使用3Dmap

在build.gradle文件加入一下包

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);
}

这样就完成对应的定位信息

2.路径规划

2.1获取路径规划起始位置和终点位置的经纬度

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

对应的终点信息,可以使用随机数来确定

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会返回对应的路径

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即可

 /**
   * 绘制路线
   */
  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即可

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接口,一般处理下面几个接口就可以了

@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来处理,主要是播报方式是队列模式。其原理就是依次将需要播报的语音放入链表中,播报过程是从头开始依次往后播报

 @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;
        }

    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容