示例程序
使用百度地图SDK版本为2.9.1。
需要将改
代码:
#import <MapKit/MapKit.h>
#import <BaiduMapAPI_Map/BMKMapView.h>
#import <BaiduMapAPI_Location/BMKLocationService.h>
#import <BaiduMapAPI_Search/BMKSearchComponent.h>
#import <BaiduMapAPI_Map/BMKPolylineView.h>
#import <BaiduMapAPI_Utils/BMKGeometry.h>
#import "HXRouteViewController.h"
#import "UIView+Extension.h"
#import "HXAnnotationView.h"
#import "HXAnnotation.h"
#import "HXMenDDetail.h"
#import "UIImage+Rotate.h"
#import "UIColor+HexString.h"
#import "FMActionSheet.h"
#import "ZoomInOrOutButton.h"
#define MYBUNDLE_NAME @ "mapapi.bundle"
#define MYBUNDLE_PATH [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: MYBUNDLE_NAME]
#define MYBUNDLE [NSBundle bundleWithPath: MYBUNDLE_PATH]
/**
* 路线的标注
*/
@interface RouteAnnotation : BMKPointAnnotation
{
int _type; ///<0:起点 1:终点 2:公交 3:地铁 4:驾乘 5:途经点
int _degree;
}
@property (nonatomic) int type;
@property (nonatomic) int degree;
@end
@implementation RouteAnnotation
@synthesize type = _type;
@synthesize degree = _degree;
@end
@interface HXRouteViewController ()<BMKMapViewDelegate, BMKRouteSearchDelegate>{
BMKMapView *_mapView;
NSString *_cityName;
BMKRouteSearch *_routesearch;
}
/**
* 返回按钮
*/
//@property (nonatomic , weak)UIButton *preBtn;
/**
* 存放标注数组
*/
@property(nonatomic , strong) NSMutableArray *annotations;
/**
* 用户当前位置
*/
@property(nonatomic , strong) BMKUserLocation *userLocation;
@property(nonatomic , strong) HXAnnotation *anno;
@end
@implementation HXRouteViewController
- (NSString*)getMyBundlePath1:(NSString *)filename
{
NSBundle * libBundle = MYBUNDLE ;
if ( libBundle && filename ){
NSString * s=[[libBundle resourcePath ] stringByAppendingPathComponent:filename];
return s;
}
return nil ;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *statusView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREENW, 20)];
statusView.backgroundColor = [UIColor colorWithR:46 G:139 B:84 alpha:1.];
[self.view addSubview:statusView];
_routesearch = [[BMKRouteSearch alloc] init];
_routesearch.delegate = self;
//初始化BMKMapView并设置代理
_mapView = [[BMKMapView alloc] initWithFrame:CGRectMake(0, 20, SCREENW, SCREENH - 140)];
[self.view addSubview:_mapView];
_mapView.delegate = self;
_mapView.buildingsEnabled = YES;
_mapView.overlookEnabled = YES;
_mapView.showMapScaleBar = YES;
_mapView.overlooking = -45;
//设置放大/缩小按钮
[self setupNavButton];
//返回按钮
[self backButton];
//设置导航按钮
// [self setupNavButton];
//驾车路线
[self showDriveSearch];
//设置放大/缩小按钮
[self setupZoomButton];
}
#pragma mark 设置放大/缩小按钮
-(void)setupZoomButton{
ZoomInOrOutButton *zoomInOrOutBtn = [[[NSBundle mainBundle] loadNibNamed:@"ZoomInOrOutButton" owner:nil options:nil] lastObject];
zoomInOrOutBtn.layer.cornerRadius = 5;
zoomInOrOutBtn.x = SCREENW - 110;
zoomInOrOutBtn.y = _mapView.height - 50;
[_mapView addSubview:zoomInOrOutBtn];
[zoomInOrOutBtn.zoomInBtn addTarget:self action:@selector(zoomInBtnClick:) forControlEvents:UIControlEventTouchUpInside];
zoomInOrOutBtn.zoomInBtn.tag = 0;
[zoomInOrOutBtn.zoomOutBtn addTarget:self action:@selector(zoomInBtnClick:) forControlEvents:UIControlEventTouchUpInside];
zoomInOrOutBtn.zoomInBtn.tag = 1;
}
#pragma mark 点击放大按钮
-(void)zoomInBtnClick:(UIButton *)sender{
_mapView.zoomLevel = sender.tag ? _mapView.zoomLevel++ : _mapView.zoomLevel--;
}
#pragma mark 返回按钮
-(void)backButton{
UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(10, 30, 30, 40)];
[backButton setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal];
backButton.backgroundColor = [UIColor blackColor];
backButton.layer.cornerRadius = 5;
backButton.alpha = 0.7;
[backButton bringSubviewToFront:_mapView];
[backButton initSpringTouch];
[self.view addSubview:backButton];
[backButton addTarget:self action:@selector(goBack) forControlEvents:UIControlEventTouchUpInside];
}
#pragma mark 返回
-(void)goBack{
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark 导航按钮
-(void)setupNavButton{
UIView *bgView = [[UIView alloc] init];
bgView.frame = CGRectMake(0, SCREENH - 120, SCREENW, 120);
bgView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:bgView];
CGFloat viewX = 15;
UILabel *shopLabel = [[UILabel alloc] initWithFrame:CGRectMake(viewX, 5, SCREENW - 30, 25)];
shopLabel.text = [NSString stringWithFormat:@"门店名称:%@",self.mendDetail.shopName];
shopLabel.textColor = [UIColor blackColor];
shopLabel.font = [UIFont systemFontOfSize:15];
[bgView addSubview:shopLabel];
UILabel *addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(viewX, 30, SCREENW - 30, 25)];
addressLabel.text = [NSString stringWithFormat:@"门店地址:%@",self.mendDetail.address];
addressLabel.textColor = [UIColor lightGrayColor];
addressLabel.font = [UIFont systemFontOfSize:14];
[bgView addSubview:addressLabel];
UIButton *navButton = [[UIButton alloc] init];
navButton.frame = CGRectMake(15, 65, SCREENW - 30, 40);
[navButton setTitle:@"导航" forState:UIControlStateNormal];
[navButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[navButton.layer setMasksToBounds:YES];
[navButton.layer setCornerRadius:6];
[navButton.layer setBorderWidth:1.0];
[navButton initSpringTouch];
//设置按钮的边界颜色
CGColorRef color = [UIColor colorWithR:46 G:139 B:84 alpha:1.].CGColor;
[navButton.layer setBorderColor:color];
[navButton addTarget:self action:@selector(navButtonClick) forControlEvents:UIControlEventTouchUpInside];
[bgView addSubview:navButton];
}
#pragma mark弹出选择框
-(void)navButtonClick{
//弹出框
FMActionSheet *sheet = [[FMActionSheet alloc] initWithTitle:@"导航方式" buttonTitles:[NSArray arrayWithObjects:@"用手机自带地图导航", @"百度地图", nil] cancelButtonTitle:@"取消" delegate:(id<FMActionSheetDelegate>)self];
sheet.tag = 103;
sheet.titleFont = [UIFont systemFontOfSize:15];
sheet.titleBackgroundColor = [UIColor colorWithHexString:@"f4f5f8"];
sheet.titleColor = [UIColor colorWithHexString:@"666666"];
sheet.lineColor = [UIColor colorWithHexString:@"dbdce4"];
[sheet show];
}
- (void)actionSheet:(FMActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0) {
//打开系统自带的地图
[self openIOSMapNav];
} else if (buttonIndex == 1) {
//打开百度地图客户端导航
[self opsenBaiduMap];
}
}
#pragma mark 打开系统自带的地图
-(void)openIOSMapNav{
CLLocationCoordinate2D endCoor = CLLocationCoordinate2DMake([self.mendDetail.dimensions doubleValue], [self.mendDetail.longitude doubleValue]);
MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:endCoor addressDictionary:nil]];
toLocation.name = self.mendDetail.shopName;
[MKMapItem openMapsWithItems:@[currentLocation, toLocation] launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];
}
-(void)opsenBaiduMap{
double latitude =self.coordinate.latitude;
double longitude =self.coordinate.longitude;
NSString *urlString = [NSString stringWithFormat:@"baidumap://map/direction?origin=%f,%f&destination=%@,%@&mode=driving®ion=北京",latitude,longitude,self.mendDetail.dimensions,self.mendDetail.longitude];
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *mapUrl = [NSURL URLWithString:urlString];
if ([[UIApplication sharedApplication] canOpenURL:mapUrl]) {
[[UIApplication sharedApplication] openURL:mapUrl];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的手机没有安装百度地图" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
[alert show];
}
}
- (UIColor *)actionSheet:(FMActionSheet *)actionSheet buttonTextColorAtIndex:(NSInteger)bottonIndex{
UIColor *textColor = [UIColor colorWithR:41 G:140 B:82 alpha:1.];
return textColor;
}
#pragma mark -显示大头针
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation{
if (![annotation isKindOfClass:[RouteAnnotation class]]) return nil;
return [self getRouteAnnotationView:mapView viewForAnnotation:(RouteAnnotation *)annotation];
}
#pragma mark 获取路线的标注,显示到地图
- (BMKAnnotationView*)getRouteAnnotationView:(BMKMapView *)mapview viewForAnnotation:(RouteAnnotation*)routeAnnotation{
BMKAnnotationView *view = nil;
switch (routeAnnotation.type) {
case 0:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"start_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"start_node"];
view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_start"]];
view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));
view.canShowCallout = true;
}
view.annotation = routeAnnotation;
}
break;
case 1:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"end_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"end_node"];
view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_end"]];
view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));
view.canShowCallout = true;
}
view.annotation =routeAnnotation;
}
break;
case 4:
{
view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"route_node"];
if (view == nil) {
view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"route_node"];
view.canShowCallout = true;
} else {
[view setNeedsDisplay];
}
UIImage *image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_direction"]];
view.image = [image imageRotatedByDegrees:routeAnnotation.degree];
view.annotation = routeAnnotation;
}
break;
default:
break;
}
return view;
}
#pragma mark 驾车路线
-(void)showDriveSearch{
//线路检索节点信息
BMKPlanNode *start = [[BMKPlanNode alloc] init];
start.pt = self.coordinate;
start.cityName = @"北京市";
BMKPlanNode *end = [[BMKPlanNode alloc] init];
CLLocationCoordinate2D endCoordinate = CLLocationCoordinate2DMake([self.mendDetail.dimensions doubleValue], [self.mendDetail.longitude doubleValue]);
end.pt = endCoordinate;
end.cityName = @"北京市";
BMKDrivingRoutePlanOption *drivingRouteSearchOption = [[BMKDrivingRoutePlanOption alloc] init];
drivingRouteSearchOption.from = start;
drivingRouteSearchOption.to = end;
BOOL flag = [_routesearch drivingSearch:drivingRouteSearchOption];
if (flag) {
}
}
#pragma mark 返回驾乘搜索结果
- (void)onGetDrivingRouteResult:(BMKRouteSearch*)searcher result:(BMKDrivingRouteResult*)result errorCode:(BMKSearchErrorCode)error
{
NSArray* array = [NSArray arrayWithArray:_mapView.annotations];
[_mapView removeAnnotations:array];
array = [NSArray arrayWithArray:_mapView.overlays];
[_mapView removeOverlays:array];
if (error == BMK_SEARCH_NO_ERROR) {
//表示一条驾车路线
BMKDrivingRouteLine* plan = (BMKDrivingRouteLine*)[result.routes objectAtIndex:0];
// 计算路线方案中的路段数目
int size = (int)[plan.steps count];
int planPointCounts = 0;
for (int i = 0; i < size; i++) {
//表示驾车路线中的一个路段
BMKDrivingStep* transitStep = [plan.steps objectAtIndex:i];
if(i==0){
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item.coordinate = plan.starting.location;
item.title = @"起点";
item.type = 0;
[_mapView addAnnotation:item]; // 添加起点标注
}else if(i==size-1){
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item.coordinate = plan.terminal.location;
item.title = @"终点";
item.type = 1;
[_mapView addAnnotation:item]; // 添加终点标注
}
//添加annotation节点
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item.coordinate = transitStep.entrace.location;
item.title = transitStep.entraceInstruction;
item.degree = transitStep.direction * 30;
item.type = 4;
[_mapView addAnnotation:item];
//轨迹点总数累计
planPointCounts += transitStep.pointsCount;
}
// 添加途经点
if (plan.wayPoints) {
for (BMKPlanNode* tempNode in plan.wayPoints) {
RouteAnnotation* item = [[RouteAnnotation alloc]init];
item.coordinate = tempNode.pt;
item.type = 5;
item.title = tempNode.name;
[_mapView addAnnotation:item];
}
}
//轨迹点
BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts];
int i = 0;
for (int j = 0; j < size; j++) {
BMKDrivingStep* transitStep = [plan.steps objectAtIndex:j];
int k=0;
for(k=0;k<transitStep.pointsCount;k++) {
temppoints[i].x = transitStep.points[k].x;
temppoints[i].y = transitStep.points[k].y;
i++;
}
}
// 通过points构建BMKPolyline
BMKPolyline* polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];
[_mapView addOverlay:polyLine]; // 添加路线overlay
delete []temppoints;
[self mapViewFitPolyLine:polyLine];
}
}
#pragma mark 根据overlay生成对应的View
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<BMKOverlay>)overlay{
if ([overlay isKindOfClass:[BMKPolyline class]]) {
BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
polylineView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:1];
polylineView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
polylineView.lineWidth = 3.0;
return polylineView;
}
return nil;
}
#pragma mark 根据polyline设置地图范围
- (void)mapViewFitPolyLine:(BMKPolyline *) polyLine {
CGFloat ltX, ltY, rbX, rbY;
if (polyLine.pointCount < 1) return;
BMKMapPoint pt = polyLine.points[0];
ltX = pt.x, ltY = pt.y;
rbX = pt.x, rbY = pt.y;
for (int i = 0; i < polyLine.pointCount; i++) {
BMKMapPoint pt = polyLine.points[i];
if (pt.x < ltX) {
ltX = pt.x;
}
if (pt.x > rbX) {
rbX = pt.x;
}
if (pt.y > ltY) {
ltY = pt.y;
}
if (pt.y < rbY) {
rbY = pt.y;
}
}
BMKMapRect rect;
rect.origin = BMKMapPointMake(ltX , ltY);
rect.size = BMKMapSizeMake(rbX - ltX, rbY - ltY);
[_mapView setVisibleMapRect:rect];
_mapView.zoomLevel = _mapView.zoomLevel - 0.3;
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[_mapView viewWillDisappear];
_mapView.delegate = nil; // 不用时,置nil
_routesearch.delegate = nil;
}
@end