日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS_mapKit与Core Location

發(fā)布時間:2024/8/22 编程问答 40 如意码农
生活随笔 收集整理的這篇文章主要介紹了 iOS_mapKit与Core Location 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
目  錄:
一、使用MKMap控件
二、根據(jù)地址定位
三、在地圖上添加錨點
 
  iOS從3.0版本開始提供了MapKit.frameword支持。該框架提供了一個可被嵌入到應(yīng)用程序中的地圖視圖類MKMapView,該地圖視圖類包含一個可上下、左右滾動的地圖視圖,而且可以非常方便地在地圖中添加定制消息,并可以將其嵌入到應(yīng)用程序中,通過編程的方式設(shè)置地圖的各種屬性(包含當前地圖顯示的區(qū)域以及用戶當前所在位置)。
  iOS從4.0開始,MapKit框架支持可拖動標注和定制覆蓋層。可拖動標注允許開發(fā)者以編程的方式或用戶交互方式來重定位某個標注的位置;覆蓋層則可用于創(chuàng)建有多個點組成的復(fù)雜標注,這種覆蓋層可用于創(chuàng)建公交路線、公園邊界或氣象信息(如雷達數(shù)據(jù))等。
  現(xiàn)在很多的社交軟件都引入了地圖和定位功能,要想實現(xiàn)這2大功能,那就不得不學習其中的2個框架:MaKit和CoreLocation
  (1)CoreLocation框架可以使用硬件設(shè)備來進行定位服務(wù)
  (2)MapKit框架能夠使應(yīng)用程序做一些地圖展示與交互的相關(guān)功能 
  iOS定位支持的3中模式:手機基站、WIFI、GPS
