iOS——定位与地图

平时在写项目的时候可能会遇到需要使用定位服务的地方,比如说获取位置和导航等。因此这里我会使用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];
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot AOP切面实现对自定义注解的属性动态修改

文章目录 需求问题解决方案示例代码 需求 项目中共用了一个redis&#xff0c;而项目中部分代码使用了JetCache的Cached注解。所以需要给Cached动态配置area属性值&#xff0c;用来区分dev和test环境。 问题 自定义注解的属性值需要常量值&#xff0c;即static final修饰&…

2013年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

文章目录 2013 级考研管理类联考数学真题一、问题求解&#xff08;本大题共 15 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。真题&#xff08;2013-01&…

【Amis Low Code 结合FastAPI进行前端框架开发】

官方文档 封装思想 直接复制官网json数据即可开发每个json中的接口由fastapi 转发&#xff08;透传&#xff09;使其开发模式与前端思维一致 基础组件 from amis import Page, Service, App from pydantic import BaseModel, Field from fastapi import FastAPI, Request, …

【计算机网络】TCP|IP协议

目录 前言 什么是TCP/IP协议&#xff1f; TCP/IP协议的层次结构 TCP/IP协议的工作原理 TCP/IP协议的重要性 结语 前言 TCP/IP协议是当今互联网世界中最重要的网络协议之一&#xff0c;它是网络通信的基石&#xff0c;为数据在网络中的传输提供了可靠性和有效性。本文将深…

将RK3399的挖掘机开发板在Android10下设置系统默认为24小时制

将RK3399的挖掘机开发板在Android10下设置系统默认为24小时制 2023/12/9 22:07 应该也可以适用于RK3399的Android12系统 --- a/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/frameworks/base/packages/SettingsProvider/res/values/defaults.xml -2…

Java王者荣耀火柴人

主要功能 键盘W,A,S,D键&#xff1a;控制玩家上下左右移动。按钮一&#xff1a;控制英雄发射一个矩形攻击红方小兵。按钮控制英雄发射魅惑技能&#xff0c;伤害小兵并让小兵停止移动。技能三&#xff1a;攻击多个敌人并让小兵停止移动。普攻&#xff1a;对小兵造成基础伤害。小…

go自带rpc框架生产环境使用demo

基础使用 序列化使用自带gob协议 server package mainimport ("net""net/rpc" )// 定义一个handler结构体 type HelloService struct { }// 定义handler方法,大小写&#xff0c;参数&#xff0c;返回值都是固定的&#xff0c;否则无法注册 func (receiv…

Axure网页端高交互组件库, 下拉菜单文件上传穿梭框日期城市选择器

作品说明 组件数量&#xff1a;共 11 套 兼容软件&#xff1a;Axure RP 9/10&#xff0c;不支持低版本 应用领域&#xff1a;web端原型设计、桌面端原型设计 作品特色 本作品为「web端组件库」&#xff0c;高保真高交互 (带仿真功能效果)&#xff1b;运用了动态面板、中继…

【智能家居】八、监控摄像采集、人脸识别比对进行开门功能点

一、使用 fswebcam 测试 USB 摄像头 二、根据demo来实现功能点 三、功能点编写编译运行实现 一、使用 fswebcam 测试 USB 摄像头 a. 安装 fswebcam orangepiorangepi:~$ sudo apt update orangepiorangepi:~$ sudo apt-get install -y fswebcamb. 安装完 fswebcam 后可以使用…

【探索Linux】—— 强大的命令行工具 P.21(多线程 | 线程同步 | 条件变量 | 线程安全)

阅读导航 引言一、线程同步1. 竞态条件的概念2. 线程同步的概念 二、条件变量1. 条件变量函数⭕使用前提&#xff08;1&#xff09;初始化条件变量&#xff08;2&#xff09;等待条件满足&#xff08;3&#xff09;唤醒等待pthread_cond_broadcast()pthread_cond_signal() &…

golang学习笔记——sync.Pool

文章目录 sync.Pool示例sync.Pool数据结构TCP连接池总结参考资料 sync.Pool示例 代码 sync.Pool对外提供的New、Get和Put方法。 var buffers sync.Pool{New: func() interface{} { return new(bytes.Buffer)}, }func GetBuffer() *bytes.Buffer {return buffers.Get().(*byt…

附录C 流水线:基础与中级概念

1. 引言 1.1 什么是流水线&#xff1f; 流水线爱是一种将多条指令重叠执行的实现技术&#xff0c;它利用了一条指令所需的多个操作之间的并行性。&#xff08;指令操作的非原子性和指令类型的多样性&#xff09; 在计算流水线中&#xff0c;每个步骤完成指令的一部分&#x…

UML概扩知识点

UML是一个重要的知识点&#xff0c;考察的频度也很高。我们需要了解的是UML的一系列的图&#xff0c;红框里的是最核心的。 其次是对各种关系有了解&#xff08;红框里的&#xff1a; 依赖关系&#xff0c;关联关系&#xff0c;泛化关系&#xff0c;实现关系&#xff09; UM…

重点车辆安全监测预警技术方案

目录 1.系统架构 2.详细设计 2.1驾驶员信息监控 2.1.1驾驶员基本信息管理 2.1.2人车匹配信息 2.1.3驾驶员在线状态管理 2.2车辆状态信息管理 2.2.1车辆信息管理 2.1.2车辆在路状态管理 2.3重点车辆安全监测预警系统云平台 2.3.1云平台需求分析 2.3.2 设计思想 2.4.…

Idea的Marketplace下载不了插件,idea下不了插件

Idea的Marketplace下载不了插件 解决方案&#xff08;配置代理&#xff09; 附一张成功界面 2.问题复现 3.问题原因和解决方式&#xff1a;下载安装IDEA之后HTTP Proxy没有进行相关配置的问题&#xff0c;解决方式如下 1.首先打开file->setting->Appearance & B…

深入浅出理解kafka存储机制

前言 Kafka 是为了解决大数据的实时日志流而生的, 每天要处理的日志量级在千亿规模。对于日志流的特点主要包括 &#xff1a; 数据实时产生。 海量数据存储与处理。 所以它必然要面临分布式系统遇到的高并发、高可用、高性能等三高问题。 对于 Kafka 的存储需要保证以下几点&a…

《PySpark大数据分析实战》-01.关于数据

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

uni-app应用设置 可以根据手机屏幕旋转进行 (横/竖) 屏切换

首先 我们打开项目的 manifest.json 在左侧导航栏中找到 源码视图 然后找到 app-plus 配置 在下面加上 "orientation": [//竖屏正方向"portrait-primary",//竖屏反方向"portrait-secondary",//横屏正方向"landscape-primary",//横屏…

计算目标检测和语义分割的PR

需求描述 实际工作中&#xff0c;相比于mAP项目更加关心的是特定阈值下的precision和recall结果&#xff1b;由于本次的GT中除了目标框之外还存在多边形标注&#xff0c;为此&#xff0c;计算IoU的方式从框与框之间变成了mask之间&#xff1b; 本文的代码适用于MMDetection下的…

kafka常见问题处理

1. 如何防⽌消息丢失 在生产者层面&#xff0c;我们有个ack参数确认机制 设置成-1&#xff0c;也就是副本全部同步了leader才发送ack&#xff0c;这样确保leader和副本挂掉只剩一个还能 保证消息不丢失 消费者&#xff1a; 把⾃动提交改成⼿动提交 2. 如何防⽌重复消费 在…