一键导航

该示例展示了如何快速导航到周边的餐馆。
下载源代码
00:00 / 00:12
体验移动端 扫码体验移动端

使用场景

将检索出来的餐馆(或其他类型的POI)作为终点,以当前位置作为起点,快速导航到检索地点,适合找餐馆、找酒店的场景。

用到产品

iOS 地图 SDK

核心类/接口

接口

说明

版本

MAMapView

addAnnotation:

向地图窗口添加标注。

V2.0.0版本起

MAMapViewDelegate

mapView:viewForAnnotation:

地图上的起始点,终点,拐点的标注的回调,可以自定义图标展示等。

V2.0.0版本起


mapView:rendererForOverlay:

地图上覆盖物的渲染的回调,可以设置路径线路的宽度,颜色等。

V3.0.0版本起

AMapSearchAPI

AMapPOIAroundSearch:

POI周边查询接口。

V3.0.0版本起

AMapPOIAroundSearchRequest

location

中心点坐标。

V3.0.0版本起

AMapPOISearchBaseRequest

requireExtension

是否返回扩展信息,默认NO。

V3.0.0版本起


types

类型,多个类型用“|”分割 可选值:文本分类、分类代码。

V3.0.0版本起

AMapSearchDelegate

onPOISearchDone:response:

POI查询完成回调。

V3.0.0版本起

iOS 导航 SDK

核心类/接口

接口

说明

版本

AMapNaviDriveManager

calculateDriveRouteWithStartPoints:endPoints:wayPoints:drivingStrategy:

带起点的驾车路径规划。

V2.0.0版本起

AMapNaviBaseManager

startEmulatorNavi

开始模拟导航。

V2.0.0版本起

AMapNaviDriveManagerDelegate

driveManagerOnCalculateRouteSuccess:

驾车路径规划成功后的回调函数。

V2.0.0版本起

核心难点

1、基于当前的位置,查询附近的餐馆。

该场景使用单次定位,在定位的回调中记录当前位置的坐标,并以此为中心点,进行POI的周边检索。

- (void)updateCurrentLocation
{
    [self.locationManager requestLocationWithReGeocode:NO completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
        
        if (error)
        {
            NSLog(@"error:%@", error);
            return;
        }
        
        _curLocation = location;
        
        CurrentLocationAnnotation *annotation = [[CurrentLocationAnnotation alloc] init];
        annotation.coordinate = _curLocation.coordinate;
        annotation.title = @"当前位置";
        [self.mapView addAnnotation:annotation];
        [self.mapView selectAnnotation:annotation animated:YES];
        
        [self startPOIAroundSearch];
    }];
}

- (void)startPOIAroundSearch
{
    if (_curLocation == nil)
    {
        NSLog(@"未获取到当前位置");
        return;
    }
    
    AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init];
    
    request.location = [AMapGeoPoint locationWithLatitude:_curLocation.coordinate.latitude
                                                longitude:_curLocation.coordinate.longitude];
    request.keywords            = @"餐饮";
    request.sortrule            = 1;
    request.requireExtension    = NO;
    
    [self.search AMapPOIAroundSearch:request];
}
func updateCurrentLocation() {
    locationManager.requestLocation(withReGeocode: false, completionBlock:{ [weak self] (location, regeo, error) -> Void in
        
        let error = error as? NSError
        if error != nil {
            NSLog("error:%@", error!)
            return
        }
        
        self?.curLocation = location
        
        guard let curLocation = self?.curLocation else {
            return
        }
        
        let annotation = CurrentLocationAnnotation()
        annotation.coordinate = curLocation.coordinate
        annotation.title = "当前位置"
        self?.mapView.addAnnotation(annotation)
        self?.mapView.selectAnnotation(annotation, animated: true)
        
        self?.startPOIAroundSearch()
    }
                                    )
}

