Storing high precision latitude/longitude numbers

2020-03-15 05:51发布

问题:

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}

回答1:

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.


回答2:

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).



回答3:

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.



回答4:

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.



回答5:

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.



回答6:

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).



回答7:

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.