美文网首页
发送定位与实时导航(集成高德地图)

发送定位与实时导航(集成高德地图)

作者: 寂寞先森666 | 来源:发表于2019-10-21 15:09 被阅读0次

第一、发送定位

IMG_9726.png IMG_9728.png IMG_9727.png

viewController

#import "ViewController.h"
#import <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapLocationKit/AMapLocationKit.h>
#import <AMapSearchKit/AMapSearchKit.h>
#import "resultTableViewCell.h"
#define mapHeight 350
@interface ViewController ()<MAMapViewDelegate,AMapLocationManagerDelegate,AMapSearchDelegate>
@property(strong,nonatomic)MAMapView * mapView;
@property(strong,nonatomic)AMapLocationManager * locationManager;//
@property(strong,nonatomic)MAPointAnnotation * centerAnnotation;
@property(strong,nonatomic)AMapSearchAPI * search;
@property(copy,nonatomic)NSArray <AMapPOI *> * pois;

@property(strong,nonatomic)UISearchController * searchC;
@end

@implementation ViewController
-(void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerNib:[UINib nibWithNibName:@"resultTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"resultTableViewCellId"];
    ///把地图添加至view
    [self.view addSubview:self.mapView];
    //检索页
    self.tableView.tableHeaderView = self.searchC.searchBar;
}
//移动结束地图回调
- (void)mapView:(MAMapView *)mapView mapDidMoveByUser:(BOOL)wasUserAction;
{
    self.centerAnnotation.lockedToScreen = YES;
    self.centerAnnotation.lockedScreenPoint = CGPointMake([UIScreen mainScreen].bounds.size.width/2 , mapHeight/2);
    [mapView addAnnotation:self.centerAnnotation];
    
    [self searchWithLatitude:self.centerAnnotation.coordinate.latitude longitude:self.centerAnnotation.coordinate.longitude];
}

/* POI 搜索回调. */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
{
    if (response.pois.count == 0)
    {
        return;
    }
    if ([request isKindOfClass:[AMapPOIAroundSearchRequest class]]) {
        NSLog(@"周边搜索");
    }
    else
    {
        NSLog(@"关键词搜索");
    }
    self.pois = response.pois;
    [self.tableView reloadData];
    //解析response获取POI信息,具体解析见 Demo
}
- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager
{
    
}
-(void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager
{
     [locationManager requestAlwaysAuthorization];
}

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
    
    [self searchWithKey:searchController.searchBar.text];
    [self.tableView reloadData];
    NSLog(@"编辑:%@",searchController.searchBar.text);
    NSLog(@"是否活跃状态:%d",searchController.active);
}
#pragma mark - <经纬度POI搜索>
-(void)searchWithLatitude:(CGFloat)latitude longitude:(CGFloat)longitude
{
    AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init];
    request.location            = [AMapGeoPoint locationWithLatitude: latitude longitude:longitude];
    //            request.keywords            = @"电影院";
    /* 按照距离排序. */
    request.sortrule            = 0;
    request.requireExtension    = YES;
    //
    [self.search AMapPOIAroundSearch:request];
}
#pragma mark - <关键词POI搜索>
-(void)searchWithKey:(NSString *)key
{
    AMapPOIKeywordsSearchRequest *request = [[AMapPOIKeywordsSearchRequest alloc] init];
    
    request.keywords            = key;
//    request.city                = @"北京";
//    request.types               = @"高等院校";
    request.requireExtension    = YES;
    
    /*  搜索SDK 3.2.0 中新增加的功能,只搜索本城市的POI。*/
    request.cityLimit           = YES;
    request.requireSubPOIs      = YES;
    [self.search AMapPOIKeywordsSearch:request];

}
#pragma mark - <lazy init>
-(MAMapView *)mapView
{
    if (!_mapView) {
        ///初始化地图
        _mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, mapHeight)];
        _mapView.mapType = MAMapTypeStandard;
        _mapView.showsScale = NO;
        _mapView.showsCompass = NO;
        _mapView.delegate = self;
        //伸缩比例
        [_mapView setZoomLevel:15.1 animated:YES];
        ///如果您需要进入地图就显示定位小蓝点
        _mapView.showsUserLocation = YES;
        //追踪小蓝点
        _mapView.userTrackingMode = MAUserTrackingModeFollow;
    }
    return _mapView;
}
-(AMapSearchAPI *)search
{
    if (!_search) {
        _search = [[AMapSearchAPI alloc] init];
        _search.delegate = self;
    }
    return _search;
}
-(AMapLocationManager *)locationManager
{
    if (!_locationManager) {
        _locationManager = [[AMapLocationManager alloc]init];
        _locationManager.delegate = self;
        // 带逆地理信息的一次定位(返回坐标和地址信息)
        [_locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
        //   定位超时时间,最低2s,此处设置为2s
        _locationManager.locationTimeout =2;
        //   逆地理请求超时时间,最低2s,此处设置为2s
        _locationManager.reGeocodeTimeout = 2;
        // 带逆地理(返回坐标和地址信息)。将下面代码中的 YES 改成 NO ,则不会返回地址信息。
        [_locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
            
            if (error)
            {
                NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
                
                if (error.code == AMapLocationErrorLocateFailed)
                {
                    return;
                }
            }
            
            NSLog(@"latitude:%lf  longitude:%lf", location.coordinate.latitude,location.coordinate.longitude);
            
            if (regeocode)
            {
                NSLog(@"reGeocode:%@", regeocode);
            }
            [self searchWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
        }];
    }
    return _locationManager;
}
-(UISearchController *)searchC
{
    if (!_searchC) {
        _searchC = [[UISearchController alloc]initWithSearchResultsController:nil];
        _searchC.delegate = self;
        _searchC.searchResultsUpdater = self;
        _searchC.obscuresBackgroundDuringPresentation=NO;
    }
    return _searchC;
}
-(MAPointAnnotation *)centerAnnotation
{
    if (!_centerAnnotation) {
        _centerAnnotation = [[MAPointAnnotation alloc]init];
    }
    return _centerAnnotation;
}
#pragma mark - <UITableViewDataSource、UITableViewDelegate>
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.pois.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    resultTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"resultTableViewCellId"];
    cell.poi = self.pois[indexPath.row];
    return cell;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return self.mapView;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return [self.searchC.searchBar.text isEqualToString:@""]?mapHeight:0;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    AMapPOI * poi = self.pois[indexPath.row];
    [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude) animated:YES];
    [self searchWithLatitude:self.centerAnnotation.coordinate.latitude longitude:self.centerAnnotation.coordinate.longitude];
    [self.searchC.searchBar setShowsCancelButton:NO animated:YES];
    [self.searchC.searchBar resignFirstResponder];
    self.searchC.searchBar.text = @"";
    [self.tableView reloadData];
}
@end

