Storing high precision latitude/longitude numbers in iOS Core Data
I'm trying to store Latitude/Longitudes in core data. These end up being anywhere from 6-20 digit precision.
And for whatever reason, i had them as floats in Core Data, its rounding them and not giving me the exact values back. I开发者_高级运维 tried "decimal" type, with no luck either.
Are NSStrings my only other option?
EDIT
NSManagedObject:
@interface Event : NSManagedObject
{
}
@property (nonatomic, retain) NSDecimalNumber * dec;
@property (nonatomic, retain) NSDate * timeStamp;
@property (nonatomic, retain) NSNumber * flo;
@property (nonatomic, retain) NSNumber * doub;
Here's the code for a sample number that I store into core data:
NSNumber *n = [NSDecimalNumber decimalNumberWithString:@"-97.12345678901234567890123456789"];
The above value printed. Sweet, value I expected:
Printing description of n:
-97.12345678901234567890123456789
Code to access it again:
NSNumber *n = [managedObject valueForKey:@"dec"];
NSNumber *f = [managedObject valueForKey:@"flo"];
NSNumber *d = [managedObject valueForKey:@"doub"];
Printed values:
Printing description of n:
-97.1234567890124
Printing description of f:
<CFNumber 0x603f250 [0xfef3e0]>{value = -97.12345678901235146441, type = kCFNumberFloat64Type}
Printing description of d:
<CFNumber 0x6040310 [0xfef3e0]>{value = -97.12345678901235146441, type = kCFNumberFloat64Type}
Have you used the NSNumber wrapper?
Configure your store to use NSNumber, instead of float or decimal, and use this to save the coordinates:
[NSNumber numberWithDouble:coordinate.latitude]
//Same for longitude.
Try using the Double data type in Core Data. Since your location coordinates are doubles, makes sense to use the same in Core Data. Though that may be available just now (iOS 5).
When Core Data stores data in SQLite, it uses numeric columns. SQLite stores numbers as--at most--8-byte values, whether integer or floating-point. So, while an NSDecimalNumber
would be quite happy to accurately represent these coordinate values, round-tripping them through a Core Data decimal attribute backed by SQLite will munge them.
since coordinate ranges are well-defined, you can add a few digits of accuracy (compared to double) by using a 64 bit int representation (or even multiple).
in reality, your sources and targets may not make use of or provide this much accuracy so... there may not be much to gain.
I believe the truncation problem could be on the logging, not on the actual data stored in Core Data.
Can you confirm by posting the code you are using to log the output?
I say this because I've noticed that when logging some of my longer NSString fields, Core Data description will only display ~50 characters or so, which might lead you to think it is truncating the data, but it's actually just truncating the description of it.
In your data model editor, make sure the types for your lat/long fields are set to double
. Otherwise CoreData will do the conversion for you, and the result will be not what you expect (in this case, the decimals will get dropped).
strongly recommend use NSDecialNumber for storing if you need precise value or compare in your code. you might have different value after store and get value back from core data in double fields.
精彩评论