【IOS开发基础系列】地图开发专题

重点参考链接:

IOS之地图和定位应用开发

http://www.cnblogs.com/syxchina/archive/2012/10/14/2723522.html


IOS开发之百度地图API应用

http://www.cocoachina.com/ios/20120507/4224.html


1 定位开发——CoreLocation库

1.1 CLLocationManager类


1.1.1 CLLocationManagerDelegate

/*

 * locationManager:didUpdateToLocation:fromLocation:

 * 

 * Discussion:

 *   Invoked when a new location is available. oldLocation may be nil ifthere is no previous location

 *   available.

 *

 *   This method is deprecated. If locationManager:didUpdateLocations: is

 *   implemented, this method will not be called.

 */

- (void)locationManager: (CLLocationManager*)manager didUpdateToLocation: (CLLocation*)newLocation fromLocation: (CLLocation *)oldLocation __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_NA, __IPHONE_2_0, __IPHONE_6_0);


/*

 * locationManager:didUpdateLocations:

 *

 * Discussion:

 *   Invoked when new locations are available.  Required for delivery of

 *   deferred locations.  Ifimplemented, updates will

 *   not be delivered to locationManager:didUpdateToLocation:fromLocation:

 *

 *   locations is an array of CLLocation objects in chronological order.

 */

- (void)locationManager: (CLLocationManager*)manager didUpdateLocations: (NSArray *)locations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);


/*

 * locationManager:didUpdateHeading:

 * 

 * Discussion:

 *   Invoked when a new heading is available.

 */

- (void) locationManager: (CLLocationManager*)manager didUpdateHeading: (CLHeading *)newHeading     __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);


/*

 * locationManagerShouldDisplayHeadingCalibration:

 *

 * Discussion:

 *   Invoked when a new heading is available. Return YES to display headingcalibration info. The display

 *   will remain until heading is calibrated, unless dismissed early viadismissHeadingCalibrationDisplay.

 */

- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager*) manager    __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);


/*

 * locationManager:didDetermineState:forRegion:

 *

 * Discussion:

 *   Invoked when there's a state transition for a monitored region or inresponse to a request for state via a

 *   a call to requestStateForRegion:.

 */

- (void)locationManager: (CLLocationManager*)manager didDetermineState: (CLRegionState)state forRegion: (CLRegion *)region     __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);


/*

 * locationManager:didRangeBeacons:inRegion:

 *

 * Discussion:

 *   Invoked when a new set of beacons are available in the specified region.

 *   beacons is an array of CLBeacon objects.

 *   If beacons is empty, it may be assumed no beacons that match thespecified region are nearby.

 *   Similarly if a specific beacon no longer appears in beacons, it may beassumed the beacon is no longer received

 *   by the device.

 */

- (void) locationManager: (CLLocationManager*)manager didRangeBeacons: (NSArray *)beacons inRegion: (CLBeaconRegion *)region  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);


/*

 * locationManager:rangingBeaconsDidFailForRegion:withError:

 *

 * Discussion:

 *   Invoked when an error has occurred ranging beacons in a region. Errortypes are defined in "CLError.h".

 */

- (void) locationManager: (CLLocationManager*)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion*)region withError: (NSError *)error __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);


/*

 * locationManager:didEnterRegion:

 *

 * Discussion:

 *   Invoked when the user enters a monitored region.  This callback will be invoked for everyallocated

 *   CLLocationManager instance with a non-nil delegate that implements thismethod.

 */

- (void) locationManager: (CLLocationManager*)manager didEnterRegion: (CLRegion *)region __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);


/*

 * locationManager:didExitRegion:

 *

 * Discussion:

 *   Invoked when the user exits a monitored region.  This callback will be invoked for everyallocated

 *   CLLocationManager instance with a non-nil delegate that implements thismethod.

 */

- (void) locationManager: (CLLocationManager*)manager didExitRegion: (CLRegion *)region __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);


/*

 * locationManager:didFailWithError:

 * 

 * Discussion:

 *   Invoked when an error has occurred. Error types are defined in"CLError.h".

 */

- (void) locationManager: (CLLocationManager*)manager didFailWithError: (NSError*)error;


