Freitag, Juni 5, 2020

Wie kann ich reduzieren die Anzahl der Anmerkungen auf einer Karte?

Ich bin der Codierung eine Kartenansicht mit rund 900 Anmerkungen. Diese vielen Anmerkungen auf einer Karte die Leistung leiden, so würde ich mag, um es zu verringern, auf etwa 300 zu einer Zeit. Die Annotationen zu repräsentieren, die Geschäfte in einem Land, so neigen Sie dazu, cluster eine Menge rund um die großen Städte, dann in kleinen Gruppen von 2 oder 3 in kleineren Städten. Ich möchte, um die Zahl zu reduzieren, so dass die Gruppen von 2 oder 3 sind allein gelassen, aber die zahlen in der Stadt werden ausgedünnt (Sie sind so nahe beieinander, dass Sie bieten keine nützlichen Informationen).

In der Abbildung kann man sehen, dass es ein paar große Gruppen (Tokyo, Nagoya und Osaka) und das will ich Dünn aus. Aber mit den pins auf Ihren eigenen oder in kleinen Gruppen, ich will zu machen sicher, dass Sie nicht gefiltert. Sobald ich zoom-in, ich möchte zeigen das fehlende pins.

Kennt jemand ein paar gute code, den ich verwenden können, so dass Punkte, die nahe zusammen sind beseitigt, aber diejenigen, die mehr verteilt sind allein gelassen?

alt-text http://img.skitch.com/20100204-jpde6wugc94nn692k7m36gmqf1.jpg

InformationsquelleAutor nevan king | 2010-02-04

