كيف يمكنني تقليل عدد التعليقات التوضيحية على الخريطة؟

StackOverflow https://stackoverflow.com/questions/2200504

سؤال

أنا ترميز عرض خريطة مع حوالي 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;
}

يمكنك أن ترى ذلك في العمل الإصدار المفرج عنه من التطبيق.

تجمع الاجتماعات في القرب القريب في التعليقات التوضيحية الحمراء، والتي تفتح قائمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top