マップ上の注釈の数を減らすにはどうすればよいですか?
-
18-09-2019 - |
質問
約900の注釈を含むマップビューをコーディングしています。マップ上にこれほど多くの注釈があるとパフォーマンスが低下するため、一度に約 300 個まで減らしたいと考えています。注釈はその国の店舗を表しているため、大都市の周囲に多く集中し、小さな町では 2 つまたは 3 つの小さなグループになる傾向があります。2 人または 3 人のグループが残るように数を減らしたいのですが、都市の数は間引かれています (グループが密集しているため、有益な情報は得られません)。
この画像では、間引きたい大きなグループ (東京、名古屋、大阪) がいくつかあることがわかります。ただし、ピンが単独または小さなグループにある場合は、それらがフィルタリングされないようにしたいと考えています。ズームインしたら、不足しているピンを表示したいと思います。
誰かが私が使用できるいくつかの良いコードを知っていますか?そうすれば、互いに近い点は削除されますが、より離れた点はそのまま残されますか?
代替テキスト http://img.skitch.com/20100204-jpde6wugc94nn692k7m36gmqf1.jpg
解決
一つのアプローチは、すでに新しいピンの距離d内に置かれた別のピンがあります場合は、新しいピンを配置する前に、確認することです。ある場合は、新しいピンを置かないでください。あなたは現在のズームレベルに基づいてDを変更する必要があります。
あなたは新しいピンを中心にバウンディングボックス内のみのピンを考慮することにより、チェック対象のピンの数を減らすことができます。ボックスは(ズームレベルに基づいてDを変化させた)側にD X D度とすることができる。
他のヒント
商用、サードパーティのライブラリがオプションである場合は、チェックアウト Superpinする(ライセンスは$ 199かかります)。それは、内部注釈記憶用クオッドツリーを使用し、グリッドベースのクラスタリングを行い、IOSのフレームワークです。アルゴリズムが含まれているサンプルアプリは、世界の空港を見せている(以上30K +注釈)と、それは3G iPhone上で非常にスムーズに実行している、非常に高速です。
また、 http://revolver.be/blog/mapkitをチェックすることもできます-clustering-で-IOS / に、非商業プロジェクトのための自由である別の既製のソリューション、。
免責事項:私はSuperpinの開発者の一人です。の
私が考えることができる 2 つのオプション:
- 操作する興味のある地点 (都市など) がある場合は、低いズーム レベルで、最も近い POI に基づいてすべてのピンを単純にグループ化できます。
- 使用できます K 平均法クラスタリング ピンをクラスターにグループ化し、それらを中点ピンで表します。
ここでMKMapViewにするCGPointの相対に変換し、MKAnnotationの座標をとり、コードスニペットはだ、とそのする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を注文する必要があります。
人口密度の高い地域で多くのピンが同じ通りになることを考慮すると、あなたの代わりに、個々のアドレス上で、特定の路上でピンを一覧表示する「スーパーピン」を行うことを検討できます。
-S!
後期パーティーに、私が知っている、しかし、あなたは、このルーチンに便利かもしれません。これは、このファイルから来ていますA>、をrel="nofollow">である。
/**************************************************************//**
\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;
}
あなたはのリリースされたバージョンの中にアクションでそれを見ることができますアプリます。
近接したミーティングは、リストを開き、赤の注釈の中に集められます。