resultTableViewCell

#import "resultTableViewCell.h"
@interface resultTableViewCell()
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *contentLabel;
@end
@implementation resultTableViewCell

- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}
-(void)setPoi:(AMapPOI *)poi
{
    _poi = poi;
    self.titleLabel.text = poi.name;
    self.contentLabel.text = poi.address;
}
@end

Podfile

platform :ios, '9.0'

#第三方库
def third_pods
  pod 'AMap3DMap'
  pod 'AMapLocation'
  pod 'AMapSearch'
end

#私有库
def internel_pods
  
end

target 'gaoDeMap' do

  third_pods

  target 'gaoDeMapTests' do
   
  end

  target 'gaoDeMapUITests' do
    
  end
end

info.plist增加权限
Privacy - Location Always and When In Use Usage Description
Privacy - Location Always Usage Description
Privacy - Location When In Use Usage Description

第二、发送定位

IMG_9723.png IMG_9724.png IMG_9725.png

ViewController

#import "ViewController.h"
#import <AMapLocationKit/AMapLocationKit.h>
#import "secondViewController.h"
#define kRoutePlanInfoViewHeight 200
@interface ViewController ()<AMapLocationManagerDelegate>
@property(strong,nonatomic)AMapLocationManager * locationManager;
@property(strong,nonatomic)UIButton * startBtn;
@property(strong,nonatomic)AMapNaviPoint * startPoint;
@end