/*

 * locationManager:monitoringDidFailForRegion:withError:

 * 

 * Discussion:

 *   Invoked when a region monitoring error has occurred. Error types aredefined in "CLError.h".

 */

- (void) locationManager: (CLLocationManager*)manager monitoringDidFailForRegion:(CLRegion*)region withError: (NSError *)error __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);


/*

 * locationManager:didChangeAuthorizationStatus:

 * 

 * Discussion:

 *   Invoked when the authorization status changes for this application.

 */

- (void) locationManager: (CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status    __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_2);


/*

 * locationManager:didStartMonitoringForRegion:

 * 

 * Discussion:

 *   Invoked when a monitoring for a region started successfully.

 */

- (void) locationManager: (CLLocationManager*)manager didStartMonitoringForRegion:(CLRegion *)region     __OSX_AVAILABLE_STARTING(__MAC_TBD,__IPHONE_5_0);


/*

 * Discussion:

 *   Invoked when location updates are automatically paused.

 */

- (void) locationManagerDidPauseLocationUpdates: (CLLocationManager *)manager __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);


/*

 * Discussion:

 *   Invoked when location updates are automatically resumed.

 *

 *   In the event that your application is terminated while suspended, youwill

 *    not receive this notification.

 */

- (void) locationManagerDidResumeLocationUpdates: (CLLocationManager *)manager __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);


/*

 * locationManager:didFinishDeferredUpdatesWithError:

 *

 * Discussion:

 *   Invoked when deferred updates will no longer be delivered. Stopping

 *   location, disallowing deferred updates, and meeting a specifiedcriterion

 *   are all possible reasons for finishing deferred updates.

 *

 *   An error will be returned if deferred updates end before the specified

 *   criteria are met (see CLError).

 */

- (void) locationManager: (CLLocationManager*)manager didFinishDeferredUpdatesWithError:(NSError *)error     __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);


/*

 * locationManager:didVisit:

 *

 * Discussion:

 *   Invoked when the CLLocationManager determines that the device hasvisited

 *   a location, if visit monitoring is currently started (possibly from a

 *   prior launch).

 */

- (void) locationManager: (CLLocationManager *)manager didVisit: (CLVisit*)visit;


1.2 使用示例

1.2.1 locationManager初始化

self.locationManager = [[CLLocationManager alloc] init];

self.locationManager.delegate = self;

self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;

self.locationManager.distanceFilter = 1000.0f;

[self.locationManager startUpdatingLocation];


1.3.2 [endif]CLLocationManagerDelegate回调处理

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma mark - CLLocationManagerDelegate 委托处理

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray*)locations

{

    _locationArray= locations;


    if (!_locationArray) {

        return;

    }


    CLLocation * location = [locations lastObject];

    [manager stopUpdatingLocation];


    // 添加一个PointAnnotation

    //缩放级别设置

    BMKCoordinateRegion viewRegion = BMKCoordinateRegionMakeWithDistance(location.coordinate, 200, 200);

    BMKCoordinateRegion adjustRegion = [_bMapView regionThatFits: viewRegion];

    adjustRegion.center.latitude += adjustRegion.span.latitudeDelta - viewRegion.span.latitudeDelta;

    adjustRegion.center.longitude += adjustRegion.span.longitudeDelta - viewRegion.span.longitudeDelta;

    BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc] init];

    annotation.coordinate = adjustRegion.center;

    annotation.title = @"I'm Here";


    //添加标注点

    [_bMapView addAnnotation: annotation];


    //设置地图中心的地理位置

    [_bMapView setRegion: adjustRegion animated: YES];

    [_annotationMArray addObject: annotation];

    LOGDEBUG([NSString stringWithFormat: @"GetLocation: Lat:%f, Long:%f", location.coordinate.latitude, location.coordinate.longitude]);

}


- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus: (CLAuthorizationStatus)status

{

    switch(status) {

        case kCLAuthorizationStatusNotDetermined:

            LOGDEBUG(@"Request Location Authorization");

            [manager requestWhenInUseAuthorization];

            break;

        default:

            break;

    }

}


- (void)locationManager:(CLLocationManager *)manager didFailWithError: (NSError*)error

