2010-02-04 27 views
17

Tôi đang mã hóa chế độ xem bản đồ với khoảng 900 chú thích. Có nhiều chú thích này trên bản đồ khiến hiệu suất bị ảnh hưởng, vì vậy tôi muốn giảm nó xuống còn khoảng 300 tại một thời điểm. Các chú thích đại diện cho các cửa hàng ở một quốc gia, vì vậy chúng có xu hướng tập trung nhiều ở các thành phố lớn, sau đó trong các nhóm nhỏ từ 2 đến 3 ở các thị trấn nhỏ hơn. Tôi muốn giảm số lượng để các nhóm 2 hoặc 3 bị bỏ lại một mình, nhưng những con số trong thành phố bị mỏng đi (chúng gần nhau đến mức chúng không cung cấp thông tin hữu ích).Làm cách nào để giảm số lượng chú thích trên bản đồ?

Trong hình ảnh bạn có thể thấy rằng có một vài nhóm lớn (Tokyo, Nagoya và Osaka) mà tôi muốn mỏng ra. Nhưng với các chân trên của riêng mình hoặc trong các nhóm nhỏ, tôi muốn chắc chắn rằng họ không được lọc. Khi tôi phóng to, tôi muốn hiển thị các chân bị thiếu.

Có ai biết về một số mã tốt mà tôi có thể sử dụng, để các điểm gần nhau bị loại bỏ, nhưng những điểm khác được trải ra chỉ còn lại một mình?

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

Trả lời

6

Một cách tiếp cận là trước khi đặt một pin mới, kiểm tra nếu có một pin đã được đặt trong khoảng cách d của pin mới. Nếu có, không đặt ghim mới. Bạn cần thay đổi d dựa trên mức thu phóng hiện tại.

Bạn có thể giảm số lượng chân bạn kiểm tra bằng cách chỉ xem xét các ghim trong hộp giới hạn ở giữa trên ghim mới. Hộp có thể là d x d độ trên một mặt (với d thay đổi dựa trên mức thu phóng).

0

Xem xét nhiều chân ở các khu vực đông dân cư sẽ nằm trên cùng một phố, bạn có thể cân nhắc tạo "ghim" liệt kê các ghim trên một con phố cụ thể thay vì trên mỗi địa chỉ riêng lẻ.

-S!

5

Hai tùy chọn tôi có thể nghĩ:

  • Nếu bạn có điểm ưa thích để làm việc với (Ví dụ, thành phố), bạn có thể chỉ đơn giản là nhóm tất cả các chân của POI họ gần, trong zoom thấp cấp độ.
  • Bạn có thể sử dụng K-means clustering để nhóm các ghim thành các cụm và đại diện cho chúng bằng một chốt giữa.
2

Đây là đoạn mã nhận tọa độ của MKAnnotation, chuyển đổi nó thành CGPoint tương ứng với MKMapView và ghi nhật ký xem cơ bản ở điểm CGPoint đó là gì.

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

Đặt điều đó trong vòng lặp lặp qua tất cả các ghim của bạn. Nếu chế độ xem cơ bản là một cá thể MKAnnotation khác thì hãy ẩn ghim đó.

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

Để điều này hoạt động bình thường, bạn cần pinsArray được yêu cầu để chỉ mục 0 là chân trước nhất.

+0

cách tiếp cận thú vị, mặc dù không hoàn hảo – chatur

6

Nếu thư viện thương mại, bên thứ ba là một tùy chọn, hãy kiểm tra Superpin (chi phí giấy phép $ 199). Đây là một Khung công tác iOS sử dụng nội bộ quadtrees để lưu trữ chú thích và thực hiện phân cụm dựa trên lưới. Thuật toán khá nhanh, ứng dụng mẫu được bao gồm hiển thị các sân bay của thế giới (hơn 30k chú thích) và nó chạy khá trơn tru trên iPhone 3G.

Bạn cũng có thể muốn kiểm tra http://revolver.be/blog/mapkit-clustering-with-ios/, một giải pháp làm sẵn khác, miễn phí cho các dự án phi thương mại.

Disclaimer: Tôi là một trong những nhà phát triển Superpin

+0

Tôi nhận thấy rằng thật dễ dàng để tích hợp dự án quay số nguồn mở vào ứng dụng của riêng tôi. Cảm ơn esad! –

0

muộn để đảng, tôi biết, nhưng bạn có thể thấy thói quen hữu ích này. Nó xuất phát từ this file, là một phần của a FOSS project.

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

Bạn có thể thấy nó hoạt động trong the released version của ứng dụng.

Cuộc họp gần nhau được tập hợp thành chú thích màu đỏ, mở danh sách.

Các vấn đề liên quan