zoukankan      html  css  js  c++  java
  • LocationCoder 地图经纬度解析

    LocationCoder 地图经纬度解析

    其实,在地图里面将地图解析成有意义的地址,或者把地址转换成有意义的经纬度都是很容易的事情,只是我将其封装了支持KVO,通知中心,block取结果,代理取结果而已.

    能通过组合的方式来封装对象扩展功能就绝对不会用继承的方式来扩展功能,只有当组合解决不了问题时才会使用继承:).

    源码:

    LocationCoder.h + LocationCoder.m

    //
    //  LocationCoder.h
    //
    //  http://home.cnblogs.com/u/YouXianMing/
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import <MapKit/MapKit.h>
    @class LocationCoder;
    
    #pragma mark - block
    typedef void(^resultBlock_t)(NSArray *placemarks, NSError *error, LocationCoder *locationCoder);
    
    #pragma mark - 代理
    @protocol LocationCoderDelegate <NSObject>
    @optional
    - (void)resultForPlacemarks:(NSArray *)placemarks
                          error:(NSError *)error
                  locationCoder:(LocationCoder *)locationCoder;
    @end
    
    
    @interface LocationCoder : NSObject
    
    // 初始化时设定的值
    @property (nonatomic, strong, readwrite) CLLocation    *location;            // 经纬度地址
    @property (nonatomic, strong, readwrite) NSString      *addressString;       // 文字描述地址
    
    // block方式取结果
    @property (nonatomic, copy)              resultBlock_t  resultBlock;         // 结果的block
    
    // 代理方式取结果
    @property (nonatomic, assign)            id<LocationCoderDelegate> delegate; // 结果代理
    
    // KVO方式取结果
    @property (nonatomic, strong, readonly)  NSString      *changeFlag;          // 用于KVO
    @property (nonatomic, strong, readonly)  NSArray       *placemarks;          // 结果
    
    // 单个的结果
    @property (nonatomic, assign, readonly)  CLLocationCoordinate2D  coordinate2D;      // 经纬度
    @property (nonatomic, strong, readonly)  NSString               *addressLines;      // 完整的地址
    @property (nonatomic, strong, readonly)  NSDictionary           *addressDictionary; // 地址字典
    
    // 初始化
    - (instancetype)initWithLocation:(CLLocation *)location;
    - (instancetype)initWithAddressString:(NSString *)string;
    
    // 开始分析
    - (void)startAnalyseLocation;       // 分析经纬度地址
    - (void)startAnalyseAddressString;  // 分析文字描述地址
    
    @end
    //
    //  LocationCoder.m
    //
    //  http://home.cnblogs.com/u/YouXianMing/
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "LocationCoder.h"
    
    @interface LocationCoder ()
    
    @property (nonatomic, strong) CLGeocoder *geocoder;     // 解析器
    @property (nonatomic, strong) NSArray    *placemarks;
    @property (nonatomic, strong) NSString   *changeFlag;   // 用于KVO
    
    @property (nonatomic, strong) NSString                *addressLines;      // 完整的地址
    @property (nonatomic, assign) CLLocationCoordinate2D   coordinate2D;      // 经纬度
    @property (nonatomic, strong) NSDictionary            *addressDictionary; // 地址字典
    
    @end
    
    @implementation LocationCoder
    
    - (instancetype)init
    {
        return [self initWithLocation:nil];
    }
    
    - (instancetype)initWithLocation:(CLLocation *)location
    {
        self = [super init];
        if (self)
        {
            _location   = location;
            _geocoder   = [[CLGeocoder alloc] init];
            _changeFlag = @"YES";
        }
        
        return self;
    }
    
    - (instancetype)initWithAddressString:(NSString *)string
    {
        self = [super init];
        if (self)
        {
            _addressString = string;
            _geocoder      = [[CLGeocoder alloc] init];
            _changeFlag    = @"YES";
        }
        
        return self;
    }
    
    - (void)startAnalyseLocation
    {
        if (_location)
        {
            [_geocoder reverseGeocodeLocation:_location
                            completionHandler:^(NSArray *placemarks, NSError *error)
             {
                 // KVO(只有使用了setter方法才能够通知KVO)
                 if (error == nil)
                 {
                     self.placemarks = placemarks;
                     
                     CLPlacemark *placemark = [placemarks objectAtIndex:0];
                     
                     // 获取地址字典
                     self.addressDictionary = placemark.addressDictionary;
                     
                     // 获取详细地址
                     self.addressLines = 
                     [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
                     
                     // 获取2D坐标信息
                     self.coordinate2D = placemark.location.coordinate;
                     
                     // 通知KVO
                     self.changeFlag = @"RIGHT DATA";
                 }
                 else
                 {
                     self.placemarks = nil;
                     self.changeFlag = @"ERROR DATA";
                 }
                 
                 // block
                 if (_resultBlock)
                 {
                     _resultBlock(placemarks, error, self);
                 }
                 
                 // 代理
                 if (_delegate)
                 {
                     [_delegate resultForPlacemarks:placemarks
                                              error:error
                                      locationCoder:self];
                 }
             }];
        }
    }
    
    - (void)startAnalyseAddressString
    {
        if (_addressString)
        {
            [_geocoder geocodeAddressString:_addressString
                          completionHandler:^(NSArray *placemarks, NSError *error) {
                              // KVO(只有使用了setter方法才能够通知KVO)
                              if (error == nil)
                              {
                                  self.placemarks = placemarks;
                                  
                                  CLPlacemark *placemark = [placemarks objectAtIndex:0];
                                  
                                  // 获取地址字典
                                  self.addressDictionary = placemark.addressDictionary;
                                  
                                  // 获取详细地址
                                  self.addressLines = 
                                  [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
                                  
                                  // 获取2D坐标信息
                                  self.coordinate2D = placemark.location.coordinate;
                                  
                                  // 通知KVO
                                  self.changeFlag = @"RIGHT DATA";
                              }
                              else
                              {
                                  self.placemarks = nil;
                                  self.changeFlag = @"ERROR DATA";
                              }
                              
                              // block
                              if (_resultBlock)
                              {
                                  _resultBlock(placemarks, error, self);
                              }
                              
                              // 代理
                              if (_delegate)
                              {
                                  [_delegate resultForPlacemarks:placemarks
                                                           error:error
                                                   locationCoder:self];
                              }
                          }];
        }
    }
    
    @end

    block方式解析地址

    代理方式解析地址

    KVO方式解析

    2014-05-26 08:57:29.808 MoreMapInfo[5911:60b] latitude = 39.906031

    KVO都能写,通知中心就不用说了:).

    试试将经纬度解析成地址信息-

    看看是什么地方....

    其实,本人写的经纬度地址是"中国国家博物馆",囧......

  • 相关阅读:
    不同进程间消息互发
    不同进程间消息互发
    div滤镜结合ajax,实现登录
    网页自适应不同浏览器和分辨率[转]
    DIV样式汇总
    用CSS中的Alpha实现渐变
    JavaScript中的null和undefined
    CSS教程:div垂直居中的N种方法[转]
    浏览器不兼容原因及解决办法
    JavaScript验证时间格式
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3752372.html
Copyright © 2011-2022 走看看