2010-09-26 16 views
32

Sto tentando di salvare una posizione e recuperare la posizione su una mappa dopo aver utilizzato Core Location, MapKit e Core Data frameworks.Come memorizzare CLLocation utilizzando Core Data (iPhone)?

Quello che ho fatto è che ho appena creato un'entità chiamata POI e ho aggiunto proprietà come latitudine (tipo doppio), longitudine (tipo doppio) con poche altre.

In poche parole, la mia app salva POI con due NSNumbers. (lat e long), ma mi sembra che ci debba essere un modo più intelligente di memorizzare CLLocation rispetto a quello.

evviva.

risposta

34

Quello che stai facendo va bene. Dovresti salvare latitudine e longitudine come doppi in Dati principali. Quando è necessario ottenere nuovamente le informazioni, recuperare il doppio dai dati principali e costruire una struttura CLLocationCoordinate2D con una funzione come CLLocationCoordinate2DMake. Non esiste un modo integrato per memorizzare una posizione, quindi la memorizzazione dei componenti di latitudine e longitudine va bene.

Se non si eseguono operazioni matematiche sulla latitudine o sulla longitudine (trovare riquadri di delimitazione, ecc.) È possibile memorizzarli come stringhe. Le virgolette e le doppie possono cambiare leggermente i loro valori, facendo fallire le operazioni di confronto.

+0

Grazie nevan, in realtà ho salvato quei valori di coordinate anche in NSString per la visualizzazione in UILabel. Ho in programma di fare un po 'di matematica con le coordinate, ma non sapevo che "Floats and doubles possono cambiare leggermente i loro valori, facendo fallire le operazioni di confronto". che mi riporta alla domanda originale con un leggero cambiamento; Se è necessario calcolare la distanza e confrontare, qual è il modo migliore per memorizzare i valori delle coordinate CLLocation utilizzando i dati principali? – bicbac

+2

Se stai facendo qualche calcolo su di loro, come trovare tutte le latitudini maggiori di 12.34, le memorizzerei come float o double. Basta non fare affidamento sul fatto che il valore float sia esattamente lo stesso tra la memorizzazione e il recupero. Se vuoi assicurarti che il valore non cambi (anche di una piccola frazione) usa il decimale. Non sono sicuro di quanto sia veloce fare matematica con i tipi decimali. Ecco un link: http://stackoverflow.com/questions/159255/che-è-il-ideale-data-tipo-di-utilizzare-quando-storing-latitude-longitudes-in-unmysql/159333#159333 –

+2

Se è necessario memorizzare valori numerici con grande precisione ed eseguire operazioni su di essi, è necessario utilizzare il numero NSDecimale. Utilizzare un trasformatore di valori per archiviarli in Core Data. Tuttavia, penso che sarebbe eccessivo in questo caso. I galleggianti e i doppi possono cambiare i valori, ma solo agli estremi della loro precisione. Latitudine/Longitudine richiedono solo al massimo 4 cifre decimali a destra in modo da poter semplicemente controllare le cifre significative per memorizzare perfettamente e recuperare quei valori con float. – TechZen

26

CLLocation implementa il protocollo NSCoding in modo da poterli archiviare in Core Data come attributi trasformabili. È possibile utilizzare il trasformatore di valori predefinito NSKeyedUnarchiveFromData.

È sufficiente passare l'oggetto CCLocation all'attributo dell'oggetto gestito e serializzarlo in base ai dati e archiviarlo come blob nell'archivio SQL. Quando è necessario l'oggetto posizione indietro, si inverte automaticamente il processo e si restituisce un oggetto CCLocation completamente popolato.

Questo potrebbe essere il modo più semplice per ottenere quello che vuoi.

+14

Se i dati sono serializzati, non sarà possibile ottenere le posizioni all'interno di un riquadro di delimitazione senza recuperare ogni posizione dal negozio. –

+0

potrebbe essere semplice ma non può essere interrogato se memorizzato in quel formato. – malhal

17

Il modo "migliore" per memorizzare dipende da cosa si vuole fare con esso:

  • Se si desidera che la "stessa" CLLocation, serializzare. NSKeyedUnarchiveFromData va bene.
  • Se si desidera eseguire la ricerca solo su latitudine e longitudine, archiviarli come duplicati (e selezionare la casella di controllo "indicizzata").

C'è un sacco di proprietà aggiuntive che è possibile salvare/ripristinare se lo si fa manualmente (altitudine, orizzontaleAccuratezza, verticaleAccuratezza, data/ora). Ce ne sono altri che non puoi (velocità, direzione); CLLocation non fornisce un metodo init appropriato e le proprietà sono di sola lettura.

Tutte le proprietà aggiuntive sono utili se si registra una traccia. L'altitudine è utile se stai registrando un PDI su un terreno montagnoso ("dobbiamo ancora salire 100 m"). la precisione orizzontale/verticale potrebbe essere utilizzata per rappresentare quanto grande è il POI (ad esempio, una città potrebbe avere una "precisione orizzontale" di diversi chilometri ed essere visualizzata come un cerchio grande).

2

È possibile farlo semplicemente impostando il tipo di attributo Dati principali su Transformable. Il trasformatore predefinito se si lascia il valore Nome trasformatore è il NSKeyedArchiver che funziona con la maggior parte dei tipi di Foundation come NSURL e CLLocation.

0

Non è necessario utilizzare NSNumber per memorizzare i punti di latitudine e longitudine. È possibile memorizzare CLLocation direttamente sui dati principali.

Configurare un'entità per ogni CLLocation, sarà una relazione troppo ampia indipendentemente dall'entità che utilizza i punti di posizione. Chiamiamo questo LocationPoint:

class LocationPoint: NSManagedObject { 

@NSManaged var game: NSNumber 
@NSManaged var time: NSDate 
@NSManaged var location: AnyObject 

} 

È quindi impostare la posizione struttura al trasformabile nel modello di dati Xcode. Questo è tutto!

In Objective-C si può effettivamente ancora dichiarare questa proprietà LocationPoint come CLLocation senza errori:

@property (nonatomic, strong) CLLocation *location 

More info here.