iOS地图和定位服务(自定义大头针)
2015-10-11 09:47
465 查看
#import "ViewController.h"
//使用地图
需导入MapKit
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "MyAnnotationView.h"
@interface ViewController ()<MKMapViewDelegate,CLLocationManagerDelegate>
{
CLLocationManager *manage;
MKMapView *myMapView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"没打开");
return;
}
//
//
不管是定位还是使用地图 都需要用户授权
manage = [[CLLocationManager alloc]init];
manage.desiredAccuracy = kCLLocationAccuracyBest;
// manage.pausesLocationUpdatesAutomatically = YES;
//
多少米
去更新一次(出了设置的范围就会更新location)位置 location
manage.distanceFilter = 100;
manage.delegate = self;
[manage requestWhenInUseAuthorization];
myMapView = [[MKMapView alloc]initWithFrame:self.view.frame];
//
挂上代理
myMapView.delegate =self;
//
设置地图的样式
/*
MKMapTypeStandard = 0,(默认普通样式)
MKMapTypeSatellite,卫星样式
MKMapTypeHybrid
鸟瞰
*/
myMapView.mapType =MKMapTypeStandard;
//
设置是否允许用户允许旋转地图
myMapView.rotateEnabled =YES;
//
是否允许方法缩小地图
myMapView.zoomEnabled =YES;
//
是否允许地图滚动
myMapView.scrollEnabled = YES;
//
是否允许有3D效果
myMapView.pitchEnabled =YES;
//
射中是否显示用户的位置
myMapView.showsUserLocation =YES;
//
设置是否显示附近的建筑物(必须是
普通样式才有效)
myMapView.showsBuildings =YES;
//
是否显示兴趣点(也是
必须是 普通样式
或则鸟瞰样式 有效)
myMapView.showsPointsOfInterest =YES;
[self.view addSubview:myMapView];
UILongPressGestureRecognizer *addPoint = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(addpointView:)];
[myMapView addGestureRecognizer:addPoint];
}
//长按
手势 的方法
-(void)addpointView:(UILongPressGestureRecognizer *)sender
{
//
解决长按手势触发两次
//
在手势开始的时候
执行
if (sender.state==UIGestureRecognizerStateBegan) {
CGPoint point = [sender locationInView:myMapView];
NSLog(@"%f %f",point.x,point.y);
CLLocationCoordinate2D coodinate = [myMapView convertPoint:point toCoordinateFromView:myMapView];
NSLog(@"%f %f",coodinate.latitude,coodinate.longitude);
MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc]init];
pointAnnotation.coordinate =coodinate;
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
CLLocation *location = [[CLLocation alloc]initWithLatitude:coodinate.latitude longitude:coodinate.longitude];
//
地理编码和范地理编码都是异步操作
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks lastObject];
pointAnnotation.title = placemark.locality;
pointAnnotation.subtitle = placemark.name;
[myMapView addAnnotation:pointAnnotation];
}];
}
}
#pragma mark
地图代理方法
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
NSLog(@"加载失败");
}
//已经
更新完成 用户位置的时候调用
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"已经
更新完成
用户位置的时候调用");
MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);
MKCoordinateRegion regin = MKCoordinateRegionMake(userLocation.location.coordinate,span);
//
如果使用Region的时候
用户移动 出现不断跳动的效果
可以屏蔽动画
[myMapView setRegion:regin animated:YES];
//
把地理位置
转换成名字
//
大头针
// 1.数据 MKPointAnnoTation <MKAnnotation>
// 2、视图 MKPinAnnotationView MKAnnotationView
//
大头针
可以理解为 表视图
的 cell
//
使用大头针(标记数据)
可以使用系统提供的MKPointAnnoTation 也可以自定义MKAnnotation
//
地图添加大头针数据 addAnnotation
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
// setCoordinate
设置大头针的经纬度
[annotation setCoordinate:userLocation.location.coordinate];
//
把定位到用户的位置 转换成地名
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placeMake = [placemarks lastObject];
NSLog(@"城市名:%@
街道名:%@",placeMake.locality,placeMake.name);
//
给大头针
添加标题
annotation.title = placeMake.locality;
//
给大头针添加副标题
annotation.subtitle =placeMake.name;
//
把大头针数据
添加到地图
[mapView addAnnotation:annotation];
}];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
NSString *annotationID = @"ID";
MyAnnotationView *annotationView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];
if (!annotationView) {
annotationView = [[ MyAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:annotationID];
}
return annotationView;
}
return nil;
}
//选中大头针的方法
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
if ([view.annotation isKindOfClass:[MKPointAnnotation class]]) {
view.image = [UIImage imageNamed:@"2.jpg"];
}
}
//取消大头针的方法
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if ([view.annotation isKindOfClass:[MKPointAnnotation class]]) {
view.image = [UIImage imageNamed:@"1.jpg"];
}
}
//定位失败
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
NSLog(@"定位失败时候调用");
}
#pragma mark ---更新位置的代理方法-------
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
// locations数组里面包含了我们更新的位置
NSLog(@"%@",locations);
//
获得最新的位置
CLLocation *curLocation = [locations lastObject];
//
通过location
或得到当前位置的经纬度
CLLocationCoordinate2D curCoordinate2D = curLocation.coordinate;
// curCoordinate2D.latitude
纬度
// curCoordinate2D.longitude
经度
NSLog(@"纬度:%f经度:%f",curCoordinate2D.latitude,curCoordinate2D.longitude);
//
获得 更新位置的时间(nsdate)可以通过更新时间计算行驶的速度
NSDate *updateTime = curLocation.timestamp;
NSLog(@"%@",updateTime);
//
获得当前的行驶速度
double speed = curLocation.speed;
NSLog(@"speed:%f",speed);
//
如果在室内 可以定位是在几楼
CLFloor *curFloor = curLocation.floor;
NSLog(@"%ld",curFloor.level);
//
获得当前的航向
// CLLocationDirection curDirection = curLocation.course;
//
获得当前的海拔的精准度
CLLocationAccuracy curAccuracy = curLocation.verticalAccuracy;
NSLog(@"%f",curAccuracy);
//
获得海拔的高度
double altitude = curLocation.altitude;
NSLog(@"海拔:%f",altitude);
//获得行驶的平均速度
得到两次更新的速度 / 更新的次数
}
- (void)viewWillAppear:(BOOL)animated
{
//
开启定位
[manage startUpdatingLocation];
}
- (void)viewWillDisappear:(BOOL)animated
{
[manage stopUpdatingLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
//使用地图
需导入MapKit
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "MyAnnotationView.h"
@interface ViewController ()<MKMapViewDelegate,CLLocationManagerDelegate>
{
CLLocationManager *manage;
MKMapView *myMapView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"没打开");
return;
}
//
//
不管是定位还是使用地图 都需要用户授权
manage = [[CLLocationManager alloc]init];
manage.desiredAccuracy = kCLLocationAccuracyBest;
// manage.pausesLocationUpdatesAutomatically = YES;
//
多少米
去更新一次(出了设置的范围就会更新location)位置 location
manage.distanceFilter = 100;
manage.delegate = self;
[manage requestWhenInUseAuthorization];
myMapView = [[MKMapView alloc]initWithFrame:self.view.frame];
//
挂上代理
myMapView.delegate =self;
//
设置地图的样式
/*
MKMapTypeStandard = 0,(默认普通样式)
MKMapTypeSatellite,卫星样式
MKMapTypeHybrid
鸟瞰
*/
myMapView.mapType =MKMapTypeStandard;
//
设置是否允许用户允许旋转地图
myMapView.rotateEnabled =YES;
//
是否允许方法缩小地图
myMapView.zoomEnabled =YES;
//
是否允许地图滚动
myMapView.scrollEnabled = YES;
//
是否允许有3D效果
myMapView.pitchEnabled =YES;
//
射中是否显示用户的位置
myMapView.showsUserLocation =YES;
//
设置是否显示附近的建筑物(必须是
普通样式才有效)
myMapView.showsBuildings =YES;
//
是否显示兴趣点(也是
必须是 普通样式
或则鸟瞰样式 有效)
myMapView.showsPointsOfInterest =YES;
[self.view addSubview:myMapView];
UILongPressGestureRecognizer *addPoint = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(addpointView:)];
[myMapView addGestureRecognizer:addPoint];
}
//长按
手势 的方法
-(void)addpointView:(UILongPressGestureRecognizer *)sender
{
//
解决长按手势触发两次
//
在手势开始的时候
执行
if (sender.state==UIGestureRecognizerStateBegan) {
CGPoint point = [sender locationInView:myMapView];
NSLog(@"%f %f",point.x,point.y);
CLLocationCoordinate2D coodinate = [myMapView convertPoint:point toCoordinateFromView:myMapView];
NSLog(@"%f %f",coodinate.latitude,coodinate.longitude);
MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc]init];
pointAnnotation.coordinate =coodinate;
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
CLLocation *location = [[CLLocation alloc]initWithLatitude:coodinate.latitude longitude:coodinate.longitude];
//
地理编码和范地理编码都是异步操作
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks lastObject];
pointAnnotation.title = placemark.locality;
pointAnnotation.subtitle = placemark.name;
[myMapView addAnnotation:pointAnnotation];
}];
}
}
#pragma mark
地图代理方法
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
NSLog(@"加载失败");
}
//已经
更新完成 用户位置的时候调用
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"已经
更新完成
用户位置的时候调用");
MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);
MKCoordinateRegion regin = MKCoordinateRegionMake(userLocation.location.coordinate,span);
//
如果使用Region的时候
用户移动 出现不断跳动的效果
可以屏蔽动画
[myMapView setRegion:regin animated:YES];
//
把地理位置
转换成名字
//
大头针
// 1.数据 MKPointAnnoTation <MKAnnotation>
// 2、视图 MKPinAnnotationView MKAnnotationView
//
大头针
可以理解为 表视图
的 cell
//
使用大头针(标记数据)
可以使用系统提供的MKPointAnnoTation 也可以自定义MKAnnotation
//
地图添加大头针数据 addAnnotation
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
// setCoordinate
设置大头针的经纬度
[annotation setCoordinate:userLocation.location.coordinate];
//
把定位到用户的位置 转换成地名
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placeMake = [placemarks lastObject];
NSLog(@"城市名:%@
街道名:%@",placeMake.locality,placeMake.name);
//
给大头针
添加标题
annotation.title = placeMake.locality;
//
给大头针添加副标题
annotation.subtitle =placeMake.name;
//
把大头针数据
添加到地图
[mapView addAnnotation:annotation];
}];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
NSString *annotationID = @"ID";
MyAnnotationView *annotationView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];
if (!annotationView) {
annotationView = [[ MyAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:annotationID];
}
return annotationView;
}
return nil;
}
//选中大头针的方法
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
if ([view.annotation isKindOfClass:[MKPointAnnotation class]]) {
view.image = [UIImage imageNamed:@"2.jpg"];
}
}
//取消大头针的方法
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if ([view.annotation isKindOfClass:[MKPointAnnotation class]]) {
view.image = [UIImage imageNamed:@"1.jpg"];
}
}
//定位失败
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
NSLog(@"定位失败时候调用");
}
#pragma mark ---更新位置的代理方法-------
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
// locations数组里面包含了我们更新的位置
NSLog(@"%@",locations);
//
获得最新的位置
CLLocation *curLocation = [locations lastObject];
//
通过location
或得到当前位置的经纬度
CLLocationCoordinate2D curCoordinate2D = curLocation.coordinate;
// curCoordinate2D.latitude
纬度
// curCoordinate2D.longitude
经度
NSLog(@"纬度:%f经度:%f",curCoordinate2D.latitude,curCoordinate2D.longitude);
//
获得 更新位置的时间(nsdate)可以通过更新时间计算行驶的速度
NSDate *updateTime = curLocation.timestamp;
NSLog(@"%@",updateTime);
//
获得当前的行驶速度
double speed = curLocation.speed;
NSLog(@"speed:%f",speed);
//
如果在室内 可以定位是在几楼
CLFloor *curFloor = curLocation.floor;
NSLog(@"%ld",curFloor.level);
//
获得当前的航向
// CLLocationDirection curDirection = curLocation.course;
//
获得当前的海拔的精准度
CLLocationAccuracy curAccuracy = curLocation.verticalAccuracy;
NSLog(@"%f",curAccuracy);
//
获得海拔的高度
double altitude = curLocation.altitude;
NSLog(@"海拔:%f",altitude);
//获得行驶的平均速度
得到两次更新的速度 / 更新的次数
}
- (void)viewWillAppear:(BOOL)animated
{
//
开启定位
[manage startUpdatingLocation];
}
- (void)viewWillDisappear:(BOOL)animated
{
[manage stopUpdatingLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
相关文章推荐
- ios 地图与定位(用户位置)
- 【IOS 开发学习总结-OC-40】★★ios开发之事件机制——控件获取方式与事件处理方式
- 线程间通信
- KVO入门介绍
- JS仿IOS风格对话框源码范例
- iOS 开发笔记-报错处理
- 原子和非原子属性
- 多线程的安全隐患
- iOS-关于页面跳转时全局变量赋值不到的问题
- [iOS]圆形进度条及计时功能
- IOS 播放音乐
- 苹果开发 笔记(80)升级IOS 9 和 XCode 7 引起的问题记录
- DSP/BIOS入门
- iOS开发者账号详细介绍
- iOS之Block
- iOS开发笔记--iOS中的触摸事件和手势处理
- iOS中多线程的实现方案之pthread和NSThread
- 多线程基础知识介绍
- ios——1
- iOS开发笔记--iOS中的多线程