一、地理编码和反地理编码
地理编码:把地址转为经纬度
反地理编码:把经纬度转为地址

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <AddressBook/AddressBook.h>
@interface ViewController ()
// 地址详情TextView
@property (weak, nonatomic) IBOutlet UITextView *addressDetailTV;
// 纬度TextField
@property (weak, nonatomic) IBOutlet UITextField *latitudeTF;
// 经度度TextField
@property (weak, nonatomic) IBOutlet UITextField *longtitudeTF;
// 用作地理编码、反地理编码的工具类
@property (nonatomic, strong) CLGeocoder *geoC;
@end
@implementation ViewController
#pragma mark - 懒加载
-(CLGeocoder *)geoC
{
if (!_geoC) {
_geoC = [[CLGeocoder alloc] init];
}
return _geoC;
}
// 地理编码
- (IBAction)geoCoder {
if ([self.addressDetailTV.text length] == 0) {
return;
}
// 地理编码方案一:直接根据地址进行地理编码(返回结果可能有多个,因为一个地点有重名)
// [self.geoC geocodeAddressString:self.addressDetailTV.text completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
// // 包含区,街道等信息的地标对象
// CLPlacemark *placemark = [placemarks firstObject];
// // 城市名称
// NSString *city = placemark.locality;
// // 街道名称
// NSString *street = placemark.thoroughfare;
// // 全称
// NSString *name = placemark.name;
// NSLog(@"city:%@,street:%@,name:%@",city,street,name);
//// self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name];
// self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
// self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
// }];
// 地理编码方案二:根据地址和区域两个条件进行地理编码(更加精确)
// [self.geoC geocodeAddressString:self.addressDetailTV.text inRegion:nil completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
// // 包含区,街道等信息的地标对象
// CLPlacemark *placemark = [placemarks firstObject];
//// self.addressDetailTV.text = placemark.description;
// NSLog(@"placemark:%@",placemark.description);
// self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
// self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
// }];
// 地理编码方案三:
NSDictionary *addressDic = @{
(__bridge NSString *)kABPersonAddressCityKey : @"北京",
(__bridge NSString *)kABPersonAddressStreetKey : @"棠下街"
};
[self.geoC geocodeAddressDictionary:addressDic completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
CLPlacemark *placemark = [placemarks firstObject];
// self.addressDetailTV.text = placemark.description;
NSLog(@"placemark:%@",placemark.description);
self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
}];
}
// 反地理编码
- (IBAction)decode {
// 过滤空数据
if ([self.latitudeTF.text length] == 0 || [self.longtitudeTF.text length] == 0) {
return;
}
// 创建CLLocation对象
CLLocation *location = [[CLLocation alloc] initWithLatitude:[self.latitudeTF.text doubleValue] longitude:[self.longtitudeTF.text doubleValue]];
// 根据CLLocation对象进行反地理编码
[self.geoC reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
// 包含区,街道等信息的地标对象
CLPlacemark *placemark = [placemarks firstObject];
// 城市名称
// NSString *city = placemark.locality;
// 街道名称
// NSString *street = placemark.thoroughfare;
// 全称
NSString *name = placemark.name;
self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name];
}];
}
@end
二、获取当前城市名称(定位+反地理编码)
import UIKit
import CoreLocation
class ViewController: UIViewController {
lazy var locationM: CLLocationManager = {
let locationM: CLLocationManager = CLLocationManager()
locationM.delegate = self
return locationM
}()
//地理编码
lazy var geoCoder: CLGeocoder = {
return CLGeocoder()
}()
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
//请求授权
locationM.requestAlwaysAuthorization()
//1.定位
if CLLocationManager.locationServicesEnabled() {
locationM.startUpdatingLocation()
}
}
}
extension ViewController: CLLocationManagerDelegate {
//更新位置信息时调用
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let lastLocation = locations.last else {
return
}
if lastLocation.horizontalAccuracy < 0 {
return
}
//在这里获取到位置信息,进行反地理编码(广州市:23.125178,113.280637)
geoCoder.reverseGeocodeLocation(lastLocation) {
(placemark: [CLPlacemark]?, error: Error?) in
if error == nil{
let place = placemark?.last
print(place?.locality ?? "")
//停止获取位置信息
self.locationM.stopUpdatingLocation()
}
}
}
}
三、使用第三方框架进行定位
(INTULocationManager框架)
注意:

代码如下:
import UIKit
class ViewController: UIViewController {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// subscribeLocation()
// requestLocation()
}
}
func subscribeLocation() {
let logMgr: INTULocationManager = INTULocationManager.sharedInstance()
logMgr.subscribeToLocationUpdates(withDesiredAccuracy: .city) { (loc:CLLocation?, accuracy: INTULocationAccuracy, status: INTULocationStatus) in
if status == INTULocationStatus.success{
print("定位成功location:\(String(describing: loc))")
}else{
print("定位失败")
}
}
}
func requestLocation() {
let logMgr: INTULocationManager = INTULocationManager.sharedInstance()
//delayUntilAuthorized: 确定超时时间从什么时候开始计算
//true: 代表从用户授权过后开始计算超时时间
//false: 代表从执行这行代码开始计算
let requestID: INTULocationRequestID = logMgr.requestLocation(withDesiredAccuracy: .city, timeout: 10.0, delayUntilAuthorized: true) { (loc:CLLocation?, accuracy: INTULocationAccuracy, status: INTULocationStatus) in
if status == INTULocationStatus.success{
print("定位成功location:\(String(describing: loc))")
}else{
print("定位失败\(String(describing: status.rawValue))")
}
}
//强制完成
// logMgr.forceCompleteLocationRequest(requestID)
//取消定位请求
// logMgr.cancelHeadingRequest(requestID)
}
网友评论