Go to the baidu map application APPkey:http://developer.baidu.com/map/index.php?title=iossdk developer center, download the baidu map SDK.

BaiduMapAPI_Base. Framework is the basic package, it is necessary to import, according to their own needs to import the required Baidu SDK framework, the new SDK has been able to choose which framework to download, reduce the size of the package.

Import the required system libraries, in the Xcode project

CoreLocation.framework                                         QuartzCore.framework                                         OpenGLES.framework                                         SystemConfiguration.framework                                         CoreGraphics.framework                                         Security.framework                                         Libsqlite3.0.tbd (xcode7 formerly libsqlite3.0.dylib)                                         CoreTelephony.framework                                         Libstdc++.6.0.9. TBD (xcode7 was libstdc++.6.0.9. Dylib)Copy the code

Introduce headers as required, we just need to locate, search and route drawing, so it’s not necessary to introduce all of them.

#import 
 
#import 
      
       // import all header files for map functionality
      
 
# import < BaiduMapAPI_Search/BMKSearchComponent. H > / / introduced retrieval functions all the header files
 
# import < BaiduMapAPI_Cloud/BMKCloudSearchComponent. H > / / into cloud retrieval functions all the header files
 
# import < BaiduMapAPI_Location/BMKLocationComponent. H > / / introduce positioning function all the header files
 
# import < BaiduMapAPI_Utils/BMKUtilsComponent. H > / / introduce computational tools all the header files
 
# import < BaiduMapAPI_Radar/BMKRadarComponent. H > / / introduction surrounding radar function all the header files
 
#import < BaiduMapAPI_Map/ bmkmapView.h >// import only the single header file required
Copy the code

Let’s start with code practice:

First reference the proxy method:

Based agent BMKRouteSearchDelegate BMKMapViewDelegate / / / / search agency BMKLocationServiceDelegate / / positioning BMKGeoCodeSearchDelegate / / geographical coding agentCopy the code

Definition declaration file:

