地图和定位

本文介绍iOS设备上实现定位服务的方法,包括启动和关闭定位、处理定位更新及错误,并演示了如何利用系统和第三方地图服务(如百度地图和高德地图)进行地理编码和展示定位信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定位

遵从协议
//定位管理类

#define BaiduUrl @"http://api.map.baidu.com/geocoder?output=json&location=%f,%f&key=dc40f705157725fc98f1fee6a15b6e60"
@property (nonatomic) CLLocationManager *manager;

开启定位

- (void)onStart
{
    //判断设备是否支持定位服务
    if ([CLLocationManager locationServicesEnabled]) {
        [self initManager];

        //启动定位
        [_manager startUpdatingLocation];
    }
}

- (void)initManager
{
    _manager = [[CLLocationManager alloc] init];

    //设置定位的精度类型
    _manager.desiredAccuracy = kCLLocationAccuracyBest;

    //设置精度
    _manager.distanceFilter = 8;

    //设置代理
    _manager.delegate = self;

    //iOS 8.0之后,定位功能需要向用户请求授权
    if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) {
        //向用户请求始终允许启用定位功能,包括前台和后台
        [_manager requestAlwaysAuthorization];
        //只是在使用期间启用定位服务,只是在前台
//        [_manager requestWhenInUseAuthorization];

        //这两个方法只能使用一个方法,不能同时使用

        //info.plist 要加两行
        //NSLocationWhenInUseDescription,允许在前台获取GPS的描述
    //NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述

    }

}

//关闭定位

    [_manager stopUpdatingLocation];

协议方法

//请求失败

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

//位置变化

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    if (locations.count) {

        CLLocation *location = [locations lastObject];
        NSLog(@"latitude = %f,longitude = %f",location.coordinate.latitude,location.coordinate.longitude);

        //地理反编码
        //1.百度的url进行地理反编码,需要传入的是坐标(经纬度)
//        [self reverseGeoCoderWithBaidu:location.coordinate];

        //2.系统的地理反编码
        [self reverseGeoCoderWithSystem:location];

    }
}

//百度反编码

- (void)reverseGeoCoderWithBaidu:(CLLocationCoordinate2D)coordinate
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:BaiduUrl,coordinate.latitude,coordinate.longitude]]];

        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

        NSDictionary *result = dict[@"result"];

        NSLog(@"result = %@",result);
        NSLog(@"city = %@",result[@"addressComponent"][@"city"]);
        NSLog(@"street = %@",result[@"addressComponent"][@"street"]);

    });
}

//系统反编码

- (void)reverseGeoCoderWithSystem:(CLLocation *)location
{
    CLGeocoder *geoCode = [[CLGeocoder alloc] init];

    [geoCode reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        for (CLPlacemark *placeMark in placemarks) {
            NSLog(@"country = %@",placeMark.country);
            for (NSString *key  in placeMark.addressDictionary) {
                NSLog(@"%@",placeMark.addressDictionary[key]);
            }
        }
    }];
}

地图和大头针

1、导入库MapKit.framework xcode5之后系统自动可以关联
2、#import

@property (nonatomic,strong) MKMapView *mapView;
//地图类型
_mapView.mapType = MKMapTypeStandard;    
//设置代理
_mapView.delegate = self;

// 设置地图初始的区域:

 #if 0
    MKCoordinateRegion region;
    //经纬度
    region.center.longitude = 113.678182;
    region.center.latitude = 34.792568;
    //缩放比例
    region.span.latitudeDelta = 0.01;
    region.span.longitudeDelta = 0.01;
    [_mapView setRegion:region];
#else
     //设定地图中心点坐标
    CLLocationCoordinate2D lc2d = CLLocationCoordinate2DMake(40.035139,116.311655);
    //设置缩放系数 (一般设置成0.01-0.05)
    MKCoordinateSpan span = MKCoordinateSpanMake(0.01,0.01);
    //显示区域的结构体
    MKCoordinateRegion region = MKCoordinateRegionMake(lc2d, span);
    //让地图基于划定区域显示
    [_mapView setRegion:region];

// 显示自己的位置

_mapView.showsUserLocation = YES;
// 经纬度需要通过地图取得当前位置坐标
CLLocation *myselfLocation = _mapView.userLocation.location

//创建数据模型,用于定位显示某个点

- (void)createAnnotaion
{
    //1.数据模型
    MKPointAnnotation * annotation1 = [[MKPointAnnotation alloc] init];

    //设定坐标
    annotation1.coordinate = CLLocationCoordinate2DMake(LATITUDE, LONGTITUDE);

    //设定title
    annotation1.title = @"河南省教育学院";

    //设定subtitle
    annotation1.subtitle = @"纬五路21号";

    [_mapView addAnnotation:annotation1];

}

协议方法

