【iOS乾貨】☞ 定位

来源:http://www.cnblogs.com/bossren/archive/2017/05/27/6912041.html
-Advertisement-
Play Games

一、簡介 1. 定位的實際應用場景: 導航:去任意陌生的地方 周邊:找餐館、找酒店、找銀行、找電影院等 2. 涉及技術: Core Location 框架:用於地理定位。(單純的定位,不需要顯示地圖) 常用類:以CL首碼開頭 CLLocation:(結構體類型)經緯度 CLLocationManag ...


一、簡介

1. 定位的實際應用場景:

  • 導航:去任意陌生的地方
  • 周邊:找餐館、找酒店、找銀行、找電影院等

2. 涉及技術:

  • Core Location 框架用於地理定位。(單純的定位,不需要顯示地圖)

常用類:以CL首碼開頭

CLLocation:(結構體類型)經緯度

CLLocationManager:  定位管理類,位置管理器,全局唯一存在,做定位用。 

CLLocationManagerDelegate:  監聽用戶是否願意定位(iOS8後要問),監聽用戶的位置(經緯度)

  • Map Kit 框架用於地圖展示。(和地圖結合的定位,如:百度地圖、高德地圖等)

常用類:以MK首碼開頭

MKMapView: 顯示地圖視圖

MKMapViewDelegate: 地圖視圖的協議(定位;地圖視圖移動;定位用戶的位置)

3. 專業術語:

  • LBS:Location Based Service,基於位置的服務。(如,打車:基於位置提供了叫車服務。)
  • SoLoMo:Social Local Mobile(索羅門),社交本地移動。(如,陌陌、微信、QQ)

4. iOS定位的方式:(按定位準確性排名)

  • GPS(Global Positioning System,全球衛星定位系統)定位
  • 移動基站/蜂窩/流量
  • wifi定位

二、CoreLocation框架的使用

1. 導入框架:CoreLocation.framework

2. 導入頭文件:#import <CoreLocation/CoreLocation.h>

3. CLLocationManager的常用操作:

  • 開始用戶定位:- (void)startUpdatingLocation;
  • 停止用戶定位:- (void)stopUpdatingLocation;
  • 當調用了startUpdatingLocation方法後,就開始不斷地定位用戶的位置,中途會頻繁地調用代理的下麵方法:

#pragma mark - CLLocationManagerDelegate 實現協議中的方法

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

 4. 定位用戶的位置:

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h> // 導入頭文件    
@interface ViewController () <CLLocationManagerDelegate>
// 聲明一個屬性幫助我們來定位,乾什麼都要問他
@property (nonatomic, strong) CLLocationManager *manager;
@end