{

    LOGDEBUG([NSString stringWithFormat: @"Get Location Fail: %@", error.userInfo]);

}

1.3.3 IOS 8.0后新增授权提示处理

    1、在locationManager对象调用startUpdatingLocation方法前,需调用授权请求方法,或者实现didChangeAuthorizationStatus回调,对于未授权情况发起授权请求。主动调用requestWhenInUseAuthorization方法:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0

    // iPhone OS SDK 0.0 以后版本的处理

    [self.locationManager requestWhenInUseAuthorization];

#else

        // iPhone OS SDK 8.0 之前版本的处理

#endif

    [self.locationManager startUpdatingLocation];


        实现didChangeAuthorizationStatus回调,对于未授权情况调用requestWhenInUseAuthorization方法:

- (void) locationManager: (CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status

{

    switch (status) {

        case kCLAuthorizationStatusNotDetermined:

            LOGDEBUG(@"Request Location Authorization");

            [manager requestWhenInUseAuthorization];

            break;

        default:

            break;

    }

}


    2、在info.plist文件中增加至少一个授权Alert框的提示文本,可为空,建议将NSLocationWhenInUseUsageDescription、NSLocationAlwaysUsageDescription两个节点都配置上:

【IOS开发基础系列】地图开发专题_第1张图片


2 IOS原生地图开发

2.1 MKMapView使用

2.1.1 接口申明

typedef NS_ENUM(NSInteger, MKUserTrackingMode) {

    MKUserTrackingModeNone =0,     // the user's location is not followed

    MKUserTrackingModeFollow,        // the map follows the user's location

    MKUserTrackingModeFollowWithHeading,    // the map follows the user's location and heading

} NS_ENUM_AVAILABLE(NA, 5_0);


#if TARGET_OS_IPHONE

MK_CLASS_AVAILABLE(NA, 3_0)

@interface MKMapView : UIView

#else

MK_CLASS_AVAILABLE(10_9, NA)

@interface MKMapView : NSView

#endif


@property (nonatomic, weak) id delegate;


// Changing the map type or region can cause the map to start loading map

content.

// The loading delegate methods will be called as map content is loaded.

@property (nonatomic) MKMapTypemapType;


// Region is the coordinate and span of the map.

// Region may be modified to fit the aspect ratio of the view using

regionThatFits:.

@property (nonatomic) MKCoordinateRegionregion;

- (void) setRegion: (MKCoordinateRegion)region animated: (BOOL)animated;


// centerCoordinate allows the coordinate of the region to be changed

without changing the zoom level.

@property (nonatomic) CLLocationCoordinate2DcenterCoordinate;

- (void) setCenterCoordinate: (CLLocationCoordinate2D)coordinate animated: (BOOL)animated;


// Returns a region of the aspect ratio of the map view that contains the

given region, with the same center point.

- (MKCoordinateRegion) regionThatFits: (MKCoordinateRegion)region;


// Access the visible region of the map in projected coordinates.

@property (nonatomic) MKMapRect visibleMapRect;

- (void) setVisibleMapRect:(MKMapRect)mapRect animated:(BOOL)animate;


// Returns an MKMapRect modified to fit the aspect ratio of the map.

- (MKMapRect) mapRectThatFits:(MKMapRect)mapRect;


// Edge padding is the minumum padding on each side around the specified

MKMapRect.

#if TARGET_OS_IPHONE

- (void)setVisibleMapRect:(MKMapRect)mapRect edgePadding:(UIEdgeInsets)insets animated:(BOOL)animate;

- (MKMapRect)mapRectThatFits:(MKMapRect)mapRect edgePadding:(UIEdgeInsets)insets;

#else

- (void)setVisibleMapRect:(MKMapRect)mapRect edgePadding: (NSEdgeInsets)insets animated:(BOOL)animate;

- (MKMapRect)mapRectThatFits:(MKMapRect)mapRect edgePadding:(NSEdgeInsets)insets;

#endif


@property (nonatomic, copy) MKMapCamera *camera NS_AVAILABLE(10_9, 7_0);

- (void)setCamera:(MKMapCamera *)camera animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);


#if TARGET_OS_IPHONE

- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView*)view;

- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView: (UIView*)view;

- (CGRect)convertRegion:(MKCoordinateRegion)region toRectToView:(UIView*)view;

- (MKCoordinateRegion)convertRect:(CGRect)rect toRegionFromView:(UIView*)view;

#else

- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(NSView *)view;

- (CLLocationCoordinate2D)convertPoint: (CGPoint)point toCoordinateFromView:(NSView *)view;

- (CGRect)convertRegion: (MKCoordinateRegion)region toRectToView: (NSView*)view;

- (MKCoordinateRegion)convertRect: (CGRect)rect toRegionFromView: (NSView*)view;

#endif


// Control the types of user interaction available

// Zoom and scroll are enabled by default.

@property (nonatomic, getter=isZoomEnabled) BOOL zoomEnabled;

@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled;

// Rotate and pitch are enabled by default on Mac OS X and on iOS 7.0 and

later.

@property (nonatomic, getter=isRotateEnabled)BOOL rotateEnabled NS_AVAILABLE(10_9, 7_0);

@property (nonatomic, getter=isPitchEnabled) BOOL pitchEnabled NS_AVAILABLE(10_9, 7_0);


#if !TARGET_OS_IPHONE

@property (nonatomic) BOOL showsCompass    NS_AVAILABLE(10_9, NA);

@property (nonatomic) BOOL showsZoomControls     NS_AVAILABLE(10_9, NA);

@property (nonatomic) BOOL showsScale NS_AVAILABLE(10_10, NA);

#endif


// Affects MKMapTypeStandard and MKMapTypeHybrid

@property (nonatomic) BOOL showsPointsOfInterest NS_AVAILABLE(10_9, 7_0); 

@property (nonatomic) BOOL showsBuildings NS_AVAILABLE(10_9, 7_0); // Affects MKMapTypeStandard


// Set to YES to add the user location annotation to the map and start updating its location

@property (nonatomic) BOOL showsUserLocation;


// The annotation representing the user's location

@property (nonatomic, readonly) MKUserLocation *userLocation;


#if TARGET_OS_IPHONE

@property (nonatomic) MKUserTrackingMode userTrackingMode NS_AVAILABLE(NA, 5_0);

- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);

#endif


// Returns YES if the user's location is displayed within the currently visible map region.

@property (nonatomic, readonly, getter=isUserLocationVisible) BOOL userLocationVisible;


// Annotations are models used to annotate coordinates on the map.

// Implement mapView:viewForAnnotation: on MKMapViewDelegate to return the annotation view for each annotation.

- (void) addAnnotation: (id) annotation;

- (void) addAnnotations: (NSArray*) annotations;


- (void) removeAnnotation: (id) annotation;

- (void) removeAnnotations: (NSArray*) annotations;


@property (nonatomic, readonly) NSArray *annotations;

- (NSSet*)annotationsInMapRect:(MKMapRect)mapRect NS_AVAILABLE(10_9, 4_2);


// Currently displayed view for an annotation; returns nil if the view for the annotation isn't being displayed.

- (MKAnnotationView *)viewForAnnotation:(id )annotation;


// Used by the delegate to acquire an already allocated annotation view, in line of allocating a new one.

- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString*)identifier;


// Select or deselect a given annotation. Asks the delegate for the corresponding annotation view if necessary.

- (void)selectAnnotation:(id )annotation animated:(BOOL)animated;

- (void)deselectAnnotation:(id )annotation animated:(BOOL)animated;

@property (nonatomic, copy) NSArray*selectedAnnotations;


// annotationVisibleRect is the visible rect where the annotations views are currently displayed.

// The delegate can use annotationVisibleRect when animating the adding of the annotations views in mapView:didAddAnnotationViews:

@property (nonatomic, readonly) CGRectannotationVisibleRect;


// Position the map such that the provided array of annotations are all visible to the fullest extent possible.

- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);


@end

2.1.2 MKMapViewDelegate委托接口申明

@protocol MKMapViewDelegate

@optional

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;

- (void)mapViewWillStartLoadingMap:(MKMapView*)mapView;

- (void)mapViewDidFinishLoadingMap:(MKMapView*)mapView;

- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError*)error;

- (void)mapViewWillStartRenderingMap:(MKMapView *)mapView NS_AVAILABLE(10_9, 7_0);

- (void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered NS_AVAILABLE(10_9, 7_0);


// mapView:viewForAnnotation: provides the view for each annotation.

// This method may be called for all or some of the added annotations.

// For MapKit provided annotations (eg. MKUserLocation) return nil to use the MapKit provided annotation view.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation;


// mapView:didAddAnnotationViews: is called after the annotation views have been added and positioned in the map.

// The delegate can implement this method to animate the adding of the annotations views.

// Use the current positions of the annotation views as the destinations of the animation.

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray*)views;


#if TARGET_OS_IPHONE

// mapView:annotationView:calloutAccessoryControlTapped: is called when the user taps on left & right callout accessory UIControls.

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl*)control;

#endif


- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(10_9, 4_0);

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(10_9, 4_0);

- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView NS_AVAILABLE(10_9, 4_0);

- (void)mapViewDidStopLocatingUser:(MKMapView *)mapView NS_AVAILABLE(10_9, 4_0);

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation NS_AVAILABLE(10_9, 4_0);

- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error NS_AVAILABLE(10_9, 4_0);

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState NS_AVAILABLE(10_9, 4_0);


#if TARGET_OS_IPHONE

- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);

#endif


- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id )overlay NS_AVAILABLE(10_9, 7_0);

- (void)mapView:(MKMapView *)mapView didAddOverlayRenderers:(NSArray *)renderers NS_AVAILABLE(10_9, 7_0);


#if TARGET_OS_IPHONE

// Prefer -mapView:rendererForOverlay:

- (MKOverlayView*)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay NS_DEPRECATED_IOS(4_0, 7_0);

// Called after the provided overlay views have been added and positioned in the map.

// Prefer -mapView:didAddOverlayRenderers:

- (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews NS_DEPRECATED_IOS(4_0, 7_0);

#endif

@end


2.1.3 使用范例

2.1.3.1 视图初始化

self.mapView.mapType = MKMapTypeStandard;

self.mapView.delegate = self;

self.mapView.showsUserLocation = YES;

[self.mapView setUserTrackingMode: MKUserTrackingModeFollow animated: YES];


2.1.3.2 MKMapViewDelegate委托处理

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma mark - MKMapViewDelegate 委托处理

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation

{

    LOGDEBUG([NSString stringWithFormat:@" viewForAnnotation %@",@"11"]);

    MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOTATION"];

    if(annotationView == nil) {

        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: @"PIN_ANNOTATION"];

    }

    annotationView.canShowCallout = YES;

    annotationView.pinColor = MKPinAnnotationColorRed;

    annotationView.animatesDrop = YES;

    annotationView.highlighted = YES;

    annotationView.draggable = YES;

    return annotationView;

}


- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation*)userLocation

{

    self.mapView.centerCoordinate = userLocation.location.coordinate;

}


- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError*)error

{

    LOGDEBUG([NSString stringWithFormat: @"Map View Loading Fail: %@", error.userInfo]);

}


- (void)mapViewDidFinishLoadingMap:(MKMapView*)mapView

{

    LOGERR(@"Map View Finish Loading");

}


2.2 MKCoordinateRegion对象

2.2.1 范例代码

#pragma mark CLLocationManagerDelegate Methods 

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation

{         

    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);      

    //[mapView setRegion: viewRegion animated:YES];

    MKCoordinateRegion adjustedRegion = [mapView regionThatFits: viewRegion];    

    [mapView setRegion: adjustedRegion animated:YES];

    manager.delegate= nil;

    [manager stopUpdatingLocation];

    MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate: newLocation.coordinate]; 

     geocoder.delegate= self;     

    [geocoder start];

}

        MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000); 该函数能够创建一个MKCoordinateRegion结构体,第一个参数是一个CLLocationCoordinate2D结构指定了目标区域的中心点,第二个是目标区域南北的跨度单位是米,第三个是目标区域东西的跨度单位是米。后两个参数的调整会影响地图缩放。

3 基于百度地图开发

