How can I group MKAnnotations automatically regard

2019-01-16 21:08发布

问题:

if the user zooms out on a MKMapView, i want MKAnnotations which are near to each other automatically grouped into one "group" annotation. if the user zooms back in, the "group" annotation should be split again to the unique/original annotations.

apple does this already in the iOS 4 Photos.app

is there a common, "predefined" way to do this?

回答1:

Its normal working with more than 1500 annotations on the map:

-(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];
}


回答2:

That's a brilliant idea. I'm working on a similar app, I hope you don't mind if I als implement the concept :).

To answer your question to the best of my own ability, no, I don't think there is a predefined way to do this.

The best way I can think of to do it (after looking at the iOS4 photos app), is to make use of the mapView:regionDidChangeAnimated: delegate method. Any time the user scrolls/zooms, this method will be called.

Inside that method, you could have some quick geometry math to determine whether your points are "close enough" to consider merging. Once they're "merged", you'd remove one or both annotations, and put another annotation back in the same place that is a reference to both (you could make an AnnotationCluster class very easily that could conform to MKAnnotation but also hold an NSArray of annotations, and also contain methods for "breaking out" or "absorbing" other annotations and/or AnnotationCluster instances, etc).

When I say "quick geometry math", I mean the distance of the two points relative to the span of the map, and taking their relative distance as a percentage of the span of the whole map.

Where that would get tricky is if you had hundreds of annotations, as I can't off-hand think of a good way to implement that w/o a double loop.

What do you reckon?



回答3:

This project does something interesting. Though, have a look at reported issues before changing too many things in your code. Because it could be not good enough for your needs yet.

I personnaly ended up implementing this