@implementation ViewController
#pragma mark ---懶載入
-(CLLocationManager *)manager {
    if (_manager==nil) {
        // 1.創建位置管理器(定位用戶的位置)
        self.manager=[[CLLocationManager alloc]init];
        // 2.設置代理(設置誰來監聽用戶的位置)
        self.manager.delegate=self;
    }
    return _manager;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // 請求用戶授權
    // iOS8之後才開始征求用戶同意,iOS8之前不用征求同意直接定位
    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
  // 註意:iOS8之後要配置info.plist文件:添加key(NSLocationAlwaysUsageDescription / NSLocationWhenInUseUsageDescription),才能彈出授權框
     // 兩種授權:始終(永久)授權、使用應用期間授權。
     // 註意:如果同時寫了下麵兩種授權,程式打開的時候會出現兩次授權提示。大多數情況下,我們根據程式的需求寫一種授權方式就可以了。        
//1) 永久授權。無論當前程式在前臺或後臺都授權/都定位 (key:NSLocationAlwaysUsageDescription)         //[self.manager requestAlwaysAuthorization]; //請求總是授權         //2) 當用戶正在使用的時候授權。只有程式在前臺運行的時候才會授權(征求用戶是否願意只在前臺定位) (key:NSLocationWhenInUseUsageDescription)         [self.manager requestWhenInUseAuthorization]; //請求在使用時的授權(在前臺),大多數APP使用的是這種授權              } else {         // 調用開始定位方法。直接定位(不需要征求用戶同意) 定位裡面乾什麼都要問manager         [self.manager startUpdatingLocation];//開始定位     } } #pragma mark - CLLocationManagerDelegate 實現協議中的方法 //1.查看用戶是否同意(這個方法監聽用戶有沒有點允許/不允許),用戶同意了就調用第二個方法 /**  *  @param status  用戶授權的狀態 (用戶是否同意)  *  常用的兩個狀態:  *   1) kCLAuthorizationStatusDenied:用戶不同意定位  *      用戶不允許自動定位時,可以手動選擇城市定位(如:墨跡天氣,用戶手動選擇一個城市,把城市的天氣推送給你)  *   2) kCLAuthorizationStatusAuthorizedWhenInUse:用戶允許在使用期間(前臺)定位  */ -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {     //判斷兩種常用的授權狀態     switch (status) {         case kCLAuthorizationStatusAuthorizedWhenInUse: //用戶允許在使用期間(前臺)定位
     // 實現持續定位,通常要做一些優化(目的是節省電量和流量)。
      // 1. 設置距離篩選器,當用戶位置發生一定改變之後再調用代理方法2(避免調用太頻繁)。
       // 當用戶位置發生超過10米的變化,再重新開始定位(即調用代理方法2)
       
self.manger.distanceFilter = 10;             // 2. 設置定位的精準度(常量值:kXXXBest最好的、十米範圍內、百米範圍內、千米範圍內、三千米範圍內)             // 我們可以降低定位的精準度,實際上降低了與衛星之間的計算,以此節省電量和流量。精確度越高越費電量/流量,一般選十米範圍內。             self.manager.desiredAccuracy = kCLLocationAccuracyBest;//定位的精確度             [self.manager startUpdatingLocation]; //開始定位操作             break;         case kCLAuthorizationStatusDenied: //用戶不允許定位(第二種方案)             NSLog(@"用戶不允許定位!");             break;         default:             break;     } } //2.已經定位到用戶的位置會調用這個方法 /**  *  當完成位置更新的時候調用。當定位到用戶的位置時,就會調用(調用的頻率比較頻繁)  *  @param locations 用戶的位置(數組類型,最後一項是用戶最新的位置;數組裡至少有一項)  */ -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {     CLLocation *location=[locations lastObject];//獲取用戶最新的位置     NSLog(@"緯度:%f, 經度:%f", location.coordinate.latitude, location.coordinate.longitude); //列印獲取用戶位置的經緯度     // 停止用戶定位/停止更新位置(不停止,就會一直不停的定位,即持續定位;停止後該代理方法就不會再頻繁調用,即一次定位)     [self.manager stopUpdatingLocation];     // Xcode7以下只定位一次(列印經緯度一次),Xcode7以上會定位三次(列印經緯度三次) } @end

 5. 計算兩點之間的直線距離

// 比較兩個位置之間的距離(如,北京與西安的距離)
CLLocation *location1 = [[CLLocation alloc]initWithLatitude:40 longitude:116];
CLLocation *location2 = [[CLLocation alloc]initWithLatitude:34.27 longitude:108.93];
// 比較直線距離
CLLocationDistance distance = [location1 distanceFromLocation:location2];
NSLog(@"北京與西安的直線距離為:%f千米", distance / 1000);

三、地理編碼/反地理編碼

  • 地理編碼:將地名 轉換成 經緯度的過程。

    給定一個地址名(城市/街道/省名字)  —> CLGeocoder  —> 返回地址名所在的位置(經緯度)

  • 反地理編碼 (使用頻率高):將經緯度 轉換成 地名的過程。

    給定一個經緯度  —> CLGeocoder —> 返回該經緯度的詳細信息(國家/省/城市/街道/店鋪)

// 1. 創建一個CLGeocoder對象
CLGeocoder *geocoder = [CLGeocoder alloc] init];
// 2. 開始地理編碼
/**
 *  說明:調用下麵的方法開始編碼,不管編碼是成功還是失敗都會調用block中的方法
 *  給一個地名,返回一個block回調參數
 *  @param placemarks 地標數組,主要的是CLLocation / 城市屬性
 */
