發(fā)送定位與實(shí)時(shí)導(dǎo)航(集成高德地圖)

第一、發(fā)送定位

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];
    //檢索頁(yè)
    self.tableView.tableHeaderView = self.searchC.searchBar;
}
//移動(dòng)結(jié)束地圖回調(diào)
- (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 搜索回調(diào). */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
{
    if (response.pois.count == 0)
    {
        return;
    }
    if ([request isKindOfClass:[AMapPOIAroundSearchRequest class]]) {
        NSLog(@"周邊搜索");
    }
    else
    {
        NSLog(@"關(guān)鍵詞搜索");
    }
    self.pois = response.pois;
    [self.tableView reloadData];
    //解析response獲取POI信息,具體解析見(jiàn) 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(@"是否活躍狀態(tài):%d",searchController.active);
}
#pragma mark - <經(jīng)緯度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 - <關(guān)鍵詞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];
        ///如果您需要進(jìn)入地圖就顯示定位小藍(lán)點(diǎn)
        _mapView.showsUserLocation = YES;
        //追蹤小藍(lán)點(diǎn)
        _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;
        // 帶逆地理信息的一次定位(返回坐標(biāo)和地址信息)
        [_locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
        //   定位超時(shí)時(shí)間,最低2s,此處設(shè)置為2s
        _locationManager.locationTimeout =2;
        //   逆地理請(qǐng)求超時(shí)時(shí)間,最低2s,此處設(shè)置為2s
        _locationManager.reGeocodeTimeout = 2;
        // 帶逆地理(返回坐標(biāo)和地址信息)。將下面代碼中的 YES 改成 NO ,則不會(huì)返回地址信息。
        [_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'

#第三方庫(kù)
def third_pods
  pod 'AMap3DMap'
  pod 'AMapLocation'
  pod 'AMapSearch'
end

#私有庫(kù)
def internel_pods
  
end

target 'gaoDeMap' do

  third_pods

  target 'gaoDeMapTests' do
   
  end

  target 'gaoDeMapUITests' do
    
  end
end

info.plist增加權(quán)限
Privacy - Location Always and When In Use Usage Description
Privacy - Location Always Usage Description
Privacy - Location When In Use Usage Description

第二、發(fā)送定位

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:@"開(kāi)始導(dǎo)航" 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;
    //市民中心的經(jīng)緯度
    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;
        // 帶逆地理信息的一次定位(返回坐標(biāo)和地址信息)
        [_locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
        //   定位超時(shí)時(shí)間,最低2s,此處設(shè)置為2s
        _locationManager.locationTimeout =2;
        //   逆地理請(qǐng)求超時(shí)時(shí)間,最低2s,此處設(shè)置為2s
        _locationManager.reGeocodeTimeout = 2;
        // 帶逆地理(返回坐標(biāo)和地址信息)。將下面代碼中的 YES 改成 NO ,則不會(huì)返回地址信息。
        [_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);
            }
            //定位本地經(jīng)緯度作為起始點(diǎn)
            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添加為導(dǎo)航數(shù)據(jù)的Representative,使其可以接收到導(dǎo)航誘導(dǎo)數(shù)據(jù)
    [[AMapNaviDriveManager sharedInstance] addDataRepresentative:self.driveView];
}

#pragma mark - <AMapNaviDriveViewDelegate>
- (void)driveManagerOnCalculateRouteSuccess:(AMapNaviDriveManager *)driveManager
{
    NSLog(@"onCalculateRouteSuccess");
    
    //算路成功后開(kāi)始GPS導(dǎo)航
    [[AMapNaviDriveManager sharedInstance] startGPSNavi];
    //顯示路徑或開(kāi)啟導(dǎo)航
}
- (BOOL)driveManagerIsNaviSoundPlaying:(AMapNaviDriveManager *)driveManager
{
    return [[SpeechSynthesizer sharedSpeechSynthesizer] isSpeaking];
}
- (void)driveManager:(AMapNaviDriveManager *)driveManager playNaviSoundString:(NSString *)soundString soundStringType:(AMapNaviSoundType)soundStringType
{
    NSLog(@"playNaviSoundString:{%ld:%@}", (long)soundStringType, soundString);
    //采用系統(tǒng)語(yǔ)音播報(bào)(文字轉(zhuǎn)語(yǔ)音)
    [[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(@"單例是否銷(xiāo)毀成功 : %d",success);
    
}
@end

語(yǔ)音播報(bào)需要自己做,高德只給了我們語(yǔ)音的文字,我們可以采用系統(tǒng)的AVFoundation框架下的 SpeechSynthesizer ,也可以采用其他第三方的科大訊飛之類(lèi)的 實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音

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

創(chuàng)建一個(gè)單例 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];
            //初始化語(yǔ)音合成器
            speechSynthesizer.avSpeaker = [[AVSpeechSynthesizer alloc] init];
            speechSynthesizer.avSpeaker.delegate = speechSynthesizer;
        }
    });
    return speechSynthesizer;
}
-(void)speakString:(NSString *)str
{
    //初始化要說(shuō)出的內(nèi)容
    AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:str];
    //設(shè)置語(yǔ)速,語(yǔ)速介于AVSpeechUtteranceMaximumSpeechRate和AVSpeechUtteranceMinimumSpeechRate之間
    //AVSpeechUtteranceMaximumSpeechRate
    //AVSpeechUtteranceMinimumSpeechRate
    //AVSpeechUtteranceDefaultSpeechRate
    utterance.rate = 0.5;
    
    //設(shè)置音高,[0.5 - 2] 默認(rèn) = 1
    //AVSpeechUtteranceMaximumSpeechRate
    //AVSpeechUtteranceMinimumSpeechRate
    //AVSpeechUtteranceDefaultSpeechRate
    utterance.pitchMultiplier = 1;
    
    //設(shè)置音量,[0-1] 默認(rèn) = 1
    utterance.volume = 1;
    
    //讀一段前的停頓時(shí)間
    utterance.preUtteranceDelay = 1;
    //讀完一段后的停頓時(shí)間
    utterance.postUtteranceDelay = 1;
    
    //設(shè)置聲音,是AVSpeechSynthesisVoice對(duì)象
    //AVSpeechSynthesisVoice定義了一系列的聲音, 主要是不同的語(yǔ)言和地區(qū).
    //voiceWithLanguage: 根據(jù)制定的語(yǔ)言, 獲得一個(gè)聲音.
    //speechVoices: 獲得當(dāng)前設(shè)備支持的聲音
    //currentLanguageCode: 獲得當(dāng)前聲音的語(yǔ)言字符串, 比如”ZH-cn”
    //language: 獲得當(dāng)前的語(yǔ)言
    //通過(guò)特定的語(yǔ)言獲得聲音
    AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
    //通過(guò)voicce標(biāo)示獲得聲音
    //AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithIdentifier:AVSpeechSynthesisVoiceIdentifierAlex];
    utterance.voice = voice;
    //開(kāi)始朗讀
    [[SpeechSynthesizer sharedSpeechSynthesizer].avSpeaker speakUtterance:utterance];
}

#pragma mark - AVSpeechSynthesizerDelegate
//已經(jīng)開(kāi)始
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = YES ;
}
//已經(jīng)說(shuō)完
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = NO;
    //如果朗讀要循環(huán)朗讀,可以在這里再次調(diào)用朗讀方法
    //[_avSpeaker speakUtterance:utterance];
}
//已經(jīng)暫停
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didPauseSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = NO;
}
//已經(jīng)繼續(xù)說(shuō)話(huà)
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didContinueSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = YES;
}
//已經(jīng)取消說(shuō)話(huà)
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didCancelSpeechUtterance:(AVSpeechUtterance *)utterance{
    [SpeechSynthesizer sharedSpeechSynthesizer].isSpeaking = NO;
}
//將要說(shuō)某段話(huà)
- (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'

#第三方庫(kù)
def third_pods
  pod 'AMap3DMap'
  pod 'AMapLocation'
  pod 'AMapSearch'
  pod 'AMapNavi'
end

#私有庫(kù)
def internel_pods
end

target 'gaoDeMap' do

  third_pods
  internel_pods
  target 'gaoDeMapTests' do
   
  end

  target 'gaoDeMapUITests' do
    
  end
end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容