2010-07-07 21 views
13

Si l'utilisateur fait un zoom arrière sur un MKMapView, je souhaite que MKAnnotations qui sont proches les unes des autres soient automatiquement regroupées dans une annotation de "groupe". si l'utilisateur effectue un zoom avant, l'annotation "groupe" doit être divisée à nouveau en annotations uniques/originales.Comment regrouper MKAnnotations automatiquement en fonction du niveau de zoom?

pomme le fait déjà dans le Photos.app iOS 4

est-il un moyen commun, « prédéfini » pour le faire?

+0

www.BMSClusterMap.com – nurxyz

Répondre

4

C'est une idée géniale. Je travaille sur une application similaire, j'espère que cela ne vous dérange pas si je mets aussi en application le concept :).

Pour répondre à votre question de mon mieux, non, je ne pense pas qu'il existe une façon prédéfinie de le faire.

La meilleure façon de le faire (après avoir regardé l'application photos iOS4), est d'utiliser la méthode mapView:regionDidChangeAnimated: delegate. Chaque fois que l'utilisateur fait défiler/zooms, cette méthode sera appelée. A l'intérieur de cette méthode, vous pourriez avoir quelques maths de géométrie rapide pour déterminer si vos points sont "assez proches" pour envisager la fusion. Une fois qu'ils sont "fusionnés", vous supprimez une ou les deux annotations, et vous remettez une autre annotation au même endroit que les deux (vous pourriez très facilement créer une classe AnnotationCluster qui pourrait être conforme à MKAnnotation mais aussi contenir une annotation NSArray d'annotations, et contient également des méthodes pour "sortir" ou "absorber" d'autres annotations et/ou des instances d'AnnotationCluster, etc. Quand je dis «mathématique de géométrie rapide», je veux dire la distance des deux points par rapport à l'étendue de la carte, et en prenant leur distance relative en pourcentage de l'étendue de la carte entière. Là où cela serait difficile, c'est que si vous aviez des centaines d'annotations, je ne peux pas penser à un bon moyen d'implémenter cela sans une double boucle.

Que pensez-vous?

6

Son fonctionnement normal avec plus de 1500 annotations sur la carte:

-(void)mapView:(MKMapView *)mapView_ regionDidChangeAnimated:(BOOL)animated 
{ 
    NSMutableSet * coordSet = [[NSMutableSet alloc] init]; 

    for(id<MKAnnotation> an in mapView_.annotations) 
    { 
     if([an isKindOfClass:[MKUserLocation class]]) 
      continue; 

     CGPoint point = [mapView_ convertCoordinate:an.coordinate toPointToView:nil]; 
     CGPoint roundedPoint; 

     roundedPoint.x = roundf(point.x/10)*10; 
     roundedPoint.y = roundf(point.y/10)*10; 

     NSValue * value = [NSValue valueWithCGPoint:roundedPoint]; 

     MKAnnotationView * av = [mapView_ viewForAnnotation:an]; 

     if([coordSet containsObject:value]) 
     { 
      av.hidden = YES; 
     } 
     else 
     { 
      [coordSet addObject:value]; 
      av.hidden = NO; 
     } 
    } 

    [coordSet release]; 
} 
+0

J'aime cette solution, mais il n'y a pas vraiment normal. Il sélectionne aléatoirement une annotation et cache les autres annotations à proximité. J'essaie de le rendre plus prévisible avec un comportement cohérent. – Mazyod

+1

OK, cet article a la meilleure réponse: http://stackoverflow.com/questions/7132207/grouped-ungroup-mkannotation-depending-on-the-zoom-level-and-keep-it-fast – Mazyod

0

Ce project fait quelque chose intéressant. Cependant, jetez un oeil aux problèmes signalés avant de modifier trop de choses dans votre code. Parce que cela pourrait ne pas être assez bon pour vos besoins.

I a fini par mettre en œuvre personnellement this