开放平台:百度地图foriOS使用相关

http://blog.csdn.net/ysy441088327/article/details/8174276

3.1 类库引入

3.1.1 引入头文件

        首先将百度MapAPI提供的头文件和静态库(.a)文件拷贝到您的工程目录下,在Xcode中添加新的文件Group,引入百度MapAPI提供的头文件(请使用Xcode 4.X以上平台)。

        在您需要使用百度MapAPI的文件中添加以下代码

#import "BMapKit.h"   

3.1.2 引入静态库文件

        百度地图SDK提供了模拟器和真机两中环境所使用的静态库文件,分别存放在libs/Release-iphonesimulator和libs/Release-iphoneos文件夹下。有三种方式可以引入静态库文件:

    第一种方式:直接将对应平台的.a文件拖拽至Xcode工程左侧的Groups&Files中,缺点是每次在真机和模拟器编译时都需要重新添加.a文件;

    第二种方式:使用lipo命令将设备和模拟器的.a合并成一个通用的.a文件,将合并后的通用.a文件拖拽至工程中即可,具体命令如下:

lipo -create Release-iphoneos/libbaidumapapi.aRelease-iphonesimulator/libbaidumapapi.a -output libbaidumapapi.a

    第三种方式:

    1.将API的libs文件夹拷贝到您的Application工程跟目录下

    2.在Xcode的Project -> Edit Active Target -> Build -> Linking -> Other Linker Flags中添加-ObjC

    3.设置静态库的链接路径,在Xcode的Project -> Edit Active Target -> Build -> Search Path -> Library Search Paths中添加您的静态库目录,比如"$(SRCROOT)/../libs/Release$(EFFECTIVE_PLATFORM_NAME)",$(SRCROOT)宏代表您的工程文件目录,$(EFFECTIVE_PLATFORM_NAME)宏代表当前配置是OS还是simulator

    :静态库中采用ObjectC++实现,因此需要您保证您工程中至少有一个.mm后缀的源文件(您可以将任意一个.m后缀的文件改名为.mm),或者在工程属性中指定编译方式,即将XcodeProject -> Edit Active Target -> Build -> GCC4.2 - Language -> Compile Sources As设置为"Objective-C++"

3.1.3 引入系统framework

        百度地图SDK中提供了定位功能和动画效果,v2.0.0版本开始使用OpenGL渲染,因此您需要在您的Xcode工程中引入CoreLocation.framework和QuartzCore.framework、OpenGLES.framework、SystemConfiguration.framework、CoreGraphics.framework、Security.framework。 添加方式:右键点击Xcode工程左侧的Frameworks文件夹,add->Existing Frameworks,在弹出窗口中选中这几个framework,点击add即可。

3.1.4 引入mapapi.bundle资源文件

        mapapi.bundle中存储了定位、默认大头针标注View及路线关键点的资源图片,还存储了矢量地图绘制必需的资源文件。如果您不需要使用内置的图片显示功能,则可以删除bundle文件中的image文件夹。您也可以根据具体需求任意替换或删除该bundle中image文件夹的图片文件。 添加方式:将mapapi.bundle拷贝到您的工程目录,直接将该bundle文件托拽至Xcode工程左侧的Groups&Files中即可。若您需要替换定位、指南针的图标,请保留原文件名称,否则不显示替换的新图片,默认大头针标注与路线关键点的新图片名称可自定义名称。 

SDK

资源文件里存放的有:

【IOS开发基础系列】地图开发专题_第2张图片


3.1.5 其他建议

        进行一系列的引入后,还需要注意以下两个细节,否则编译和运行时都会出错:

    1:让XCode 处于 Objective - C++ 混编模式进行编译: 最简单方法就是:随便更改工程文件中的某一个,将.m更改为.mm .

    2:由于静态库里面包含类别条目(第四点),所以需要让工程支持类别的编译: Project->Build Settings->Other Linker Flags   添加值:  -all_load

    3:关于 setPaopaoView 警告 临时解决方案如下: 在 Other Linker Flags新增一个 -w 

    4:建议合并静态库


3.2 api使用

3.2.1 反地理编码获取省市地理位置数据

