17

約900個の注釈を使用してマップビューをコーディングしています。マップ上にこれだけ多くの注釈があるとパフォーマンスが低下するので、一度に約300に減らしたいと思います。注釈は国のショップを表しているため、主要都市の周りにたくさん集まって、小さな町では2つか3つの小さなグループになっている傾向があります。2、3のグループが残されるように数を減らしたいのですが、市内の数は薄くなっています(それらは非常に接近しているため、有用な情報を提供していません)。

画像では、私が間引きしたいいくつかの大きなグループ(東京、名古屋、大阪)があることがわかります。ただし、ピンを単独で、または小グループで使用する場合は、ピンがフィルタリングされないようにします。ズームインしたら、不足しているピンを表示したいと思います。

誰かが私が使用できるいくつかの良いコードを知っているので、近くにあるポイントは削除されますが、より広がっているポイントはそのままになりますか?

代替テキストhttp://img.skitch.com/20100204-jpde6wugc94nn692k7m36gmqf1.jpg

4

6 に答える 6

6

1つのアプローチは、新しいピンを配置する前に、新しいピンの距離d内に別のピンがすでに配置されているかどうかを確認することです。ある場合は、新しいピンを配置しないでください。現在のズームレベルに基づいてdを変更する必要があります。

新しいピンの中心にあるバウンディングボックス内のピンのみを考慮することで、チェックするピンの数を減らすことができます。ボックスは、側面がdxd度である可能性があります(dはズームレベルに基づいて変化します)。

于 2010-02-04T15:13:55.093 に答える
6

商用のサードパーティライブラリがオプションの場合は、Superpinをチェックしてください(ライセンス料は199ドル)。これは、アノテーションストレージにクアッドツリーを内部的に使用し、グリッドベースのクラスタリングを実行するiOSフレームワークです。アルゴリズムは非常に高速で、含まれているサンプルアプリは世界の空港(3万以上の注釈)を表示しており、3GiPhoneで非常にスムーズに実行されています。

また、 http://revolver.be/blog/mapkit-clustering-with-ios/を確認することもできます。これは、非商用プロジェクトでは無料の別の既製のソリューションです。

免責事項:私はSuperpin開発者の1人です

于 2011-09-29T03:53:15.110 に答える
5

私が考えることができる2つのオプション:

  • 作業するポイント(都市など)がある場合は、ズームレベルを下げて、すべてのピンを最も近いPOIでグループ化するだけです。
  • K-meansクラスタリングを使用して、ピンをクラスターにグループ化し、それらを中点ピンで表すことができます。
于 2010-02-08T10:47:48.880 に答える
2

これは、MKAnnotationの座標を取得し、それをMKMapViewを基準にしたCGPointに変換し、そのCGPointの基になるビューをログに記録するコードスニペットです。

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

それをすべてのピンを繰り返すループの中に入れます。基になるビューが別のMKAnnotationインスタンスである場合は、そのピンを非表示にします。

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

これを正しく機能させるには、インデックス0が最前面のピンになるようにpinsArrayを並べ替える必要があります。

于 2010-10-11T21:30:34.050 に答える
0

人口密集地域の多くのピンが同じ通りにあることを考えると、個々の住所ではなく、特定の通りのピンを一覧表示する「スーパーピン」を作成することを検討できます。

-S!

于 2010-02-04T16:22:31.377 に答える
0

パーティーに遅れて、私は知っています、しかしあなたはこのルーチンが役に立つと思うかもしれません。これは、FOSSプロジェクトの一部であるこのファイルから取得されます。

/**************************************************************//**
 \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;
}

アプリのリリースバージョンで実際の動作を確認できます。

近接する会議は赤い注釈にまとめられ、リストが開きます。

于 2012-04-22T15:00:28.753 に答える