كيف يمكنني تقليل عدد التعليقات التوضيحية على الخريطة؟
-
18-09-2019 - |
سؤال
أنا ترميز عرض خريطة مع حوالي 900 شروح. وجود هذه التعليقات التوضيحية العديدة على الخريطة تجعل الأداء يعاني، لذلك أود أن تقلل من حوالي 300 مرة في كل مرة. تشكل التعليقات التوضيحية للمتاجر في بلد ما، لذلك تميل إلى تجميع الكثير حول المدن الكبرى، ثم في مجموعات صغيرة من 2 أو 3 في بلدات أصغر. أريد تقليل الأرقام بحيث يتم ترك مجموعات 2 أو 3 بمفردها، ولكن يتم تخفيف الأرقام الموجودة في المدينة (أنها قريبة من بعضها البعض أنها لا تقدم أي معلومات مفيدة).
في الصورة، يمكنك أن ترى أن هناك بعض المجموعات الكبيرة (طوكيو، ناغويا وأوساكا) التي أريد أن تخرجها. ولكن مع دبابيس من تلقاء نفسها أو في مجموعات صغيرة، أريد أن أتأكد من عدم تصفيةها. بمجرد التكبير، أريد أن أظهر المسامير المفقودة.
هل يعرف أي شخص ببعض الكود الجيد الذي يمكنني استخدامه، بحيث يتم القضاء على هذه النقاط القريبة من بعضها البعض، ولكن يتم تركها أكثر انتشارها وحدها؟
نص Alt http://img.skitch.com/2017204-jpde6wugc94nn692k7m36gmqf1.jpg.
المحلول
نهج واحد هو أنه قبل وضع دبوس جديد، تحقق مما إذا كان هناك دبوس آخر وضعت بالفعل على مسافة D من رقم التعريف الشخصي الجديد. إذا كان هناك، لا تضع رقم التعريف الشخصي الجديد. تحتاج إلى تختلف D بناء على مستوى التكبير الحالي.
يمكنك تقليل عدد المسدسات التي تسيطر عليها عن طريق النظر في دبابيس فقط في مربع محيط تركز على رقم التعريف الشخصي الجديد. يمكن أن يكون المربع درجات DXD على جانب (مع D Dareing بناء على مستوى التكبير).
نصائح أخرى
إذا كانت مكتبة تجارية ثالثة هي خيار، تحقق من سوبربين (تكاليف الترخيص 199 دولار). إنه إطار IOS يستخدم داخليا Quadstrees لتخزين Cheanotation ويقوم بإجراء التجمعات المستندة إلى الشبكة. الخوارزمية سريعة جدا، يظهر تطبيق العينة المشمول مطارات العالم (أكثر من 30K + التوضيحية) وهو يعمل على نحو سلس تماما على 3G iPhone.
قد ترغب أيضا في التحقق http://revolver.be/blog/mapkit-clustering-with-ios/, أو حل جاهز آخر، وهو مجاني للمشاريع غير التجارة.
إخلاء المسئولية: أنا أحد مطوري SuperPin
خياران يمكنني التفكير فيه:
- إذا كان لديك نقاط اهتمام العمل مع (على سبيل المثال، المدن)، فيمكنك ببساطة إجماع جميع المسامير من قبل POI أنها الأقرب إلى مستويات التكبير منخفضة.
- يمكنك استخدام K يعني التجميع إلى مجموعات المجموعات في مجموعات وتمثلها مع دبوس منتصف نقطة.
إليك مقتطف كود يأخذ إحداثيات Mkannotation، وتحويله إلى CGPoint بالنسبة إلى MKMapView، وتسجيل ما هو العرض الأساسي في هذه 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 هو رقم التعريف الشخصي الأمامي.
بالنظر إلى أن العديد من المسامير في المناطق المكتظة بالسكان ستكون في نفس الشارع، فيمكنك التفكير في صنع "دبابيس فائقة" التي تسرد الدوافع في شارع معين، بدلا من كل عنوان فردي.
-س!
في وقت متأخر إلى الحفلة، أعرف، ولكن قد تجد هذا الروتين مفيدا. انها تاتي من هذا الملف, ، وهو جزء من مشروع فوس.
/**************************************************************//**
\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;
}
يمكنك أن ترى ذلك في العمل الإصدار المفرج عنه من التطبيق.
تجمع الاجتماعات في القرب القريب في التعليقات التوضيحية الحمراء، والتي تفتح قائمة.