IOS百度地图API开发自定义气泡,点击气泡自动生成路线,以及拖拽 第一部分--牛刀小试
百度地图零基础到各种效果界面。上面的几行不用看,那是为了SEO,就是为了让我这篇博客让更多的人搜索到,上面的问题我都已经解决,我QQ915893620,有问题欢迎和我交流。我也会持续更新兄弟们的问题。下面是步骤:1.申请百度地图key,要想使用百度地图,你需要申请key,这个key是安桌苹果通用,但是你的项目名必须跟你的key吻合,至于什么是项目名,不多说,到网址http://api.map.baidu.com/lbsapi/cloud/ios-mobile-apply-key.htm 申请, 2.下载百度开发包,http://api.map.baidu.com/lbsapi/cloud/sdkiosdev-download.htm, 3.建立一个项目,项目名为cscapp,然后加入3个框架,MapKit.framework,CoreLocation.framework,QuartzCore.framework,将下载的开发包inc,libbaidumapapi.a,mapapi.bundle这三个文件加入到程序中 4.将ViewController的.m改成.mm 5.在委托中.h文件中中加入#import "BMapKit.h",并声明变量BMKMapManager* _mapManager;在.m委托中加入 _ mapManager = [[BMKMapManager alloc]init]; // 如果要关注网络及授权验证事件,请设定 generalDelegate 参数 BOOL ret = [_mapManager start:@"3102732B30E0D66EF51415C9E6CE055EC78FF07E" generalDelegate:nil]; if (!ret) { NSLog(@"manager start failed!"); } 6.注意:在这里就开始运行程序的话,我在我的iphone上运行这个百度地图,会出现-[UIDevice uniqueGlobalDeviceIdentifier]: unrecognized selector sent to instance 0x1ed19370 这么一个bug,解决办法很多,但是我感觉最爽的一种办法就是加入4个文件NSString+MD5Addition,UIDevice+IdentifierAddition,直接加入到项目里面就可以,无需引入头文件,下载地址http://www./file/id_30491149655344975.htm 7.在viewController.mm中的viewDidLoad改为如下代码 - (void)viewDidLoad { [super viewDidLoad]; BMKMapView* mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, 0, 320, 548)]; self.view = mapView; // Do any additional setup after loading the view, typically from a nib. } 保存后运行,一个最简单的百度地图API应用就完成了 源代码下载http://www./file/id_30491149655344976.htm 百度地图的功能很强大,上面只是牛刀小试 第二部分--百度DEMO解析
相对很多牛逼的公司的API和一些用的广泛的语言,百度API帮助文档略显粗糙。很多用法不尽详细,下载到DEMO肯定要仔细研究一番。功能一:MapViewDemo;这个部分就跟第一部分--牛刀小试的内容一样,仅仅显示一个地图画面,什么都没有,只不过我是用代码写上去的,百度这个DEMO是XIB文件弄的。为了兼容iphone5的分辨率,肯定用我那种方法要更人性化一些。 功能二:LocationDemo;这个是在百度地图上现实显示手机当前的问题,是一个蓝色的圆球,这个过程是程序启动定位,然后获取到准确经纬度坐标,还有可能在中途出现错误,我们需要提示定位出错,因为gps并不是无所不能,会受到天气,位置等的影响,如同在山上电话信号很差一样。如果要在自己的程序中实现这个功能,在.h,需要实现BMKMapViewDelegate,以及可以实现它的3个委托方法,并不是一定要实现。 首先_mapView.showsUserLocation = YES;//设置显示模式开启 如果你仅仅想显示那个圆球,那个已经够了。但是实际应用中肯定没有这么用的,需要实现下面委托 - (void)mapViewWillStartLocatingUser:(BMKMapView *)mapView//开始定位委托 //检测定位失败委托 - (void)mapView:(BMKMapView *)mapView didFailToLocateUserWithError:(NSError *)error{ if (error != nil)NSLog(@"locate failed: %@", [error localizedDescription]); } //当检测到手机位置发生了变化执行委托 - (void)mapView:(BMKMapView *)mapView didUpdateUserLocation:(BMKUserLocation *)userLocation 功能三:AnnotationDemo显示大头钉到地图上,这个功能仅仅实现显示一个大头钉到指定坐标,在点击大头钉时气泡显示标题和副标题,没有讲如何定制大头钉,以及如何定制大头钉上的气泡,我们是可以随意定制大头钉的 功能四:定制一个层到层,这个没什么好说的,用的较少,需要的时候再来看看 功能五,搜索,用的很广泛,这个功能很强大,你可以搜索某一坐标点附近的加油站,停车场,宾馆,酒店,餐厅,甚至厕所都能搜索到,比如说你想查找5000米内的加油站,以及1000米内的停车场。 flag = [_search poiSearchNearBy:@"加油站" center:coor1 radius:5000 pageIndex:0]; flag = [_search poiSearchNearBy:@"停车场" center:coor1 radius:1000 pageIndex:0]; 然后用委托- (void)onGetPoiResult:(NSArray*)poiResultList searchType:(int)type errorCode:(int)error 输出结果。 功能六:规划路线,就是导航,重点功能,分为3种方式,想不出有什么难的 功能七:剩下功能没什么好纪录的,看一遍自然懂 第三部分--常用功能
搜索附近的宾馆,停车场,加油站等等都是用以下代码实现- (void)onGetPoiResult:(NSArray*)poiResultList searchType:(int)type errorCode:(int)error { if (error == BMKErrorOk) { BMKPoiResult* result = [poiResultList objectAtIndex:0]; for (int i = 0; i < result.poiInfoList.count; i++) { BMKPoiInfo* poi = [result.poiInfoList objectAtIndex:i]; BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init]; item.coordinate = poi.pt; item.title = poi.name; [_mapView addAnnotation:item]; [item release]; } } } -(IBAction)onClickOk { NSArray* array = [NSArray arrayWithArray:_mapView.annotations]; [_mapView removeAnnotations:array]; array = [NSArray arrayWithArray:_mapView.overlays]; [_mapView removeOverlays:array]; BOOL flag = [_search poiSearchInCity:_cityText.text withKey:_keyText.text pageIndex:0]; if (!flag) { NSLog(@"search failed!"); } } //更新坐标 -(void)mapView:(BMKMapView *)mapView didUpdateUserLocation:(BMKUserLocation *)userLocation{ self._latitude = userLocation.coordinate.latitude; self._longitude = userLocation.coordinate.longitude; if (!testcheckMap) { //给view中心定位 BMKCoordinateRegion region; region.center.latitude = userLocation.location.coordinate.latitude; region.center.longitude = userLocation.location.coordinate.longitude; region.span.latitudeDelta = 0.02; region.span.longitudeDelta = 0.02; _mapView.region = region; //加个当前坐标的小气泡 [_search reverseGeocode:userLocation.location.coordinate]; } } //定位停止 -(void)mapViewDidStopLocatingUser:(BMKMapView *)mapView{ //添加圆形覆盖 // BMKCircle* circle = [BMKCircle circleWithCenterCoordinate:mapView.centerCoordinate radius:1000]; // [mapView addOverlay:circle]; //标记我的位置 BMKUserLocation *userLocation = mapView.userLocation; userLocation.title = @"我的位置"; [_mapView addAnnotation:userLocation]; [mapView setShowsUserLocation:YES]; } 将百度地图视角切换到某一坐标点 -(void)Region{ CLLocationCoordinate2D coor; coor.latitude = self._latitude; coor.longitude = self._longitude; NSDictionary *tip = BMKBaiduCoorForWgs84(coor); CLLocationCoordinate2D coor1= BMKCoorDictionaryDecode(tip); BMKCoordinateRegion viewRegion = BMKCoordinateRegionMake(coor1, BMKCoordinateSpanMake(0.05,0.05)); BMKCoordinateRegion adjustedRegion = [_mapView regionThatFits:viewRegion]; [_mapView setRegion:adjustedRegion animated:YES]; } 清除地图上所有痕迹和路线 -(void)clereOldYJDH{ NSArray* array = [NSArray arrayWithArray:_mapView.annotations]; [_mapView removeAnnotations:array]; array = [NSArray arrayWithArray:_mapView.overlays]; [_mapView removeOverlays:array]; [self Region]; } //当选中一个annotation views时,调用此接口 - (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view { NSLog(@"选中一个annotation views:%f,%f",view.annotation.coordinate.latitude,view.annotation.coordinate.longitude); } //当取消选中一个annotation views时,调用此接口 - (void)mapView:(BMKMapView *)mapView didDeselectAnnotationView:(BMKAnnotationView *)view{ NSLog(@"取消选中一个annotation views"); } //*在地图View将要启动定位时,会调用此函数 - (void)mapViewWillStartLocatingUser:(BMKMapView *)mapView { NSLog(@"地图View将要启动定位"); } //当mapView新添加annotation views时,调用此接口 - (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views { NSLog(@"mapView新添加annotation views"); } //*在地图View停止定位后,会调用此函数 - (void)mapViewDidStopLocatingUser:(BMKMapView *)mapView { NSLog(@"地图View停止定位"); } //当点击annotation view弹出的泡泡时,调用此接口 - (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view { NSLog(@"点击annotation view弹出的泡泡"); } //annotation view有许多不同的状态,在不同状态的时候我们都可以设置不同的操作,拖动annotation view时view的状态变化 - (void)mapView:(BMKMapView *)mapView annotationView:(BMKAnnotationView *)view didChangeDragState:(BMKAnnotationViewDragState)newStatefromOldState:(BMKAnnotationViewDragState)oldState { NSLog(@"动annotation view时view的状态变化"); } ((BMKPinAnnotationView *)annotationView).pinColor = BMKPinAnnotationColorGreen;//标注呈绿色样式[annotationView setDraggable:YES];//允许用户拖动 annotationView.leftCalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_location.png"]];//气泡框左侧显示的View,可自定义 annotationView.rightCalloutAccessoryView =selectButton;//气泡框右侧显示的View 可自定义 [annotationView setSelected:YES animated:YES];//让标注在进入界面时就处于弹出气泡框的状态 annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5));整个标注的偏移量 annotationView.annotation = annotation;//绑定对应的标点经纬度 annotationView.canShowCallout = TRUE;//允许点击弹出气泡框 在地图上定制标注替代大头钉,可以将文字图片所有能加到view中的,都可以以大头钉的形式显示出来,需要将view转换为image主要代码,最重要的是知道这个原理,然后实现起来就很简单: - (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation 在这个委托中实现如下代码 UIView *viewForImage=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 132, 64)]; UIImageView *imageview=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 32, 64)]; [imageview setImage:[UIImage imageNamed:@"车位置.png"]]; [viewForImage addSubview:imageview]; UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(32, 0, 100, 64)]; label.text=@"陈双超"; label.backgroundColor=[UIColor clearColor]; [viewForImage addSubview:label]; annotationView.image=[self getImageFromView:viewForImage]; -(UIImage *)getImageFromView:(UIView *)view{ UIGraphicsBeginImageContext(view.bounds.size); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } 部分效果图 第四部分--问题
1.有一个朋友问我他做导航时,传参数遇到问题,就是输入汉字部分没有,仅靠两点的经纬度怎么实现路线导航,他试了很久没弄出来。然后我把解决这个问题的源码贴出来。我做的是驾车路线,如果需要步行或者公交则需要作调整。主要涉及的方法如下,实现这个的代码,我直接从我的项目中弄出来的http://www./file/id_30491149655345069.htm-(void)onClickDriveSearch { NSLog(@"%f,%f,%f,%f",_startCoordainateXText,_startCoordainateYText,_endCoordainateXText,_endCoordainateYText); count = 0; isLoadingMap=2; if(!_endCoordainateXText ||!_endCoordainateYText )isLoadingMap=1; NSArray* array = [NSArray arrayWithArray:_mapView.annotations]; [_mapView removeAnnotations:array]; array = [NSArray arrayWithArray:_mapView.overlays]; [_mapView removeOverlays:array]; CLLocationCoordinate2D startPt = (CLLocationCoordinate2D){0, 0}; CLLocationCoordinate2D endPt = (CLLocationCoordinate2D){0, 0}; if (_startCoordainateXText && _startCoordainateYText ) { startPt = (CLLocationCoordinate2D){_startCoordainateYText ,_startCoordainateXText }; } if (_endCoordainateYText && _endCoordainateXText ) { endPt = (CLLocationCoordinate2D){ _endCoordainateYText ,_endCoordainateXText}; } BMKPlanNode* start = [[BMKPlanNode alloc]init]; start.pt = startPt; start.name = nil; BMKPlanNode* end = [[BMKPlanNode alloc]init]; end.pt = endPt; end.name = nil; BOOL flag = [_search drivingSearch:nil startNode:start endCity:nil endNode:end]; if (!flag) { NSLog(@"search failed"); } [start release]; [end release]; [self Region]; } |
|