func startPOIAroundSearch() {
    
    guard let curLocation = curLocation else {
        NSLog("未获取到当前位置")
        return
    }
    
    let request = AMapPOIAroundSearchRequest()
    
    request.location = AMapGeoPoint.location(withLatitude: CGFloat(curLocation.coordinate.latitude),
                                             longitude: CGFloat(curLocation.coordinate.longitude))
    request.keywords = "餐饮"
    request.sortrule = 1
    request.requireExtension = false
    
    search.aMapPOIAroundSearch(request)
}

2、当看到POI的详细信息后,确认此处是您想去的地方,快速进行导航,完成一连串的动作。

弹出的POI的callout后,以当前位置为起点,以POI所在的位置为终点,采用默认的驾车策略,进行路径规划并导航。

- (void)mapView:(MAMapView *)mapView annotationView:(MAAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    if ([view.annotation isKindOfClass:[MAPointAnnotation class]])
    {
        MAPointAnnotation *annotation = (MAPointAnnotation *)view.annotation;
        
        _endPoint = [AMapNaviPoint locationWithLatitude:annotation.coordinate.latitude
                                              longitude:annotation.coordinate.longitude];
        
        [self routePlanAction];
    }
}

//路径规划
- (void)routePlanAction
{
    if (_curLocation == nil)
    {
        NSLog(@"未获取到当前位置");
        return;
    }
    
    AMapNaviPoint *startPoint = [AMapNaviPoint locationWithLatitude:_curLocation.coordinate.latitude
                                                          longitude:_curLocation.coordinate.longitude];
    
    [self.driveManager calculateDriveRouteWithStartPoints:@[startPoint]
                                                endPoints:@[_endPoint]
                                                wayPoints:nil
                                          drivingStrategy:AMapNaviDrivingStrategySingleDefault];
}

//算路成功回调后开始导航
- (void)driveManagerOnCalculateRouteSuccess:(AMapNaviDriveManager *)driveManager
{
    NSLog(@"onCalculateRouteSuccess");
    
    DriveNaviViewController *driveVC = [[DriveNaviViewController alloc] init];
    [driveVC setDelegate:self];
    
    //将driveView添加为导航数据的Representative,使其可以接收到导航诱导数据
    [self.driveManager addDataRepresentative:driveVC.driveView];
    
    [self.navigationController pushViewController:driveVC animated:NO];
    [self.driveManager startEmulatorNavi];
}
func mapView(_ mapView: MAMapView!, annotationView view: MAAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
    if view.annotation is MAPointAnnotation {
        
        let annotation = view.annotation as! MAPointAnnotation
        
        endPoint = AMapNaviPoint.location(withLatitude: CGFloat(annotation.coordinate.latitude), longitude: CGFloat(annotation.coordinate.longitude))
        
        routePlanAction()
    }
}

//路径规划
func routePlanAction() {
    guard let endPoint = endPoint else {
        return
    }
    
    guard let curLocation = curLocation else {
        NSLog("未获取到当前位置")
        return
    }
    
    let startP = AMapNaviPoint.location(withLatitude: CGFloat(curLocation.coordinate.latitude), longitude: CGFloat(curLocation.coordinate.longitude))!
    driveManager.calculateDriveRoute(withStart: [startP], end: [endPoint], wayPoints: nil, drivingStrategy: .singleDefault)
}

//算路成功后开始导航
func driveManager(onCalculateRouteSuccess driveManager: AMapNaviDriveManager) {
    NSLog("CalculateRouteSuccess")
    
    let driveVC = DriveNaviViewViewController()
    driveVC.delegate = self
    
    //将driveView添加为导航数据的Representative,使其可以接收到导航诱导数据
    driveManager.addDataRepresentative(driveVC.driveView)
    
    _ = navigationController?.pushViewController(driveVC, animated: false)
    driveManager.startEmulatorNavi()
}

 

下载源代码
00:00 / 00:12
体验移动端 扫码体验移动端

