iOS中有三個(gè)定位服務(wù)組件:
?? Wifi定位,通過查詢一個(gè)Wifi路由器的地理位置的信息。比較省電,iPod touch和iPad也可以采用。
?? 蜂窩基站定位,通過移動運(yùn)用商基站定位。也適合有3G版本的iPod touch和iPad。
?? GPS衛(wèi)星定位,通過3-4顆GPS定位位置定位,最為準(zhǔn)確,但是耗電量大,不能遮擋。
Core Location
Core Location是iPhone、iPad等開發(fā)定位服務(wù)應(yīng)用程序的框架。我們要在Xcode中添加“CoreLocation.framework”存在的框架。
主要使用的類是:CLLocationManager,通過CLLocationManager實(shí)現(xiàn)定位服務(wù)。
CoreLocation.framework
定位服務(wù)實(shí)例
項(xiàng)目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是定位服務(wù)的委托,常用的位置變化回調(diào)方法是:
locationManager:didUpdateToLocation:fromLocation: locationManager:didFailWithError:
CLLocationManager 是定位服務(wù)管理類,通過它可以設(shè)置定位服務(wù)的參數(shù)、獲取經(jīng)緯度等。
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方法啟動所有定位硬件,對應(yīng)的方法是stopUpdatingLocation,通過調(diào)用該方法關(guān)閉定位服務(wù)器更新,為了省電必須在不用的時(shí)候調(diào)用該方法關(guān)閉定位服務(wù)。
此外,我們還可以在這里設(shè)定定位服務(wù)的參數(shù),包括:distanceFilter和desiredAccuracy。
distanceFilter,這個(gè)屬性用來控制定位服務(wù)更新頻率。單位是“米”。 desiredAccuracy,這個(gè)屬性用來控制定位精度,精度
越高耗電量越大。
定位精度?
desiredAccuracy精度參數(shù)可以iOS SDK通過常量實(shí)現(xiàn):
? kCLLocationAccuracyNearestTenMeters,10米?
? kCLLocationAccuracyHundredMeters ,100米
? kCLLocationAccuracyKilometer ,1000米
? kCLLocationAccuracyThreeKilometers,3000米
? kCLLocationAccuracyBest ,最好的精度
? kCLLocationAccuracyBestForNavigation,導(dǎo)航情況下最好精度,iOS 4 SDK新增加。一般要有外接電源時(shí)候才能使用。
委托方法用于實(shí)現(xiàn)位置的更新
-(
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");
}
?
該委托方法不僅可以獲得當(dāng)前位置(newLocation),還可以獲得上次的位置(oldLocation ),CLLocation 對象coordinate.latitude屬性獲得經(jīng)度,coordinate.longitude屬性獲得緯度。
[NSString stringWithFormat:@"%3.5f”, newLocation.coordinate.latitude]? 中的%3.5f是輸出整數(shù)部分是3位,小數(shù)部分是5位的浮點(diǎn)數(shù)。
11.2 iOS地圖
iOS應(yīng)用程序中使用Map Kit API開發(fā)地圖應(yīng)用程序。
其核心是MKMapView類使用。
多數(shù)情況下地圖會與定位服務(wù)結(jié)合使用。
地圖開發(fā)一般過程
添加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是定位服務(wù)委托。
MKMapViewDelegate是地圖視圖委托,主要方法:
?? -mapView:viewForAnnotation:
?? -mapViewDidFailLoadingMap:withError:
MKReverseGeocoderDelegate是給地理坐標(biāo)獲得標(biāo)志點(diǎn)信息的委托,用于地理信息編碼(即:從坐標(biāo)獲得地點(diǎn)獲得信息),主要委托方法:
?? – 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提供了三種風(fēng)格的地圖:
? MKMapTypeStandard標(biāo)準(zhǔn)地圖模式
? MKMapTypeSatellite衛(wèi)星地圖模式
? MKMapTypeHybrid具有街道等信息的衛(wèi)星地圖模式
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];
}
?
點(diǎn)擊按鈕時(shí)候通過定位服務(wù)獲取當(dāng)前位置信息。
通過lm.delegate = self;是將委托對象指定為自身。
因此,點(diǎn)擊事件發(fā)生時(shí)候?qū)卣{(diào)CLLocationManagerDelegate委托的
-locationManager:didUpdateToLocation:fromLocation:方法。
回調(diào)位置更新方法
#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); 該函數(shù)能夠創(chuàng)建一個(gè)MKCoordinateRegion結(jié)構(gòu)體,第一個(gè)參數(shù)是一個(gè)CLLocationCoordinate2D結(jié)構(gòu)指定了目標(biāo)區(qū)域的中心點(diǎn),第二個(gè)是目標(biāo)區(qū)域南北的跨度單位是米,第三個(gè)是目標(biāo)區(qū)域東西的跨度單位是米。后兩個(gè)參數(shù)的調(diào)整會影響地圖縮放。
[[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; 創(chuàng)建地理編碼對象geocoder,通過該對象可以把坐標(biāo)轉(zhuǎn)換成為地理信息的描述。
geocoder.delegate = self;指定編碼的處理是自身對象。
? [geocoder start];開始編碼處理。
? MKReverseGeocoderDelegate
是地理編碼委托對象,該委托的方法:
? 成功時(shí)候調(diào)用-reverseGeocoder:didFindPlacemark:
? 失敗時(shí)候調(diào)用-reverseGeocoder:didFailWithError:
成功編碼回調(diào)方法
- (
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;
}
?
成功編碼后需要在該方法中創(chuàng)建標(biāo)注對象(MapLocation)。MapLocation 是我們自定義的實(shí)現(xiàn)MKAnnotation協(xié)議標(biāo)注對象。 該方法的placemark是MKPlacemark獲得很多地理信息,詳細(xì)見下表。
[mapView addAnnotation:annotation]; 為地圖添加標(biāo)注,該方法將會觸發(fā)mapView:viewForAnnotation:方法回調(diào)。
MKPlacemark類屬性
addressDictionary? 地址信息的dictionary
thoroughfare? 指定街道級別信息
subThoroughfare? 指定街道級別的附加信息
locality? 指定城市信息
subLocality? 指定城市信息附加信息
administrativeArea? 行政區(qū)域
subAdministrativeArea? 行政區(qū)域附加信息
country? 國家信息
countryCode? 國家代號
postalCode? 郵政編碼
失敗編碼回調(diào)方法
- (
void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *
)error {UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"地理解碼錯誤息"message:@"地理代碼不能識別" delegate:nilcancelButtonTitle:@"Ok"otherButtonTitles:nil];[alert show];[alert release];geocoder.delegate =
nil;[geocoder autorelease];[activity stopAnimating];
}
?
MKMapViewDelegate
是地圖視圖委托對象,本例子我們使用的方法:
? - mapView:viewForAnnotation:為地圖設(shè)置標(biāo)注時(shí)候回調(diào)方法。
? -mapViewDidFailLoadingMap:withError:地圖加載錯誤時(shí)候回調(diào)方法。
地圖標(biāo)注回調(diào)方法
#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:annotationreuseIdentifier:@"PIN_ANNOTATION"] autorelease];}annotationView.canShowCallout =
YES;annotationView.pinColor =
MKPinAnnotationColorRed;annotationView.animatesDrop =
YES;annotationView.highlighted =
YES;annotationView.draggable =
YES;return annotationView;
}
?
與表格視圖單元格處理類似,地圖標(biāo)注對象由于會很多,因此需要重復(fù)利用,通過
dequeueReusableAnnotationViewWithIdentifier方法可以查找可重復(fù)利用的標(biāo)注對象,以達(dá)到節(jié)省內(nèi)存的目的。
annotationView.canShowCallout = YES;指定標(biāo)注上的插圖,點(diǎn)擊圖釘有氣泡顯示。
annotationView.pinColor 設(shè)置圖釘?shù)念伾?/p>
annotationView.animatesDrop動畫效果。
地圖加載失敗回調(diào)方法
- (
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];
}
?
自定義地圖標(biāo)注對象?
#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
?
作為地圖標(biāo)注對象實(shí)現(xiàn)MKAnnotation協(xié)議是必須的,只有實(shí)現(xiàn)該協(xié)議才能使該類成為標(biāo)注類。實(shí)現(xiàn)NSCoding協(xié)議是可選的,實(shí)現(xiàn)該協(xié)議可以使標(biāo)注對象能夠復(fù)制。 里面的屬性有哪些要看你自己的需要。
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協(xié)議要求實(shí)現(xiàn)的方法。
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協(xié)議要求實(shí)現(xiàn)方法。
11.3 Web地圖
在iOS中我們還可以使用Web地圖。
?
?
- (IBAction)webMap:(
id)sender {CLLocation *lastLocation =
[locationManager location];if(!
lastLocation) {UIAlertView *
alert;alert =
[[UIAlertView alloc] initWithTitle:@"系統(tǒng)錯誤" message:@"還沒有接收到數(shù)據(jù)!" 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];
}
與iOS6的蘋果didUpdateLocations代替didUpdateToLocation的釋放。任何人都可以解釋如何didUpdateLocations?
本文地址 :CodeGo.net/507856/?
-------------------------------------------------------------------------------------------------------------------------
1. 我以下的委托,以獲得最后一個(gè)位置?
- (void)locationManager:(CLLocationManager *)manager?
?didUpdateToLocation:(CLLocation *)newLocation?
? ?fromLocation:(CLLocation *)oldLocation
上述委托棄用的iOS 6。現(xiàn)在,下面應(yīng)該
- (void)locationManager:(CLLocationManager *)manager?
? didUpdateLocations:(NSArray *)locations
為了獲得最后的位置,只需獲取數(shù)組的最后一個(gè)對象:
[locations lastObject]
換句話說,[locations lastObject](新代表)等于newLocation(老代表)。?
2. 它給你的對象數(shù)組來訪問最后一個(gè)位置你
[locations lastObject]
由此
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
3. 這里沒有其他的答案中解釋了為什么有一個(gè)位置陣列,以及如何將新didUpdateLocations:提供的數(shù)組。 貶低的目的locationManager:didUpdateToLocation:fromLocation:和發(fā)送位置一個(gè)NSArray,而不是在后臺運(yùn)行時(shí)降低功耗。 與iPhone 5開始時(shí),GPS芯片具有存儲位置的一段,然后傳送在一次陣列中的他們所有的能力。這被稱為延遲的位置更新。這允許主CPU進(jìn)入睡眠狀態(tài),而在背景中較長的時(shí)間。的iOS不具備啟動主CPU的每個(gè)位置更新時(shí),CPU可以睡,而GPS芯片集的位置。 您可以檢查這個(gè)deferredLocationUpdatesAvailable方法。如果可用,您可以啟用allowDeferredLocationUpdatesUntilTraveled:timeout:方法。條件適用,看到這個(gè)答案的細(xì)節(jié)。?
4. 如果你支持的iOS 5和6,你應(yīng)該叫
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations,?
從舊
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation?
功能,通過建立的位置的陣列。
本文標(biāo)題 :didUpdateLocations代替didUpdateToLocation
本文地址 :CodeGo.net/507856/?
繼續(xù)瀏覽 :Maven的javadoc中,插件和故障安全maven的插件缺失時(shí)生成JBoss Seam的例子
您可以會感興趣的文章:
1. EmberJS嵌套視圖和控制器
2. listview與復(fù)選框,單選按鈕,TextView的和按鈕無法正常工作在Android
3. 使用自定義控制臺為Visual Studio控制臺應(yīng)用程序調(diào)試
4. 升級到4.5的Xcode后的iOS 5 SDK中消失了
5. 從基本形式訪問連接字符串會導(dǎo)致錯誤的設(shè)計(jì)師
6. 在小區(qū)的空值處理
7. 無法顯示在欲望的格式報(bào)告[關(guān)閉]
8. Mysql的動態(tài)觸發(fā)創(chuàng)建存儲過程
9. NoClassDefFoundError的:android/support/v4/content/LocalBroadcastManager
10. 如何正確地安裝mysqlconnecter java嗎?
11. 可以選擇的樣式元素,以便選定的選項(xiàng)樣式顯示下拉列表時(shí),'封閉'?
12. 在JavaEE的6子進(jìn)程執(zhí)行
13. R和矩陣1的行
14. 旋轉(zhuǎn)和尺度不變性的模板匹配在OpenCV的[復(fù)制]
15. 在列表中創(chuàng)建使用數(shù)據(jù)填充的等高線圖
16. 安卓+PhoneGap的攔截的URL(相當(dāng)于iOS的shouldStartLoadWithRequest的)
17. 泛型類與約束訪問問題
18. 什么是法律約束緩存事件意思?
19. SBT:添加依賴scalatest庫。在哪里?
20. 什么是PK和FK我應(yīng)該分配給我的桌子嗎?
IOS定位核心與地圖
? ? ? ? ? ? ???
Core Location以及Map框架包通常能給我們的應(yīng)用程序添加定位和地圖相關(guān)的服務(wù)。Core Location框架包通常是使用硬件設(shè)備來進(jìn)行定位服務(wù)的,Map框架包通常能夠使你的應(yīng)用程序做一些地圖展示與交互的相關(guān)功能。地圖的定位服務(wù)一般需要依賴設(shè)備的硬件組成部分。如果有定位的硬件設(shè)備,那么肯定是可以利用地圖框架包來進(jìn)行地圖的一些相關(guān)的操作。?
為了能夠在項(xiàng)目中使用到位置服務(wù)以及地圖展示的相關(guān)功能,你必須要導(dǎo)入Core Location?和Map這兩個(gè)框架包。如果你不知道怎么做,那么請參照如下步驟。?
1.點(diǎn)擊你的項(xiàng)目工程圖標(biāo)文件。?
2.然后選擇target選項(xiàng),如圖1所示。?
3.然后選擇Build Phase模塊欄。?
4.然后點(diǎn)開Link Binary With Libraries欄目,在點(diǎn)擊+號按鈕。
圖1?添加相關(guān)的框架包
5.添加MapKit.framework和CoreLocation.framework這兩個(gè)庫
6.在使用地圖和定位的地方,導(dǎo)入:
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
MKMapView是UIView的子類,所以可以像一個(gè)普通的View一樣添加到ViewController的View當(dāng)中。
?
以下是相關(guān)的代碼
ViewController.h
#import?<UIKit/UIKit.h>? #import?<CoreLocation/CoreLocation.h>? #import?<MapKit/MapKit.h>? #import?"MyAnnotation.h"? @interface?ViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate>? // MapView @property (nonatomic,strong) MKMapView *myMapView;// 地圖控件? // LocationManager @property (nonatomic,strong) CLLocationManager *myLocationManager;// 位置管理器? @property (nonatomic,strong) CLGeocoder *myGeoCoder ;// 地理位置和真實(shí)地址轉(zhuǎn)換? @end?
?
ViewController.m
#import?"ViewController.h"? #import?"MKMapView+ZoomLevel.h"? @interface?ViewController ()? @end? @implementation ViewController? @synthesize myMapView;? @synthesize myLocationManager;? @synthesize myGeoCoder;? - (void)viewDidLoad? {? ????[super?viewDidLoad];? ???// Do any additional setup after loading the view, typically from a nib. ????// 設(shè)置根View的背景顏色 ????self.view.backgroundColor = [UIColor colorWithRed:0x33 / 255.0f green:0x66 / 255.0f blue:0x99 / 255.0f alpha:0xFF / 255.0f];? ????// 初始化MapView并且設(shè)置MapView顯示的邊界 ????self.myMapView = [[MKMapView alloc]initWithFrame:self.view.bounds];? // self.myMapView.mapType = MKMapTypeSatellite; // self.myMapView.mapType = MKMapTypeHybrid; ????self.myMapView.mapType = MKMapTypeStandard;? ????self.myMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;? ????self.myMapView.delegate?= self;? ? ????CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(40.034122, 116.289574);? ????MyAnnotation *annotation = [[MyAnnotation alloc]initWithCoordinate:coordinate title:@"我的位置" subTitle:@"這里就是寡人的位置,嘿嘿!"];? ????annotation.pinColor = MKPinAnnotationColorPurple;? ? ????[self.myMapView addAnnotation:annotation];? ? ????[self.myMapView setShowsUserLocation:YES];? ????[self.myMapView setCenterCoordinate:coordinate zoomLevel:15 animated:YES];? ? ????[self.view addSubview:myMapView];? ? ????if([CLLocationManager locationServicesEnabled]){? ????????self.myLocationManager = [[CLLocationManager alloc]init];? ????????self.myLocationManager.delegate?= self;? // // 提示用戶是否允許當(dāng)前應(yīng)用使用地理位置,已過時(shí),在Info.plist中使用NSLocationUsageDescription鍵值替換 // self.myLocationManager.purpose = @"提示用戶是否允許當(dāng)前應(yīng)用使用位置,已過時(shí)"; ????????[self.myLocationManager startUpdatingLocation];? ????}else{? ????????NSLog(@">>>>>>>>>> 位置服務(wù)不可用 <<<<<<<<<<<<");? ????????UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的位置服務(wù)當(dāng)前不可用,請打開位置服務(wù)后重試"?delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];? ????????[alertView show];? ????}? ? ????CLLocation *location = [[CLLocation alloc]initWithLatitude:40.034122 longitude:116.289574];? ? ????self.myGeoCoder = [[CLGeocoder alloc]init];? ????[self.myGeoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks,NSError *error){? ????????if(error == nil && [placemarks count] > 0){? ????????????CLPlacemark *pm = [placemarks objectAtIndex:0];? ????????????NSLog(@"國家:%@" ,pm.country);? ????????????NSLog(@"郵編:%@",pm.postalCode);? ????????????NSLog(@"Locality:%@",pm.locality);? ????????}else?if(error == nil && [placemarks count] == 0){? ????????????NSLog(@"沒有地址返回");? ????????}else?if(error != nil){? ????????????NSLog(@"出錯了:%@",error);? ????????}? ????}];? ? ????[self.myGeoCoder geocodeAddressString:@"中國北京市海淀區(qū)花園東路10號高德大廈" completionHandler:^(NSArray *placemarks,NSError *error){? ????????if(nil == error && [placemarks count] > 0){? ????????????NSLog(@"placemarks count:%i",[placemarks count]);? ????????????CLPlacemark *pm = [placemarks objectAtIndex:0];? ????????????NSLog(@"longitude=%f",pm.location.coordinate.longitude);? ????????????NSLog(@"latitude=%f",pm.location.coordinate.latitude);? ????????}else?if([placemarks count] == 0 && error == nil){? ????????????NSLog(@"找不到給定地址的經(jīng)緯度");? ????????}else?if(nil != nil){? ????????????NSLog(@"發(fā)生了錯誤:%@",error);? ????????}? ????}];? ? ? }? - (void)didReceiveMemoryWarning? {? ????[super?didReceiveMemoryWarning];? ????// Dispose of any resources that can be recreated. ? }? -(void)viewDidUnload? {? ????[super?viewDidUnload];? ????self.myMapView = nil;? ????[self.myLocationManager stopUpdatingLocation];? ????self.myLocationManager = nil;? }? -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation? {? ????return?YES;? }? ? /*******************************************************************************************/ /*******************************************************************************************/ /*************************** MapView的Delegate的方法,全部都是Option的 *************************/ /*******************************************************************************************/ /*******************************************************************************************/ /*******************************************************************************************/ - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {? ????NSLog(@"mapView:regionWillChangeAnimated:方法被調(diào)用");? }? // 用戶的地理位置發(fā)生改變的時(shí)候調(diào)用 - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {? ????NSLog(@"mapView:regionDidChangeAnimated:方法被調(diào)用");? }? // 當(dāng)?shù)貓D界面將要加載的時(shí)候?qū){(diào)用這個(gè)方法 - (void)mapViewWillStartLoadingMap:(MKMapView *)mapView{? ????NSLog(@"mapViewWillStartLoadingMap:方法被調(diào)用");? }? // 當(dāng)?shù)貓D界面加載完成的時(shí)候?qū)⒁{(diào)用這個(gè)方法 - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView{? ????NSLog(@"mapViewDidFinishLoadingMap:方法被調(diào)用");? }? // 當(dāng)?shù)貓D界面加載失敗的時(shí)候調(diào)用這個(gè)方法 - (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error{? ????NSLog(@"mapViewDidFailLoadingMap:withError:方法被調(diào)用,error is:%@" , [error description]);? }? // 添加到地圖的Annotation // 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 <MKAnnotation>)annotation? {? ????MKAnnotationView *view = nil;? ????if([annotation isKindOfClass:[MyAnnotation?class]] == NO){? ????????return?view;? ????}? ????if([mapView isEqual:self.myMapView] == NO){? ????????return?view;? ????}? ? ????MyAnnotation *senderAnnotation = (MyAnnotation*)annotation;? ????NSString *pinReusableIdentifier = [MyAnnotation reusableIdentifierForPinColor:senderAnnotation.pinColor];? ????MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier];? ????if(annotationView == nil){? ????????annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:senderAnnotation reuseIdentifier:pinReusableIdentifier];? ????????[annotationView setCanShowCallout:YES];? ????}? ????annotationView.pinColor = senderAnnotation.pinColor;? ? ????NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);? ????NSString *documentPath = [paths objectAtIndex:0];? ? ????NSString *cachePath = [documentPath stringByAppendingString:@"/images"];? ????NSString *cacheFile = [cachePath stringByAppendingString:@"icon.image"];? ????if([[NSFileManager defaultManager]fileExistsAtPath:cacheFile]){? ????????UIImage *image = [UIImage imageWithContentsOfFile:cacheFile];? ????????if(image != nil){? ????????????annotationView.image = image;? ????????????NSLog(@"通過本地設(shè)置圖片");? ????????}else{? ????????????[self setAnnotionImageByUrl:annotationView cacheFile:cacheFile];? ????????}? ????}else{? ????????[self setAnnotionImageByUrl:annotationView cacheFile:cacheFile];? ????}? ????view = annotationView;? ? ????return?view;? }? -(void) setAnnotionImageByUrl:(MKPinAnnotationView *)annotationView cacheFile:(NSString *) cacheFile{? ????NSLog(@"通過網(wǎng)絡(luò)設(shè)置文件");? ????dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);? ????dispatch_async(queue, ^{? ? ? ????????NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/img/duanwulogo_94a0060bda0885d1c2320ca0d7d7c342.gif"];? ????????NSData *data = [NSData dataWithContentsOfURL:url];? ????????if(data != nil){? ????????????[data writeToFile:cacheFile atomically:YES];? ????????????UIImage *image = [UIImage imageWithData:data];? ????????????dispatch_queue_t mainQueue = dispatch_get_main_queue();? ????????????dispatch_async(mainQueue, ^{? ????????????????if(image != nil){? ????????????????????annotationView.image = image;? ????????????????}? ????????????});? ????????}? ????});? }? /**? // 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;? ? // 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;? - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);? - (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);? ? - (void)mapViewWillStartLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);? - (void)mapViewDidStopLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);? - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation NS_AVAILABLE(NA, 4_0);? - (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error NS_AVAILABLE(NA, 4_0);? - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState? fromOldState:(MKAnnotationViewDragState)oldState NS_AVAILABLE(NA, 4_0);? ? - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay NS_AVAILABLE(NA, 4_0);? ? // Called after the provided overlay views have been added and positioned in the map.? - (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews NS_AVAILABLE(NA, 4_0);? - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);? */ ? ? /*******************************************************************************************/ /*******************************************************************************************/ /*************************** 位置相關(guān) *************************/ /*******************************************************************************************/ /*******************************************************************************************/ /*******************************************************************************************/ ? -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation? {? ????NSLog(@"Latitude=%f",newLocation.coordinate.latitude);? ????NSLog(@"Longitude=%f",newLocation.coordinate.longitude);? }? -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error? {? ? ????NSLog(@"獲得位置失敗");? }? @end?
MKMapView+ZoomLevel.h
#import?<MapKit/MapKit.h>? ? @interface?MKMapView (ZoomLevel)? - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate? ??????????????????zoomLevel:(NSUInteger)zoomLevel? ???????????????????animated:(BOOL)animated;? @end?
?
MKMapView+ZoomLevel.m
#import?"MKMapView+ZoomLevel.h"? ? @implementation MKMapView (ZoomLevel)? #define MERCATOR_OFFSET 268435456? #define MERCATOR_RADIUS 85445659.44705395? ? #pragma mark -? #pragma mark Map conversion methods? - (double)longitudeToPixelSpaceX:(double)longitude? {? ????return?round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0);? }? ? - (double)latitudeToPixelSpaceY:(double)latitude? {? ????return?round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0);? }? - (double)pixelSpaceXToLongitude:(double)pixelX? {? ????return?((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI;? }? ? - (double)pixelSpaceYToLatitude:(double)pixelY? {? ????return?(M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI;? }? #pragma mark -? #pragma mark Helper methods? ? - (MKCoordinateSpan)coordinateSpanWithMapView:(MKMapView *)mapView? ?????????????????????????????centerCoordinate:(CLLocationCoordinate2D)centerCoordinate? ?????????????????????????????????andZoomLevel:(NSUInteger)zoomLevel? {? ????// convert center coordiate to pixel space ????double?centerPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];? ????double?centerPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude];? ? ????// determine the scale value from the zoom level ????NSInteger zoomExponent = 20 - zoomLevel;? ????double?zoomScale = pow(2, zoomExponent);? ? ????// scale the map's size in pixel space ????CGSize mapSizeInPixels = mapView.bounds.size;? ????double?scaledMapWidth = mapSizeInPixels.width * zoomScale;? ????double?scaledMapHeight = mapSizeInPixels.height * zoomScale;? ????// figure out the position of the top-left pixel ????double?topLeftPixelX = centerPixelX - (scaledMapWidth / 2);? ????double?topLeftPixelY = centerPixelY - (scaledMapHeight / 2);? ????// find delta between left and right longitudes ????CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX];? ????CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth];? ????CLLocationDegrees longitudeDelta = maxLng - minLng;? ? ????// find delta between top and bottom latitudes ????CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];? ????CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight];? ????CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);? ????// create and return the lat/lng span ????MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);? ????return?span;? }? ? #pragma mark -? #pragma mark Public methods? - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate? ??????????????????zoomLevel:(NSUInteger)zoomLevel? ???????????????????animated:(BOOL)animated? {? ????// clamp large numbers to 28 ????zoomLevel = MIN(zoomLevel, 28);? ? ????// use the zoom level to compute the region ????MKCoordinateSpan span = [self coordinateSpanWithMapView:self centerCoordinate:centerCoordinate andZoomLevel:zoomLevel];? ????MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span);? ? ????// set the region like normal ????[self setRegion:region animated:animated];? }? ? @end?
MyAnnotation.h
#import?<Foundation/Foundation.h>? #import?<CoreLocation/CoreLocation.h>? #import?<MapKit/MapKit.h>? ? #define REUSABLE_PIN_RED @"Red"? #define REUSABLE_PIN_GREEN @"Green"? #define REUSABLE_PIN_PURPLE @"Purple"? ? @interface?MyAnnotation : NSObject <MKAnnotation>? ? @property (nonatomic,readonly) CLLocationCoordinate2D coordinate;? @property (nonatomic, readonly, copy) NSString *title;? @property (nonatomic, readonly, copy) NSString *subtitle;? ? @property (nonatomic,unsafe_unretained) MKPinAnnotationColor pinColor;? ? -(id) initWithCoordinate:(CLLocationCoordinate2D) coordinate? ???????????????????title:(NSString*) paramTitle? ????????????????subTitle:(NSString*) paramSubTitle;? // 得到顏色 +(NSString *) reusableIdentifierForPinColor:(MKPinAnnotationColor) paramColor;? ? @end?
?
MyAnnotation.m
#import?"MyAnnotation.h"? ? @implementation MyAnnotation? ? @synthesize coordinate,title,subtitle,pinColor;? ? -(id) initWithCoordinate? :(CLLocationCoordinate2D) paramCoordinate title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle? {? ????self = [super?init];? ????if(self != nil){? ????????coordinate = paramCoordinate;? ????????title = paramTitle;? ????????subtitle = paramSubTitle;? ????????pinColor = MKPinAnnotationColorGreen;? ????}? ????return?self;? }? ? +(NSString *)reusableIdentifierForPinColor:(MKPinAnnotationColor)paramColor? {? ????NSString *result = nil;? ????switch?(paramColor) {? ????????case?MKPinAnnotationColorRed:? ????????????result = REUSABLE_PIN_RED;? ????????????break;? ????????case?MKPinAnnotationColorGreen:? ????????????result = REUSABLE_PIN_GREEN;? ????????????break;? ????????case?MKPinAnnotationColorPurple:? ????????????result = REUSABLE_PIN_PURPLE;? ????}? ????return?result;? }? ? @end?
?
注意,在使用用戶的位置的時(shí)候,系統(tǒng)會彈出是否允許應(yīng)用使用位置的對話框,這個(gè)對話框中的提示文字,可以自己進(jìn)行定義
?
在系統(tǒng)版本是6.0(包括6.0)以上的時(shí)候,在Info.plist文件中進(jìn)行定義
<key>NSLocationUsageDescription</key>
<string>是否可以使用位置?如果需要使用本應(yīng)用,是必須的!</string>
?
在6.0以下,這樣進(jìn)行定義
// // 提示用戶是否允許當(dāng)前應(yīng)用使用地理位置,已過時(shí),在Info.plist中使用NSLocationUsageDescription鍵值替換// self.myLocationManager.purpose = @"提示用戶是否允許當(dāng)前應(yīng)用使用位置,已過時(shí)";
總結(jié)
以上是生活随笔為你收集整理的iOS 定位和地图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。