[geocoder geocodeAddressString:@"下沙" completionHandler:^(NSArray *placemarks, NSError *error) {
    //1)如果有錯誤信息,或者是數組中獲取的地名元素數量為0,那麼說明沒有找到
    if (placemarks.count == 0 || error) {
        NSLog(@"你輸入的地址沒找到,可能在火星上");
    } else {
        //2)編碼成功,找到了具體的位置信息
        /**
         *  遍歷地表數組:
         *  這裡數組中有一個/多個相關的位置信息對象(給一個名稱,可能對應多個位置信息)
         */
        for (CLPlacemark *placemark in placemarks) {
         // 列印查看找到的所有的位置信息
            NSLog(@"詳細地址名稱:%@", placemark.name);
            NSLog(@"經緯度坐標:%.4f, %.4f" , placemark.location.coordinate.longitude, placemark.location.coordinate.latitude);
        }
        // 取得第一個地標,地標中存儲了詳細的地址信息,註意:一個地名可能搜索出多個地址
        CLPlacemark *placemark = [placemarks firstObject];
        //1>詳細地址名稱
        NSLog(@"詳細地址名稱:%@", placemark.name);
        //2>經緯度
        NSLog(@"經緯度坐標:%.4f, %.4f" , placemark.location.coordinate.longitude, placemark.location.coordinate.latitude);
    }
}];

// 1. 設置經緯度 CLLocation *location = [[CLLocation alloc]initWithLatitude:40 longitude:116]; // 2.開始反地理編碼 [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { // 1)如果有錯誤信息,或者是數組中獲取的地名元素數量為0,那麼說明沒有找到 if (placemarks.count == 0 || error) { NSLog(@"你輸入的地址沒找到,可能在火星上"); } else { //2)編碼成功 //這裡不用for迴圈遍歷,因為數組中只有唯一的一個對象(經緯度一定,地名也一定),直接取出即可 CLPlacemark *placemark = [placemarks firstObject]; self.reverseDetailAddressLabel.text = placemark.name; NSLog(@"詳細地址名稱:%@", placemark.addressDictionary[@"FormattedAddressLines"]); } }];

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • css基礎 1、 Css新建格式 Css語法: 選擇符{屬性名稱:屬性值;} 1、內部樣式表(嵌套到頁面中) 語法: <style type="text/css"> css語句 </style> 註:使用style標記創建樣式時,最好將該標記寫在<head></head>; 2、內聯樣式(行間樣式, ...
  • 一、寫在前面的話   Node.js是一個開放源代碼、跨平臺的JavaScript語言運行環境,採用Google開發的V8運行代碼,使用事件驅動、非阻塞和非同步輸入輸出模型等技術來提高性能,可優化應用程式的傳輸量和規模。這些技術通常用於數據密集的事實應用程式。—— "來自維基百科" ...
  • 課程2B的內容主要包括:使用變數來更新欲顯示在屏幕上的內容,為按鈕添加事件響應(聯繫XML屬性與Java方法)邏輯等。 ...
  • android-support-v4.jar 是谷歌提供給我們的一個相容低版本安卓設備的軟體包,裡面包囊了只有在 Android 3.0 以上可用的API。而 ViewPager 就是其中之一。利用它,我們可以做很多事情,從最簡單的導航,到頁面菜單等等。 準備 在使用ViewPager之前,需要在 ...
  • Big Nerd Ranch是美國一家專業的移動開發技術培訓機構。本書主要以其Android訓練營教學課程為基礎,融合了幾位作者多年的心得體會,是一本完全面向實戰的Android編程指南。全書共34章,詳細介紹了8個Android 應用。通過這些精心設計的應用,讀者可掌握很多重要的理論知識和開發技巧 ...
  • 最近在做iOS系統通訊錄備份到伺服器,並且可以從伺服器中下載備份文件恢復到手機的功能,部分實現細節記錄如下。 將iphone系統通訊錄生成.vcf文件 運行後系統沙盒Document目錄下會生成contacts.vcf文件,上傳至伺服器即可。 通訊錄恢復: 從伺服器下載contents.vcf文件, ...
  • 用as開發過程中遇見問題app閃退 log如下圖: 解決: File—Settings: 點擊Apply—OK重新運行即可 ...
  • Shader學習筆記 例子: Mesh Filter : 存儲一個Mesh(網格,模型的網格,就是模型的由哪些三角面組成,組成一個什麼樣子的模型,三角面的一些頂點信息) Mesh Renderer:用來渲染一個模型的外觀,就是樣子, 按照 mesh給它皮膚,給它顏色 通過Material(材質)控制 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...