@interface RouteSearchDemoViewController : BaseViewCtrl<BMKMapViewDelegate, BMKRouteSearchDelegate,BMKLocationServiceDelegate,BMKGeoCodeSearchDelegate> { IBOutlet BMKMapView* _mapView; // map view IBOutlet UITextField* _startCityText; IBOutlet UITextField* _startAddrText; IBOutlet UITextField* _endCityText; IBOutlet UITextField* _endAddrText; BMKRouteSearch* _routesearch; // search for BMKLocationService *locService; } -(IBAction)onClickBusSearch; // Bus route -(IBAction)onClickDriveSearch; -(IBAction)onClickWalkSearch; Fetch - (IBAction)textFiledReturnEditing:(id)sender; @property(nonatomic,retain)MapAlertView *mapview; // a cover view@endCopy the code

You use XIB files in your classes, so you can drag and drop, position and size the controls as you want.

In the implementation file to add a picture out of the function, some line drawing and icon changes need to use (Baidu Demo has this function)

@implementation UIImage(InternalMethod)

- (UIImage*)imageRotatedByDegrees:(CGFloat)degrees
{
    
    CGFloat width = CGImageGetWidth(self.CGImage);
    CGFloat height = CGImageGetHeight(self.CGImage);
    
    CGSize rotatedSize;
    
    rotatedSize.width = width;
    rotatedSize.height = height;
    
    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
    CGContextRotateCTM(bitmap, degrees * M_PI / 180);
    CGContextRotateCTM(bitmap, M_PI);
    CGContextScaleCTM(bitmap, -1.0, 1.0);
    CGContextDrawImage(bitmap, CGRectMake(-rotatedSize.width/2, -rotatedSize.height/2, rotatedSize.width, rotatedSize.height), self.CGImage);
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

@end
Copy the code

Now comes the actual implementation phase of the map: encapsulating a function to fetch resource files, retrieving images from Baidu’s bundle, and so on:

- (void)viewDidLoad {
    [super viewDidLoad];
    //适配ios7
    if(([[[UIDevice currentDevice] systemVersion] doubleValue] > = 7.0)) {self. NavigationController. NavigationBar. Translucent =  NO; } _routesearch = [[BMKRouteSearch alloc] init]; _routesearch.delegate = self; [_mapViewsetZoomEnabled:YES];
    [_mapView setZoomLevel:13]; // Level, 3-19 _mapView.showMapScaleBar = YES; / / scale _mapView. MapScaleBarPosition = CGPointMake (10, _mapView. Frame. The size, height - 45); . / / the position of the scale _mapView showsUserLocation = YES; / / show the location of the current device _mapView. UserTrackingMode = BMKUserTrackingModeFollow; _mapview.delegate = self; [_mapViewsetMapType:BMKMapTypeStandard]; LocService = [[BMKLocationService alloc] init]; locService.delegate = self; // Start LocationService [locService startUserLocationService]; }Copy the code

Start positioning and geo-inverse coding to obtain location information:

/ update location information * * * * * @ param userLocation acquire the position data to * / - (void) didUpdateBMKUserLocation: (userLocation BMKUserLocation *) { CLLocationCoordinate2D coordinate = userLocation.location.coordinate; // Coordinatespan span = BMKCoordinateSpanMake(0.1, 0.1); BMKCoordinateRegion region = BMKCoordinateRegionMake(coordinate, span); [_mapViewsetRegion:region]; BMKReverseGeoCodeOption *option = [[BMKReverseGeoCodeOption alloc] init]; option.reverseGeoPoint = CLLocationCoordinate2DMake(userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude); BMKGeoCodeSearch *geoCode = [[BMKGeoCodeSearch alloc] init]; geoCode.delegate = self; [geoCode reverseGeoCode:option]; [option release]; [geoCode release]; } / reverse coding location back to agent * * * * * @ param result returned results * / - (void) onGetReverseGeoCodeResult (BMKGeoCodeSearch *) a searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error {if(result) { _startCityText.text = result.addressDetail.city;; _startAddrText.text = result.addressDetail.streetName; [locService stopUserLocationService] [locService stopUserLocationService] [locService stopUserLocationService] }}Copy the code

Through the above two functions, the city and location address can be obtained. More detailed information can be seen in addressDetail, which generally includes the district, street, street number, etc.

Add a button to the View. When clicked, a custom AlertView pops up with three buttons: Bus, Drive, and Walk. Add a gesture to remove or hide the AlertView by clicking somewhere outside the button.

Click the navigation path to be drawn, and there is a corresponding search class:

-(IBAction)onClickBusSearch
{
    if ([_startCityText.text isEqualToString:@""]) {
         [self AddStatusLabelWithText:@"Obtaining location"];
        return; } [self.mapview removeFromSuperview]; BMKPlanNode* start = [[[BMKPlanNode alloc]init] autorelease]; start.name = _startAddrText.text; BMKPlanNode* end = [[[BMKPlanNode alloc]init] autorelease]; end.name = _endAddrText.text; / / bus BMKTransitRoutePlanOption * transitRouteSearchOption = [[BMKTransitRoutePlanOption alloc] init]; transitRouteSearchOption.city = _startCityText.text; transitRouteSearchOption.from = start; transitRouteSearchOption.to = end; BOOL flag = [_routesearch transitSearch:transitRouteSearchOption]; [transitRouteSearchOption release];if(flag)
    {
        NSLog(@"Bus retrieval sent successfully");
    }
    else
    {
        NSLog(@"Bus retrieval send failed");
    }
}

-(IBAction)onClickDriveSearch
{
    if ([_startCityText.text isEqualToString:@""]) {
        [self AddStatusLabelWithText:@"Obtaining location"];
        return; } [self.mapview removeFromSuperview]; BMKPlanNode* start = [[[BMKPlanNode alloc]init] autorelease]; start.name = _startAddrText.text; BMKPlanNode* end = [[[BMKPlanNode alloc]init] autorelease]; end.name = _endAddrText.text; / / / driving based information query class BMKDrivingRoutePlanOption * drivingRouteSearchOption = [[BMKDrivingRoutePlanOption alloc] init]; drivingRouteSearchOption.from = start; drivingRouteSearchOption.to = end; BOOL flag = [_routesearch drivingSearch:drivingRouteSearchOption]; [drivingRouteSearchOption release];if(flag)
    {
        NSLog(@"Car retrieval sent successfully");
    }
    else
    {
        NSLog(@"Car retrieval send failed");
    }

}

-(IBAction)onClickWalkSearch
{
    if ([_startCityText.text isEqualToString:@""]) {
    [self AddStatusLabelWithText:@"Obtaining location"];
    return; } [self.mapview removeFromSuperview]; BMKPlanNode* start = [[[BMKPlanNode alloc]init] autorelease]; start.name = _startAddrText.text; BMKPlanNode* end = [[[BMKPlanNode alloc]init] autorelease]; end.name = _endAddrText.text; / / / walk based information query BMKWalkingRoutePlanOption * walkingRouteSearchOption = [[BMKWalkingRoutePlanOption alloc] init]; walkingRouteSearchOption.from = start; walkingRouteSearchOption.to = end; BOOL flag = [_routesearch walkingSearch:walkingRouteSearchOption]; [walkingRouteSearchOption release];if(flag)
    {
        NSLog(@"Walk retrieval sent successfully");
    }
    else
    {
        NSLog(@"Walk retrieve send failed"); }}Copy the code

Each start city and address can be set, where the start city of the bus line and transitRouteSearchOption city are required, otherwise the search will fail or the route can not be retrieved;

The corresponding draw line agent method will be called back after the send retrieval is successful:

- (void)onGetTransitRouteResult:(BMKRouteSearch*)searcher result:(BMKTransitRouteResult*)result errorCode:(BMKSearchErrorCode)error { MapExplainViewController *exp=[[[MapExplainViewController alloc]init]autorelease];  exp.array=result.routes; [self.navigationController pushViewController:exp animated:YES]; NSArray* array = [NSArray arrayWithArray:_mapView.annotations]; [_mapView removeAnnotations:array]; array = [NSArray arrayWithArray:_mapView.overlays]; [_mapView removeOverlays:array];if(error == BMK_SEARCH_NO_ERROR) { BMKTransitRouteLine* plan = (BMKTransitRouteLine*)[result.routes objectAtIndex:0]; Int size = [plan. Steps count]; int planPointCounts = 0;for (int i = 0; i < size; i++) {
            BMKTransitStep* transitStep = [plan.steps objectAtIndex:i];
            if(i==0){
                RouteAnnotation* item = [[RouteAnnotation alloc]init];
                item.coordinate = plan.starting.location;
                item.title = @"Starting point"; item.type = 0; [_mapView addAnnotation:item]; // add the starting tag [item release]; }else if(i==size-1){
                RouteAnnotation* item = [[RouteAnnotation alloc]init];
                item.coordinate = plan.terminal.location;
                item.title = @"The end"; item.type = 1; [_mapView addAnnotation:item]; // add the starting tag [item release]; } RouteAnnotation* item = [[RouteAnnotation alloc]init]; item.coordinate = transitStep.entrace.location; item.title = transitStep.instruction; item.type = 3; [_mapView addAnnotation:item]; [item release]; // planPointCounts += transitstep-pointscount; } // BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts]; int i = 0;for (int j = 0; j < size; j++) {
            BMKTransitStep* 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++; }} / / by points to construct BMKPolyline BMKPolyline * polyLine = [BMKPolyline polylineWithPoints: temppoints count: planPointCounts]; [_mapView addOverlay:polyLine]; // add route overlay delete []temppoints; }} // drive the route draw - (void)onGetDrivingRouteResult:(BMKRouteSearch*)searcher result:(BMKDrivingRouteResult*)result errorCode:(BMKSearchErrorCode)error { MapExplainViewController *exp=[[[MapExplainViewController alloc]init]autorelease];  exp.array=result.routes; [self.navigationController pushViewController:exp animated:YES]; 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 = [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 = @"Starting point"; item.type = 0; [_mapView addAnnotation:item]; // add the starting tag [item release]; }else if(i==size-1){
                RouteAnnotation* item = [[RouteAnnotation alloc]init];
                item.coordinate = plan.terminal.location;
                item.title = @"The end"; item.type = 1; [_mapView addAnnotation:item]; // add the starting tag [item release]; } // Add annotation node 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]; [item release]; // planPointCounts += transitstep-pointscount; } // Add passing pointsif (plan.wayPoints) {
            for (BMKPlanNode* tempNode inplan.wayPoints) { RouteAnnotation* item = [[RouteAnnotation alloc]init]; item = [[RouteAnnotation alloc]init]; item.coordinate = tempNode.pt; item.type = 5; item.title = tempNode.name; [_mapView addAnnotation:item]; [item release]; 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++; }} / / by points to construct BMKPolyline BMKPolyline * polyLine = [BMKPolyline polylineWithPoints: temppoints count: planPointCounts]; [_mapView addOverlay:polyLine]; // add route overlay delete []temppoints; }} // the route to walk is drawn - (void)onGetWalkingRouteResult:(BMKRouteSearch*)searcher result:(BMKWalkingRouteResult*)result errorCode:(BMKSearchErrorCode)error { MapExplainViewController *exp=[[[MapExplainViewController alloc]init] autorelease]; exp.array=result.routes; [self.navigationController pushViewController:exp animated:YES]; NSArray* array = [NSArray arrayWithArray:_mapView.annotations]; [_mapView removeAnnotations:array]; array = [NSArray arrayWithArray:_mapView.overlays]; [_mapView removeOverlays:array];if (error == BMK_SEARCH_NO_ERROR) {
        BMKWalkingRouteLine* plan = (BMKWalkingRouteLine*)[result.routes objectAtIndex:0];
        int size = [plan.steps count];
        int planPointCounts = 0;
        for (int i = 0; i < size; i++) {
            BMKWalkingStep* transitStep = [plan.steps objectAtIndex:i];
            if(i==0){
                RouteAnnotation* item = [[RouteAnnotation alloc]init];
                item.coordinate = plan.starting.location;
                item.title = @"Starting point"; item.type = 0; [_mapView addAnnotation:item]; // add the starting tag [item release]; }else if(i==size-1){
                RouteAnnotation* item = [[RouteAnnotation alloc]init];
                item.coordinate = plan.terminal.location;
                item.title = @"The end"; item.type = 1; [_mapView addAnnotation:item]; // add the starting tag [item release]; } // Add annotation node 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]; [item release]; // planPointCounts += transitstep-pointscount; } // BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts]; int i = 0;for (int j = 0; j < size; j++) {
            BMKWalkingStep* 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++; }} / / by points to construct BMKPolyline BMKPolyline * polyLine = [BMKPolyline polylineWithPoints: temppoints count: planPointCounts]; [_mapView addOverlay:polyLine]; // add route overlay delete []temppoints; }}Copy the code

After the searched callback agent is successful, you need to draw lines on the MapView:

///<0: starting point 1: ending point 2: bus 3: - (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"] autorelease];
                view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_start.png"]]. 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"] autorelease];
                view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_end.png"]]. View. centerOffset = CGPointMake(0, -(view.frame.size. Height * 0.5)); view.canShowCallout = TRUE; } view.annotation = routeAnnotation; }break;
        case 2:
        {
            view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"bus_node"];
            if (view == nil) {
                view = [[[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"bus_node"] autorelease];
                view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_bus.png"]];
                view.canShowCallout = TRUE;
            }
            view.annotation = routeAnnotation;
        }
            break;
        case 3:
        {
            view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"rail_node"];
            if (view == nil) {
                view = [[[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"rail_node"] autorelease];
                view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_rail.png"]];
                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"] autorelease];
                view.canShowCallout = TRUE;
            } else {
                [view setNeedsDisplay];
            }
            
            UIImage* image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_direction.png"]];
            view.image = [image imageRotatedByDegrees:routeAnnotation.degree];
            view.annotation = routeAnnotation;
            
        }
            break;
        case 5:
        {
            view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"waypoint_node"];
            if (view == nil) {
                view = [[[BMKAnnotationView alloc]initWithAnnotation:routeAnnotation reuseIdentifier:@"waypoint_node"] autorelease];
                view.canShowCallout = TRUE;
            } else {
                [view setNeedsDisplay];
            }
            
            UIImage* image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_waypoint.png"]];
            view.image = [image imageRotatedByDegrees:routeAnnotation.degree];
            view.annotation = routeAnnotation;
        }
            break;
        default:
            break;
    }
    