http://my.oschina.net/u/1025290/blog/305749

    要做百度的逆地理编码功能,肯定是要先启动百度服务了,这些就不再扯了。

//初始化地理编码类 注意:必须初始化地理编码类

 BMKGeoCodeSearch *_geoCodeSearch = [[BMKGeoCodeSearch alloc] init];

 _geoCodeSearch.delegate = self;

 //初始化逆地理编码类

BMKReverseGeoCodeOption *reverseGeoCodeOption = [[BMKReverseGeoCodeOption alloc] init];

//需要逆地理编码的坐标位置

 reverseGeoCodeOption.reverseGeoPoint = cllocation.coordinate;

 [_geoCodeSearch reverseGeoCode: reverseGeoCodeOption];

        这个是初始化的逆地理编码的类 ,其中reverseGeoPoint是需要做逆地理编码的poi坐标点,然后执行reverseGeoCode这个方法,根据地理坐标去获取地理位置信息。

        逆地理编码的返回结果会再这个方法中返回,也就是个监听方法。

/**

 *返回反地理编码搜索结果

 *@param searcher 搜索对象

 *@param result 搜索结果

 *@param error 错误号,@see BMKSearchErrorCode

 */

- (void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error

{

    //BMKReverseGeoCodeResult是编码的结果,包括地理位置,道路名称,uid,城市名等信息

}

        返回结果就是BMKReverseGeoCodeResult中得属性值,具体属性值 大家点击类里面去看,这个我就不多说了,好了,最简单的逆地理编码功能。

        注意:逆地理编码监听方法不调用请查看百度key是否正确有效,是否授权成功。

        当多类中使用地理编码功能时,建议将这些功能创建公用管理类,只需单利初始化,在监听方法中接收地理位置信息就可以了!


3.2.2 自定义标注图标

        在地图上定制标注替代大头钉,可以将文字图片所有能加到view中的,都可以以大头钉的形式显示出来,需要将view转换为image主要代码,最重要的是知道这个原理,然后实现起来就很简单:

- (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id )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;

}


3.2.3 显示比例尺

[self.mapView setShowMapScaleBar: YES];


3.2.4 设置缩放比例

        BMKMapView.zoomLevel,不过要注意,设置完中心点之后再设置才有效!!!示例代码:

//设置地图中心的地理位置

[_mapView setCenterCoordinate: coordinate];

[_mapView setZoomLevel: 9.0];


3.2.5 微调与设置中心点

//设置中心点

-(BMKCoordinateRegion)setCenterRegionWithCoordinate:(CLLocationCoordinate2D) coordinate

{

    NSLog(@"MyLat:%f, Lon:%f",coordinate.latitude,coordinate.longitude);


    //缩放级别设置

    BMKCoordinateRegion viewRegion = BMKCoordinateRegionMakeWithDistance(coordinate, AQ_Map_SearchSpan, AQ_Map_SearchSpan * self.mapView.frame.size.height / self.mapView.frame.size.width);

    BMKCoordinateRegion adjustRegion = [_mapView regionThatFits:viewRegion];


    //   adjustRegion.center.latitude += adjustRegion.span.latitudeDelta -viewRegion.span.latitudeDelta;

    //   adjustRegion.center.longitude += adjustRegion.span.longitudeDelta -viewRegion.span.longitudeDelta;


    //设置地图中心的地理位置

    //   if (!_isSetMapSpan) {

    [_mapView setRegion: viewRegion animated: YES];

    //       _isSetMapSpan = true;

    //   }

    //   else [self.mapView setCenterCoordinate:adjustRegion.centeranimated:YES];


    return adjustRegion;

}


3.2.6 添加标注点

BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];

annotation.coordinate = CLLocationCoordinate2DMake(cObj.latitude, cObj.longitude);

annotation.title = cObj.cityName;

//添加标注点

[_mapView addAnnotation: annotation];


3.2.7 更新标注点

-(void) updateBMKPointAnnotationsWithCityInfoArray

