2015-04-01 5 views
8

Ho integrato Google Maps nella mia applicazione e anche utilizzando l'API di Google Places. Dopo aver ottenuto tutti i risultati dall'API di Google Places (circa 60), li visualizzo con l'aiuto di un indicatore personalizzato. L'indicatore personalizzato che sto facendo si compone di "Luogo immagine" e "nome di luogo" a causa della quale devo disegnare un primo momento in un UIView e poi lo rendono come un UIImage con l'aiuto della seguente funzioneLe prestazioni del marcatore personalizzato iOS, arresto anomalo del risultato "((null)) erano false: raggiunto il numero massimo di atlanti di trama, non è possibile allocare altro."

- (UIImage *)imageFromView:(UIView *) view 
{ 
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { 

     UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, [[UIScreen mainScreen] scale]); 
    } else { 
     UIGraphicsBeginImageContext(view.frame.size); 
    } 
    [view.layer renderInContext: UIGraphicsGetCurrentContext()]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return image; 
} 

All'inizio tutti i marcatori sono disegnati e disegnati facilmente.

Ora ho un dispositivo di scorrimento che va da 100 a 5 km, che funge da ottimizzatore del raggio di ricerca. Quando il cursore verrà spostato (supponiamo in un valore di 2 km), tutti i marker verranno rimossi e solo i marker la cui distanza dalla posizione dell'utente è inferiore al valore del cursore verranno nuovamente disegnati. Mentre sto testando la funzionalità di scorrimento, l'applicazione si blocca dicendo

((null)) era falso: raggiunto il numero massimo di atlanti di trama, non è possibile allocare altro.

Sto caricando schermate per una chiara comprensione della situazione. Per favore aiuto.

image when radius is 5km

image when radius is 2.4km

image when radius is 1.7km

anche parlare, nelle schermate si vedrà indicatori verdi così come marcatori azzurri. I marker blu sono quelli che sono più vicini alla posizione dell'utente, mentre quelli verdi sono lontani da una distanza particolare. Come la posizione dell'utente cambierà ci sono 2 casi:

  1. Se si sta avvicinando ad un pennarello verde, poi si trasformerà in un indicatore blu
  2. Se sta lontano da un indicatore blu, poi si gira a un pennarello verde.
+4

@LoVo Laggiù utilizzando una singola immagine è un'opzione disponibile come tutti hanno lo stesso marcatore, ma nel mio caso il mio marcatore ha contenuti diversi, nome di luogo e immagine Posto. –

+0

Provare a utilizzare il bias della vista per il rendering dei marcatori. Ecco una libreria GitHub che lo fa (+ Clustering per prestazioni migliori) per iOS: https://github.com/romaonthego/REMarkerClusterer. Se funziona per il tuo caso d'uso, altrimenti puoi semplicemente adottare la logica di implementazione e il codice te stesso. – KayAnn

+2

Segnalazione bug relativa all'API di Google Maps: https://code.google.com/p/gmaps-api-issues/issues/detail?id=7457 – Pang

risposta

2

Sto lavorando a un'app che può avere diverse migliaia di avatar che si spostano sulla mappa e incontrano anche questo errore. Il clustering è una potenziale soluzione, ma con questo numero di avatar tutti in movimento, ho il sospetto che i calcoli siano troppo intensi per la CPU.

La soluzione che uso è mantenere un riferimento all'immagine avatar di base e usarla quando sullo schermo sono presenti> 50 avatar. Solo quando ci sono < 50 avatar sullo schermo, quindi genererò immagini uniche per ogni avatar con i loro nomi.

// GMSMarker 
static var avatarDic:[String:UIImage] = Dictionary() 

func removeName() { 
    // use a single image reference here so that google map does not crash 
    if let image = avatarDic[avatarBase] { 
     self.icon = image 
    } 
    else { 
     avatarDic[avatarBase] = UIImage(named:avatarBase) 
     self.icon = avatarDic[avatarBase] 
    } 
} 

func addName() { 
    self.icon = // draw name on base image 
} 

// GMSMapView 
var userIcons:[String:MyMarker] = Dictionary() 
var iconWithNames:Set<MyMarker> = Set() 

func mapView(mapView: GMSMapView!, didChangeCameraPosition position: GMSCameraPosition!) { 
    // find visible avatars til limit 
    let bottomLeft = self.mapView.projection.visibleRegion().nearLeft 
    let topRight = self.mapView.projection.visibleRegion().farRight 
    var visibleMarkerSet:Set<MyMarker> = Set() 
    for (key, marker) in self.userIcons { 
     if (marker.position.latitude > bottomLeft.latitude && marker.position.latitude < topRight.latitude && marker.position.longitude > bottomLeft.longitude && marker.position.longitude < topRight.longitude) { 
      visibleMarkerSet.insert(marker) 
     } 

     // not showing if > 50 
     if (visibleMarkerSet.count > 50) { 
      visibleMarkerSet = Set() 
      break 
     } 
    } 

    // remove names 
    for markerWithName in self.iconWithNames { 
     if (visibleMarkerSet.contains(markerWithName) == false) { 
      markerWithName.removeName() 
     } 
    } 
    // add names 
    for visibleMarker in visibleMarkerSet { 
     visibleMarker.addName() 
    } 
    self.iconWithNames = visibleMarkerSet 
}