iPhone मानचित्र किट क्लस्टर pinpoints

वोट
23

IPhone के बारे में मानचित्र किट क्लस्टर pinpoints:

मैं 1000 के निशान है कि मैं नक्शे पर दिखाना चाहते हैं की है, लेकिन यह इतना संभाल करने मैं उन्हें क्लस्टर करना चाहते हैं अभी भी कई हैं।

वहाँ चौखटे उपलब्ध या अवधारणाओं का सबूत हैं? यह संभव है या पहले से ही किया गया है?

12/01/2010 को 09:52
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


8 जवाब

वोट
13

आप उपयोग कर सकते हैं REVClusterMap क्लस्टर के लिए

18/07/2011 को 06:54
का स्रोत उपयोगकर्ता

वोट
8

नोट: यह एक व्यावसायिक उत्पाद मैं के साथ संबद्ध कर रहा हूँ, लेकिन यह यह बहुत ही समस्या का हल।

मैं अपने कुछ एप्लिकेशन में इस समस्या का समाधान और एक पुन: प्रयोज्य ढांचे में यह निकालने का फैसला किया। यह कहा जाता है Superpin और यह एक है आईओएस फ्रेमवर्क कि आंतरिक रूप से एनोटेशन भंडारण के लिए quadtrees उपयोग करता है और करता है ग्रिड आधारित क्लस्टरिंग (वाणिज्यिक, लाइसेंस $ 149 लागत)। एल्गोरिथ्म है काफी तेजी से, शामिल नमूना एप्लिकेशन दुनिया (एक से अधिक 30k + एनोटेशन) के हवाई अड्डों को दिखा रहा है और यह एक 3 जी iPhone पर काफी चिकनी चल रहा है।

02/05/2011 को 15:18
का स्रोत उपयोगकर्ता

वोट
6

मैं दूसरों को यहाँ का सुझाव दिया की कोशिश की, और मैंने यह भी पाया OCMapView जो सबसे अच्छा काम किया है।

अपने नि: शुल्क और एनोटेशन की आसान समूहीकरण, जो है मैं क्या जरूरत के लिए अनुमति देता है। इसका थोड़ा नए और रिवॉल्वर से और मुझे लागू करना आसान है के लिए और अधिक अद्यतन किया गया।

05/02/2013 को 22:05
का स्रोत उपयोगकर्ता

वोट
6

यह लॉन घास काटना एक चेनसॉ का उपयोग कर की तरह एक सा हो सकता है, लेकिन यहाँ से एक अंश है संक्षेप में एल्गोरिदम

एक केडी-ट्री बना रहा है ...

public class KDFactory {
  // Known comparators for partitioning points along dimensional axes.
  private static Comparator<IMultiPoint> comparators[ ] ;
  // Recursively construct KDTree using median method on input points.
  public static KDTree generate (IMultiPoint [ ] points) {
    if (points. length == 0) { return null; }
    // median will be the root.
    int maxD = points[ 0] . dimensionality( );
    KDTree tree = new KDTree(maxD) ;
    // Make dimensional comparators that compare points by ith dimension
    comparators = new Comparator[ maxD+1] ;
    for (int i = 1; i <= maxD; i++) {
      comparators[ i] = new DimensionalComparator(i) ;
    }
    tree. setRoot(generate (1, maxD, points, 0, points. length-1) ) ;
    return tree;
  }

  // generate the node for the d-th dimension (1 <= d <= maxD)
  // for points[ left, right]
  private static DimensionalNode generate (int d, int maxD,
                                           IMultiPoint points[ ] ,
                                           int left, int right) {
    // Handle the easy cases first
    if (right < left) { return null; }
    if (right == left) { return new DimensionalNode (d, points[ left] ) ; }
    // Order the array[ left, right] so the mth element will be the median
    // and the elements prior to it will all be <=, though they won' t
    // necessarily be sorted; similarly, the elements after will all be >=
    int m = 1+(right-left) /2;
    Selection. select(points, m, left, right, comparators[ d] ) ;
    // Median point on this dimension becomes the parent
    DimensionalNode dm = new DimensionalNode (d, points[ left+m-1] ) ;
    // update to the next dimension, or reset back to 1
    if (++d > maxD) { d = 1; }
    // recursively compute left and right sub-trees, which translate
    // into ' below' and ' above' for n-dimensions.
    dm. setBelow(maxD, generate (d, maxD, points, left, left+m-2) ) ;
    dm. setAbove(maxD, generate (d, maxD, points, left+m, right) ) ;
    return dm;
  }
}

