iOS——定位与地图

news2025/2/25 17:13:39

平时在写项目的时候可能会遇到需要使用定位服务的地方,比如说获取位置和导航等。因此这里我会使用OC自带的库以及苹果系统的地图来获取定位以及显示在地图上。

开始前的设置

在获取定位前,需要在项目文件的info中添加两个关键字,用于向用户请求定位服务。在请求定位服务的弹窗中会显示我们添加的字段

<key>Privacy - Location When In Use Usage Description
<value>使用程序的时候获取本机位置

<key>Privacy - Location Always Usage Description
<value>总是获取本机位置

在这里插入图片描述

运行效果:
在这里插入图片描述

获取当前位置的经纬度

  • 在写代码前需要添加对应的库以及设置相关的属性:

#import <UIKit/UIKit.h>
// 关于定位以及地图的库
#import <MapKit/MKMapView.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>

@interface ViewController : UIViewController<CLLocationManagerDelegate, MKMapViewDelegate>

//设置一个定位管理者的属性
@property (nonatomic, strong) CLLocationManager *locationManager;
//存储推算出当前的地理位置信息,这个属性用于获取当前位置信息推算出的信息,比如有了经纬度而推算出的省、市、区等
@property (nonatomic, strong) CLGeocoder *geoCoder;

//定义属性获取存储到的位置信息
@property (nonatomic, retain) CLLocation *myLocation;

//MKMapView是iOS中MapKit框架中的一个类,用于显示地图,并提供与地图相关的交互功能
@property (nonatomic, strong) MKMapView *mapView;

@end

  • 开始定位:

//开始定位
- (void)dingWei {
    self.locationManager = [[CLLocationManager alloc] init];
    //desiredAccuracy用于指定定位服务精度, kCLLocationAccuracyBest表示最高精度,这个设置的优势是提供了最准确的位置信息,但代价是更高的能耗。其他定位精度设置,例如 kCLLocationAccuracyNearestTenMeters 或 kCLLocationAccuracyHundredMeters,它们提供了较低的精度但更节能。
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    //distanceFilter 属性用于设置设备移动的距离,当设备移动超过这个距离时,会触发位置更新。distanceFilter 被设置为 10.0 米。这意味着只有当设备移动超过 10.0 米时,才会触发新的位置更新。
    self.locationManager.distanceFilter = 10.0f;
    //检查设备的系统版本是否可以进行定位
    if ([CLLocationManager locationServicesEnabled]) {
        self.locationManager.delegate = self;
        //如果是,则调用 requestWhenInUseAuthorization 方法请求用户在应用处于前台时获取位置信息的授权。
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [self.locationManager requestWhenInUseAuthorization];
        });
        self.geoCoder = [[CLGeocoder alloc] init];
    } else {
        NSLog(@"ERROR");
    }
}

CLLocationManager其相关的属性:

desiredAccuracy位置的精度属性,取值有如下几种:
kCLLocationAccuracyBest:精确度最佳
kCLLocationAccuracynearestTenMeters:精确度10m以内
kCLLocationAccuracyHundredMeters:精确度100m以内
kCLLocationAccuracyKilometer:精确度1000m以内
kCLLocationAccuracyThree:精确度3000m以内

  • 在代理方法中获取需要的位置信息
//在代理方法中获取需要的位置信息
//下面的方法中,locations是一个数组类型,其最后一个元素就是我们的经纬度坐标,类型为CLLocation,如果想将它设置为属性,修饰符一定要是retain
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    NSLog(@"%lu", locations.count);
    self.myLocation = locations.lastObject;
    NSLog(@"经度: %f, 纬度: %f", self.myLocation.coordinate.longitude, self.myLocation.coordinate.latitude);
    
    // 获取到位置后再进行反地理编码
    [self reverseGeocodeLocation:self.myLocation];
}

- (void)reverseGeocodeLocation:(CLLocation *)location {
    [self.geoCoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count > 0) {
            CLPlacemark *placemark = [placemarks objectAtIndex:0];
            NSLog(@"%@", placemark.name);
            NSString *city = placemark.locality;
            if (!city) {
                city = placemark.administrativeArea;
            }
            NSLog(@"位置名:%@", placemark.name);
            NSLog(@"街道:%@", placemark.thoroughfare);
            NSLog(@"子街道:%@", placemark.subThoroughfare);
            NSLog(@"市:%@", placemark.locality);
            NSLog(@"区:%@", placemark.subLocality);
            NSLog(@"国家:%@", placemark.country);
            
            // 在这里调用显示地图的方法
            [self showLocationOnMapWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
        }
    }];
}

  • 改变定位权限

