iPhone térkép Kit klaszter tűhegynyi

szavazat
23

Ami iPhone térkép Kit klaszter tűhegynyi:

Van 1000-es jelek, hogy meg akarom mutatni a térképen, de ez túl sok ahhoz, hogy kezelni, így szeretnék klaszter őket.

Vannak keretek állnak rendelkezésre, vagy igazolást fogalmak? Hogy ez lehetséges, vagy már meg is történt?

A kérdést 12/01/2010 09:52
a forrás felhasználó
Más nyelveken...                            


8 válasz

szavazat
13

Használhatja REVClusterMap klaszterezni

Válaszolt 18/07/2011 06:54
a forrás felhasználó

szavazat
8

Megjegyzés: Ez egy kereskedelmi termék én kapcsolatban, de megoldja ezt a nagyon problémát.

Azt megoldotta ezt a problémát néhány az én apps, és úgy döntött, hogy bontsa ki egy újrafelhasználható keretben. Úgy hívják SuperPIN és ez egy (kereskedelmi, licenc ára $ 149) iOS-keretrendszer belsőleg használ négyfák a kommentárok tárolására, és végrehajtja a hálózat-alapú csoportosítás. Az algoritmus elég gyors, a mellékelt minta app mutatja repülőtér a világon (több mint 30k + jelöléseit), és ez fut elég sima egy iPhone 3G.

Válaszolt 02/05/2011 15:18
a forrás felhasználó

szavazat
6

Próbáltam a többiek itt javasolt, és azt is megállapította, OCMapView ami működött a legjobban.

A szabad és lehetővé teszi az egyszerű csoportosítása jelölések, amelyek az, amit szükség. Ez egy kicsit újabb és frissebb, mint a Revolver és nekem könnyebb megvalósítani.

Válaszolt 05/02/2013 22:05
a forrás felhasználó

szavazat
6

Ez lehet egy kicsit olyan, mint egy láncfűrész a fűnyírás, de itt egy részlet algoritmusok dióhéjban

Létrehozása KD-fa ...

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;
  }
}

Megtaláljuk a legközelebbi szomszédok legjobb: O (log n) legrosszabb 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;
  }

Bővebben a KD-fák a Wikipedia

Válaszolt 13/01/2010 17:39
a forrás felhasználó

szavazat
1

Nemrég volt, hogy végre kommentár klaszterezést MapKit. A fent említett megoldást jók, használattól függően ügyben. Így végül megy FBAnnotationClustering (Objective-C), mert ingyen volt, és volt sok csillag és néhány kérdés a GitHub:

https://github.com/infinum/FBAnnotationClustering

Az alkalmazás dolgoztam volt nagyon map-centrikus, ezért logikus, hogy lefordítani FBAnnotationClustering a Swift. Itt egy blogbejegyzést a megközelítést, amely magában foglal egy linket a minta projekt GitHub.

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

Válaszolt 29/06/2015 17:50
a forrás felhasználó

szavazat
1

A prototípus az Offline Maps app „OffMaps”)

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

Válaszolt 14/01/2010 21:23
a forrás felhasználó

szavazat
0

Ihlette WWDC 2011 video, ezt a kódot nagyon jól működik nekem. Lehet, hogy nem a leggyorsabb az összes itt javasolt, de ez ingyenes, és ez egyértelműen a legegyszerűbb.

Ez alapvetően használjon 2 térképeket. Egy rejtett és tartsa minden kommentár (allAnnotationMapView én kód). Egy látható és csak azokat a csoportokat, vagy a kommentárok, ha egyetlen (mapView én kód).

- (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];
}
Válaszolt 29/11/2013 14:55
a forrás felhasználó

szavazat
-1

Azt hiszem Foto Brisko (iTunes link) ez.
Nem hiszem, hogy van egy Cocoa Touch keretet biztosítson.

Válaszolt 12/01/2010 10:06
a forrás felhasználó

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