一、使用MKMapView控件
  MKMapView控件中位于MapKit.framework中,因此為了在iOS應(yīng)用中使用該控件,需要完成兩件事情:1,為該應(yīng)用添加MapKit框架;2,在使用MKMapView及相關(guān)類的源文件中使用“#import<MapKit/MapKit.h>”導入MapKit.framework的頭文件。本章絕大部分示例都使用了MKMapView,因此都需要執(zhí)行上面兩步操作。
  1.指定地圖顯示中心和顯示區(qū)域
  為了控制地圖顯示指定區(qū)域,只要兩步即可。
  1、創(chuàng)建一個MKCoordinateRegion結(jié)構(gòu)體變量,該結(jié)構(gòu)體變量包含center,span兩個成員,其中center控制顯示區(qū)域的中心,span控制顯示區(qū)域的范圍。
  2、將MKMapView的region屬性設(shè)為制定的MKCoordinateRegion結(jié)構(gòu)體變量。
  iOS中為開發(fā)者提供了以下三種地圖類型,開發(fā)者可以通過設(shè)置MKMapView的mapViewType設(shè)置地圖類型。

  (1)MKMapTypeStandard 普通地圖
  (2)MKMapTypeSatellite 衛(wèi)星云圖 
  (3)MKMapTypeHybrid 普通地圖覆蓋于衛(wèi)星云圖之上
  2.在地圖中使用大頭針
  (1)通過MapView的addAnnotation方法可以添加一個大頭針到地圖上
  (2)通過MapView的addAnnotations方法可以添加多個大頭針到地圖上
    - (void)addAnnotation:(id <MKAnnotation>)annotation;
    說明:需要傳入一個遵守了MKAnnotation協(xié)議的對象(下面代碼中進行演示)
  不但如此還要實現(xiàn)MapView的代理方法
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *ID = @"anno";
MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];
if (annoView == nil) {
annoView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
// 顯示氣泡
annoView.canShowCallout = YES;
// 設(shè)置綠色
annoView.pinColor = MKPinAnnotationColorGreen;
} return annoView;
}
  案例:顯示指定區(qū)域的地圖
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "MyAnnotation.h"
@interface ViewController ()<MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView; @property (weak, nonatomic) IBOutlet UITextField *latitude;
@property (weak, nonatomic) IBOutlet UITextField *longitude; @end @implementation ViewController - (void)viewDidLoad
{
[super viewDidLoad]; //設(shè)置地圖的顯示風格
self.mapView.mapType = MKMapTypeStandard;
//設(shè)置地圖可縮放
self.mapView.zoomEnabled = YES;
//設(shè)置地圖可滾動
self.mapView.scrollEnabled = YES;
//設(shè)置地圖可旋轉(zhuǎn)
self.mapView.rotateEnabled = YES;
//設(shè)置顯示用戶顯示位置
self.mapView.showsUserLocation = YES;
//為MKMapView設(shè)置delegate
self.mapView.delegate = self;
// [self locateToLatitude:23.12672 longtitude:113.395];
NSLog(@"用戶當前是否位于地圖中:%d",self.mapView.userLocationVisible); }
- (IBAction)goClicked:(UIButton *)sender
{
//關(guān)閉兩個文本框的虛擬鍵盤
// [self.latitude resignFirstResponder];
// [self.longitude resignFirstResponder];
//經(jīng)度
NSString *latitudeStr = self.latitude.text;
//緯度
NSString *longtitudeStr = self.longitude.text;
//如果用戶輸入的經(jīng)度、緯度為空
if (latitudeStr != nil && latitudeStr.length >
&& longtitudeStr!= nil && longtitudeStr.length > )
{
//設(shè)置經(jīng)度、緯度
[self locateToLatitude:latitudeStr.floatValue longtitude:longtitudeStr.floatValue];
}
}
-(void)locateToLatitude:(CGFloat)latitude longtitude:(CGFloat)longitude
{
//設(shè)置地圖中的的經(jīng)度、緯度
CLLocationCoordinate2D center = {latitude,longitude};
//也可以使用如下方式設(shè)置經(jīng)度、緯度
//center.latitude = latitude;
//center.longitude = longitude;
//設(shè)置地圖顯示的范圍
MKCoordinateSpan span;
//地圖顯示范圍越小,細節(jié)越清楚;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
//創(chuàng)建MKCoordinateRegion對象,該對象代表地圖的顯示中心和顯示范圍
MKCoordinateRegion region = {center,span};
//設(shè)置當前地圖的顯示中心和顯示范圍
[self.mapView setRegion:region animated:YES]; UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
[self.mapView addGestureRecognizer:longPress];
} -(void)longPress:(UILongPressGestureRecognizer *)sender
{
CGPoint location = [sender locationInView:self.mapView];
//轉(zhuǎn)換經(jīng)緯度
CLLocationCoordinate2D coordinate = [self.mapView convertPoint:location toCoordinateFromView:self.mapView];
// 創(chuàng)建標注
MyAnnotation *annotation = [[MyAnnotation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"新的標注";
annotation.subtitle = @"開發(fā)...";
[self.mapView addAnnotation:annotation];
}
#pragma mark - mapView代理方法 #pragma mark 顯示標注視圖
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *annotationID = @"annotation";
MKPinAnnotationView *view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];
if (!view)
{
view = [[MKPinAnnotationView alloc]init];
}
view.annotation = annotation;
// view.leftCalloutAccessoryView
view.pinColor = MKPinAnnotationColorGreen;
view.canShowCallout = YES;
return view;
}
#pragma mark 代理方法
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{ CLLocationCoordinate2D coordinate = userLocation.location.coordinate;
MKCoordinateSpan span = {0.001,0.001};
MKCoordinateRegion region = {coordinate,span};
//設(shè)置顯示區(qū)域
[self.mapView setRegion:region animated:YES]; MyAnnotation *annotation = [[MyAnnotation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"中國";
annotation.subtitle = @"好牛B的地方";
//讓地圖顯示標注的區(qū)域
[self.mapView setCenterCoordinate:annotation.coordinate animated:YES]; }
//當MKMapView顯示區(qū)域?qū)⒁l(fā)生改變時激發(fā)該方法
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
NSLog(@"地圖控件的顯示區(qū)域要發(fā)生改變");
}
//當MKMapView顯示區(qū)域改變完成時激發(fā)該方法
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
NSLog(@"地圖控件完成了改變");
}
//當?shù)貓D控件MKMapView開始加載數(shù)據(jù)時激發(fā)該方法
-(void)mapViewWillStartLoadingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件開始加載地圖數(shù)據(jù)");
//創(chuàng)建MKCoordinateRegion對象,該對象代表地圖的顯示中心和顯示范圍
MKCoordinateRegion region = mapView.region;
self.latitude.text = [NSString stringWithFormat:@"%f",region.center.latitude];
self.longitude.text = [NSString stringWithFormat:@"%f",region.center.longitude]; }
//當MKMapView加載數(shù)據(jù)完成時激發(fā)該方法
-(void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件加載地圖數(shù)據(jù)完成");
NSLog(@"%@",mapView);
}
//當MKMapView加載數(shù)據(jù)失敗時激發(fā)該方法
-(void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
NSLog(@"地圖控件加載地圖數(shù)據(jù)發(fā)生錯誤:錯誤信息:%@",error);
}
//當MKMapView開始渲染地圖時激發(fā)該方法
-(void)mapViewWillStartRenderingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件開始渲染地圖");
}
//當MKMapView渲染地圖完成時激發(fā)該方法
-(void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered
{
NSLog(@"地圖控件渲染完成");
}
@end

  MyAnnotation.h文件內(nèi)容

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface MyAnnotation : NSObject<MKAnnotation>
@property(copy,nonatomic)NSString *title;
@property(copy,nonatomic)NSString *subtitle;
@property(assign,nonatomic)CLLocationCoordinate2D coordinate;
@end

  程序運行結(jié)果如下:

  程序中還為MKMapView指定了delegate,因此該delegate將會響應(yīng)地圖位置改變、加載過程中的相關(guān)事件,所以大家可以看到Xcode的控制輸出消息。

二、根據(jù)地址定位

  1.地址解析與反向地址解析

  地址解析:把普通用戶能看懂的字符串地址轉(zhuǎn)換為經(jīng)度、緯度。

  反向地址解析:把經(jīng)度、緯度轉(zhuǎn)換成普通的字符串地址。

  iOS為地址解析提供了CLGeocoder工具類,該工具類提供了如下3種方法來進行地址解析和反向地址解析。

  -geocodeAddressString:completionHandler: :根據(jù)給定的字符串地址進行解析,解析將會得到該地址對應(yīng)的經(jīng)度、緯度信息。

  -geocodeAddressString:inRegion:completonHandler: :根據(jù)給定的字符串進行解析,解析將會得到該地址對應(yīng)的經(jīng)度、緯度信息。

  -reverseGeocodeLocation:completionHandler: :根據(jù)給定的經(jīng)度、緯度地址方向解析得到字符串地址。

  一般來說:地址解析可能得到多個結(jié)果——這是因為全球完全可能有多個同名的地點;但反向地址解析一般只會得到一個結(jié)果——因為根據(jù)指定經(jīng)度、緯度得到的地址通常是唯一的。

  2.根據(jù)地址定位

  根據(jù)地址定位的思路非常簡單,只要如下兩步即可。

  (1)使用CLGeocoder根據(jù)字符串地址得到該地址的經(jīng)度、緯度。

  (2)根據(jù)解析得到的經(jīng)度、緯度進行定位。

  

#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h> @interface ViewController ()<CLLocationManagerDelegate>
@property(strong,nonatomic)CLLocationManager *locationManager;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// 創(chuàng)建定位管理器
self.locationManager = [[CLLocationManager alloc]init];
//獲取用戶授權(quán)
[self.locationManager requestAlwaysAuthorization]; //獲取當前授權(quán)狀態(tài)
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse)
{
NSLog(@"授權(quán)通過");
}
else
{
NSLog(@"授權(quán)不通過");
}
//設(shè)置代理
self.locationManager.delegate = self;
//設(shè)置經(jīng)度
self.locationManager.desiredAccuracy =kCLLocationAccuracyBest;
//開始定位
[self.locationManager startUpdatingLocation];
}
#pragma mark - 定位管理器的代理方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// NSLog(@"%@",locations);
//取出位置信息
CLLocation *location = [locations lastObject]; //創(chuàng)建地理信息編解碼對象
CLGeocoder *geoCoder = [[CLGeocoder alloc]init]; //轉(zhuǎn)換位置信息
[geoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
// NSLog(@"%@",placemarks[0]);
CLPlacemark *placeMark = placemarks[];
NSLog(@"%@%@",placeMark.country,placeMark.locality);
}];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"%@",error);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
[geoCoder geocodeAddressString:@"西三旗" completionHandler:^(NSArray *placemarks, NSError *error) {
if ([placemarks count] == ) {
NSLog(@"沒有找到相應(yīng)的地理信息");
}
else
{
CLPlacemark *placemark = [placemarks objectAtIndex:];
//NSLog(@"%@",placeMark);
// NSLog(@"%f,%f",placeMark.location.coordinate.latitude,placeMark.location.coordinate.longitude); MKMapItem *mapItem1 = [[MKMapItem alloc]initWithPlacemark:(MKPlacemark*)placemark];
[geoCoder geocodeAddressString:@"八達嶺長城" completionHandler:^(NSArray *placemarks, NSError *error) {
MKMapItem *mapItem2 = [[MKMapItem alloc]initWithPlacemark:(MKPlacemark*)placemarks[]];
//調(diào)用系統(tǒng)地圖打開一個位置
[MKMapItem openMapsWithItems:@[mapItem1,mapItem2] launchOptions:nil];
}];
}
}];
}
@end