// 在此回调中处理定位权限的改变
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
    CLAuthorizationStatus status = manager.authorizationStatus;
    
    dispatch_async(dispatch_get_main_queue(), ^{
        if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusAuthorizedAlways) {
            // 在这里执行需要权限的操作,例如启动定位服务
            //设置允许在应用在后台运行时继续获取位置更新
            self.locationManager.allowsBackgroundLocationUpdates = NO;
            
            //开始获取设备的当前位置信息
            [self.locationManager startUpdatingLocation];
            self.geoCoder = [[CLGeocoder alloc] init];
            [self jiSuanDistance];
            self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
            self.mapView.delegate = self;
            [self.view addSubview:self.mapView];
        } else {
            NSLog(@"ERROR");
        }
    });
}

  • 获取定位出错时调用如下方法:

//获取位置出错的时候调用下面的协议方法
- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    if (error) {
        NSLog(@"ERROR");
    }
}

运行结果:
在这里插入图片描述

测算两个经纬度之间的距离


//测算两个经纬度坐标之间的距离
- (void) jiSuanDistance {
    CLLocation *before = [[CLLocation alloc] initWithLatitude:11.111 longitude:222.222];
    CLLocationDistance meters = [self.myLocation distanceFromLocation:before];
    NSLog(@"相距: %f米", meters);
}

运行结果:
在这里插入图片描述

将位置定位在地图上

这里使用的是苹果自带的地图


- (void)showLocationOnMapWithLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude {
    //创建坐标点
    CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
    //以指定的坐标为中心,设置地图显示范围。这里的参数 1000 表示地图的纬度和经度跨度都为 1000 米。
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coordinate, 1000, 1000);
    //调整地图显示区域,region 是一个 MKCoordinateRegion 结构体,表示地图的中心点和跨度,这里 region 代表指定的坐标点为中心
    [self.mapView setRegion:region animated:YES];
    
    // 添加标注
    //MKPointAnnotation是 MapKit 框架中的一部分,用于表示地图上的点标注
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    //将coordinate属性设置为当前经纬度坐标
    annotation.coordinate = coordinate;
    //为地图添加标记
    [self.mapView addAnnotation:annotation];
}

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1297696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ooTD I 这么精致优雅的套装也太好看了吧

精致到每一个细节的国风套装 领口袖口拼接环保毛条 精美的绣花增添浓重的高级感 外套90白鸭绒填充 敲暖和裙子的门襟处 也是做了定制盘扣&#xff0c;外套和裙子单独来穿也很精致

STM32L051使用HAL库操作实例(13)- 读取IAQ-CORE-C传感器实例

目录 一、前言 二、传感器参数 三、STM32CubeMX配置&#xff08;本文使用的STM32CubeMX版本为6.1.2&#xff09;例程使用模拟I2C进行数据读取 1.MCU选型 2.使能时钟 3.时钟配置 4.GPIO口配置 四、配置STM32CubeMX生成工程文件 五、点击GENERATE CODE生成工程文件 六、…

人类的耳朵:听觉的动态范围

作者&#xff1a;听觉健康 听觉的动态范围即可用的听力范围。在坐标系中&#xff0c;它可以表示为以听阈和最大舒适级为界形成的区域&#xff0c;其坐标轴分别为频率和声压级&#xff08;刺激持续时间在某种程度上对其产生影响&#xff09;。是什么因素决定了人类听力的极限&am…

ST-Link usb communication error 解决,如何解决STlink驱动连不上的错误

电脑连接不上ST-Link&#xff0c;怎么办&#xff0c;以下方法可以一条一条试试。 方法1 重启电脑。 方法2 确信自己的电脑驱动是装好了的&#xff0c;没有装好&#xff0c;可以看下面这个链接的驱动装一下。 http://www.openedv.com/docs/tool/dap/ST-LINKV2.html 能在设…

【数据结构(九)】顺序存储二叉树(2)

文章目录 1. 相关概念2. 顺序存储二叉树的遍历 1. 相关概念 从数据存储来看&#xff0c;数组存储方式和树的存储方式可以相互转换&#xff0c;即数组可以转换成树&#xff0c;树也可以转换成数组&#xff0c;看右面的示意图。 转换原则:     1.上图的二叉树的结点&#xff…

【PHP】php发送邮箱验证码格式美化,样式美化

效果展示&#xff1a; 格式美化前 格式美化后 代码 大多数框架都自带有封装好的发送email方法&#xff0c;就不多赘述&#xff0c;主要写格式&#xff1a; <? php// 验证码过期时间 $expire 120; // 发件人邮箱 $from_email xx163.com; // 收件人 $to_email to163.com…

48.Go简要实现令牌桶限流与熔断器并集成到Gin框架中

文章目录 一、简介二、限流器与熔断器在微服务中的作用1.限流器 &#xff1a; 对某个接口单位时间内的访问量做限制2. 熔断器&#xff1a;当服务连续报错&#xff0c;超过一定阈值时&#xff0c;打开熔断器使得服务不可用 三、具体实现1. 限流器实现逻辑&#xff08;以令牌桶算…

yolov8火灾报警检测和烟雾检测

