地图坐标不解码

Posted

技术标签:

【中文标题】地图坐标不解码【英文标题】:Map coordinates not decoding 【发布时间】:2013-01-12 02:41:10 【问题描述】:

在我的应用程序中,我试图保存地图上的图钉,以便用户在应用程序终止后打开应用程序时它们就在那里。我已经使我的 mkAnnotation 类符合 NSCoding,并实现了两个必需的方法。注释都存储在单例类的 NSMutableArray 中,所以我真的只是想将数组保存在单例类中。一切都被很好地编码,但我认为它们没有被解码。这是一些代码: 这是我的 MKAnnotation 类:

#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface MapPoint : NSObject <MKAnnotation, NSCoding>



- (id)initWithAddress:(NSString*)address
        coordinate:(CLLocationCoordinate2D)coordinate
                title:(NSString *)t;

@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;

//This is an optional property from MKAnnotataion
@property (nonatomic, copy) NSString *title;
@property (nonatomic, readonly, copy) NSString *subtitle;
@property (nonatomic) BOOL animatesDrop;
@property (nonatomic) BOOL canShowCallout;

@property (copy) NSString *address;
@property (nonatomic, copy) NSString *imageKey;
@property (nonatomic, copy) UIImage *image;

@end 

@implementation MapPoint

@synthesize title, subtitle, animatesDrop, canShowCallout, imageKey, image;
@synthesize address = _address, coordinate = _coordinate;

-(id)initWithAddress:(NSString *)address
       coordinate:(CLLocationCoordinate2D)coordinate
            title:(NSString *)t 
    self = [super init];

    if (self) 
        _address = [address copy];
        _coordinate = coordinate;

        [self setTitle:t];

        NSDate *theDate = [NSDate date];

        subtitle = [NSDateFormatter localizedStringFromDate:theDate
                                                  dateStyle:NSDateFormatterShortStyle
                                                  timeStyle:NSDateFormatterShortStyle];
    
    return self;


- (void)encodeWithCoder:(NSCoder *)aCoder 

    [aCoder encodeObject:_address forKey:@"address"];

    NSLog(@"ENCODING coordLatitude %f coordLongitude %f ", _coordinate.latitude, _coordinate.longitude);
    [aCoder encodeDouble:_coordinate.longitude forKey:@"coordinate.longitude"];
    [aCoder encodeDouble:_coordinate.latitude forKey:@"coordinate.latitude"];

    [aCoder encodeObject:title forKey:@"title"];


- (id)initWithCoder:(NSCoder *)aDecoder 
    self = [super init];
    if (self) 
        [self setAddress:[aDecoder decodeObjectForKey:@"address"]];

        NSLog(@"DECODING coordLatitude %f coordLongitude %f ", _coordinate.latitude, _coordinate.longitude);
        _coordinate.longitude = [aDecoder decodeDoubleForKey:@"coordinate.longitude"];
        _coordinate.latitude = [aDecoder decodeDoubleForKey:@"coordinate.latitude"];

        [self setTitle:[aDecoder decodeObjectForKey:@"title"]];
    
    return self;


@end

这是我的单例类:

#import <Foundation/Foundation.h>
@class MapPoint;

@interface Data : NSObject

NSMutableArray *_annotations;


@property (retain, nonatomic) NSMutableArray *annotations;

+ (Data *)singleton;
- (NSString *)pinArchivePath;
- (BOOL)saveChanges;

@end

@implementation Data

@synthesize annotations = _annotations;

+ (Data *)singleton 
    static dispatch_once_t pred;
    static Data *shared = nil;
    dispatch_once(&pred, ^
        shared = [[Data alloc] init];
        shared.annotations = [[NSMutableArray alloc]init];
    );
    return shared;


- (id)init 
    self = [super init];
    if (self) 
        NSString *path = [self pinArchivePath];
        _annotations = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
        if (!_annotations) 
            _annotations = [[NSMutableArray alloc]init];
        
    
    return self;


- (NSString *)pinArchivePath 
    NSArray *cachesDirectories = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);

    NSString *cachesDirectory = [cachesDirectories objectAtIndex:0];

    return [cachesDirectory stringByAppendingPathComponent:@"pins.archive"];


- (BOOL)saveChanges 
    NSString *path = [self pinArchivePath];

    return [NSKeyedArchiver archiveRootObject:[Data singleton].annotations
                                       toFile:path];


@end

在地图视图控制器上的 viewDidLoad 方法中,我尝试将注释放置在地图上的单例数组中:

for (MapPoint *mp in [Data singleton].annotations) 
        [_worldView addAnnotation:mp];

【问题讨论】:

在解码的地方,尝试将 NSLog 放在解码行之后。 好的,但是当我重新打开应用程序时,图钉没有显示在地图上。 【参考方案1】:

主要问题在于singleton 方法中的这些行:

dispatch_once(&pred, ^
    shared = [[Data alloc] init];
    shared.annotations = [[NSMutableArray alloc]init]; //<-- problem line
);

shared = [[Data alloc] init]; 行解码并初始化 annotations 数组。

然后shared.annotations = [[NSMutableArray alloc]init]; 行重新创建并重新初始化annotations 数组从而丢弃刚刚解码的注释,因此单例总是返回一个空数组。

删除shared.annotations = [[NSMutableArray alloc]init]; 行。 正如评论中已经提到的,另一个导致简单混淆的小问题是NSLog 的位置,坐标正在被解码。 NSLog 应该在解码完成之后

【讨论】:

以上是关于地图坐标不解码的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序--百度地图坐标转换成腾讯地图坐标

谈谈地图坐标系

安卓 百度地图API怎么点击地图获取坐标

Android 百度地图API 如何计算两个坐标之间的驾车距离?

高德地图腾讯地图谷歌中国区地图与百度地图坐标系

嗯那个嗯地图上的坐标一般都画在地图的啥位置