iOS專案開發實戰——CoreLocation地理編碼和反地理編碼
地理編碼是把某個具體的位置計算為經緯度,反地理編碼正好相反。這個功能在CoreLocation中如何實現呢?
(1)程式碼如下:
#import "ViewController.h"
#import <MapKit/MapKit.h>
@interface ViewController ()<CLLocationManagerDelegate,MKMapViewDelegate>
@property (nonatomic, strong) MKMapView * mapView;
@property (nonatomic, strong) CLLocationManager * locationManager;
@property (nonatomic, strong) UITextField * textField;
@property (nonatomic, strong) NSString * titleString;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 116.456011,39.941272
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
[_mapView setDelegate:self];
[_mapView setShowsUserLocation:YES];
[_mapView setMapType:MKMapTypeStandard];
[self.view addSubview:_mapView];
UILongPressGestureRecognizer * longpressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];
[_mapView addGestureRecognizer:longpressGestureRecognizer];
_textField = [[UITextField alloc] init];
[_textField setTranslatesAutoresizingMaskIntoConstraints:NO];
[_textField setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:_textField];
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundColor:[UIColor orangeColor]];
[btn setTitle:@"查詢" forState:UIControlStateNormal];
[btn setTranslatesAutoresizingMaskIntoConstraints:NO];
[btn addTarget:self action:@selector(theBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[_textField][btn(100)]-20-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_textField,btn)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[_textField(30)]-(-30)-[btn(30)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_textField,btn)]];
//檢測定位功能是否開啟
if([CLLocationManager locationServicesEnabled]){
if(!_locationManager){
_locationManager = [[CLLocationManager alloc] init];
if([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
[_locationManager requestWhenInUseAuthorization];
[_locationManager requestAlwaysAuthorization];
}
//設定代理
[_locationManager setDelegate:self];
//設定定位精度
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//設定距離篩選
[_locationManager setDistanceFilter:100];
//開始定位
[_locationManager startUpdatingLocation];
//設定開始識別方向
[_locationManager startUpdatingHeading];
}
}else{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:nil
message:@"您沒有開啟定位功能"
delegate:nil
cancelButtonTitle:@"確定"
otherButtonTitles:nil, nil];
[alertView show];
}
}
//點選按鈕執行此方法
- (void)theBtnPressed:(id)sender {
[_textField resignFirstResponder];
if([_textField.text length] == 0){
return;
}
[self geocoder:_textField.text];
}
#pragma mark LongPress
- (void)longPressed:(UILongPressGestureRecognizer *)recognizer {
if(recognizer.state == UIGestureRecognizerStateBegan){
CGPoint point = [recognizer locationInView:_mapView];
CLLocationCoordinate2D coordinate2D = [_mapView convertPoint:point toCoordinateFromView:_mapView];
[_mapView removeAnnotations:_mapView.annotations];
CLLocation * location = [[CLLocation alloc] initWithLatitude:coordinate2D.latitude longitude:coordinate2D.longitude];
[self reverseGeocoder:location];
// MKPointAnnotation * pointAnnotation = [[MKPointAnnotation alloc] init];
// [pointAnnotation setTitle:_titleString];
// [pointAnnotation setCoordinate:coordinate2D];
// [_mapView addAnnotation:pointAnnotation];
}
}
//授權狀態發生改變的時候執行
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
switch(status){
case kCLAuthorizationStatusDenied:
{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:nil
message:@"定位功能沒有開啟" delegate:nil
cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alertView show];
}
break;
default:
break;
}
}
#pragma mark mapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString * key = @"key";
MKPinAnnotationView * pinAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:key];
if(pinAnnotationView == nil){
pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:key];
[pinAnnotationView setCanShowCallout:YES];
}
if([annotation isKindOfClass:[MKUserLocation class]]){
[pinAnnotationView setPinColor:MKPinAnnotationColorRed];
[((MKUserLocation *)annotation) setTitle:_titleString];
}else{
[pinAnnotationView setPinColor:MKPinAnnotationColorPurple];
}
return pinAnnotationView;
}
#pragma mark - CLLocationManangerDelegate
//定位成功以後呼叫
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[_locationManager stopUpdatingLocation];
CLLocation * location = locations.lastObject;
MKCoordinateRegion coordinateRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude), MKCoordinateSpanMake(0.1, 0.1));
[_mapView setRegion:[_mapView regionThatFits:coordinateRegion] animated:YES];
// [self reverseGeocoder:location];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"error:%@",error);
}
#pragma mark Geocoder
//反地理編碼
- (void)reverseGeocoder:(CLLocation *)currentLocation {
CLGeocoder * geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if(error || placemarks.count == 0){
NSLog(@"error");
}else{
CLPlacemark * placemark = placemarks.firstObject;
self.titleString = placemark.name;
MKPointAnnotation * pointAnnotation = [[MKPointAnnotation alloc] init];
[pointAnnotation setTitle:placemark.name];
[pointAnnotation setCoordinate:CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude)];
[_mapView addAnnotation:pointAnnotation];
NSLog(@"placemark:%@",[[placemark addressDictionary] objectForKey:@"City"]);
}
}];
}
//地理編碼
- (void)geocoder:(NSString *)str {
CLGeocoder * geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:str completionHandler:^(NSArray *placemarks, NSError *error) {
if(error || placemarks.count == 0){
NSLog(@"error");
}else{
CLPlacemark * placemark = placemarks.firstObject;
MKCoordinateRegion coordinateRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude), MKCoordinateSpanMake(0.1, 0.1));
[_mapView setRegion:[_mapView regionThatFits:coordinateRegion] animated:YES];
MKPointAnnotation * pointAnnotation = [[MKPointAnnotation alloc] init];
[pointAnnotation setTitle:placemark.name];
[pointAnnotation setCoordinate:CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude)];
[_mapView addAnnotation:pointAnnotation];
}
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
(2)實現效果如下:
。
(3)通過輸入框的搜尋,也能定位到具體的位置。長按地圖,就能獲得某個位置的詳細地址。應該說非常方便。
github主頁:https://github.com/chenyufeng1991 。歡迎大家訪問!
相關文章
- iOS - GeoCoder 地理編碼iOS
- tableau自定義地理編碼
- iOS專案開發實戰——使用CoreLocation實現定位iOS
- iOS專案開發實戰——使用CoreLocation獲取當前位置資訊iOS
- 【搬磚筆記】 利用GeoHash為地理位置編碼筆記
- IDEA如何設定編碼格式,字元編碼,全域性編碼和專案編碼格式Idea字元
- iOS開發——OC編碼規範iOS
- 【iOS】iOS開發編碼規範小結iOS
- [混編] iOS原生專案- iOS/flutter 程式碼互動iOSFlutter
- iOS專案開發實戰——使用程式碼實現頁面跳轉iOS
- 微信小程式“反編譯”實戰(二):原始碼還原微信小程式編譯原始碼
- ElasticSearch實戰-編碼實踐Elasticsearch
- iOS專案開發實戰——使用程式碼獲取螢幕寬高iOS
- 使用Reflector和Filedisassembler逆向編譯反編譯.cs.dll檔案程式碼編譯
- 靶場專案編寫實戰
- Android反編譯和程式碼混淆Android編譯
- ReactNative專案實踐編碼規範React
- Swift-定位,編碼/反編碼功能的封裝Swift封裝
- iOS專案開發實戰——使用同步請求獲取網頁原始碼iOS網頁原始碼
- iOS專案開發實戰——網頁原始碼實現二進位制和HTML的轉換iOS網頁原始碼HTML
- Kotlin實戰:用實戰程式碼更深入地理解預定義擴充套件函式Kotlin套件函式
- Hadoop專案實戰-使用者行為分析之編碼實踐Hadoop
- 編碼風格和開發習慣
- Swift原始碼專案編譯Swift原始碼編譯
- Linux下檢視檔案編碼,檔案編碼格式轉換和檔名編碼Linux
- iOS專案開發實戰——iOS網路程式設計獲取網頁Html原始碼iOS程式設計網頁HTML原始碼
- Android開發:APK的反編譯(獲取程式碼和資原始檔)AndroidAPK編譯
- kubebuilder實戰之五:operator編碼UI
- iOS專案開發實戰——理解frame,bounds,centeriOS
- iOS專案開發實戰——檢視動畫效果iOS動畫
- iOS專案開發實戰——配置自定義動畫iOS動畫
- iOS專案開發實戰——plist陣列解析iOS陣列
- iOS Emoji表情編碼/解碼iOS
- iOS文字檔案的編碼檢測iOS
- 反編譯 iOS APP編譯iOSAPP
- 音訊編解碼·實戰篇(1)WAV轉至AAC(AAC編碼)音訊
- 音訊編解碼·實戰篇(1)PCM轉至AAC(AAC編碼)音訊
- iOS專案開發實戰——使用非同步請求獲取網頁HTML原始碼iOS非同步網頁HTML原始碼