O (n लॉग इन करें) सबसे खराब हे (एन): निकटतम पड़ोसियों सबसे अच्छा ढूँढना

// method in KDTree
public IMultiPoint nearest (IMultiPoint target) {
  if (root == null) return null;
  // find parent node to which target would have been inserted. This is our
  // best shot at locating closest point; compute best distance guess so far
  DimensionalNode parent = parent(target) ;
  IMultiPoint result = parent. point;
  double smallest = target. distance(result) ;
  // now start back at the root, and check all rectangles that potentially
  // overlap this smallest distance. If better one is found, return it.
  double best[ ] = new double[ ] { smallest };
  double raw[ ] = target. raw( );
  IMultiPoint betterOne = root. nearest (raw, best) ;
  if (betterOne ! = null) { return betterOne; }
  return result;
}

// method in DimensionalNode. min[ 0] contains best computed shortest distance.
IMultiPoint nearest (double[ ] rawTarget, double min[ ] ) {
    // Update minimum if we are closer.
    IMultiPoint result = null;
    // If shorter, update minimum
    double d = shorter(rawTarget, min[ 0] ) ;
    if (d >= 0 && d < min[ 0] ) {
      min[ 0] = d;
      result = point;
    }
    // determine if we must dive into the subtrees by computing direct
    // perpendicular distance to the axis along which node separates
    // the plane. If d is smaller than the current smallest distance,
    // we could "bleed" over the plane so we must check both.
    double dp = Math. abs(coord - rawTarget[ dimension-1] ) ;
    IMultiPoint newResult = null;
    if (dp < min[ 0] ) {
      // must dive into both. Return closest one.
      if (above ! = null) {
        newResult = above. nearest (rawTarget, min) ;
        if (newResult ! = null) { result = newResult; }
      }
      if (below ! = null) {
        newResult = below. nearest(rawTarget, min) ;
        if (newResult ! = null) {  result = newResult; }
      }
    } else {
      // only need to go in one! Determine which one now.
      if (rawTarget[ dimension-1] < coord) {
        if (below ! = null) {
          newResult = below. nearest (rawTarget, min) ;
        }
      } else {
        if (above ! = null) {
          newResult = above. nearest (rawTarget, min) ;
        }
      }
      // Use smaller result, if found.
      if (newResult ! = null) { return newResult; }
    }
    return result;
  }

के बारे में अधिक विकिपीडिया पर केडी-पेड़

13/01/2010 को 17:39
का स्रोत उपयोगकर्ता

वोट
1

मैं हाल ही में MapKit के साथ टिप्पणी क्लस्टरिंग को लागू करने के लिए किया था। समाधान जैसा कि ऊपर उल्लेख अच्छे हैं, आपके उपयोग के मामले पर निर्भर करता है। मैं FBAnnotationClustering (ऑब्जेक्टिव-सी), क्योंकि यह मुक्त था के साथ जा रहा समाप्त हो गया है, और सितारों और GitHub पर कुछ मुद्दों के बहुत सारे थे:

https://github.com/infinum/FBAnnotationClustering

एप्लिकेशन मैं पर काम कर रहा था बहुत नक्शा केंद्रित किया गया था, तो यह समझ में स्विफ्ट में FBAnnotationClustering अनुवाद करने के लिए बनाया है। यहाँ दृष्टिकोण है, जो GitHub पर नमूना परियोजना के लिए एक लिंक शामिल पर एक ब्लॉग पोस्ट है।

http://ribl.co/blog/2015/05/28/map-clustering-with-swift-how-we-implemented-it-into-the-ribl-ios-app/

29/06/2015 को 17:50
का स्रोत उपयोगकर्ता

वोट
1

