2011-02-09 14 views
9

Quando avvio la mia applicazione o riprendo dopo un lungo periodo, la nozione di utente di MKMapView è errata e mi mostra in mezzo al mare.L'ubicazione dell'utente di MKMapView è errata all'avvio o ripresa.

Sto usando il seguente codice:

self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate; 
[mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES]; 

accade dopo un lungo curriculum di app o nuovo inizio ....

+0

Ehi, hai mai trovato una soluzione a questo problema? La posizione in lat: 0.0 e long: 0.0? – mbogh

+0

Ho riscontrato lo stesso problema, ma ci sono poche informazioni online su come risolverlo. Sono curioso di sapere se c'è un modo più pulito oltre a usare l'ultima posizione conosciuta. –

risposta

1

Questo è, purtroppo, una funzione del chip GPS. Non è sempre attivo, quindi i dati di solito saranno errati per i primi due momenti. La soluzione migliore sarebbe probabilmente quella di memorizzare l'ultima posizione registrata dall'app in NSUserDefaults, quindi attendere che la precisione sia dove desideri che sia prima di passare ai dati in tempo reale, oppure nascondere MkMapView fino a quando la precisione non è dove desideri essere, quindi visualizzarlo in quel punto (è possibile visualizzare una schermata di caricamento nel frattempo)

+0

Come si assicura che la precisione sia corretta? Posso fermarmi finché non è corretto, ma come posso verificarlo? Chiamata –

+0

- (void) startUpdatingLocation su CLLocationManager, quindi eseguire l'override di locationManager: didUpdateToLocation: fromLocation: nel proprio delegato. Se si memorizza l'ultima posizione nota, è possibile determinare quando l'utente è a una distanza ragionevole dall'ultima posizione e visualizzare la mappa –

0

Quanto lontano è lontano dalla posizione attuale? Quando un'applicazione si avvia o riprende da un lungo periodo di tempo, la posizione dell'utente è in generale sempre sbagliata. Mentre l'applicazione viene eseguita, diventerà sempre più accurata. Esistono metodi per ottenere l'accuratezza della posizione dell'utente in CLLocationManager, vedere che tipo di valori si ottengono lì.

+0

È necessario attendere il caricamento dell'applicazione? Come un sonno? –

1

Nelle mie applicazioni ho usato questi metodi:

prima - è bene avere una posizione predefinita (per esempio - applicazione è di una città - quindi ingrandisci per mostrare l'intera città) (sulla prima - prima apertura dell'app, quando non sono stati scaricati dati)

Secondo - se l'utente ha già utilizzato la mappa - può memorizzare le sue coordinate e mostrare quelle (livello + span (zoom)) nel caso in cui non ci siano altri dati disponibili.

Terzo - in caso di dati:

1.) Se database ha già alcune coordinate - su prima apertura mappa (quando l'applicazione è stata chiusa) - diminuire/a per mostrare tutti i perni su carta.

2.) Quando ancora in mappa e appena arrivato aggiornamenti (nuove posizioni o cambiato qualcosa), ci sono due possibilità:

2.1) Se l'utente non ha lo zoom in qualsiasi posizione - mappa. esegue lo zoom in/out per mostrare tutte le posizioni. .

2,2) se l'utente ha ingrandita - posizioni vengono aggiornati, ma map doesnt zoom out

Naturalmente - poi ci sono anche alcuni pulsanti di filtro (ad esempio: ricerca, posizione dell'utente, e un po 'di più - che filtra le posizioni e ingrandisce/chiude per mostrare i risultati filtrati)

21

Questo è il comportamento previsto: la posizione dell'utente non viene sempre tracciata dall'iPhone tramite GPS (si consuma molta batteria).Quindi, non appena viene visualizzata la mappa, l'istanza MKMapView mostra l'ultima posizione "migliore" dell'utente che conosce e quindi, migliora la precisione attivando il tracciamento (questo è un processo continuo, non devi preoccupartene).

È possibile monitorare quando lo MKMapView aggiorna la posizione dell'utente sulla mappa implementando il protocollo MKMapViewDelegate. Basta implementare:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation  { 
    CLLocationAccuracy accuracy = userLocation.location.horizontalAccuracy; 
    if (accuracy ......) { 
    } 
} 

(Maggiori informazioni dalla documentazione mela here)

Il codice di cui sopra nel mio esempio controlla la precisione della posizione attualmente visualizzata dal MapView e reagisce di conseguenza.

[EDIT]
Se mostrare la posizione dell'utente in mezzo al mare in un primo momento ti infastidisce, puoi nascondere la posizione dell'utente finché non ottieni una posizione sufficientemente precisa/fresca.
Per fare ciò, impostare la proprietà showsUserLocation dello MKMapView su NO inizialmente finché non si ottiene una posizione sufficientemente precisa (grazie alla precedente richiamata delegato) e quindi impostarla su YES.
Facendo voi, evitare la visualizzazione di una posizione che non è accurato o troppo vecchi per essere diplayed (c'è una proprietà timestamp nel CLLocation per controllare wether è una vecchia posizione e non)

NB: non devi creare un'istanza CLLocationManager dalla tua parte, MKMapView ne crea uno internamente e pubblicare i luoghi che riceve tramite questo selettore dei delegati.

+2

+1 sei la prima persona ad affrontare la visione in mezzo al mare parte di questa domanda. –

1

Quello che faccio qui è-

  1. aggiornamenti sulla posizione di partenza
  2. aggiornata posizione, controllare l'età di posizione, se è troppo vecchio, aspetto
  3. sulla ricezione nuovo aggiornamento aggiorno esso sulla mappa

Se hai bisogno di una posizione molto precisa, controlla anche l'accuratezza e un timeout oltre il quale non puoi tollerare l'attesa e utilizzare la correzione meno accurata.

+0

aggiungere il controllo per lat e lon per essere 0, e questa risposta è come mi occupo del problema – AtomRiot

4

Quando si utilizza CLLocationManager direttamente, si ottiene normalmente una posizione memorizzata nella prima callback. Normalmente è una buona posizione, anche se vecchia. Dopodiché puoi ottenere rapidamente ulteriori callback che offrono posizioni migliori utilizzando la rete wifi, cella tower (se disponibile). Se hai richiesto la precisione di < 1000m (dopo più secondi) otterrai la triangolazione GPS.

Nessuno di questi dovrebbe essere abbastanza preciso da trovarsi nel mezzo dell'oceano. Ho il sospetto che il questa riga di codice:

self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate; 

sta accedendo la coordinata mentre userLocation o location è nil. Se userLocation o location è nulla, questo restituirà 0 coordinate. La posizione di lat = 0, lon = 0 si trova nell'Oceano Atlantico, al largo della costa africana.Si potrebbe aggiungere un controllo di location per assicurarsi che non è pari a zero prima di ottenere la coordinata da esso, vale a dire:

if (self.mapView.userLocation.location) { 
    self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate; 
    [mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];   
} 

Si vuole anche aspettare che richiami alla MKMapViewDelegatemapView:didUpdateUserLocation: di sapere quando c'è una posizione valida a disposizione. La tua implementazione di didUpdateUserLocation: dovrebbe eliminare qualsiasi posizione che abbia uno che indica una posizione non valida.

-(void)mapView:(MKMapView*)mapView didUpdateUserLocation:(MKUserLocation*)userLocation 
{ 
    if (userLocation.location.horizontalAccuracy > 0) { 
     [mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];   
    } 
} 
+0

Risolto il problema di Middle Sea nelle mappe, grazie! –