11.1 iOS定位服務
11.2 iOS地圖
11.3 Web地圖
來自:http://www.itboat.net/thread-55296-1-1.html html
11.1 iOS定位服務
iOS中有三個定位服務組件:
Wifi定位,經過查詢一個Wifi路由器的地理位置的信息。比較省電,iPod touch和iPad也能夠採用。
蜂窩基站定位,經過移動運用商基站定位。也適合有3G版本的iPod touch和iPad。
GPS衛星定位,經過3-4顆GPS定位位置定位,最爲準確,可是耗電量大,不能遮擋。
Core Location
Core Location是iPhone、iPad等開發定位服務應用程序的框架。咱們要在Xcode中添加"CoreLocation.framework"存在的框架。
主要使用的類是:CLLocationManager,經過CLLocationManager實現定位服務。
CoreLocation.framework
定位服務實例
項目WhereAmI:
WhereAmIViewController.h
- #import <UIKit/UIKit.h>
- #import <CoreLocation/CoreLocation.h>
- @interface ViewController : UIViewController<CLLocationManagerDelegate> {
- CLLocationManager* locationManager;
- }
- @property (strong, nonatomic) CLLocationManager* locationManager;
- @property (retain, nonatomic) IBOutlet UILabel *longitudeText;
- @property (retain, nonatomic) IBOutlet UILabel *latituduText;
- @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;
- - (IBAction)findMe:(id)sender;
- - (IBAction)webMap:(id)sender;
- @end
複製代碼
CLLocationManagerDelegate是定位服務的委託,經常使用的位置變化回調方法是:
locationManager:didUpdateToLocation:fromLocation: locationManager:didFailWithError:
CLLocationManager 是定位服務管理類,經過它能夠設置定位服務的參數、獲取經緯度等。
m中加載方法
- - (IBAction)findMe:(id)sender {
- self.locationManager = [[[CLLocationManager alloc] init] autorelease];
- self.locationManager.delegate = self;
- self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
- self.locationManager.distanceFilter = 1000.0f;
- [self.locationManager startUpdatingLocation];
- [activity startAnimating];
- NSLog(@"start gps");
- }
複製代碼
CLLocationManager 是的startUpdatingLocation方法啓動全部定位硬件,對應的方法是stopUpdatingLocation,經過調用該方法關閉定位服務器更新,爲了省電必須在不用的時候調用該方法關閉定位服務。
此外,咱們還能夠在這裏設定定位服務的參數,包括:distanceFilter和desiredAccuracy。
distanceFilter,這個屬性用來控制定位服務更新頻率。單位是"米"。 desiredAccuracy,這個屬性用來控制定位精度,精度
越高耗電量越大。
定位精度
desiredAccuracy精度參數能夠iOS SDK經過常量實現:
kCLLocationAccuracyNearestTenMeters,10米
kCLLocationAccuracyHundredMeters ,100米
kCLLocationAccuracyKilometer ,1000米
kCLLocationAccuracyThreeKilometers,3000米
kCLLocationAccuracyBest ,最好的精度
kCLLocationAccuracyBestForNavigation,導航狀況下最好精度,iOS 4 SDK新增長。通常要有外接電源時候才能使用。
委託方法用於實現位置的更新
- -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
- latituduText.text = [NSString stringWithFormat:@"%3.5f",newLocation.coordinate.latitude];
- longitudeText.text = [NSString stringWithFormat:@"%3.5f",newLocation.coordinate.longitude];
- [activity stopAnimating];
- [locationManager stopUpdatingLocation];
- NSLog(@"location ok");
- }
複製代碼
該委託方法不只能夠得到當前位置(newLocation),還能夠得到上次的位置(oldLocation ),CLLocation 對象coordinate.latitude屬性得到經度,coordinate.longitude屬性得到緯度。
[NSString stringWithFormat:@"%3.5f", newLocation.coordinate.latitude] 中的%3.5f是輸出整數部分是3位,小數部分是5位的浮點數。
11.2 iOS地圖
iOS應用程序中使用Map Kit API開發地圖應用程序。
其核心是MKMapView類使用。
多數狀況下地圖會與定位服務結合使用。
地圖開發通常過程
添加MapKit類庫
MapKit.framework
MapMeViewController.h
- #import <UIKit/UIKit.h>
- #import <MapKit/MapKit.h>
- #import <CoreLocation/CoreLocation.h>
- #import "MapLocation.h"
- @interface ViewController : UIViewController<CLLocationManagerDelegate, MKReverseGeocoderDelegate, MKMapViewDelegate> {
- }
- @property (retain, nonatomic) IBOutlet MKMapView *mapView;
- @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;
- - (IBAction)findMe:(id)sender;
- @end
複製代碼
CLLocationManagerDelegate是定位服務委託。
MKMapViewDelegate是地圖視圖委託,主要方法:
-mapView:viewForAnnotation:
-mapViewDidFailLoadingMap:withError:
MKReverseGeocoderDelegate是給地理座標得到標誌點信息的委託,用於地理信息編碼(即:從座標得到地點得到信息),主要委託方法:
– reverseGeocoder:didFindPlacemark:
– reverseGeocoder:didFailWithError:
m文件中的視圖加載和卸載
- - (void)viewDidLoad {
- [super viewDidLoad];
- mapView.mapType = MKMapTypeStandard;
- //mapView.mapType = MKMapTypeSatellite;
- //mapView.mapType = MKMapTypeHybrid;
- mapView.delegate = self;
- }
複製代碼
mapView.mapType = MKMapTypeStandard;是指定地圖的類型,iOS提供了三種風格的地圖:
MKMapTypeStandard標準地圖模式
MKMapTypeSatellite衛星地圖模式
MKMapTypeHybrid具備街道等信息的衛星地圖模式
mapView.delegate = self;是將委託對象指定爲自身。
按鈕事件
- - (IBAction)findMe:(id)sender {
- CLLocationManager *lm = [[CLLocationManager alloc] init];
- lm.delegate = self;
- lm.desiredAccuracy = kCLLocationAccuracyBest;
- [lm startUpdatingLocation];
- activity.hidden = NO;
- [activity startAnimating];
- }
複製代碼
點擊按鈕時候經過定位服務獲取當前位置信息。
經過lm.delegate = self;是將委託對象指定爲自身。
所以,點擊事件發生時候將會回調CLLocationManagerDelegate委託的
-locationManager:didUpdateToLocation:fromLocation:方法。
回調位置更新方法
- #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結構指定了目標區域的中心點,第二個是目標區域南北的跨度單位是米,第三個是目標區域東西的跨度單位是米。後兩個參數的調整會影響地圖縮放。
[[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; 建立地理編碼對象geocoder,經過該對象能夠把座標轉換成爲地理信息的描述。
geocoder.delegate = self;指定編碼的處理是自身對象。
[geocoder start];開始編碼處理。
MKReverseGeocoderDelegate
是地理編碼委託對象,該委託的方法:
成功時候調用-reverseGeocoder:didFindPlacemark:
失敗時候調用-reverseGeocoder:didFailWithError:
成功編碼回調方法
- - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
- MapLocation *annotation = [[MapLocation alloc] init];
- annotation.streetAddress = placemark.thoroughfare;
- annotation.city = placemark.locality;
- annotation.state = placemark.administrativeArea;
- annotation.zip = placemark.postalCode;
- annotation.coordinate = geocoder.coordinate;
- [mapView addAnnotation:annotation];
- [annotation release];
- geocoder.delegate = nil;
- [geocoder autorelease];
- [activity stopAnimating];
- activity.hidden = YES;
- }
複製代碼
成功編碼後須要在該方法中建立標註對象(MapLocation)。MapLocation 是咱們自定義的實現MKAnnotation協議標註對象。 該方法的placemark是MKPlacemark得到不少地理信息,詳細見下表。
[mapView addAnnotation:annotation]; 爲地圖添加標註,該方法將會觸發mapView:viewForAnnotation:方法回調。
MKPlacemark類屬性
addressDictionary 地址信息的dictionary
thoroughfare 指定街道級別信息
subThoroughfare 指定街道級別的附加信息
locality 指定城市信息
subLocality 指定城市信息附加信息
administrativeArea 行政區域
subAdministrativeArea 行政區域附加信息
country 國家信息
countryCode 國家代號
postalCode 郵政編碼
失敗編碼回調方法
- - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
- UIAlertView *alert = [[UIAlertView alloc]
- initWithTitle:@"地理解碼錯誤息"
- message:@"地理代碼不能識別"
- delegate:nil
- cancelButtonTitle:@"Ok"
- otherButtonTitles:nil];
- [alert show];
- [alert release];
- geocoder.delegate = nil;
- [geocoder autorelease];
- [activity stopAnimating];
- }
複製代碼
MKMapViewDelegate
是地圖視圖委託對象,本例子咱們使用的方法:
- mapView:viewForAnnotation:爲地圖設置標註時候回調方法。
-mapViewDidFailLoadingMap:withError:地圖加載錯誤時候回調方法。
地圖標註回調方法
- #pragma mark Map View Delegate Methods
- - (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {
- MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOTATION"];
- if(annotationView == nil) {
- annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
- reuseIdentifier:@"PIN_ANNOTATION"] autorelease];
- }
- annotationView.canShowCallout = YES;
- annotationView.pinColor = MKPinAnnotationColorRed;
- annotationView.animatesDrop = YES;
- annotationView.highlighted = YES;
- annotationView.draggable = YES;
- return annotationView;
- }
複製代碼
與表格視圖單元格處理相似,地圖標註對象因爲會不少,所以須要重複利用,經過
dequeueReusableAnnotationViewWithIdentifier方法能夠查找可重複利用的標註對象,以達到節省內存的目的。
annotationView.canShowCallout = YES;指定標註上的插圖,點擊圖釘有氣泡顯示。
annotationView.pinColor 設置圖釘的顏色。
annotationView.animatesDrop動畫效果。
地圖加載失敗回調方法
- - (void)mapViewDidFailLoadingMap:(MKMapView *)theMapView withError:(NSError *)error {
- UIAlertView *alert = [[UIAlertView alloc]
- initWithTitle:@"地圖加載錯誤"
- message:[error localizedDescription]
- delegate:nil
- cancelButtonTitle:@"Ok"
- otherButtonTitles:nil];
- [alert show];
- [alert release];
- }
複製代碼
自定義地圖標註對象
- #import <Foundation/Foundation.h>
- #import <MapKit/MapKit.h>
- @interface MapLocation : NSObject <MKAnnotation, NSCoding> {
- NSString *streetAddress;
- NSString *city;
- NSString *state;
- NSString *zip;
- CLLocationCoordinate2D coordinate;
- }
- @property (nonatomic, copy) NSString *streetAddress;
- @property (nonatomic, copy) NSString *city;
- @property (nonatomic, copy) NSString *state;
- @property (nonatomic, copy) NSString *zip;
- @property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
- @end
複製代碼
做爲地圖標註對象實現MKAnnotation協議是必須的,只有實現該協議才能使該類成爲標註類。實現NSCoding協議是可選的,實現該協議可使標註對象可以複製。 裏面的屬性有哪些要看你本身的須要。
MapLocation.m
- - (NSString *)title {
- return @"您的位置!";
- }
- - (NSString *)subtitle {
- NSMutableString *ret = [NSMutableString string];
- if (streetAddress)
- [ret appendString:streetAddress];
- if (streetAddress && (city || state || zip))
- [ret appendString:@" • "];
- if (city)
- [ret appendString:city];
- if (city && state)
- [ret appendString:@", "];
- if (state)
- [ret appendString:state];
- if (zip)
- [ret appendFormat:@", %@", zip];
- return ret;
- }
複製代碼
title 和subtitle 是MKAnnotation協議要求實現的方法。
MapLocation.m
- #pragma mark -
- - (void)dealloc {
- [streetAddress release];
- [city release];
- [state release];
- [zip release];
- [super dealloc];
- }
- #pragma mark -
- #pragma mark NSCoding Methods
- - (void) encodeWithCoder: (NSCoder *)encoder {
- [encoder encodeObject: [self streetAddress] forKey: @"streetAddress"];
- [encoder encodeObject: [self city] forKey: @"city"];
- [encoder encodeObject: [self state] forKey: @"state"];
- [encoder encodeObject: [self zip] forKey: @"zip"];
- }
- - (id) initWithCoder: (NSCoder *)decoder {
- if (self = [super init]) {
- [self setStreetAddress: [decoder decodeObjectForKey: @"streetAddress"]];
- [self setCity: [decoder decodeObjectForKey: @"city"]];
- [self setState: [decoder decodeObjectForKey: @"state"]];
- [self setZip: [decoder decodeObjectForKey: @"zip"]];
- }
- return self;
- }
複製代碼
encodeWithCoder:和initWithCoder:是NSCoding協議要求實現方法。
11.3 Web地圖
在iOS中咱們還可使用Web地圖。
- - (IBAction)webMap:(id)sender {
- CLLocation *lastLocation = [locationManager location];
- if(!lastLocation)
- {
- UIAlertView *alert;
- alert = [[UIAlertView alloc]
- initWithTitle:@"系統錯誤"
- message:@"尚未接收到數據!"
- delegate:nil cancelButtonTitle:nil
- otherButtonTitles:@"OK", nil];
- [alert show];
- [alert release];
- return;
- }
- NSString *urlString = [NSString stringWithFormat:
- @"http://maps.google.com/maps?q=Here+I+Am!@%f,%f",
- lastLocation.coordinate.latitude,
- lastLocation.coordinate.longitude];
- NSURL *url = [NSURL URLWithString:urlString];
- [[UIApplication sharedApplication] openURL:url];
- }
複製代碼
http://maps.google.com/maps?q=Here+I+Am!@%f,%f是請求Web地圖的網站,q後面上參數。
[[UIApplication sharedApplication] openURL:url];打開iOS內置的瀏覽器,即在內置瀏覽器中打開地圖。
注: 1 本教程是基於關東昇老師的教程 2 基於黑蘋果10.6.8和xcode4.2 3 本人初學,有什麼不對的望指教 4 教程會隨着本人學習,持續更新 5 教程是本人從word筆記中拷貝出來了,因此格式請見諒