火灾和烟雾的跟踪和检测使用YOLOv8 介绍 该代码库包含使用YOLOv8在实时视频中跟踪和检测火灾和烟雾的代码。该项目使用预训练的YOLOv8模型在给定的视频帧中识别火灾和烟雾的存在&#xff0c;并在后续帧中进行跟踪。 应用场景 火灾烟雾检测技术可以应用于各种公共场所&…

特殊进程之守护进程

文章目录 1、守护进程的概念2、如何查看守护进程3、编写守护进程的步骤3.1 创建子进程&#xff0c;父进程退出3.2 在子进程中创建新会话3.3 改变当前工作目录3.4 重设文件权限掩码3.5 关闭不需要的文件描述符3.6 某些特殊的守护进程打开/dev/null 4、守护进程代码示例 1、守护进…

L1-028:判断素数

题目描述 本题的目标很简单&#xff0c;就是判断一个给定的正整数是否素数。 输入格式&#xff1a; 输入在第一行给出一个正整数N&#xff08;≤ 10&#xff09;&#xff0c;随后N行&#xff0c;每行给出一个小于231的需要判断的正整数。 输出格式&#xff1a; 对每个需要判断的…

深入解析Linux内核网络-拥塞控制系列(二)

上篇文章&#xff1a;深入解析Linux内核网络-拥塞控制系列(一&#xff09;对Linux内核网络中网络拥塞框架的框架进行了分析。本次针对具体的Cubic拥塞控制算法进行简单分析。在进行代码的梳理前&#xff0c;同样还是先来看一下相关概念、原理&#xff1a; 在上一篇文章中也提到…

TypeScript入门实战笔记 -- 开篇 为什么要选择 TypeScript ?

typescript 在线编辑器http://typescript.p2hp.com/play?#code/JYOwLgpgTgZghgYwgAgJIFUDO1Uhge2QG8AoZc5YAEwC5kQBXAWwCNoBuMikOJiOzGCigA5pwrI4ANzhg4UAPwChozgF8SmmAxAIwwfCGRYcefAAoADlHyXMdDNii4CASmJdyCQ5nwAbCAA6P3wRKxs7ABpkAHJrW0wY1xINEhNnM3MiSlpkAEZonj46GIBrROQ1…

PHP 二维码内容解析、二维码识别

目录 1.首先是一些错误的示例 2.正确示例 3.二维码解析 4.完整示例&#xff0c;含生成 5.代码执行结果 6.参考文档 1.首先是一些错误的示例 本示例使用的是php7.3 通过搜索各种结果逐个尝试以后&#xff0c;得出一个可使用版本 解析错误经历&#xff1a;vendor核心报错 …

m_map绘图添加遥感图片

在matlab下的m_map可以绘制地形图。那么&#xff0c;如何在m_map添加卫星遥感图片呢&#xff1f;这需要使用m_image函数。 基本语法为&#xff1a; m_image(lonlim,latlim,c)其中lonlim和latlim是这个图像地理坐标&#xff08;经纬度&#xff09;的边界&#xff0c;是一个长度…

机器学习实验四:贝叶斯分类器

系列文章目录 机器学习实验一&#xff1a;线性回归机器学习实验二&#xff1a;决策树模型机器学习实验三&#xff1a;支持向量机模型机器学习实验四&#xff1a;贝叶斯分类器机器学习实验五&#xff1a;集成学习机器学习实验六&#xff1a;聚类 文章目录 系列文章目录一、实验…

ubuntu22.04 安装cuda

CUDA&#xff08;Compute Unified Device Architecture&#xff09;是由 NVIDIA 开发的一种并行计算平台和编程模型。它允许开发者利用 NVIDIA 的 GPU&#xff08;图形处理单元&#xff09;进行高效的计算处理。CUDA 通过提供一系列的 C、C 和 Fortran 扩展&#xff0c;使得开发…

谈谈对OOA、OOD、OOP理解

1 前言 按照开发阶段排序&#xff0c;有如下排序&#xff1a; OOA阶段&#xff1a;面向对象分析&#xff0c;此阶段领域建模&#xff0c;需求分析。OOD阶段&#xff1a;面向对象设计&#xff0c;此阶段输出系统概要设计、系统详细设计。OOP阶段&#xff1a;面向对象编程&#…

Android引用SDK包实现高德地图展示

一、准备工作 注册高德地图开放平台 注册过程我就不多说了&#xff0c;挺简单的&#xff0c;需要登录&#xff0c;然后注册成为开发者&#xff0c;还需要支付宝认证、手机号码验证、邮箱验证挺多的&#xff0c;但是速度很快。基本上随时验证随时注册成功。新建应用新建…

C# | 对比不同种类的锁

文章目录 C# 对比不同种类的锁异同点对比表使用方法lock语句Monitor类Mutex类Semaphore类ReaderWriterLock类 结语 C# 对比不同种类的锁 Hi&#xff0c;在C#编程中&#xff0c;想要保护共享资源&#xff0c;通常会用到各种类型的锁。今天我们就来一起看看C#中不同种类的锁&…