@implementation ViewController
-(void)viewDidLoad
{
    [super viewDidLoad];
    [self.view addSubview:self.startBtn];
    [self initLocationManager];
}
-(UIButton *)startBtn
{
    if (!_startBtn) {
        _startBtn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 200, 50)];
        [_startBtn setTitle:@"开始导航" forState:0];
        _startBtn.titleLabel.font = [UIFont systemFontOfSize:30];
        [_startBtn setTitleColor:[UIColor whiteColor] forState:0];
        _startBtn.backgroundColor = [UIColor greenColor];
        [_startBtn addTarget:self action:@selector(startAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _startBtn;
}
-(void)startAction
{
    secondViewController * secondVC = [[secondViewController alloc]init];
    secondVC.startPoint = self.startPoint;
    //市民中心的经纬度
    secondVC.endPoint = [AMapNaviPoint locationWithLatitude:22.5436700000 longitude:114.0596400000];
    [self presentViewController:secondVC animated:YES completion:nil];
}
-(void)initLocationManager
{
    if (!_locationManager) {
        _locationManager = [[AMapLocationManager alloc]init];
        _locationManager.delegate = self;
        // 带逆地理信息的一次定位(返回坐标和地址信息)
        [_locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
        //   定位超时时间,最低2s,此处设置为2s
        _locationManager.locationTimeout =2;
        //   逆地理请求超时时间,最低2s,此处设置为2s
        _locationManager.reGeocodeTimeout = 2;
        // 带逆地理(返回坐标和地址信息)。将下面代码中的 YES 改成 NO ,则不会返回地址信息。
        [_locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {

            if (error)
            {
                NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);

                if (error.code == AMapLocationErrorLocateFailed)
                {
                    return;
                }
            }

            NSLog(@"latitude:%lf  longitude:%lf", location.coordinate.latitude,location.coordinate.longitude);

            if (regeocode)
            {
                NSLog(@"reGeocode:%@", regeocode);
            }
            //定位本地经纬度作为起始点
            self.startPoint = [AMapNaviPoint locationWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
        }];
    }
}
@end

secondViewController

#import <UIKit/UIKit.h>
#import <AMapNaviKit/AMapNaviKit.h>
#import <MAMapKit/MAMapKit.h>
#import <AMapLocationKit/AMapLocationKit.h>
NS_ASSUME_NONNULL_BEGIN

@interface secondViewController : UIViewController
@property(strong,nonatomic)AMapNaviPoint * startPoint;
@property(strong,nonatomic)AMapNaviPoint * endPoint;
@end

NS_ASSUME_NONNULL_END
#import "secondViewController.h"
#import "SpeechSynthesizer.h"
@interface secondViewController ()<AMapNaviDriveViewDelegate,AMapNaviDriveManagerDelegate>
@property(strong,nonatomic)AMapNaviDriveView * driveView;
@end

@implementation secondViewController
-(void)viewDidLoad
{
    [super viewDidLoad];
    [self initDriveView];
    [self initDriveManager];
    [[AMapNaviDriveManager sharedInstance] calculateDriveRouteWithStartPoints:@[self.startPoint]
                                                                    endPoints:@[self.endPoint]
                                                                    wayPoints:nil
                                                              drivingStrategy:17];
}
- (void)initDriveView
{
    if (self.driveView == nil)
    {
        self.driveView = [[AMapNaviDriveView alloc] initWithFrame:self.view.bounds];
        self.driveView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        [self.view addSubview:self.driveView];
        [self.driveView setDelegate:self];
    }
}
- (void)initDriveManager
{
    [[AMapNaviDriveManager sharedInstance] setDelegate:self];
    //将driveView添加为导航数据的Representative,使其可以接收到导航诱导数据
    [[AMapNaviDriveManager sharedInstance] addDataRepresentative:self.driveView];
}

#pragma mark - <AMapNaviDriveViewDelegate>
- (void)driveManagerOnCalculateRouteSuccess:(AMapNaviDriveManager *)driveManager
{
    NSLog(@"onCalculateRouteSuccess");
    
    //算路成功后开始GPS导航
    [[AMapNaviDriveManager sharedInstance] startGPSNavi];
    //显示路径或开启导航
}
- (BOOL)driveManagerIsNaviSoundPlaying:(AMapNaviDriveManager *)driveManager
{
    return [[SpeechSynthesizer sharedSpeechSynthesizer] isSpeaking];
}
- (void)driveManager:(AMapNaviDriveManager *)driveManager playNaviSoundString:(NSString *)soundString soundStringType:(AMapNaviSoundType)soundStringType
{
    NSLog(@"playNaviSoundString:{%ld:%@}", (long)soundStringType, soundString);
    //采用系统语音播报(文字转语音)
    [[SpeechSynthesizer sharedSpeechSynthesizer] speakString:soundString];
}

#pragma mark - <dealloc>
- (void)dealloc
{
    [[AMapNaviDriveManager sharedInstance] stopNavi];
    [[AMapNaviDriveManager sharedInstance] removeDataRepresentative:self.driveView];
    [[AMapNaviDriveManager sharedInstance] setDelegate:nil];
    
    BOOL success = [AMapNaviDriveManager destroyInstance];
    NSLog(@"单例是否销毁成功 : %d",success);
    
}
@end

语音播报需要自己做,高德只给了我们语音的文字,我们可以采用系统的AVFoundation框架下的 SpeechSynthesizer ,也可以采用其他第三方的科大讯飞之类的 实现文字转语音

屏幕快照 2019-11-08 上午10.52.16.png

创建一个单例 SpeechSynthesizer

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SpeechSynthesizer : NSObject
@property(assign,nonatomic)BOOL isSpeaking;
+(instancetype)sharedSpeechSynthesizer;
-(void)speakString:(NSString *)str;
@end

NS_ASSUME_NONNULL_END
#import "SpeechSynthesizer.h"
#import <AVFoundation/AVFoundation.h>
@interface SpeechSynthesizer()<AVSpeechSynthesizerDelegate>
@property(strong,nonatomic)AVSpeechSynthesizer * avSpeaker;
@end

@implementation SpeechSynthesizer
+(instancetype)sharedSpeechSynthesizer;
{
    static SpeechSynthesizer * speechSynthesizer = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (speechSynthesizer == nil) {
            speechSynthesizer = [[SpeechSynthesizer alloc]init];
            //初始化语音合成器
            speechSynthesizer.avSpeaker = [[AVSpeechSynthesizer alloc] init];
            speechSynthesizer.avSpeaker.delegate = speechSynthesizer;
        }
    });
    return speechSynthesizer;
}
-(void)speakString:(NSString *)str
{
    //初始化要说出的内容
    AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:str];
    //设置语速,语速介于AVSpeechUtteranceMaximumSpeechRate和AVSpeechUtteranceMinimumSpeechRate之间
    //AVSpeechUtteranceMaximumSpeechRate
    //AVSpeechUtteranceMinimumSpeechRate
    //AVSpeechUtteranceDefaultSpeechRate
    utterance.rate = 0.5;
    
    //设置音高,[0.5 - 2] 默认 = 1
    //AVSpeechUtteranceMaximumSpeechRate
    //AVSpeechUtteranceMinimumSpeechRate
    //AVSpeechUtteranceDefaultSpeechRate
    utterance.pitchMultiplier = 1;
    
    //设置音量,[0-1] 默认 = 1
    utterance.volume = 1;
    
    //读一段前的停顿时间
    utterance.preUtteranceDelay = 1;
    //读完一段后的停顿时间
    utterance.postUtteranceDelay = 1;
    
    //设置声音,是AVSpeechSynthesisVoice对象
    //AVSpeechSynthesisVoice定义了一系列的声音, 主要是不同的语言和地区.
    //voiceWithLanguage: 根据制定的语言, 获得一个声音.
    //speechVoices: 获得当前设备支持的声音
    //currentLanguageCode: 获得当前声音的语言字符串, 比如”ZH-cn”
    //language: 获得当前的语言
    //通过特定的语言获得声音
    AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
    //通过voicce标示获得声音
    //AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithIdentifier:AVSpeechSynthesisVoiceIdentifierAlex];
    utterance.voice = voice;
    //开始朗读
    [[SpeechSynthesizer sharedSpeechSynthesizer].avSpeaker speakUtterance:utterance];
}