अवधारणा का सबूत ऑफलाइन नक्शे एप्लिकेशन "OffMaps";)

http://itunes.apple.com/us/app/offmaps/id313854422?mt=8

14/01/2010 को 21:23
का स्रोत उपयोगकर्ता

वोट
0

WWDC 2011 वीडियो से प्रेरित होकर, इस कोड को मेरे लिए बहुत अच्छी तरह से काम करता है। हो सकता है कि नहीं सभी का सबसे तेजी से यहां प्रस्तावित लेकिन यह मुक्त करने के लिए है और यह निश्चित रूप से सबसे सरल है।

यह मूल रूप से 2 नक्शे का उपयोग करें। एक छिपा हुआ है और हर एक एनोटेशन (मेरे कोड में allAnnotationMapView) पकड़ो। एक दिखाई देता है और केवल समूहों या टिप्पणियां दिखाने यदि एकल (मेरे कोड में MapView)।

- (void)didZoom:(UIGestureRecognizer*)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
        [self updateVisibleAnnotations];
    }
}
- (void)updateVisibleAnnotations {
    static float marginFactor = 2.0f;
    static float bucketSize = 50.0f;
    MKMapRect visibleMapRect = [self.mapView visibleMapRect];
    MKMapRect adjustedVisibleMapRect = MKMapRectInset(visibleMapRect, -marginFactor * visibleMapRect.size.width, -marginFactor * visibleMapRect.size.height);

    CLLocationCoordinate2D leftCoordinate = [self.mapView convertPoint:CGPointZero toCoordinateFromView:self.view];
    CLLocationCoordinate2D rightCoordinate = [self.mapView convertPoint:CGPointMake(bucketSize, 0) toCoordinateFromView:self.view];
    double gridSize = MKMapPointForCoordinate(rightCoordinate).x - MKMapPointForCoordinate(leftCoordinate).x;
    MKMapRect gridMapRect = MKMapRectMake(0, 0, gridSize, gridSize);

    double startX = floor(MKMapRectGetMinX(adjustedVisibleMapRect) / gridSize) * gridSize;
    double startY = floor(MKMapRectGetMinY(adjustedVisibleMapRect) / gridSize) * gridSize;
    double endX = floor(MKMapRectGetMaxX(adjustedVisibleMapRect) / gridSize) * gridSize;
    double endY = floor(MKMapRectGetMaxY(adjustedVisibleMapRect) / gridSize) * gridSize;

    gridMapRect.origin.y = startY;
    while(MKMapRectGetMinY(gridMapRect) <= endY) {
        gridMapRect.origin.x = startX;
        while (MKMapRectGetMinX(gridMapRect) <= endX) {
            NSSet *allAnnotationsInBucket = [self.allAnnotationMapView annotationsInMapRect:gridMapRect];
            NSSet *visibleAnnotationsInBucket = [self.mapView annotationsInMapRect:gridMapRect];

            NSMutableSet *filteredAnnotationsInBucket = [[allAnnotationsInBucket objectsPassingTest:^BOOL(id obj, BOOL *stop) {
                BOOL isPointMapItem = [obj isKindOfClass:[PointMapItem class]];
                BOOL shouldBeMerged = NO;
                if (isPointMapItem) {
                    PointMapItem *pointItem = (PointMapItem *)obj;
                    shouldBeMerged = pointItem.shouldBeMerged;
                }
                return shouldBeMerged;
            }] mutableCopy];
            NSSet *notMergedAnnotationsInBucket = [allAnnotationsInBucket objectsPassingTest:^BOOL(id obj, BOOL *stop) {
                BOOL isPointMapItem = [obj isKindOfClass:[PointMapItem class]];
                BOOL shouldBeMerged = NO;
                if (isPointMapItem) {
                    PointMapItem *pointItem = (PointMapItem *)obj;
                    shouldBeMerged = pointItem.shouldBeMerged;
                }
                return isPointMapItem && !shouldBeMerged;
            }];
            for (PointMapItem *item in notMergedAnnotationsInBucket) {
                [self.mapView addAnnotation:item];
            }

            if(filteredAnnotationsInBucket.count > 0) {
                PointMapItem *annotationForGrid = (PointMapItem *)[self annotationInGrid:gridMapRect usingAnnotations:filteredAnnotationsInBucket];
                [filteredAnnotationsInBucket removeObject:annotationForGrid];
                annotationForGrid.containedAnnotations = [filteredAnnotationsInBucket allObjects];
                [self.mapView addAnnotation:annotationForGrid];
                //force reload of the image because it's not done if annotationForGrid is already present in the bucket!!
                MKAnnotationView* annotationView = [self.mapView viewForAnnotation:annotationForGrid];
                NSString *imageName = [AnnotationsViewUtils imageNameForItem:annotationForGrid selected:NO];
                UILabel *countLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 2, 8, 8)];
                [countLabel setFont:[UIFont fontWithName:POINT_FONT_NAME size:10]];
                [countLabel setTextColor:[UIColor whiteColor]];
                [annotationView addSubview:countLabel];
                imageName = [AnnotationsViewUtils imageNameForItem:annotationForGrid selected:NO];
                annotationView.image = [UIImage imageNamed:imageName];

                if (filteredAnnotationsInBucket.count > 0){
                    [self.mapView deselectAnnotation:annotationForGrid animated:NO];
                }
                for (PointMapItem *annotation in filteredAnnotationsInBucket) {
                    [self.mapView deselectAnnotation:annotation animated:NO];
                    annotation.clusterAnnotation = annotationForGrid;
                    annotation.containedAnnotations = nil;
                    if ([visibleAnnotationsInBucket containsObject:annotation]) {
                        CLLocationCoordinate2D actualCoordinate = annotation.coordinate;
                        [UIView animateWithDuration:0.3 animations:^{
                            annotation.coordinate = annotation.clusterAnnotation.coordinate;
                        } completion:^(BOOL finished) {
                            annotation.coordinate = actualCoordinate;
                            [self.mapView removeAnnotation:annotation];
                        }];
                    }
                }
            }
            gridMapRect.origin.x += gridSize;
        }
        gridMapRect.origin.y += gridSize;
    }
}