//返回大头针视图

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {

        //MKPinAnnotationView 大头针头上的视图,mapView中有对大头针视图的重用机制
        MKPinAnnotationView * pinView = (id)[mapView dequeueReusableAnnotationViewWithIdentifier:@"MKPinAnnotationView"];

        if (pinView == nil) {
            pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MKPinAnnotationView"];
        }

        //定制显示
        //设置显示气泡
        pinView.canShowCallout = YES;

        //设置掉落动画
        pinView.animatesDrop = YES;

        //设置pin 颜色
        pinView.pinColor = MKPinAnnotationColorPurple;

        //设置气泡的左侧辅助视图
        UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
        leftView.backgroundColor = [UIColor redColor];

        pinView.leftCalloutAccessoryView = leftView;

        //设置右侧的气泡辅助视图
        UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark];
        button.frame = CGRectMake(0, 0, 30, 30);

        pinView.rightCalloutAccessoryView = button;

        return pinView;
    }

    return nil;
}

自定义大头针视图

大头针

一般不用系统的需要定制
遵守协议即可
自定义大头针数据模型

大头针视图MKPinAnnotationView
模型数据MKPointAnnotation

#import <MapKit/MapKit.h>

@interface MyAnnotation : NSObject<MKAnnotation>
//遵守协议

@property (nonatomic) CLLocationCoordinate2D myCoordinate;

@property (nonatomic) NSString *myTitle;

@property (nonatomic) NSString *mySubtitle;

@end
//重写代理方法
@implementation MyAnnotation
- (CLLocationCoordinate2D) coordinate {
    return CLLocationCoordinate2DMake(self.latitude, self.longitude);
}
- (NSString *) title {
    return self.name;
}
- (NSString *) subtitle {
    return self.subname;
}

@end

长按手势

//长按手势
    UILongPressGestureRecognizer *lp = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressedMap:)];
    [_mapView addGestureRecognizer:lp];

- (void)longPressedMap:(UILongPressGestureRecognizer *)lp{
    if (lp.state ==UIGestureRecognizerStateBegan) {
        //拿到手势按在地图上的点坐标
        CGPoint pt =[lp locationInView:_mapView];
        //convertPoint 要转化的点  toCoordinateFromView:点坐标的来源
        //返回值为对应的经纬度坐标(重要)
     CLLocationCoordinate2D  lc2d = [_mapView convertPoint:pt toCoordinateFromView:_mapView];
        //创建模型数据
        MKPointAnnotation *annotaion = [[MKPointAnnotation alloc] init];

        annotaion.coordinate = coordinate;
        //title内容应该反编码获得
        annotaion.title = @"中南海";
        annotaion.subtitle = @"国务院";

        [_mapView addAnnotation:annotaion];
    }
}

高德地图

先注册一个账号成为开发者
开发者网址http://lbs.amap.com/
//2d 和3d 只能做一个
b.假设做的是2d地图
1》导入MAMapKit.framework 和 MAMapKit.framework—>resource-》Amap.bundle

2》环境配置
                 在TARGETS->Build Settings->Other Linker Flags 中添加-ObjC。

3》手动导入MAMapKit.framework 关联的一大堆库
1.

UIKit.framework
2D、3D、Search
2.
Foundation.framework
2D、3D、Search
3.
CoreGraphics.framework
2D、3D、Search
4.
QuartzCore.framework
2D、3D

6.
CoreLocation.framework
2D、3D
7.
CoreTelephony.framework
2D、3D、Search
8.
SystemConfiguration.framework
2D、3D、Search
9.
libz.dylib
2D、3D、Search
10.
libstdc++6.09.dylib
2D、3D、Search
11.
Security.framework
2D、3D
也可以用cocoapods 自动下载高德地图sdk 自动导入关联的库
pod ‘AMap3DMap’ #3D地图SDK
pod ‘AMap2DMap’ #2D地图SDK(2D地图和3D地图不能同时使用)
pod ‘AMapSearch’ #搜索服务SDK

4》//导入高德的头文件
import

[MAMapServices sharedServices].apiKey = @"53b46dbbd86441a3693075e525e715ca";

viewcontroller

import <MAMapKit/MAMapKit.h>

遵从协议MAMapViewDelegate

@property (nonatomic) MAMapView *mapView;

//设置地图属性

_mapView.desiredAccuracy = kCLLocationAccuracyBest;

    _mapView.distanceFilter = 10;

    _mapView.delegate = self;

    _mapView.mapType = MAMapTypeStandard;

    //设置显示的区域
    MACoordinateRegion region = MACoordinateRegionMake(CLLocationCoordinate2DMake(34.77274892, 113.67591140), MACoordinateSpanMake(0.01, 0.01));
    [_mapView setRegion:region];

//创建数据模型

- (void)createAnnotation
{
    MAPointAnnotation * maPoint = [[MAPointAnnotation alloc] init];

    maPoint.coordinate =CLLocationCoordinate2DMake(34.77274892, 113.67591140);

    maPoint.title = @"高德";
    maPoint.subtitle = @"高德.阿里";

    [_mapView addAnnotation:maPoint];
}

pragma mark - 代理方法
//返回大头针视图

#pragma mark - 代理方法
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MAPointAnnotation class]]) {

        MAPinAnnotationView * pinView = (id)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pin view"];

        if (pinView == nil) {
            pinView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin view"];
        }

        pinView.canShowCallout = YES;
        pinView.animatesDrop = YES;
        pinView.pinColor = MAPinAnnotationColorGreen;

        return pinView;

    }

    return nil;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值