Authored by Thomas Rasch

o Finer control over the clustering by separating clusterAreaSize and clusterMarkerSize

... ... @@ -84,7 +84,7 @@ typedef enum {
NSMutableSet *visibleAnnotations;
RMQuadTree *quadTree;
BOOL enableClustering, positionClusterMarkersAtTheGravityCenter;
CGSize clusterMarkerSize;
CGSize clusterMarkerSize, clusterAreaSize;
id <RMTileSource> tileSource;
RMTileCache *tileCache; // Generic tile cache
... ... @@ -125,6 +125,7 @@ typedef enum {
@property (nonatomic, assign) BOOL enableClustering;
@property (nonatomic, assign) BOOL positionClusterMarkersAtTheGravityCenter;
@property (nonatomic, assign) CGSize clusterMarkerSize;
@property (nonatomic, assign) CGSize clusterAreaSize;
@property (nonatomic, readonly) RMProjection *projection;
@property (nonatomic, readonly) id <RMMercatorToTileProjection> mercatorToTileProjection;
... ...
... ... @@ -110,7 +110,7 @@
@synthesize screenScale;
@synthesize tileCache;
@synthesize quadTree;
@synthesize enableClustering, positionClusterMarkersAtTheGravityCenter, clusterMarkerSize;
@synthesize enableClustering, positionClusterMarkersAtTheGravityCenter, clusterMarkerSize, clusterAreaSize;
@synthesize adjustTilesForRetinaDisplay;
#pragma mark -
... ... @@ -148,6 +148,7 @@
[self setQuadTree:[[[RMQuadTree alloc] initWithMapView:self] autorelease]];
enableClustering = positionClusterMarkersAtTheGravityCenter = NO;
clusterMarkerSize = CGSizeMake(100.0, 100.0);
clusterAreaSize = CGSizeMake(150.0, 150.0);
[self setTileCache:[[[RMTileCache alloc] init] autorelease]];
[self setTileSource:newTilesource];
... ... @@ -1536,7 +1537,11 @@
boundingBox.size.width += 2*boundingBoxBuffer;
boundingBox.size.height += 2*boundingBoxBuffer;
NSArray *annotationsToCorrect = [quadTree annotationsInProjectedRect:boundingBox createClusterAnnotations:self.enableClustering withClusterSize:RMProjectedSizeMake(self.clusterMarkerSize.width * self.metersPerPixel, self.clusterMarkerSize.height * self.metersPerPixel) findGravityCenter:self.positionClusterMarkersAtTheGravityCenter];
NSArray *annotationsToCorrect = [quadTree annotationsInProjectedRect:boundingBox
createClusterAnnotations:self.enableClustering
withProjectedClusterSize:RMProjectedSizeMake(self.clusterAreaSize.width * self.metersPerPixel, self.clusterAreaSize.height * self.metersPerPixel)
andProjectedClusterMarkerSize:RMProjectedSizeMake(self.clusterMarkerSize.width * self.metersPerPixel, self.clusterMarkerSize.height * self.metersPerPixel)
findGravityCenter:self.positionClusterMarkersAtTheGravityCenter];
NSMutableSet *previousVisibleAnnotations = [[NSMutableSet alloc] initWithSet:visibleAnnotations];
for (RMAnnotation *annotation in annotationsToCorrect)
... ...
... ... @@ -76,6 +76,10 @@ typedef enum {
// Returns all annotations that are either inside of or intersect with boundingBox
- (NSArray *)annotationsInProjectedRect:(RMProjectedRect)boundingBox;
- (NSArray *)annotationsInProjectedRect:(RMProjectedRect)boundingBox createClusterAnnotations:(BOOL)createClusterAnnotations withClusterSize:(RMProjectedSize)clusterSize findGravityCenter:(BOOL)findGravityCenter;
- (NSArray *)annotationsInProjectedRect:(RMProjectedRect)boundingBox
createClusterAnnotations:(BOOL)createClusterAnnotations
withProjectedClusterSize:(RMProjectedSize)clusterSize
andProjectedClusterMarkerSize:(RMProjectedSize)clusterMarkerSize
findGravityCenter:(BOOL)findGravityCenter;
@end
... ...
... ... @@ -25,7 +25,12 @@
- (void)addAnnotation:(RMAnnotation *)annotation;
- (void)removeAnnotation:(RMAnnotation *)annotation;
- (void)addAnnotationsInBoundingBox:(RMProjectedRect)aBoundingBox toMutableArray:(NSMutableArray *)someArray createClusterAnnotations:(BOOL)createClusterAnnotations withClusterSize:(RMProjectedSize)clusterSize findGravityCenter:(BOOL)findGravityCenter;
- (void)addAnnotationsInBoundingBox:(RMProjectedRect)aBoundingBox
toMutableArray:(NSMutableArray *)someArray
createClusterAnnotations:(BOOL)createClusterAnnotations
withProjectedClusterSize:(RMProjectedSize)clusterSize
andProjectedClusterMarkerSize:(RMProjectedSize)clusterMarkerSize
findGravityCenter:(BOOL)findGravityCenter;
- (void)removeUpwardsAllCachedClusterAnnotations;
... ... @@ -363,7 +368,12 @@
return clusteredAnnotations;
}
- (void)addAnnotationsInBoundingBox:(RMProjectedRect)aBoundingBox toMutableArray:(NSMutableArray *)someArray createClusterAnnotations:(BOOL)createClusterAnnotations withClusterSize:(RMProjectedSize)clusterSize findGravityCenter:(BOOL)findGravityCenter
- (void)addAnnotationsInBoundingBox:(RMProjectedRect)aBoundingBox
toMutableArray:(NSMutableArray *)someArray
createClusterAnnotations:(BOOL)createClusterAnnotations
withProjectedClusterSize:(RMProjectedSize)clusterSize
andProjectedClusterMarkerSize:(RMProjectedSize)clusterMarkerSize
findGravityCenter:(BOOL)findGravityCenter
{
if (createClusterAnnotations)
{
... ... @@ -455,16 +465,17 @@
averageX /= (double)enclosedAnnotationsCount;
averageY /= (double) enclosedAnnotationsCount;
double halfClusterWidth = clusterSize.width / 2.0, halfClusterHeight = clusterSize.height / 2.0;
double halfClusterMarkerWidth = clusterMarkerSize.width / 2.0,
halfClusterMarkerHeight = clusterMarkerSize.height / 2.0;
if (averageX - halfClusterWidth < boundingBox.origin.x)
averageX = boundingBox.origin.x + halfClusterWidth;
if (averageX + halfClusterWidth > boundingBox.origin.x + boundingBox.size.width)
averageX = boundingBox.origin.x + boundingBox.size.width - halfClusterWidth;
if (averageY - halfClusterHeight < boundingBox.origin.y)
averageY = boundingBox.origin.y + halfClusterHeight;
if (averageY + halfClusterHeight > boundingBox.origin.y + boundingBox.size.height)
averageY = boundingBox.origin.y + boundingBox.size.height - halfClusterHeight;
if (averageX - halfClusterMarkerWidth < boundingBox.origin.x)
averageX = boundingBox.origin.x + halfClusterMarkerWidth;
if (averageX + halfClusterMarkerWidth > boundingBox.origin.x + boundingBox.size.width)
averageX = boundingBox.origin.x + boundingBox.size.width - halfClusterMarkerWidth;
if (averageY - halfClusterMarkerHeight < boundingBox.origin.y)
averageY = boundingBox.origin.y + halfClusterMarkerHeight;
if (averageY + halfClusterMarkerHeight > boundingBox.origin.y + boundingBox.size.height)
averageY = boundingBox.origin.y + boundingBox.size.height - halfClusterMarkerHeight;
// TODO: anchorPoint
clusterMarkerPosition = RMProjectedPointMake(averageX, averageY);
... ... @@ -515,13 +526,13 @@
}
if (RMProjectedRectIntersectsProjectedRect(aBoundingBox, northWestBoundingBox))
[northWest addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withClusterSize:clusterSize findGravityCenter:findGravityCenter];
[northWest addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withProjectedClusterSize:clusterSize andProjectedClusterMarkerSize:clusterMarkerSize findGravityCenter:findGravityCenter];
if (RMProjectedRectIntersectsProjectedRect(aBoundingBox, northEastBoundingBox))
[northEast addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withClusterSize:clusterSize findGravityCenter:findGravityCenter];
[northEast addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withProjectedClusterSize:clusterSize andProjectedClusterMarkerSize:clusterMarkerSize findGravityCenter:findGravityCenter];
if (RMProjectedRectIntersectsProjectedRect(aBoundingBox, southWestBoundingBox))
[southWest addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withClusterSize:clusterSize findGravityCenter:findGravityCenter];
[southWest addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withProjectedClusterSize:clusterSize andProjectedClusterMarkerSize:clusterMarkerSize findGravityCenter:findGravityCenter];
if (RMProjectedRectIntersectsProjectedRect(aBoundingBox, southEastBoundingBox))
[southEast addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withClusterSize:clusterSize findGravityCenter:findGravityCenter];
[southEast addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withProjectedClusterSize:clusterSize andProjectedClusterMarkerSize:clusterMarkerSize findGravityCenter:findGravityCenter];
@synchronized (annotations)
{
... ... @@ -616,16 +627,16 @@
- (NSArray *)annotationsInProjectedRect:(RMProjectedRect)boundingBox
{
return [self annotationsInProjectedRect:boundingBox createClusterAnnotations:NO withClusterSize:RMProjectedSizeMake(0.0, 0.0) findGravityCenter:NO];
return [self annotationsInProjectedRect:boundingBox createClusterAnnotations:NO withProjectedClusterSize:RMProjectedSizeMake(0.0, 0.0) andProjectedClusterMarkerSize:RMProjectedSizeMake(0.0, 0.0) findGravityCenter:NO];
}
- (NSArray *)annotationsInProjectedRect:(RMProjectedRect)boundingBox createClusterAnnotations:(BOOL)createClusterAnnotations withClusterSize:(RMProjectedSize)clusterSize findGravityCenter:(BOOL)findGravityCenter
- (NSArray *)annotationsInProjectedRect:(RMProjectedRect)boundingBox createClusterAnnotations:(BOOL)createClusterAnnotations withProjectedClusterSize:(RMProjectedSize)clusterSize andProjectedClusterMarkerSize:(RMProjectedSize)clusterMarkerSize findGravityCenter:(BOOL)findGravityCenter
{
NSMutableArray *annotations = [NSMutableArray array];
@synchronized (self)
{
[rootNode addAnnotationsInBoundingBox:boundingBox toMutableArray:annotations createClusterAnnotations:createClusterAnnotations withClusterSize:clusterSize findGravityCenter:findGravityCenter];
[rootNode addAnnotationsInBoundingBox:boundingBox toMutableArray:annotations createClusterAnnotations:createClusterAnnotations withProjectedClusterSize:clusterSize andProjectedClusterMarkerSize:clusterMarkerSize findGravityCenter:findGravityCenter];
}
return annotations;
... ...
... ... @@ -92,6 +92,10 @@
mapView.enableClustering = YES;
mapView.positionClusterMarkersAtTheGravityCenter = YES;
UIImage *clusterMarkerImage = [UIImage imageNamed:@"marker-blue.png"];
mapView.clusterMarkerSize = clusterMarkerImage.size;
mapView.clusterAreaSize = CGSizeMake(clusterMarkerImage.size.width * 1.25, clusterMarkerImage.size.height * 1.25);
center.latitude = 47.5635;
center.longitude = 10.20981;
... ...