    return view;
}

- (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[RouteAnnotation class]]) {
        return [self getRouteAnnotationView:view viewForAnnotation:(RouteAnnotation*)annotation];
    }
    returnnil; } // overlay :(BMKOverlayView*)mapView:(BMKMapView *)map viewForOverlay:(id<BMKOverlay>)overlay {if([overlay isKindOfClass:[BMKPolyline class]]) { BMKPolylineView* polylineView = [[[BMKPolylineView alloc] initWithOverlay:overlay] autorelease]; polylineView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:1]; PolylineView. StrokeColor = [[UIColor blueColor] colorWithAlphaComponent: 0.7]; PolylineView. Our lineWidth = 3.0;return polylineView;
    }
    return nil;
}
Copy the code

After the above method, basically in mapView you can see the route navigation map, if not, you can enumerate those errors to check the reason, after all, Baidu is China, so the SDK annotations are Chinese, for English poor for me, it is too happy.

Another place uses Baidu location to obtain weather information, which is much faster than the system’s geo-coding, and quickly obtains the location of the city.

The same weather API uses Baidu weather, the data returned directly has the url of the corresponding weather picture, although the picture is ugly, but it is better than no, the following is baidu weather API address:

-(void)WeatherRequest
{
     [self ShowWaitView:@"Loading..."]; //[GlobalData GetInstance].GB_CityString = [[GlobalData GetInstance].GB_CityString URLEncoding]; NSString *strurl=[NSString stringWithFormat:@"http://api.map.baidu.com/telematics/v3/weather?location=%@&output=json&ak=C3d2845360d091a5e8f42f605b7472ea",str];
    ASIFormDataRequest *weatherRequest = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:strurl]];
    
    weatherRequest.delegate = self;
    [weatherRequest startAsynchronous];
}
Copy the code