三、在地圖上添加錨點

  1.添加簡單地錨點

  對于iOS的地圖而言,添加錨點只要調(diào)用MKMapView的-(void)addAnnotation:(id<MKAnnotation>)annotation方法即可,每調(diào)用一次,就像地圖添加一個錨點。MKAnnotation是一個協(xié)議,該協(xié)議中定義了3個屬性,用于設(shè)置和返回錨點的信息。

  - coordinate:用于設(shè)置和返回錨點的位置。該屬性值必須是一個CLLocationCoordinate2D結(jié)構(gòu)體變量,封裝了經(jīng)度、緯度信息。

  - title:用于設(shè)置和返回錨點的標題。

  - subtitle:用于設(shè)置和返回錨點的副標題。

  2.添加自定義錨點

  錨點由兩部分組成。

  錨點信息:錨點信息包括錨點的位置、標題、副標題等信息,這些信息有MKAnnotation對象代表。

  錨點控件:錨點控件決定地圖上顯示的錨點外觀,包括錨點的圖片等。

  iOS為錨點控件提供了MKAnnotationView和MKPinAnnotationView,其中MKPinAnnotationView是MKAnnotationView的子類,而MKAnnotationView繼承了UIView——也就是說,它只是一個可視化的UI控件。

  為定制地圖上的錨點,需要完成如下兩步。

  1.為MKMapView指定delegate對象。

  2.重寫delegatede-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation方法,該方法的返回值將作為地圖上的錨點控件。

  案例:在圖上添加錨點

