Authored by Justin R. Miller

fixes #12: remove boundingMask & make minZoom automatic per frame

... ... @@ -49,13 +49,6 @@
@class RMQuadTree;
@class RMUserLocation;
// constants for boundingMask
enum : NSUInteger {
RMMapNoMinBound = 0, // Map can be zoomed out past view limits
RMMapMinHeightBound = 1, // Minimum map height when zooming out restricted to view height
RMMapMinWidthBound = 2 // Minimum map width when zooming out restricted to view width (default)
};
// constants for the scrollview deceleration mode
typedef enum : NSUInteger {
RMMapDecelerationNormal = 0,
... ... @@ -129,8 +122,6 @@ typedef enum : NSUInteger {
/** Take missing tiles from lower-numbered zoom levels, up to a given number of zoom levels. This can be used in order to increase perceived tile load performance or to allow zooming in beyond levels supported natively by a given tile source. Defaults to 1. */
@property (nonatomic, assign) NSUInteger missingTilesDepth;
@property (nonatomic, assign) NSUInteger boundingMask;
/** A custom, static view to use behind the map tiles. The default behavior is to use grid imagery that moves with map panning like MapKit. */
@property (nonatomic, retain) UIView *backgroundView;
... ...
... ... @@ -85,8 +85,6 @@
- (void)correctPositionOfAllAnnotationsIncludingInvisibles:(BOOL)correctAllLayers animated:(BOOL)animated;
- (void)correctOrderingOfAllAnnotations;
- (void)correctMinZoomScaleForBoundingMask;
- (void)updateHeadingForDeviceOrientation;
@end
... ... @@ -192,11 +190,12 @@
RMAnnotation *_currentAnnotation;
SMCalloutView *_currentCallout;
BOOL _rotateAtMinZoom;
}
@synthesize decelerationMode = _decelerationMode;
@synthesize boundingMask = _boundingMask;
@synthesize zoomingInPivotsAroundCenter = _zoomingInPivotsAroundCenter;
@synthesize minZoom = _minZoom, maxZoom = _maxZoom;
@synthesize screenScale = _screenScale;
... ... @@ -246,7 +245,6 @@
_screenScale = [UIScreen mainScreen].scale;
_boundingMask = RMMapMinWidthBound;
_adjustTilesForRetinaDisplay = NO;
_missingTilesDepth = 1;
_debugTiles = NO;
... ... @@ -288,7 +286,6 @@
[self setCenterCoordinate:initialCenterCoordinate animated:NO];
[self setDecelerationMode:RMMapDecelerationFast];
[self setBoundingMask:RMMapMinHeightBound];
self.showLogoBug = YES;
... ... @@ -393,7 +390,8 @@
[self setCenterProjectedPoint:centerPoint animated:NO];
[self correctPositionOfAllAnnotations];
[self correctMinZoomScaleForBoundingMask];
self.minZoom = 0; // force new minZoom calculation
}
}
... ... @@ -466,10 +464,17 @@
//
if (self.userTrackingMode == RMUserTrackingModeFollowWithHeading)
[self locationManager:_locationManager didUpdateHeading:_locationManager.heading];
// fix UIScrollView artifacts from rotation at minZoomScale
//
_rotateAtMinZoom = fabs(self.zoom - self.minZoom) < 0.1;
}
- (void)handleDidChangeOrientationNotification:(NSNotification *)notification
{
if (_rotateAtMinZoom)
[_mapScrollView setZoomScale:_mapScrollView.minimumZoomScale animated:YES];
[self updateHeadingForDeviceOrientation];
}
... ... @@ -833,31 +838,6 @@
#pragma mark -
#pragma mark Zoom
- (void)setBoundingMask:(NSUInteger)mask
{
_boundingMask = mask;
[self correctMinZoomScaleForBoundingMask];
}
- (void)correctMinZoomScaleForBoundingMask
{
if (self.boundingMask != RMMapNoMinBound)
{
if ([_tiledLayersSuperview.subviews count] == 0)
return;
CGFloat newMinZoomScale = (self.boundingMask == RMMapMinWidthBound ? self.bounds.size.width : self.bounds.size.height) / ((CATiledLayer *)((RMMapTiledLayerView *)[_tiledLayersSuperview.subviews objectAtIndex:0]).layer).tileSize.width;
if (_mapScrollView.minimumZoomScale > 0 && newMinZoomScale > _mapScrollView.minimumZoomScale)
{
RMLog(@"clamping min zoom of %f to %f due to %@", log2f(_mapScrollView.minimumZoomScale), log2f(newMinZoomScale), (self.boundingMask == RMMapMinWidthBound ? @"RMMapMinWidthBound" : @"RMMapMinHeightBound"));
_mapScrollView.minimumZoomScale = newMinZoomScale;
}
}
}
- (RMProjectedRect)projectedBounds
{
CGPoint bottomLeft = CGPointMake(_mapScrollView.contentOffset.x, _mapScrollView.contentSize.height - (_mapScrollView.contentOffset.y + _mapScrollView.bounds.size.height));
... ... @@ -895,48 +875,6 @@
[_mapScrollView zoomToRect:zoomRect animated:animated];
}
- (float)adjustedZoomForCurrentBoundingMask:(float)zoomFactor
{
if (_boundingMask == RMMapNoMinBound)
return zoomFactor;
double newMetersPerPixel = _metersPerPixel / zoomFactor;
RMProjectedRect mercatorBounds = [_projection planetBounds];
// Check for MinWidthBound
if (_boundingMask & RMMapMinWidthBound)
{
double newMapContentsWidth = mercatorBounds.size.width / newMetersPerPixel;
double screenBoundsWidth = [self bounds].size.width;
double mapContentWidth;
if (newMapContentsWidth < screenBoundsWidth)
{
// Calculate new zoom facter so that it does not shrink the map any further.
mapContentWidth = mercatorBounds.size.width / _metersPerPixel;
zoomFactor = screenBoundsWidth / mapContentWidth;
}
}
// Check for MinHeightBound
if (_boundingMask & RMMapMinHeightBound)
{
double newMapContentsHeight = mercatorBounds.size.height / newMetersPerPixel;
double screenBoundsHeight = [self bounds].size.height;
double mapContentHeight;
if (newMapContentsHeight < screenBoundsHeight)
{
// Calculate new zoom facter so that it does not shrink the map any further.
mapContentHeight = mercatorBounds.size.height / _metersPerPixel;
zoomFactor = screenBoundsHeight / mapContentHeight;
}
}
return zoomFactor;
}
- (BOOL)shouldZoomToTargetZoom:(float)targetZoom withZoomFactor:(float)zoomFactor
{
// bools for syntactical sugar to understand the logic in the if statement below
... ... @@ -978,7 +916,6 @@
if (![self tileSourceBoundsContainScreenPoint:pivot])
return;
zoomFactor = [self adjustedZoomForCurrentBoundingMask:zoomFactor];
float zoomDelta = log2f(zoomFactor);
float targetZoom = zoomDelta + [self zoom];
... ... @@ -1331,6 +1268,12 @@
_mapScrollViewIsZooming = NO;
// slight jiggle fixes problems with UIScrollView
// briefly allowing zoom beyond min
//
[self moveBy:CGSizeMake(-1, -1)];
[self moveBy:CGSizeMake( 1, 1)];
[self correctPositionOfAllAnnotations];
if (_loadingTileView)
... ... @@ -2275,16 +2218,18 @@
- (void)setMinZoom:(float)newMinZoom
{
if (newMinZoom < 0.0)
newMinZoom = 0.0;
float boundingDimension = fmaxf(self.bounds.size.width, self.bounds.size.height);
float tileSideLength = _tileSourcesContainer.tileSideLength;
float clampedMinZoom = log2(boundingDimension / tileSideLength);
if (newMinZoom < clampedMinZoom)
newMinZoom = clampedMinZoom;
_minZoom = newMinZoom;
// RMLog(@"New minZoom:%f", newMinZoom);
_mapScrollView.minimumZoomScale = exp2f(newMinZoom);
[self correctMinZoomScaleForBoundingMask];
}
- (float)tileSourcesMinZoom
... ...