많은 주석이있는지도 뷰가 있습니다. 대다수는 서로 매우 가깝습니다. 내가하고 싶은 일은 iOS의 사진 앱과 유사합니다. 주석이 서로 너무 가까울 때 그룹화되며 축소 할 때마다 너무 멀리 떨어져 있으면 그룹화되지 않습니다.확대/축소 수준에 따라 그룹화/그룹 해제 (빠른 속도로 유지)
나는 this question을 이미 보았지만 주어진 답은 실제로 내가 찾던 것이 아닙니다.
내가 구현할 수있는 라이브러리 또는 알고리즘을 찾고 있습니다.
많은 주석이있는지도 뷰가 있습니다. 대다수는 서로 매우 가깝습니다. 내가하고 싶은 일은 iOS의 사진 앱과 유사합니다. 주석이 서로 너무 가까울 때 그룹화되며 축소 할 때마다 너무 멀리 떨어져 있으면 그룹화되지 않습니다.확대/축소 수준에 따라 그룹화/그룹 해제 (빠른 속도로 유지)
나는 this question을 이미 보았지만 주어진 답은 실제로 내가 찾던 것이 아닙니다.
내가 구현할 수있는 라이브러리 또는 알고리즘을 찾고 있습니다.
완전한 대답을 보려면 here을보십시오. 여기에는 MapKit과 Google Maps에 대한 구현이 모두 포함되어 있습니다. 이 코드는 WWDC 2011 비디오에서 영감을 얻었으며 내 응용 프로그램에서 잘 작동합니다.
어쨌든 여기에 MapKit에 대한 코드를 게시하지만 다른 유용한 답변이 있습니다.
- (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];
}
Apple의 WWDC 2011 세션 비디오 중 하나에서이 작업을 정확하게 수행하는 방법을 보여줍니다. https://developer.apple.com/videos/wwdc/2011/ (개발자 등록 필요)으로 이동하여 "MapKit으로 정보를 시각적으로 시각화하기"라는 비디오로 스크롤하십시오. 기본 아이디어는 오프 스크린지도보기를 사용하여 모든 주석을 보관하고 필요에 따라 화면 맵보기에 복사하여 한 번에 너무 많은지도를 표시하지 않도록합니다. 확대/축소 할 때 주석이있는 멋진 애니메이션도 수행합니다.
어디에서 동영상의 데모 소스 코드를 얻을 수 있습니까? –
그건 나도 몰라. – shawkinaw
여기에 샘플이 있습니까? – karthikeyan