使用场景

将检索出来的餐馆(或其他类型的POI)作为终点,以当前位置作为起点,快速导航到检索地点,适合找餐馆、找酒店的场景。

用到产品

Android 地图 SDK

核心类/接口

接口

说明

版本

PoiSearch.Query

Query(java.lang.String query, java.lang.String ctgr, java.lang.String city)

构造函数,构造POI搜索查询参数对象。

V2.1.0版本起


setCityLimit(boolean isLimit)

返回是否严格按照设定城市搜索。

V2.8.0版本起

PoiSearch

PoiSearch(Context context, PoiSearch.Query query)

根据给定的参数构造一个PoiSearch 的新对象。

V2.1.0版本起


setOnPoiSearchListener(PoiSearch.OnPoiSearchListener listener)

设置查询监听。

V2.1.0版本起


searchPOIAsyn()

POI搜索异步接口。

V2.1.0版本起

PoiSearch.OnPoiSearchListener

onPoiSearched(PoiResult pageResult, int errorCode)

返回POI搜索异步处理的结果。

V2.1.0版本起

Android 导航 SDK

核心类/接口

接口

说明

版本

AMapNavi

strategyConvert(boolean congestion, boolean avoidspeed, boolean cost, boolean hightspeed, boolean multipleRoute)

进行算路策略转换,将传入的特定规则转换成PathPlanningStrategy的枚举值。

V1.9.0


calculateDriveRoute(java.util.List<NaviLatLng> from, java.util.List<NaviLatLng> to, java.util.List<NaviLatLng> wayPoints, int strategy)

计算驾车路径(包含起点)。

V1.0.0


startNavi(int naviType)

开始导航。实时导航GPS未开启时,会自动打开GPS定位功能。模拟导航则不需要使用定位功能。

V1.0.0

AMapNaviListener

onCalculateRouteSuccess() 

路径规划的成功的回调函数。

V1.0.0

AMapNaviViewListener

onNaviBackClick()

导航页面左下角返回按钮的回调接口 false-由SDK主动弹出『退出导航』对话框,true-SDK不主动弹出『退出导航对话框』,由用户自定义。

V1.0.0

核心难点

1、基于当前的位置,查询附近的餐馆。

该场景使用单次定位,在定位的回调中记录当前位置的坐标,并以此为中心点,进行POI的周边检索。

@Override
public void onLocationChanged(AMapLocation aMapLocation) {
    if (aMapLocation == null || aMapLocation.getErrorCode() != AMapLocation.LOCATION_SUCCESS) {
        return;
    }
    mCurrentLocation = aMapLocation;
    
    initPoiSearch(aMapLocation.getLatitude(), aMapLocation.getLongitude());
}

private void initPoiSearch(double lat, double lon) {
    if (mPoiSearch == null) {
        PoiSearch.Query poiQuery = new PoiSearch.Query("", "餐饮服务");
        LatLonPoint centerPoint = new LatLonPoint(lat, lon);
        PoiSearch.SearchBound searchBound = new PoiSearch.SearchBound(centerPoint, 5000);
        mPoiSearch = new PoiSearch(this.getApplicationContext(), poiQuery);
        mPoiSearch.setBound(searchBound);
        mPoiSearch.setOnPoiSearchListener(this);
        mPoiSearch.searchPOIAsyn();
    }
}

2、当看到POI的详细信息后,确认此处是您想去的地方,快速进行导航,完成一连串的动作。

弹出的POI的infowindow后触发导航,以当前位置为起点,以POI所在的位置为终点,采用默认的驾车策略,进行导航。

a)在检索页面,在弹出的infowindow中开始导航。