6 Kommentare

  1. 6

    Ein Ansatz ist, dass, bevor Sie eine neue pin ein, überprüfen Sie, ob es eine andere pin-bereits innerhalb der Entfernung d der neuen pin. Wenn es nicht, legen Sie die neue pin ein. Sie müssen unterscheiden d basierend auf der aktuellen zoom-Stufe.

    Können Sie reduzieren die Anzahl der pins, die du überprüfen, wenn nur die Stifte in einer bounding-box zentriert auf die neue pin. Die box könnte d x d Grad auf einer Seite (mit d basierend auf unterschiedlichen zoom-level).

  2. 6

    Wenn ein Handels -, Drittanbieter-Bibliothek ist eine option, check-out Superpin (Lizenz kostet $199). Es ist ein iOS-Framework, das intern verwendet quadtrees für die annotation Speicher und führt die grid-based clustering. Der Algorithmus ist Recht schnell, die mitgelieferte Beispiel-app zeigt Flughäfen der Welt (mehr als 30k+ Anmerkungen) und es läuft ziemlich glatt auf ein 3G-iPhone.

    Möglicherweise möchten Sie auch zu prüfen,http://revolver.be/blog/mapkit-clustering-with-ios/, ein weiteres ready-made-Lösung, die ist kostenlos für nicht-kommerzielle Projekte.

    Disclaimer: ich bin einer der Superpin Entwickler

    • Ich fand, dass es Recht einfach war die Integration der open-source-revolver Projekt in meine eigene app. Danke esad!
  3. 5

    Zwei Optionen, die ich denken kann:

    • Wenn Sie Punkte von Interesse in der Arbeit mit (ZB Städte), Sie können einfach gruppieren Sie alle pins, indem Sie die POI, die Sie am nächsten sind, in niedrigeren Zoomstufen.
    • Können Sie K-means-clustering Gruppe pins in Clustern zusammen und stellen Sie mit a Mitte pin.
  4. 2

    Hier ist ein code-snippet, das dauert ein MKAnnotation die Koordinaten konvertieren, um ein CGPoint relativ zu der MKMapView, und protokolliert, was die zugrunde liegende Ansicht, dass CGPoint.

    CGPoint pinPoint = [mapView convertCoordinate:pinView.annotation.coordinate toPointToView:mapView];
    NSLog(@"pointing to %@", [[mapView hitTest:pinPoint withEvent:nil] description]);

    Setzen, die innerhalb einer Schleife, dass durchläuft alle Ihre Stifte. Wenn die zugrunde liegende Ansicht ist eine andere MKAnnotation-Instanz, dann ausblenden, die pin.

    if([[mapView hitTest:pinPoint withEvent:nil] isKindOfClass:[FFMapPinView class]])
        pinView.hidden = YES;

    Damit dies ordnungsgemäß funktioniert, müssen Sie die pinsArray bestellt werden, so dass der index 0 ist das vorderste pin.

    • interessanter Ansatz, wenn auch nicht perfekt
  5. 0

    Bedenkt, dass viele pins in dicht besiedelten Gebieten auf der gleichen Straße, die Sie könnte in Erwägung ziehen, „super-Stifte“, die Liste der pins, die auf einer bestimmten Straße, statt auf jeder einzelnen Adresse.

    -S!

  6. 0

    Spät zur party, ich weiß, aber Sie können finden, diese routine nützlich. Es kommt aus diese Datei, die Teil der ein FOSS-Projekt.

    /**************************************************************//**
     \brief This function looks for meetings in close proximity to each
            other, and collects them into "red markers."
     \returns an NSArray of BMLT_Results_MapPointAnnotation objects.
     *****************************************************************/
    - (NSArray *)mapMeetingAnnotations:(NSArray *)inResults ///< This is an NSArray of BMLT_Meeting objects. Each one represents a meeting.
    {
    #ifdef DEBUG
        NSLog(@"BMLTMapResultsViewController mapMeetingAnnotations - Checking %d Meetings.", [inResults count]);
    #endif
        NSMutableArray  *ret = nil;
    
        NSInteger   displayIndex = 1;
    
        if ( [inResults count] )
            {
            NSMutableArray  *points = [[NSMutableArray alloc] init];
            for ( BMLT_Meeting *meeting in inResults )
                {
    #ifdef DEBUG
                NSLog(@"BMLTMapResultsViewController mapMeetingAnnotations - Checking Meeting \"%@\".", [meeting getBMLTName]);
    #endif
                CLLocationCoordinate2D  meetingLocation = [meeting getMeetingLocationCoords].coordinate;
                CGPoint meetingPoint = [(MKMapView *)[self view] convertCoordinate:meetingLocation toPointToView:nil];
                CGRect  hitTestRect = CGRectMake(meetingPoint.x - BMLT_Meeting_Distance_Threshold_In_Pixels,
                                                 meetingPoint.y - BMLT_Meeting_Distance_Threshold_In_Pixels,
                                                 BMLT_Meeting_Distance_Threshold_In_Pixels * 2,
                                                 BMLT_Meeting_Distance_Threshold_In_Pixels * 2);
    
                BMLT_Results_MapPointAnnotation *annotation = nil;
    #ifdef DEBUG
                NSLog(@"BMLTMapResultsViewController mapMeetingAnnotations - Meeting \"%@\" Has the Following Hit Test Rect: (%f, %f), (%f, %f).", [meeting getBMLTName], hitTestRect.origin.x, hitTestRect.origin.y, hitTestRect.size.width, hitTestRect.size.height);
    #endif
    
                for ( BMLT_Results_MapPointAnnotation *annotationTemp in points )
                    {
                    CGPoint annotationPoint = [(MKMapView *)[self view] convertCoordinate:annotationTemp.coordinate toPointToView:nil];
    #ifdef DEBUG
                    NSLog(@"BMLTMapResultsViewController mapMeetingAnnotations - Comparing the Following Annotation Point: (%f, %f).", annotationPoint.x, annotationPoint.y);
    #endif
    
                    if ( !([[annotationTemp getMyMeetings] containsObject:meeting]) && CGRectContainsPoint(hitTestRect, annotationPoint) )
                        {
    #ifdef DEBUG
                        for ( BMLT_Meeting *t_meeting in [annotationTemp getMyMeetings] )
                            {
                            NSLog(@"BMLTMapResultsViewController mapMeetingAnnotations - Meeting \"%@\" Is Close to \"%@\".", [meeting getBMLTName], [t_meeting getBMLTName]);
                            }
    #endif
                        annotation = annotationTemp;
                        }
                    }
    
                if ( !annotation )
                    {
    #ifdef DEBUG
                    NSLog(@"BMLTMapResultsViewController mapMeetingAnnotations -This meeting gets its own annotation.");
    #endif
                    NSArray *meetingsAr = [[NSArray alloc] initWithObjects:meeting, nil];  
                    annotation = [[BMLT_Results_MapPointAnnotation alloc] initWithCoordinate:[meeting getMeetingLocationCoords].coordinate andMeetings:meetingsAr andIndex:0];
                    [annotation setDisplayIndex:displayIndex++];
                    [points addObject:annotation];
                    }
                else
                    {
    #ifdef DEBUG
                    NSLog(@"BMLTMapResultsViewController mapMeetingAnnotations -This meeting gets lumped in with others.");
    #endif
                    [annotation addMeeting:meeting];
                    }
    
                if ( annotation )
                    {
                    if ( !ret )
                        {
                        ret = [[NSMutableArray alloc] init];
                        }
    
                    if ( ![ret containsObject:annotation] )
                        {
                        [ret addObject:annotation];
                        }
                    }
                }
            }
    
        //This is the black marker.
        BMLT_Results_MapPointAnnotation *annotation = [[BMLT_Results_MapPointAnnotation alloc] initWithCoordinate:[[BMLTAppDelegate getBMLTAppDelegate] searchMapMarkerLoc] andMeetings:nil andIndex:0];
    
        if ( annotation )
            {
            [annotation setTitle:NSLocalizedString(@"BLACK-MARKER-TITLE", nil)];
            [ret addObject:annotation];
            }
    
        return ret;
    }

    Können Sie sehen, Sie in Aktion in die freigegebene version der app.

    Treffen in der Nähe versammelt sind in rot Annotationen, die eine Liste zu öffnen.

Kostenlose Online-Tests