- (id<MKAnnotation>)annotationInGrid:(MKMapRect)gridMapRect usingAnnotations:(NSSet *)annotations {
    NSSet *visibleAnnotationsInBucket = [self.mapView annotationsInMapRect:gridMapRect];
    NSSet *annotationsForGridSet = [annotations objectsPassingTest:^BOOL(id obj, BOOL *stop) {
        BOOL returnValue = ([visibleAnnotationsInBucket containsObject:obj]);
        if (returnValue) {
            *stop = YES;
        }
        return returnValue;
    }];

    if (annotationsForGridSet.count != 0) {
        return [annotationsForGridSet anyObject];
    }
    MKMapPoint centerMapPoint = MKMapPointMake(MKMapRectGetMinX(gridMapRect), MKMapRectGetMidY(gridMapRect));
    NSArray *sortedAnnotations = [[annotations allObjects] sortedArrayUsingComparator:^(id obj1, id obj2) {
        MKMapPoint mapPoint1 = MKMapPointForCoordinate(((id<MKAnnotation>)obj1).coordinate);
        MKMapPoint mapPoint2 = MKMapPointForCoordinate(((id<MKAnnotation>)obj2).coordinate);

        CLLocationDistance distance1 = MKMetersBetweenMapPoints(mapPoint1, centerMapPoint);
        CLLocationDistance distance2 = MKMetersBetweenMapPoints(mapPoint2, centerMapPoint);

        if (distance1 < distance2) {
            return NSOrderedAscending;
        }
        else if (distance1 > distance2) {
            return NSOrderedDescending;
        }
        return NSOrderedSame;
    }];
    return [sortedAnnotations objectAtIndex:0];
}
29/11/2013 को 14:55
का स्रोत उपयोगकर्ता

वोट
-1

मुझे लगता है कि तस्वीरें Brisko (iTunes लिंक) करता है।
मुझे नहीं लगता कि इसके लिए एक कोको टच रूपरेखा वहाँ है।

12/01/2010 को 10:06
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more