diff --git a/.gitmodules b/.gitmodules index 332f239..ec02bc2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,4 +6,4 @@ url = https://github.com/groue/GRMustache.git [submodule "MapView/Map/SMCalloutView"] path = MapView/Map/SMCalloutView - url = https://github.com/mapbox/SMCalloutView.git + url = https://github.com/nfarina/calloutview.git diff --git a/MapView/Map/Mapbox.h b/MapView/Map/Mapbox.h index 5a24389..53572b1 100644 --- a/MapView/Map/Mapbox.h +++ b/MapView/Map/Mapbox.h @@ -36,6 +36,7 @@ #import "RMConfiguration.h" #import "RMCoordinateGridSource.h" #import "RMDatabaseCache.h" +#import "RMGreatCircleAnnotation.h" #import "RMInteractiveSource.h" #import "RMMBTilesSource.h" #import "RMMapboxSource.h" diff --git a/MapView/Map/RMAnnotation.h b/MapView/Map/RMAnnotation.h index 2d55782..b522924 100644 --- a/MapView/Map/RMAnnotation.h +++ b/MapView/Map/RMAnnotation.h @@ -157,6 +157,6 @@ #pragma mark - // Used internally -@property (nonatomic, strong) RMMapView *mapView; +@property (nonatomic, weak) RMMapView *mapView; @end diff --git a/MapView/Map/RMAttributionViewController.m b/MapView/Map/RMAttributionViewController.m index 9c07e32..d184fc6 100644 --- a/MapView/Map/RMAttributionViewController.m +++ b/MapView/Map/RMAttributionViewController.m @@ -133,7 +133,11 @@ { // add SDK info // - [attribution insertString:[NSString stringWithFormat:@"%@ uses the Mapbox iOS SDK © 2013 Mapbox, Inc.<br/><a href='http://mapbox.com/mapbox-ios-sdk'>More</a><br/><br/>", [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleDisplayName"]] atIndex:0]; + NSString *appName = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleDisplayName"]; + NSDateFormatter *dateFormatter = [NSDateFormatter new]; + [dateFormatter setDateFormat:@"yyyy"]; + NSString *currentYear = [dateFormatter stringFromDate:[NSDate date]]; + [attribution insertString:[NSString stringWithFormat:@"%@ uses the Mapbox iOS SDK © %@ Mapbox, Inc.<br/><a href='http://mapbox.com/mapbox-ios-sdk'>More</a><br/><br/>", appName, currentYear] atIndex:0]; // add tinted logo // diff --git a/MapView/Map/RMCompositeSource.h b/MapView/Map/RMCompositeSource.h index 6397d77..1664916 100644 --- a/MapView/Map/RMCompositeSource.h +++ b/MapView/Map/RMCompositeSource.h @@ -28,10 +28,23 @@ #import "RMAbstractMercatorTileSource.h" +/** RMCompositeSource combines two or more other tile sources, compositing them into a single image per tile and caching that composited result to the tile cache. +* +* RMCompositeSource can have better performance for instances of fully opaque tiles that are layered above other tiles in the tile source stacking order. It will determine if a tile is opaque and stop iteration of tile sources below it early as a result, since they would be obscured anyway. */ @interface RMCompositeSource : RMAbstractMercatorTileSource +/** @name Creating Tile Sources */ + +/** Initialize a compositing tile source. +* +* @param tileSources An array of tile sources to be composited. +* @param tileCacheKey A tile cache key for storage of composited result tiles. +* @return An initialized compositing tile source. */ - (id)initWithTileSources:(NSArray *)tileSources tileCacheKey:(NSString *)tileCacheKey; +/** @name Querying Tile Source Information */ + +/** An array of tile sources being composited. */ @property (nonatomic, weak, readonly) NSArray *tileSources; @end diff --git a/MapView/Map/RMDatabaseCache.m b/MapView/Map/RMDatabaseCache.m index 196eb32..2f263f7 100644 --- a/MapView/Map/RMDatabaseCache.m +++ b/MapView/Map/RMDatabaseCache.m @@ -227,10 +227,11 @@ { BOOL result = [db executeUpdate:@"DELETE FROM ZCACHE WHERE last_used < ?", [NSDate dateWithTimeIntervalSinceNow:-_expiryPeriod]]; - if (result == NO) - RMLog(@"Error expiring cache"); + if (result) + result = [db executeUpdate:@"VACUUM"]; - [[db executeQuery:@"VACUUM"] close]; + if ( ! result) + RMLog(@"Error expiring cache"); }]; [_writeQueueLock unlock]; @@ -333,10 +334,11 @@ { BOOL result = [db executeUpdate:@"DELETE FROM ZCACHE WHERE tile_hash IN (SELECT tile_hash FROM ZCACHE ORDER BY last_used LIMIT ?)", [NSNumber numberWithUnsignedLongLong:count]]; - if (result == NO) - RMLog(@"Error purging cache"); + if (result) + result = [db executeUpdate:@"VACUUM"]; - [[db executeQuery:@"VACUUM"] close]; + if ( ! result) + RMLog(@"Error purging cache"); }]; [_writeQueueLock unlock]; @@ -355,10 +357,11 @@ { BOOL result = [db executeUpdate:@"DELETE FROM ZCACHE"]; - if (result == NO) - RMLog(@"Error purging cache"); + if (result) + result = [db executeUpdate:@"VACUUM"]; - [[db executeQuery:@"VACUUM"] close]; + if ( ! result) + RMLog(@"Error purging cache"); }]; [_writeQueueLock unlock]; @@ -378,7 +381,10 @@ { BOOL result = [db executeUpdate:@"DELETE FROM ZCACHE WHERE cache_key = ?", cacheKey]; - if (result == NO) + if (result) + result = [db executeUpdate:@"VACUUM"]; + + if ( ! result) RMLog(@"Error purging cache"); }]; diff --git a/MapView/Map/RMGreatCircleAnnotation.h b/MapView/Map/RMGreatCircleAnnotation.h new file mode 100644 index 0000000..9941aa0 --- /dev/null +++ b/MapView/Map/RMGreatCircleAnnotation.h @@ -0,0 +1,38 @@ +// +// RMGreatCircleAnnotation.m +// MapView +// +// Copyright (c) 2008-2013, Route-Me Contributors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#import "RMShapeAnnotation.h" + +@interface RMGreatCircleAnnotation : RMShapeAnnotation + +- (id)initWithMapView:(RMMapView *)aMapView coordinate1:(CLLocationCoordinate2D)coordinate1 coordinate2:(CLLocationCoordinate2D)coordinate2; + +@property (nonatomic, readonly, assign) CLLocationCoordinate2D coordinate1; +@property (nonatomic, readonly, assign) CLLocationCoordinate2D coordinate2; + +@end diff --git a/MapView/Map/RMGreatCircleAnnotation.m b/MapView/Map/RMGreatCircleAnnotation.m new file mode 100644 index 0000000..54d417a --- /dev/null +++ b/MapView/Map/RMGreatCircleAnnotation.m @@ -0,0 +1,117 @@ +// +// RMGreatCircleAnnotation.m +// MapView +// +// Copyright (c) 2008-2013, Route-Me Contributors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#import "RMGreatCircleAnnotation.h" + +#import "RMShape.h" + +@implementation RMGreatCircleAnnotation + +- (id)initWithMapView:(RMMapView *)aMapView coordinate1:(CLLocationCoordinate2D)coordinate1 coordinate2:(CLLocationCoordinate2D)coordinate2 +{ + if (!(self = [super initWithMapView:aMapView points:@[ [[CLLocation alloc] initWithLatitude:coordinate1.latitude longitude:coordinate1.longitude], [[CLLocation alloc] initWithLatitude:coordinate2.latitude longitude:coordinate2.longitude]]])) + return nil; + + _coordinate1 = coordinate1; + _coordinate2 = coordinate2; + + return self; +} + +- (RMMapLayer *)layer +{ + if ( ! [super layer]) + { + RMShape *shape = [[RMShape alloc] initWithView:self.mapView]; + + [shape performBatchOperations:^(RMShape *aShape) + { + // based on implementation at http://stackoverflow.com/questions/6104517/drawing-great-circle-overlay-lines-on-an-mkmapview + // + double lat1 = self.coordinate1.latitude; + double lon1 = self.coordinate1.longitude; + double lat2 = self.coordinate2.latitude; + double lon2 = self.coordinate2.longitude; + lat1 = lat1 * (M_PI/180); + lon1 = lon1 * (M_PI/180); + lat2 = lat2 * (M_PI/180); + lon2 = lon2 * (M_PI/180); + double d = 2 * asin( sqrt(pow(( sin( (lat1-lat2)/2) ), 2) + cos(lat1) * cos(lat2) * pow(( sin( (lon1-lon2)/2) ), 2))); + int numsegs = 100; + NSMutableArray *coords = [NSMutableArray arrayWithCapacity:numsegs]; + double f = 0.0; + for(int i=1; i<=numsegs; i++) + { + f += 1.0 / (float)numsegs; + double A=sin((1-f)*d)/sin(d); + double B=sin(f*d)/sin(d); + double x = A*cos(lat1) * cos(lon1) + B * cos(lat2) * cos(lon2); + double y = A*cos(lat1) * sin(lon1) + B * cos(lat2) * sin(lon2); + double z = A*sin(lat1) + B*sin(lat2); + double latr=atan2(z, sqrt(pow(x, 2) + pow(y, 2) )); + double lonr=atan2(y, x); + double lat = latr * (180/M_PI); + double lon = lonr * (180/M_PI); + [coords addObject:[[CLLocation alloc] initWithLatitude:lat longitude:lon]]; + } + CLLocationCoordinate2D prevCoord; + NSMutableArray *coords2 = [NSMutableArray array]; + for(int i=0; i<numsegs; i++) + { + CLLocationCoordinate2D coord = ((CLLocation *)coords[i]).coordinate; + if(prevCoord.longitude < -170 && prevCoord.longitude > -180 && prevCoord.longitude < 0 + && coord.longitude > 170 && coord.longitude < 180 && coord.longitude > 0) + { + [coords2 addObjectsFromArray:[coords subarrayWithRange:NSMakeRange(i, [coords count] - i)]]; + [coords removeObjectsInRange:NSMakeRange(i, [coords count] - i)]; + break; + } + prevCoord = coord; + } + + [aShape moveToCoordinate:((CLLocation *)coords[0]).coordinate]; + + for (int i = 1; i < [coords count]; i++) + [aShape addLineToCoordinate:((CLLocation *)coords[i]).coordinate]; + + if ([coords2 count]) + { + [aShape moveToCoordinate:((CLLocation *)coords2[0]).coordinate]; + + for (int j = 1; j < [coords2 count]; j++) + [aShape addLineToCoordinate:((CLLocation *)coords2[j]).coordinate]; + } + }]; + + super.layer = shape; + } + + return [super layer]; +} + +@end diff --git a/MapView/Map/RMMapLayer.h b/MapView/Map/RMMapLayer.h index 8007eaa..dcd3e8c 100644 --- a/MapView/Map/RMMapLayer.h +++ b/MapView/Map/RMMapLayer.h @@ -77,7 +77,7 @@ * * If the value of this property is `NO`, the value of the title string is ignored and the annotation remains enabled by default. You can still disable the annotation explicitly using the enabled property. * -* Note that callouts are not supported on cluster annotation layers. These annotations can be interacted with, but do not remain consistent visually during map pan and zoom events; thus, callout behavior would be inconsistent. */ +* Note that callouts are not supported on non-marker or cluster annotation layers. These annotations can be interacted with, but do not remain consistent visually during map pan and zoom events; thus, callout behavior would be inconsistent. */ @property (nonatomic, assign) BOOL canShowCallout; /** The offset (in pixels) at which to place the callout bubble. diff --git a/MapView/Map/RMMapLayer.m b/MapView/Map/RMMapLayer.m index 4bb41be..cad6e76 100644 --- a/MapView/Map/RMMapLayer.m +++ b/MapView/Map/RMMapLayer.m @@ -29,6 +29,7 @@ #import "RMPixel.h" #import "RMAnnotation.h" #import "RMMapView.h" +#import "RMMarker.h" @interface RMMapView (PrivateMethods) @@ -74,8 +75,13 @@ - (void)setCanShowCallout:(BOOL)canShowCallout { - if ( ! self.annotation.isClusterAnnotation) - _canShowCallout = canShowCallout; + if (canShowCallout) + { + NSAssert([self isKindOfClass:[RMMarker class]], @"Callouts are not supported on non-marker annotation layers"); + NSAssert( ! self.annotation.isClusterAnnotation, @"Callouts are not supported on cluster annotation layers"); + } + + _canShowCallout = canShowCallout; } - (void)setPosition:(CGPoint)position animated:(BOOL)animated diff --git a/MapView/Map/RMMapTiledLayerView.m b/MapView/Map/RMMapTiledLayerView.m index f898f31..b45aa89 100644 --- a/MapView/Map/RMMapTiledLayerView.m +++ b/MapView/Map/RMMapTiledLayerView.m @@ -41,7 +41,7 @@ @implementation RMMapTiledLayerView { - RMMapView *_mapView; + __weak RMMapView *_mapView; id <RMTileSource> _tileSource; } @@ -176,7 +176,7 @@ { // ensure only one request for a URL at a time // - @synchronized ([(RMAbstractWebMapSource *)_tileSource URLForTile:RMTileMake(x, y, zoom)]) + @synchronized ([(RMAbstractWebMapSource *)_tileSource URLsForTile:RMTileMake(x, y, zoom)]) { // this will return quicker if cached since above attempt, else block on fetch // diff --git a/MapView/Map/RMMapView.m b/MapView/Map/RMMapView.m index dc9040b..a9942f6 100644 --- a/MapView/Map/RMMapView.m +++ b/MapView/Map/RMMapView.m @@ -131,8 +131,6 @@ @implementation RMMapView { - id <RMMapViewDelegate> _delegate; - BOOL _delegateHasBeforeMapMove; BOOL _delegateHasAfterMapMove; BOOL _delegateHasBeforeMapZoom; @@ -197,7 +195,7 @@ RMUserTrackingBarButtonItem *_userTrackingBarButtonItem; - UIViewController *_viewControllerPresentingAttribution; + __weak UIViewController *_viewControllerPresentingAttribution; UIButton *_attributionButton; UIPopoverController *_attributionPopover; @@ -655,11 +653,6 @@ #pragma mark - #pragma mark Delegate -- (id <RMMapViewDelegate>)delegate -{ - return _delegate; -} - - (void)setDelegate:(id <RMMapViewDelegate>)aDelegate { if (_delegate == aDelegate) @@ -710,12 +703,16 @@ { BOOL flag = wasUserEvent; + __weak RMMapView *weakSelf = self; + BOOL hasBeforeMapMove = _delegateHasBeforeMapMove; + BOOL hasAfterMapMove = _delegateHasAfterMapMove; + if ([_moveDelegateQueue operationCount] == 0) { dispatch_async(dispatch_get_main_queue(), ^(void) { - if (_delegateHasBeforeMapMove) - [_delegate beforeMapMove:self byUser:flag]; + if (hasBeforeMapMove) + [_delegate beforeMapMove:weakSelf byUser:flag]; }); } @@ -727,8 +724,8 @@ { dispatch_async(dispatch_get_main_queue(), ^(void) { - if (_delegateHasAfterMapMove) - [_delegate afterMapMove:self byUser:flag]; + if (hasAfterMapMove) + [_delegate afterMapMove:weakSelf byUser:flag]; }); }]; } @@ -749,12 +746,16 @@ { BOOL flag = wasUserEvent; + __weak RMMapView *weakSelf = self; + BOOL hasBeforeMapZoom = _delegateHasBeforeMapZoom; + BOOL hasAfterMapZoom = _delegateHasAfterMapZoom; + if ([_zoomDelegateQueue operationCount] == 0) { dispatch_async(dispatch_get_main_queue(), ^(void) { - if (_delegateHasBeforeMapZoom) - [_delegate beforeMapZoom:self byUser:flag]; + if (hasBeforeMapZoom) + [_delegate beforeMapZoom:weakSelf byUser:flag]; }); } @@ -766,8 +767,8 @@ { dispatch_async(dispatch_get_main_queue(), ^(void) { - if (_delegateHasAfterMapZoom) - [_delegate afterMapZoom:self byUser:flag]; + if (hasAfterMapZoom) + [_delegate afterMapZoom:weakSelf byUser:flag]; }); }]; } @@ -1070,17 +1071,27 @@ - (void)setZoom:(float)newZoom atCoordinate:(CLLocationCoordinate2D)newCenter animated:(BOOL)animated { - [UIView animateWithDuration:(animated ? 0.3 : 0.0) - delay:0.0 - options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationCurveEaseInOut - animations:^(void) - { - [self setZoom:newZoom]; - [self setCenterCoordinate:newCenter animated:NO]; + if (animated) + { + [UIView animateWithDuration:0.3 + delay:0.0 + options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationCurveEaseInOut + animations:^(void) + { + [self setZoom:newZoom]; + [self setCenterCoordinate:newCenter animated:NO]; - self.userTrackingMode = RMUserTrackingModeNone; - } - completion:nil]; + self.userTrackingMode = RMUserTrackingModeNone; + } + completion:nil]; + } + else + { + [self setZoom:newZoom]; + [self setCenterCoordinate:newCenter animated:NO]; + + self.userTrackingMode = RMUserTrackingModeNone; + } } - (void)zoomByFactor:(float)zoomFactor near:(CGPoint)pivot animated:(BOOL)animated @@ -1595,21 +1606,6 @@ { [self correctPositionOfAllAnnotationsIncludingInvisibles:NO animated:(_mapScrollViewIsZooming && !_mapScrollView.zooming)]; - if (_currentAnnotation && ! [_currentAnnotation isKindOfClass:[RMMarker class]]) - { - // adjust shape annotation callouts for frame changes during zoom - // - _currentCallout.delegate = nil; - - [_currentCallout presentCalloutFromRect:_currentAnnotation.layer.bounds - inLayer:_currentAnnotation.layer - constrainedToLayer:self.layer - permittedArrowDirections:SMCalloutArrowDirectionDown - animated:NO]; - - _currentCallout.delegate = self; - } - _lastZoom = _zoom; } @@ -1833,13 +1829,13 @@ _draggedAnnotation = nil; } } - else if ([hit isKindOfClass:[RMMapLayer class]] && _delegateHasLongPressOnAnnotation) + else if (recognizer.state == UIGestureRecognizerStateBegan && [hit isKindOfClass:[RMMapLayer class]] && _delegateHasLongPressOnAnnotation) { // pass annotation long-press to delegate // [_delegate longPressOnAnnotation:[((RMMapLayer *)hit) annotation] onMap:self]; } - else if (_delegateHasLongPressOnMap) + else if (recognizer.state == UIGestureRecognizerStateBegan && _delegateHasLongPressOnMap) { // pass map long-press to delegate // @@ -1894,16 +1890,15 @@ } else if (anAnnotation.isEnabled && ! [anAnnotation isEqual:_currentAnnotation]) { + self.userTrackingMode = RMUserTrackingModeNone; + [self deselectAnnotation:_currentAnnotation animated:NO]; _currentAnnotation = anAnnotation; if (anAnnotation.layer.canShowCallout && anAnnotation.title) { - _currentCallout = [SMCalloutView new]; - - if (RMPreVersion7) - _currentCallout.backgroundView = [SMCalloutBackgroundView systemBackgroundView]; + _currentCallout = [SMCalloutView platformCalloutView]; if (RMPostVersion7) _currentCallout.tintColor = self.tintColor; @@ -1931,10 +1926,11 @@ _currentCallout.delegate = self; + _currentCallout.permittedArrowDirection = SMCalloutArrowDirectionDown; + [_currentCallout presentCalloutFromRect:anAnnotation.layer.bounds inLayer:anAnnotation.layer constrainedToLayer:self.layer - permittedArrowDirections:SMCalloutArrowDirectionDown animated:animated]; } @@ -2628,10 +2624,12 @@ _logoBug.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin; _logoBug.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_logoBug]; + [self updateConstraints]; } else if ( ! showLogoBug && _logoBug) { [_logoBug removeFromSuperview]; + _logoBug = nil; } _showLogoBug = showLogoBug; @@ -3126,6 +3124,9 @@ - (void)addAnnotation:(RMAnnotation *)annotation { + if ( ! annotation) + return; + @synchronized (_annotations) { if ([_annotations containsObject:annotation]) @@ -3158,6 +3159,9 @@ - (void)addAnnotations:(NSArray *)newAnnotations { + if ( ! newAnnotations || ! [newAnnotations count]) + return; + @synchronized (_annotations) { [_annotations addObjectsFromArray:newAnnotations]; @@ -3602,7 +3606,9 @@ if (_delegateHasDidUpdateUserLocation) [_delegate mapView:self didUpdateUserLocation:self.userLocation]; - if (newHeading.trueHeading != 0 && self.userTrackingMode == RMUserTrackingModeFollowWithHeading) + CLLocationDirection headingDirection = (newHeading.trueHeading > 0 ? newHeading.trueHeading : newHeading.magneticHeading); + + if (headingDirection != 0 && self.userTrackingMode == RMUserTrackingModeFollowWithHeading) { if (_userHeadingTrackingView.alpha < 1.0) [UIView animateWithDuration:0.5 animations:^(void) { _userHeadingTrackingView.alpha = 1.0; }]; @@ -3616,7 +3622,7 @@ options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationCurveEaseInOut animations:^(void) { - CGFloat angle = (M_PI / -180) * newHeading.trueHeading; + CGFloat angle = (M_PI / -180) * headingDirection; _mapTransform = CGAffineTransformMakeRotation(angle); _annotationTransform = CATransform3DMakeAffineTransform(CGAffineTransformMakeRotation(-angle)); @@ -3781,10 +3787,12 @@ _attributionButton.bounds.size.width, _attributionButton.bounds.size.height); [self addSubview:_attributionButton]; + [self updateConstraints]; } else if ( ! _viewControllerPresentingAttribution && _attributionButton) { [_attributionButton removeFromSuperview]; + _attributionButton = nil; } } diff --git a/MapView/Map/RMMapboxSource.h b/MapView/Map/RMMapboxSource.h index 806f62b..dbd578a 100644 --- a/MapView/Map/RMMapboxSource.h +++ b/MapView/Map/RMMapboxSource.h @@ -92,7 +92,7 @@ typedef enum : NSUInteger { * @return An initialized Mapbox tile source. */ - (id)initWithTileJSON:(NSString *)tileJSON; -/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data. +/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add point annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data. * * This method requires a network connection in order to download the TileJSON used to define the tile source. * @@ -101,7 +101,7 @@ typedef enum : NSUInteger { * @return An initialized Mapbox tile source. */ - (id)initWithMapID:(NSString *)mapID enablingDataOnMapView:(RMMapView *)mapView; -/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data, optionally enabling SSL. +/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add point annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data, optionally enabling SSL. * * This method requires a network connection in order to download the TileJSON used to define the tile source. * @@ -111,13 +111,13 @@ typedef enum : NSUInteger { * @return An initialized Mapbox tile source. */ - (id)initWithMapID:(NSString *)mapID enablingDataOnMapView:(RMMapView *)mapView enablingSSL:(BOOL)enableSSL; -/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data. +/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add point annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data. * @param tileJSON A string containing TileJSON. * @param mapView A map view on which to display the annotations. * @return An initialized Mapbox tile source. */ - (id)initWithTileJSON:(NSString *)tileJSON enablingDataOnMapView:(RMMapView *)mapView; -/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data. +/** For TileJSON 2.1.0+ layers, initialize a tile source and automatically find and add point annotations from [simplestyle](http://mapbox.com/developers/simplestyle/) data. * * Passing a remote URL requires a network connection. If offline functionality is desired, you should cache the TileJSON locally at a prior date, then pass a file path URL to this method. * diff --git a/MapView/Map/RMMapboxSource.m b/MapView/Map/RMMapboxSource.m index 375c7ff..a798678 100644 --- a/MapView/Map/RMMapboxSource.m +++ b/MapView/Map/RMMapboxSource.m @@ -85,11 +85,14 @@ _tileJSON = tileJSON; - _uniqueTilecacheKey = [NSString stringWithFormat:@"Mapbox-%@%@", [_infoDictionary objectForKey:@"id"], ([_infoDictionary objectForKey:@"version"] ? [@"-" stringByAppendingString:[_infoDictionary objectForKey:@"version"]] : @"")]; + if ([_infoDictionary[@"id"] hasPrefix:@"examples."]) + RMLog(@"Using watermarked example map ID %@. Please go to http://mapbox.com and create your own map style.", _infoDictionary[@"id"]); + + _uniqueTilecacheKey = [NSString stringWithFormat:@"Mapbox-%@%@", _infoDictionary[@"id"], (_infoDictionary[@"version"] ? [@"-" stringByAppendingString:_infoDictionary[@"version"]] : @"")]; id dataObject = nil; - if (mapView && (dataObject = [_infoDictionary objectForKey:@"data"]) && dataObject) + if (mapView && (dataObject = _infoDictionary[@"data"]) && dataObject) { dispatch_async(_dataQueue, ^(void) { @@ -111,28 +114,31 @@ if ((jsonObject = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]) && [jsonObject isKindOfClass:[NSDictionary class]]) { - for (NSDictionary *feature in [jsonObject objectForKey:@"features"]) + for (NSDictionary *feature in jsonObject[@"features"]) { - NSDictionary *properties = [feature objectForKey:@"properties"]; - - CLLocationCoordinate2D coordinate = { - .longitude = [[[[feature objectForKey:@"geometry"] objectForKey:@"coordinates"] objectAtIndex:0] floatValue], - .latitude = [[[[feature objectForKey:@"geometry"] objectForKey:@"coordinates"] objectAtIndex:1] floatValue] - }; - - RMAnnotation *annotation = nil; - - if ([mapView.delegate respondsToSelector:@selector(mapView:layerForAnnotation:)]) - annotation = [RMAnnotation annotationWithMapView:mapView coordinate:coordinate andTitle:[properties objectForKey:@"title"]]; - else - annotation = [RMPointAnnotation annotationWithMapView:mapView coordinate:coordinate andTitle:[properties objectForKey:@"title"]]; - - annotation.userInfo = properties; - - dispatch_async(dispatch_get_main_queue(), ^(void) + if ([feature[@"geometry"][@"type"] isEqualToString:@"Point"]) { - [mapView addAnnotation:annotation]; - }); + NSDictionary *properties = feature[@"properties"]; + + CLLocationCoordinate2D coordinate = { + .longitude = [feature[@"geometry"][@"coordinates"][0] floatValue], + .latitude = [feature[@"geometry"][@"coordinates"][1] floatValue] + }; + + RMAnnotation *annotation = nil; + + if ([mapView.delegate respondsToSelector:@selector(mapView:layerForAnnotation:)]) + annotation = [RMAnnotation annotationWithMapView:mapView coordinate:coordinate andTitle:properties[@"title"]]; + else + annotation = [RMPointAnnotation annotationWithMapView:mapView coordinate:coordinate andTitle:properties[@"title"]]; + + annotation.userInfo = properties; + + dispatch_async(dispatch_get_main_queue(), ^(void) + { + [mapView addAnnotation:annotation]; + }); + } } } } @@ -187,9 +193,9 @@ - (NSURL *)tileJSONURL { - BOOL useSSL = [[[self.infoDictionary objectForKey:@"tiles"] objectAtIndex:0] hasPrefix:@"https"]; + BOOL useSSL = [self.infoDictionary[@"tiles"][0] hasPrefix:@"https"]; - return [NSURL URLWithString:[NSString stringWithFormat:@"http%@://api.tiles.mapbox.com/v3/%@.json%@", (useSSL ? @"s" : @""), [self.infoDictionary objectForKey:@"id"], (useSSL ? @"?secure" : @"")]]; + return [NSURL URLWithString:[NSString stringWithFormat:@"http%@://api.tiles.mapbox.com/v3/%@.json%@", (useSSL ? @"s" : @""), self.infoDictionary[@"id"], (useSSL ? @"?secure" : @"")]]; } - (NSURL *)URLForTile:(RMTile)tile @@ -198,16 +204,16 @@ NSInteger x = tile.x; NSInteger y = tile.y; - if ([self.infoDictionary objectForKey:@"scheme"] && [[self.infoDictionary objectForKey:@"scheme"] isEqual:@"tms"]) + if (self.infoDictionary[@"scheme"] && [self.infoDictionary[@"scheme"] isEqual:@"tms"]) y = pow(2, zoom) - tile.y - 1; NSString *tileURLString = nil; - if ([self.infoDictionary objectForKey:@"tiles"]) - tileURLString = [[self.infoDictionary objectForKey:@"tiles"] objectAtIndex:0]; + if (self.infoDictionary[@"tiles"]) + tileURLString = self.infoDictionary[@"tiles"][0]; else - tileURLString = [self.infoDictionary objectForKey:@"tileURL"]; + tileURLString = self.infoDictionary[@"tileURL"]; tileURLString = [tileURLString stringByReplacingOccurrencesOfString:@"{z}" withString:[[NSNumber numberWithInteger:zoom] stringValue]]; tileURLString = [tileURLString stringByReplacingOccurrencesOfString:@"{x}" withString:[[NSNumber numberWithInteger:x] stringValue]]; @@ -276,17 +282,17 @@ - (float)minZoom { - return [[self.infoDictionary objectForKey:@"minzoom"] floatValue]; + return [self.infoDictionary[@"minzoom"] floatValue]; } - (float)maxZoom { - return [[self.infoDictionary objectForKey:@"maxzoom"] floatValue]; + return [self.infoDictionary[@"maxzoom"] floatValue]; } - (RMSphericalTrapezium)latitudeLongitudeBoundingBox { - id bounds = [self.infoDictionary objectForKey:@"bounds"]; + id bounds = self.infoDictionary[@"bounds"]; NSArray *parts = nil; @@ -329,15 +335,15 @@ - (NSString *)legend { - return [self.infoDictionary objectForKey:@"legend"]; + return self.infoDictionary[@"legend"]; } - (CLLocationCoordinate2D)centerCoordinate { - if ([self.infoDictionary objectForKey:@"center"]) + if (self.infoDictionary[@"center"]) { - return CLLocationCoordinate2DMake([[[self.infoDictionary objectForKey:@"center"] objectAtIndex:1] doubleValue], - [[[self.infoDictionary objectForKey:@"center"] objectAtIndex:0] doubleValue]); + return CLLocationCoordinate2DMake([self.infoDictionary[@"center"][1] doubleValue], + [self.infoDictionary[@"center"][0] doubleValue]); } return CLLocationCoordinate2DMake(0, 0); @@ -345,9 +351,9 @@ - (float)centerZoom { - if ([self.infoDictionary objectForKey:@"center"]) + if (self.infoDictionary[@"center"]) { - return [[[self.infoDictionary objectForKey:@"center"] objectAtIndex:2] floatValue]; + return [self.infoDictionary[@"center"][2] floatValue]; } return roundf(([self maxZoom] + [self minZoom]) / 2); @@ -360,17 +366,17 @@ - (NSString *)shortName { - return [self.infoDictionary objectForKey:@"name"]; + return self.infoDictionary[@"name"]; } - (NSString *)longDescription { - return [self.infoDictionary objectForKey:@"description"]; + return self.infoDictionary[@"description"]; } - (NSString *)shortAttribution { - return [self.infoDictionary objectForKey:@"attribution"]; + return self.infoDictionary[@"attribution"]; } - (NSString *)longAttribution diff --git a/MapView/Map/RMQuadTree.m b/MapView/Map/RMQuadTree.m index 181014e..f7e828b 100644 --- a/MapView/Map/RMQuadTree.m +++ b/MapView/Map/RMQuadTree.m @@ -70,7 +70,7 @@ NSMutableArray *_annotations; RMQuadTreeNode *_parentNode, *_northWest, *_northEast, *_southWest, *_southEast; RMQuadTreeNodeType _nodeType; - RMMapView *_mapView; + __weak RMMapView *_mapView; RMAnnotation *_cachedClusterAnnotation; NSArray *_cachedClusterEnclosedAnnotations; @@ -596,7 +596,7 @@ @implementation RMQuadTree { RMQuadTreeNode *_rootNode; - RMMapView *_mapView; + __weak RMMapView *_mapView; } - (id)initWithMapView:(RMMapView *)aMapView diff --git a/MapView/Map/RMShape.h b/MapView/Map/RMShape.h index 62f8ae6..a525768 100644 --- a/MapView/Map/RMShape.h +++ b/MapView/Map/RMShape.h @@ -84,6 +84,9 @@ /** The bounding box of the shape in the current viewport. */ @property (nonatomic, readonly) CGRect pathBoundingBox; +/** An additional pixel area around the shape that is applied to touch hit testing events. Defaults to none. */ +@property (nonatomic, assign) CGFloat additionalTouchPadding; + /** @name Drawing Shapes */ /** Move the drawing pen to a projected point. diff --git a/MapView/Map/RMShape.m b/MapView/Map/RMShape.m index 59ca748..a9ded69 100644 --- a/MapView/Map/RMShape.m +++ b/MapView/Map/RMShape.m @@ -435,10 +435,24 @@ { // if shape is not filled with a color, do a simple "point on path" test // - UIGraphicsBeginImageContext(self.bounds.size); - CGContextAddPath(UIGraphicsGetCurrentContext(), shapeLayer.path); - containsPoint = CGContextPathContainsPoint(UIGraphicsGetCurrentContext(), thePoint, kCGPathStroke); - UIGraphicsEndImageContext(); + if (self.additionalTouchPadding) + { + CGPathRef tapTargetPath = CGPathCreateCopyByStrokingPath(shapeLayer.path, nil, fmaxf(self.additionalTouchPadding, shapeLayer.lineWidth), 0, 0, 0); + + if (tapTargetPath) + { + containsPoint = [[UIBezierPath bezierPathWithCGPath:tapTargetPath] containsPoint:thePoint]; + + CGPathRelease(tapTargetPath); + } + } + else + { + UIGraphicsBeginImageContext(self.bounds.size); + CGContextAddPath(UIGraphicsGetCurrentContext(), shapeLayer.path); + containsPoint = CGContextPathContainsPoint(UIGraphicsGetCurrentContext(), thePoint, kCGPathStroke); + UIGraphicsEndImageContext(); + } } else { diff --git a/MapView/Map/RMStaticMapView.m b/MapView/Map/RMStaticMapView.m index 9aa717c..c9f4592 100644 --- a/MapView/Map/RMStaticMapView.m +++ b/MapView/Map/RMStaticMapView.m @@ -89,7 +89,7 @@ - (void)performInitializationWithMapID:(NSString *)mapID centerCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(CGFloat)zoomLevel completionHandler:(void (^)(UIImage *))handler { - RMMapboxSource *tileSource = [[RMMapboxSource alloc] initWithMapID:kMapboxPlaceholderMapID enablingDataOnMapView:self]; + RMMapboxSource *tileSource = [[RMMapboxSource alloc] initWithMapID:(mapID ? mapID : kMapboxPlaceholderMapID) enablingDataOnMapView:self]; self.tileSource = tileSource; diff --git a/MapView/Map/RMTileCache.h b/MapView/Map/RMTileCache.h index 9579a40..7d10d1f 100644 --- a/MapView/Map/RMTileCache.h +++ b/MapView/Map/RMTileCache.h @@ -81,14 +81,14 @@ typedef enum : short { * @param tileCache The tile cache. * @param tileCount The total number of tiles required for coverage of the desired geographic area. * @param tileSource The tile source providing the tiles. */ -- (void)tileCache:(RMTileCache *)tileCache didBeginBackgroundCacheWithCount:(int)tileCount forTileSource:(id <RMTileSource>)tileSource; +- (void)tileCache:(RMTileCache *)tileCache didBeginBackgroundCacheWithCount:(NSUInteger)tileCount forTileSource:(id <RMTileSource>)tileSource; /** Sent upon caching of each tile in a background cache operation. * @param tileCache The tile cache. * @param tile A structure representing the tile in question. * @param tileIndex The index of the tile in question, beginning with `1` and ending with totalTileCount. * @param totalTileCount The total number of of tiles required for coverage of the desired geographic area. */ -- (void)tileCache:(RMTileCache *)tileCache didBackgroundCacheTile:(RMTile)tile withIndex:(int)tileIndex ofTotalTileCount:(int)totalTileCount; +- (void)tileCache:(RMTileCache *)tileCache didBackgroundCacheTile:(RMTile)tile withIndex:(NSUInteger)tileIndex ofTotalTileCount:(NSUInteger)totalTileCount; /** Sent when all tiles have completed downloading and caching. * @param tileCache The tile cache. */ @@ -156,11 +156,19 @@ typedef enum : short { * @param northEast The northeast corner of the geographic area to cache. * @param minZoom The minimum zoom level to cache. * @param maxZoom The maximum zoom level to cache. */ -- (void)beginBackgroundCacheForTileSource:(id <RMTileSource>)tileSource southWest:(CLLocationCoordinate2D)southWest northEast:(CLLocationCoordinate2D)northEast minZoom:(float)minZoom maxZoom:(float)maxZoom; +- (void)beginBackgroundCacheForTileSource:(id <RMTileSource>)tileSource southWest:(CLLocationCoordinate2D)southWest northEast:(CLLocationCoordinate2D)northEast minZoom:(NSUInteger)minZoom maxZoom:(NSUInteger)maxZoom; /** Cancel any background caching. * * This method returns immediately so as to not block the calling thread. If you wish to be notified of the actual cancellation completion, implement the tileCacheDidCancelBackgroundCache: delegate method. */ - (void)cancelBackgroundCache; +/** A count of the number of tiles that would be downloaded in a background tile cache download operation. +* @param southWest The southwest corner of the geographic area to cache. +* @param northEast The northeast corner of the geographic area to cache. +* @param minZoom The minimum zoom level to cache. +* @param maxZoom The maximum zoom level to cache. +* @return The number of tiles representing the coverage area. */ +- (NSUInteger)tileCountForSouthWest:(CLLocationCoordinate2D)southWest northEast:(CLLocationCoordinate2D)northEast minZoom:(NSUInteger)minZoom maxZoom:(NSUInteger)maxZoom; + @end diff --git a/MapView/Map/RMTileCache.m b/MapView/Map/RMTileCache.m index 5c47773..be35c8d 100644 --- a/MapView/Map/RMTileCache.m +++ b/MapView/Map/RMTileCache.m @@ -252,32 +252,25 @@ return (_activeTileSource || _backgroundFetchQueue); } -- (void)beginBackgroundCacheForTileSource:(id <RMTileSource>)tileSource southWest:(CLLocationCoordinate2D)southWest northEast:(CLLocationCoordinate2D)northEast minZoom:(float)minZoom maxZoom:(float)maxZoom +- (NSUInteger)tileCountForSouthWest:(CLLocationCoordinate2D)southWest northEast:(CLLocationCoordinate2D)northEast minZoom:(NSUInteger)minZoom maxZoom:(NSUInteger)maxZoom { - if (self.isBackgroundCaching) - return; + NSUInteger minCacheZoom = minZoom; + NSUInteger maxCacheZoom = maxZoom; - _activeTileSource = tileSource; - - _backgroundFetchQueue = [[NSOperationQueue alloc] init]; - [_backgroundFetchQueue setMaxConcurrentOperationCount:6]; - - int minCacheZoom = (int)minZoom; - int maxCacheZoom = (int)maxZoom; - float minCacheLat = southWest.latitude; - float maxCacheLat = northEast.latitude; - float minCacheLon = southWest.longitude; - float maxCacheLon = northEast.longitude; + CLLocationDegrees minCacheLat = southWest.latitude; + CLLocationDegrees maxCacheLat = northEast.latitude; + CLLocationDegrees minCacheLon = southWest.longitude; + CLLocationDegrees maxCacheLon = northEast.longitude; NSAssert(minCacheZoom <= maxCacheZoom, @"Minimum zoom should be less than or equal to maximum zoom"); NSAssert(maxCacheLat > minCacheLat, @"Northernmost bounds should exceed southernmost bounds"); NSAssert(maxCacheLon > minCacheLon, @"Easternmost bounds should exceed westernmost bounds"); - int n, xMin, yMax, xMax, yMin; + NSUInteger n, xMin, yMax, xMax, yMin; - int totalTiles = 0; + NSUInteger totalTiles = 0; - for (int zoom = minCacheZoom; zoom <= maxCacheZoom; zoom++) + for (NSUInteger zoom = minCacheZoom; zoom <= maxCacheZoom; zoom++) { n = pow(2.0, zoom); xMin = floor(((minCacheLon + 180.0) / 360.0) * n); @@ -288,12 +281,37 @@ totalTiles += (xMax + 1 - xMin) * (yMax + 1 - yMin); } + return totalTiles; +} + +- (void)beginBackgroundCacheForTileSource:(id <RMTileSource>)tileSource southWest:(CLLocationCoordinate2D)southWest northEast:(CLLocationCoordinate2D)northEast minZoom:(NSUInteger)minZoom maxZoom:(NSUInteger)maxZoom +{ + if (self.isBackgroundCaching) + return; + + _activeTileSource = tileSource; + + _backgroundFetchQueue = [[NSOperationQueue alloc] init]; + [_backgroundFetchQueue setMaxConcurrentOperationCount:6]; + + NSUInteger totalTiles = [self tileCountForSouthWest:southWest northEast:northEast minZoom:minZoom maxZoom:maxZoom]; + + NSUInteger minCacheZoom = minZoom; + NSUInteger maxCacheZoom = maxZoom; + + CLLocationDegrees minCacheLat = southWest.latitude; + CLLocationDegrees maxCacheLat = northEast.latitude; + CLLocationDegrees minCacheLon = southWest.longitude; + CLLocationDegrees maxCacheLon = northEast.longitude; + if ([_backgroundCacheDelegate respondsToSelector:@selector(tileCache:didBeginBackgroundCacheWithCount:forTileSource:)]) [_backgroundCacheDelegate tileCache:self didBeginBackgroundCacheWithCount:totalTiles forTileSource:_activeTileSource]; - __block int progTile = 0; + NSUInteger n, xMin, yMax, xMax, yMin; + + __block NSUInteger progTile = 0; - for (int zoom = minCacheZoom; zoom <= maxCacheZoom; zoom++) + for (NSUInteger zoom = minCacheZoom; zoom <= maxCacheZoom; zoom++) { n = pow(2.0, zoom); xMin = floor(((minCacheLon + 180.0) / 360.0) * n); @@ -301,9 +319,9 @@ xMax = floor(((maxCacheLon + 180.0) / 360.0) * n); yMin = floor((1.0 - (logf(tanf(maxCacheLat * M_PI / 180.0) + 1.0 / cosf(maxCacheLat * M_PI / 180.0)) / M_PI)) / 2.0 * n); - for (int x = xMin; x <= xMax; x++) + for (NSUInteger x = xMin; x <= xMax; x++) { - for (int y = yMin; y <= yMax; y++) + for (NSUInteger y = yMin; y <= yMax; y++) { RMTileCacheDownloadOperation *operation = [[RMTileCacheDownloadOperation alloc] initWithTile:RMTileMake(x, y, zoom) forTileSource:_activeTileSource diff --git a/MapView/Map/SMCalloutView b/MapView/Map/SMCalloutView index 05d2211..58ce460 160000 --- a/MapView/Map/SMCalloutView +++ b/MapView/Map/SMCalloutView @@ -1 +1 @@ -Subproject commit 05d22115c5702408ecf0c7f2810321dde6a5a26e +Subproject commit 58ce4607e7967e4d22fec6ef6d202433c44dd3a0 diff --git a/MapView/MapView.xcodeproj/project.pbxproj b/MapView/MapView.xcodeproj/project.pbxproj index c4871c4..7cba0d4 100755 --- a/MapView/MapView.xcodeproj/project.pbxproj +++ b/MapView/MapView.xcodeproj/project.pbxproj @@ -114,8 +114,12 @@ DD41960116250ED40049E6BA /* RMTileCacheDownloadOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DD4195FF16250ED40049E6BA /* RMTileCacheDownloadOperation.h */; settings = {ATTRIBUTES = (Private, ); }; }; DD41960216250ED40049E6BA /* RMTileCacheDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DD41960016250ED40049E6BA /* RMTileCacheDownloadOperation.m */; }; DD4BE198161CE296003EF677 /* Mapbox.h in Headers */ = {isa = PBXBuildFile; fileRef = DD4BE197161CE296003EF677 /* Mapbox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DD5F5F9518C7C03C0085DE98 /* SMClassicCalloutView.h in Headers */ = {isa = PBXBuildFile; fileRef = DD5F5F9318C7C03C0085DE98 /* SMClassicCalloutView.h */; }; + DD5F5F9618C7C03C0085DE98 /* SMClassicCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD5F5F9418C7C03C0085DE98 /* SMClassicCalloutView.m */; }; DD5FA1EB15E2B020004EB6C5 /* RMLoadingTileView.h in Headers */ = {isa = PBXBuildFile; fileRef = DD5FA1E915E2B020004EB6C5 /* RMLoadingTileView.h */; settings = {ATTRIBUTES = (Private, ); }; }; DD5FA1EC15E2B020004EB6C5 /* RMLoadingTileView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD5FA1EA15E2B020004EB6C5 /* RMLoadingTileView.m */; }; + DD63175F17D1506D008CA79B /* RMGreatCircleAnnotation.h in Headers */ = {isa = PBXBuildFile; fileRef = DD63175D17D1506D008CA79B /* RMGreatCircleAnnotation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DD63176017D1506D008CA79B /* RMGreatCircleAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DD63175E17D1506D008CA79B /* RMGreatCircleAnnotation.m */; }; DD63176317D15EB5008CA79B /* RMCircleAnnotation.h in Headers */ = {isa = PBXBuildFile; fileRef = DD63176117D15EB5008CA79B /* RMCircleAnnotation.h */; settings = {ATTRIBUTES = (Public, ); }; }; DD63176417D15EB5008CA79B /* RMCircleAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DD63176217D15EB5008CA79B /* RMCircleAnnotation.m */; }; DD63DD531811AD0B00726E03 /* libGRMustache6-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD63DD521811AD0B00726E03 /* libGRMustache6-iOS.a */; }; @@ -293,8 +297,12 @@ DD4195FF16250ED40049E6BA /* RMTileCacheDownloadOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMTileCacheDownloadOperation.h; sourceTree = "<group>"; }; DD41960016250ED40049E6BA /* RMTileCacheDownloadOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMTileCacheDownloadOperation.m; sourceTree = "<group>"; }; DD4BE197161CE296003EF677 /* Mapbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mapbox.h; sourceTree = "<group>"; }; + DD5F5F9318C7C03C0085DE98 /* SMClassicCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SMClassicCalloutView.h; path = SMCalloutView/SMClassicCalloutView.h; sourceTree = "<group>"; }; + DD5F5F9418C7C03C0085DE98 /* SMClassicCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SMClassicCalloutView.m; path = SMCalloutView/SMClassicCalloutView.m; sourceTree = "<group>"; }; DD5FA1E915E2B020004EB6C5 /* RMLoadingTileView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMLoadingTileView.h; sourceTree = "<group>"; }; DD5FA1EA15E2B020004EB6C5 /* RMLoadingTileView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMLoadingTileView.m; sourceTree = "<group>"; }; + DD63175D17D1506D008CA79B /* RMGreatCircleAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMGreatCircleAnnotation.h; sourceTree = "<group>"; }; + DD63175E17D1506D008CA79B /* RMGreatCircleAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMGreatCircleAnnotation.m; sourceTree = "<group>"; }; DD63176117D15EB5008CA79B /* RMCircleAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCircleAnnotation.h; sourceTree = "<group>"; }; DD63176217D15EB5008CA79B /* RMCircleAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCircleAnnotation.m; sourceTree = "<group>"; }; DD63DD521811AD0B00726E03 /* libGRMustache6-iOS.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libGRMustache6-iOS.a"; path = "GRMustache/lib/libGRMustache6-iOS.a"; sourceTree = "<group>"; }; @@ -543,6 +551,8 @@ DDE357F716522CD8001DB842 /* RMPolygonAnnotation.m */, DD63176117D15EB5008CA79B /* RMCircleAnnotation.h */, DD63176217D15EB5008CA79B /* RMCircleAnnotation.m */, + DD63175D17D1506D008CA79B /* RMGreatCircleAnnotation.h */, + DD63175E17D1506D008CA79B /* RMGreatCircleAnnotation.m */, 16FAB66213E03D55002F4E1C /* RMQuadTree.h */, 16FAB66313E03D55002F4E1C /* RMQuadTree.m */, B86F26AC0E87442C007A3773 /* RMMapLayer.h */, @@ -605,6 +615,8 @@ children = ( DD1E3C6C161F954F004FC649 /* SMCalloutView.h */, DD1E3C6D161F954F004FC649 /* SMCalloutView.m */, + DD5F5F9318C7C03C0085DE98 /* SMClassicCalloutView.h */, + DD5F5F9418C7C03C0085DE98 /* SMClassicCalloutView.m */, ); name = SMCallout; path = Map; @@ -755,6 +767,7 @@ DDE357F816522CD8001DB842 /* RMPolygonAnnotation.h in Headers */, DD1985C1165C5F6400DF667F /* RMTileMillSource.h in Headers */, DD63176317D15EB5008CA79B /* RMCircleAnnotation.h in Headers */, + DD63175F17D1506D008CA79B /* RMGreatCircleAnnotation.h in Headers */, B8C974220E8A19B2007D16AD /* RMProjection.h in Headers */, B8C974260E8A19B2007D16AD /* RMTile.h in Headers */, B8C974270E8A19B2007D16AD /* RMPixel.h in Headers */, @@ -763,6 +776,7 @@ 23A0AAEB0EB90AA6003A4521 /* RMFoundation.h in Headers */, 96492C400FA8AD3400EBA6D2 /* RMGlobalConstants.h in Headers */, B1EB26C610B5D8E6009F8658 /* RMNotifications.h in Headers */, + DD5F5F9518C7C03C0085DE98 /* SMClassicCalloutView.h in Headers */, D1437B37122869E400888DAE /* RMDBMapSource.h in Headers */, 1606C9FE13D86BA400547581 /* RMOpenCycleMapSource.h in Headers */, 16FAB66413E03D55002F4E1C /* RMQuadTree.h in Headers */, @@ -919,6 +933,7 @@ B8C9746C0E8A1A50007D16AD /* RMMapView.m in Sources */, B8F3FC610EA2B382004D8F85 /* RMMapLayer.m in Sources */, B8F3FC650EA2E792004D8F85 /* RMMarker.m in Sources */, + DD5F5F9618C7C03C0085DE98 /* SMClassicCalloutView.m in Sources */, B8474BA50EB40094006A0BC1 /* RMDatabaseCache.m in Sources */, 126693040EB76C0B00E002D5 /* RMConfiguration.m in Sources */, 23A0AAE90EB90A99003A4521 /* RMFoundation.c in Sources */, @@ -935,6 +950,7 @@ 16128CF6148D295300C23C0E /* RMOpenSeaMapSource.m in Sources */, DD2B374614CF8041008DE8CB /* FMDatabase.m in Sources */, DD2B374814CF8041008DE8CB /* FMDatabaseAdditions.m in Sources */, + DD63176017D1506D008CA79B /* RMGreatCircleAnnotation.m in Sources */, DD2B374A14CF8041008DE8CB /* FMResultSet.m in Sources */, DD2B375014CF814F008DE8CB /* FMDatabasePool.m in Sources */, DD2B375214CF814F008DE8CB /* FMDatabaseQueue.m in Sources */, @@ -1063,10 +1079,6 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = ( - "-O", - "-Wuninitialized", - ); OTHER_LDFLAGS = ""; RUN_CLANG_STATIC_ANALYZER = NO; SDKROOT = iphoneos; diff --git a/Mapbox.podspec b/Mapbox.podspec index 2a07ecd..678df45 100644 --- a/Mapbox.podspec +++ b/Mapbox.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |m| m.description = 'Open source alternative to MapKit supporting custom tile sources, offline use, and complete cache control.' m.homepage = 'http://mapbox.com/mobile' m.license = 'BSD' - m.author = { 'Mapbox' => 'ios@mapbox.com' } + m.author = { 'Mapbox' => 'mobile@mapbox.com' } m.screenshot = 'https://raw.github.com/mapbox/mapbox-ios-sdk/packaging/screenshot.png' m.source = { :git => 'https://github.com/mapbox/mapbox-ios-sdk.git', :tag => m.version.to_s } @@ -31,10 +31,12 @@ Pod::Spec.new do |m| m.xcconfig = { 'OTHER_LDFLAGS' => '-ObjC', 'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/Mapbox/Proj4"' } - m.preserve_paths = 'Proj4/libProj4.a', 'MapView/MapView.xcodeproj', 'MapView/Map/Resources' + m.preserve_paths = 'MapView/MapView.xcodeproj', 'MapView/Map/Resources' + + m.vendored_libraries = 'Proj4/libProj4.a' m.dependency 'FMDB', '2.0' m.dependency 'GRMustache', '6.8.3' - m.dependency 'SMCalloutView', '1.1' + m.dependency 'SMCalloutView', '2.0' end