#pragma mark - AVSpeechSynthesizerDelegate
//已经开始
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = YES ;
}
//已经说完
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = NO;
    //如果朗读要循环朗读,可以在这里再次调用朗读方法
    //[_avSpeaker speakUtterance:utterance];
}
//已经暂停
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = NO;
}
//已经继续说话
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = YES;
}
//已经取消说话
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = NO;
}
//将要说某段话
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer willSpeakRangeOfSpeechString:(NSRange)characterRange utterance:(AVSpeechUtterance *)utterance{
    
} 
@end

podfile文件

# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'

#第三方库
def third_pods
  pod 'AMap3DMap'
  pod 'AMapLocation'
  pod 'AMapSearch'
  pod 'AMapNavi'
end

#私有库
def internel_pods
end

target 'gaoDeMap' do

  third_pods
  internel_pods
  target 'gaoDeMapTests' do
   
  end

  target 'gaoDeMapUITests' do
    
  end
end

相关文章

  • 发送定位与实时导航(集成高德地图)

    第一、发送定位 viewController resultTableViewCell Podfile info.p...

  • 解决高德百度地图后台运行无法导航播报

    关于集成完高德地图后,App后台运行时,不再语音播报问题解决。 1、地图集成完了2、前台实时导航正常3、前台播报也...

  • 高德地图集成总结

    iOS开发,第一次集成高德地图,实现了简单的定位,绘制气泡,导航。简单总结: 1.定位只是为了获取当前位置(如果需...

  • iOS 高德地图的使用

    iOS:高德地图的使用 本人花了点时间集成了高德地图的几乎所有的功能,包含:地图的显示、地图的绘制、地图的定位、地...

  • 获取SHA1

    今天遇到集成高德地图,不,是融云中的高德地图定位,填坑的。定位失败,一直提示定位失败,报错说key过期或者不正确。...

  • 高德地图导航使用指南

    高德地图是我们常用的导航地图之一,其强大性就不说了,直接开始主题,高德地图导航功能的使用方法。 概览 高德地图导航...

  • iOS集成高德地图SDK

    前言:关于这次集成高德地图,打算分几个内容定位 POI检索 导航 线路规划,现在只是简单地实现了前两个功能,先记录...

  • 高德地图导航,不显示地图只有语音

    详情描述:项目中集成了高德全家桶(地图,导航,搜索,定位) 所以我就导入一个(我已经修复了,所以看一下svn) 就...

  • 安卓获取当前地理位置(集成高德地图)

    高德地图定位优缺点: 优点:自带地址解析,对比百度地图,不含额外的so库 缺点:需要引入高德的sdk库 集成方法 ...

  • RN-地图导航

    调起百度网页地图路径导航 调起高德网页地图路径导航 iOS调起百度APP地图路径导航 iOS调起高德app地图路径...

网友评论

      本文标题:发送定位与实时导航(集成高德地图)

      本文链接:https://www.haomeiwen.com/subject/zkutvctx.html