#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "MyAnnoation.h"
@interface ViewController ()<MKMapViewDelegate>
@property(strong,nonatomic)MKMapView *mapView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// 創(chuàng)建mapView
self.mapView = [[MKMapView alloc]initWithFrame:self.view.frame];
//設(shè)置地圖的類型
self.mapView.mapType = MKMapTypeStandard;
[self.view addSubview:self.mapView]; self.mapView.delegate = self; //創(chuàng)建標注
MyAnnoation *annoation = [[MyAnnoation alloc]init];
annoation.coordinate= CLLocationCoordinate2DMake(, );
annoation.title = @"中國";
annoation.subtitle = @"好牛B的地方";
//添加標注
[self.mapView addAnnotation:annoation]; //讓地圖顯示標注的區(qū)域
[self.mapView setCenterCoordinate:annoation.coordinate animated:YES]; //添加手勢
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
[self.mapView addGestureRecognizer:longPress];
}
-(void)longPress:(UILongPressGestureRecognizer *)sender
{ //獲取當前位置
CGPoint location = [sender locationInView:self.view];
//轉(zhuǎn)換經(jīng)緯度
CLLocationCoordinate2D coordinate =[self.mapView convertPoint:location toCoordinateFromView:self.mapView];
//創(chuàng)建標注
MyAnnoation *annotation = [[MyAnnoation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"新的標注";
annotation.subtitle = @"待開發(fā)。。";
//添加標注
[self.mapView addAnnotation:annotation]; }
#pragma mark - mapView代理方法
#pragma mark 顯示標注視圖
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *annotationID =@"annotation";
//先從重用隊列中去找
MKPinAnnotationView *view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];
//如果找不到,自己創(chuàng)建
if (!view)
{
view = [[MKPinAnnotationView alloc]init];
}
//設(shè)置屬性
view.annotation = annotation;
view.canShowCallout = YES;//顯示氣泡視圖
view.pinColor = MKPinAnnotationColorPurple;//設(shè)置大頭針顏色
//顯示圖片(這種方式設(shè)置圖片會取代大頭針)
view.image = [UIImage imageNamed:@"0.png"];
//設(shè)置氣泡的輔助視圖(顯示圖片)
view.leftCalloutAccessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"0.png"]];
return view;
}
#pragma mark 選中了標注后的處理 -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
NSLog(@"選中了標注");
}
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
NSLog(@"取消了標注");
}
@end

總結(jié)

以上是生活随笔為你收集整理的iOS_mapKit与Core Location的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。