//自定义marker点击弹窗内容
@Override
public View getInfoWindow(final Marker marker) {
    View view = getLayoutInflater().inflate(R.layout.poikeywordsearch_uri,
            null);
    TextView title = (TextView) view.findViewById(R.id.title);
    title.setText(marker.getTitle());

    TextView snippet = (TextView) view.findViewById(R.id.snippet);
    int index = mPoiOverlay.getPoiIndex(marker);
    float distance = mPoiOverlay.getDistance(index);
    String showDistance = Utils.getFriendlyDistance((int) distance);
    snippet.setText("距当前位置" + showDistance);
    ImageButton button = (ImageButton) view
            .findViewById(R.id.start_amap_app);
    // 调起导航
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startAMapNavi(marker);
        }
    });
    return view;
}

//点击一键导航按钮跳转到导航页面
private void startAMapNavi(Marker marker) {
    if (mCurrentLocation == null) {
        return;
    }
    Intent intent = new Intent(this, RouteNaviActivity.class);
    intent.putExtra("gps", false);
    intent.putExtra("start", new NaviLatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()));
    intent.putExtra("end", new NaviLatLng(marker.getPosition().latitude, marker.getPosition().longitude));
    startActivity(intent);
}

b)在导航页面,初始化AMapNavi对象、算路,开始导航。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_basic_navi);
    mTtsManager = TTSController.getInstance(getApplicationContext());
    mTtsManager.init();

    mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
    mAMapNaviView.onCreate(savedInstanceState);
    mAMapNaviView.setAMapNaviViewListener(this);

    mAMapNavi = AMapNavi.getInstance(getApplicationContext());
    mAMapNavi.addAMapNaviListener(this);
    mAMapNavi.addAMapNaviListener(mTtsManager);
    mAMapNavi.setEmulatorNaviSpeed(60);
    getNaviParam();
}

//实现AMapNaviView的生命周期函数
@Override
protected void onResume() {
    super.onResume();
    mAMapNaviView.onResume();
}

@Override
protected void onPause() {
    super.onPause();
    mAMapNaviView.onPause();
    //        仅仅是停止你当前在说的这句话,一会到新的路口还是会再说的
    mTtsManager.stopSpeaking();
    //
    //        停止导航之后,会触及底层stop,然后就不会再有回调了,但是讯飞当前还是没有说完的半句话还是会说完
    //        mAMapNavi.stopNavi();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mAMapNaviView.onDestroy();
    mAMapNavi.stopNavi();
    //		mAMapNavi.destroy();
    mTtsManager.destroy();
}

//获取intent参数并计算路线
private void getNaviParam() {
    Intent intent = getIntent();
    if (intent == null) {
        return;
    }
    mIsGps = intent.getBooleanExtra("gps", false);
    NaviLatLng start = intent.getParcelableExtra("start");
    NaviLatLng end = intent.getParcelableExtra("end");
    calculateDriveRoute(start, end);
}

//驾车路径规划计算,计算单条路径
private void calculateDriveRoute(NaviLatLng start, NaviLatLng end) {
    int strategyFlag = 0;
    List<NaviLatLng> startList = new ArrayList<NaviLatLng>();
    /**
     * 途径点坐标集合
     */
    List<NaviLatLng> wayList = new ArrayList<NaviLatLng>();
    /**
     * 终点坐标集合[建议就一个终点]
     */
    List<NaviLatLng> endList = new ArrayList<NaviLatLng>();
    try {
        strategyFlag = mAMapNavi.strategyConvert(true, false, false, true, false);
    } catch (Exception e) {
        e.printStackTrace();
    }
    startList.add(start);
    endList.add(end);
    mAMapNavi.calculateDriveRoute(startList, endList, wayList, strategyFlag);
}

//路径规划成功后开始导航
@Override
public void onCalculateRouteSuccess() {
    if (mIsGps) {
        mAMapNavi.startNavi(AMapNavi.GPSNaviMode);
    } else {
        mAMapNavi.startNavi(AMapNavi.EmulatorNaviMode);
    }
}

 

返回顶部 示例中心 常见问题 智能客服 公众号
二维码