{

    NSArray * array = [self getCityInfoArrayInDefaultSpan];


    if (array && [array count] > 0) {

        BMKPointAnnotation *pointAn;

        NSMutableArray * _preDeleteMArray = [[NSMutableArray alloc] init];

        BOOL needDelete = TRUE;


        //查询需要移除的标注点

        NSArray * tmpArray = [_pointAnnotationMArray copy];

        for (BMKPointAnnotation * ann intmpArray) {

            needDelete =TRUE;

            for (AQCityInfoObject * ciObj inarray) {

                if ([ciObj.cityName isEqualToString: ann.title]) {

                    needDelete =false;

                    continue;

                }

            }


            if(needDelete) {

                [_preDeleteMArray addObject: ann];

                [_pointAnnotationMArray removeObject: ann];

            }

        }


        //移除待删除的标注视图

        [_mapView removeAnnotations: _preDeleteMArray];

        pointAn =nil;

        BOOL needAdd = TRUE;


        //比较差异标注,更新或新增标注视图

        for (AQCityInfoObject * obj inarray) {

            needAdd =TRUE;

            pointAn =nil;


            for (BMKPointAnnotation * ann in _pointAnnotationMArray) {

                if ([obj.cityName isEqualToString:ann.title]) {

                    needAdd =FALSE;

                    pointAn = ann;

                    continue;

                }

            }


            if(needAdd) {

                pointAn = [self addAnnotationViewWithCityInfoObject:obj];

                [_pointAnnotationMArray addObject:pointAn];

            }

            else

            {

                BMKAnnotationView * annView = [_mapView viewForAnnotation:pointAn];


                if(annView) {

                    [self updateAnnotationView:annView WithCityInfoObject:obj];

                }

            }

        }

    }

}


3.3 注意事项

3.3.1 不要再Storyboard或者xib中直接使用BMKMapView

        因为BMKMapView的初始化需要先进行开发账号认证,因此不能在设计页面中直接添加BMKMapView。正确地初始化顺序是:

_mapManager = [[BMKMapManager alloc] init];

// 如果要关注网络及授权验证事件,请设定     generalDelegate参数

BOOL ret = [_mapManager start: @"在此处输入您的授权Key" generalDelegate: nil];

if(!ret) {

    LOGERR(@"manager start failed!");

}


_bMapView  = [[BMKMapView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];

// [[BMKMapView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];

self.mapView = _bMapView;

if (![self.view.subviews containsObject: self.mapView]) {

    [self.view addSubview: self.mapView];

}


_bMapView.delegate = self;

[_bMapView setMapType: BMKMapTypeStandard];


4 参考链接

CLLocationManagerDelegate不调用didUpdateLocations

http://www.cocoachina.com/bbs/read.php?tid=259171


iOS8下的开发变化

http://www.cocoachina.com/bbs/read.php?tid=217107


(Good)IOS之地图和定位应用开发

http://www.cnblogs.com/syxchina/archive/2012/10/14/2723522.html


IOS开发之百度地图API应用

http://www.cocoachina.com/ios/20120507/4224.html


iOS开发那些事-iOS6苹果地图实用开发

http://blog.csdn.net/tonny_guan/article/details/9239947


[IOS地图开发系类]2、位置解码CLGeocoder

http://my.oschina.net/chengliqun/blog/147871


ios6下使用CLGeocoder替换MKReverseGeocoder

http://blog.csdn.net/nogodoss/article/details/8786867


iOS地图位置开发

http://www.cnblogs.com/tangbinblog/archive/2012/07/11/2586472.html


iOS学习之Map,定位,标记位置的使用

http://blog.csdn.net/totogo2010/article/details/7701026


iOS地图位置开发方法

http://wenku.baidu.com/link?url=DO5AEJjIHJJkLzq5jPezpj_duEkmdAJwCGDDIFyupXsyiEZgxV-WO3kpfuRXjq0z-5V9_RO6UGWRiisbK0vsTs8xcmcRt6An77VavsOmBOu


[ios]设置缩放比例和中心,一些地图中的位置

http://www.itstrike.cn/Question/ea8d1965-ad02-49e5-ad02-85f40af12bcc.html


【改】IOS-百度地图API用点生成线路、导航、自定义标注2013年11月更新

http://www.cnblogs.com/wengzilin/p/3444471.html

你可能感兴趣的:(【IOS开发基础系列】地图开发专题)