第一、發(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