Authored by Thomas Rasch

o Some random code cleanup

... ... @@ -37,7 +37,8 @@
#pragma mark --- end constants ---
@interface RMAbstractMercatorTileSource : NSObject <RMTileSource> {
@interface RMAbstractMercatorTileSource : NSObject <RMTileSource>
{
RMFractalTileProjection *tileProjection;
// supported zoom levels
... ...
... ... @@ -28,8 +28,7 @@
#import "RMAbstractMercatorTileSource.h"
#import "RMProjection.h"
@interface RMAbstractWebMapSource : RMAbstractMercatorTileSource {
}
@interface RMAbstractWebMapSource : RMAbstractMercatorTileSource
- (NSURL *)URLForTile:(RMTile)tile;
... ...
... ... @@ -60,77 +60,88 @@
tile = [[self mercatorToTileProjection] normaliseTile:tile];
image = [tileCache cachedImage:tile withCacheKey:[self uniqueTilecacheKey]];
if (image) return image;
if (image)
return image;
[[NSNotificationCenter defaultCenter] postNotificationName:RMTileRequested object:nil];
[tileCache retain];
NSArray *URLs = [self URLsForTile:tile];
// fill up collection array with placeholders
//
NSMutableArray *tilesData = [NSMutableArray arrayWithCapacity:[URLs count]];
for (int p = 0; p < [URLs count]; p++)
[tilesData addObject:[NSNull null]];
dispatch_group_t fetchGroup = dispatch_group_create();
for (int u = 0; u < [URLs count]; u++)
{
NSURL *currentURL = [URLs objectAtIndex:u];
dispatch_group_async(fetchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{
NSData *tileData = nil;
for (int try = 0; try < RMAbstractWebMapSourceRetryCount; try++)
{
if ( ! tileData)
// Beware: dataWithContentsOfURL is leaking like hell. Better use AFNetwork or ASIHTTPRequest
tileData = [NSData dataWithContentsOfURL:currentURL options:NSDataReadingUncached error:NULL];
}
if (tileData)
{
dispatch_sync(dispatch_get_main_queue(), ^(void)
{
// safely put into collection array in proper order
//
[tilesData replaceObjectAtIndex:u withObject:tileData];
[tilesData replaceObjectAtIndex:u withObject:tileData];
});
}
});
}
// wait for whole group of fetches (with retries) to finish, then clean up
//
dispatch_group_wait(fetchGroup, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * RMAbstractWebMapSourceWaitSeconds));
dispatch_release(fetchGroup);
// composite the collected images together
//
for (NSData *tileData in tilesData)
{
if (tileData && [tileData isKindOfClass:[NSData class]] && [tileData length]) {
if (image != nil) {
if (tileData && [tileData isKindOfClass:[NSData class]] && [tileData length])
{
if (image != nil)
{
UIGraphicsBeginImageContext(image.size);
[image drawAtPoint:CGPointMake(0,0)];
[[UIImage imageWithData:tileData] drawAtPoint:CGPointMake(0,0)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
} else {
}
else
{
image = [UIImage imageWithData:tileData];
}
}
}
if (image) [tileCache addImage:image forTile:tile withCacheKey:[self uniqueTilecacheKey]];
if (image)
[tileCache addImage:image forTile:tile withCacheKey:[self uniqueTilecacheKey]];
[tileCache release];
[[NSNotificationCenter defaultCenter] postNotificationName:RMTileRetrieved object:nil];
if (!image) return [RMTileImage errorTile];
if (!image)
return [RMTileImage errorTile];
return image;
}
... ...
... ... @@ -112,15 +112,17 @@
{
[mapView autorelease];
mapView = [aMapView retain];
if (!aMapView) {
if (!aMapView)
self.layer = nil;
}
}
- (void)setPosition:(CGPoint)aPosition
{
position = aPosition;
if (layer) layer.position = aPosition;
if (layer)
layer.position = aPosition;
}
- (RMMapLayer *)layer
... ... @@ -130,12 +132,16 @@
- (void)setLayer:(RMMapLayer *)aLayer
{
if (layer != aLayer) {
if (layer.superlayer) [layer removeFromSuperlayer];
if (layer != aLayer)
{
if (layer.superlayer)
[layer removeFromSuperlayer];
[layer release]; layer = nil;
}
if (aLayer) {
if (aLayer)
{
layer = aLayer;
[layer retain];
layer.annotation = self;
... ... @@ -145,10 +151,13 @@
- (BOOL)isAnnotationWithinBounds:(CGRect)bounds
{
if (self.hasBoundingBox) {
if (self.hasBoundingBox)
{
RMProjectedRect projectedScreenBounds = [mapView projectedBounds];
return RMProjectedRectIntersectsProjectedRect(projectedScreenBounds, projectedBoundingBox);
} else {
}
else
{
return CGRectContainsPoint(bounds, self.position);
}
}
... ... @@ -176,15 +185,15 @@
max.latitude = kRMMinLatitude; max.longitude = kRMMinLongitude;
CLLocationDegrees currentLatitude, currentLongitude;
for (CLLocation *currentLocation in locations)
{
currentLatitude = currentLocation.coordinate.latitude;
currentLongitude = currentLocation.coordinate.longitude;
// POIs outside of the world...
if (currentLatitude < kRMMinLatitude || currentLatitude > kRMMaxLatitude || currentLongitude < kRMMinLongitude || currentLongitude > kRMMaxLongitude) {
if (currentLatitude < kRMMinLatitude || currentLatitude > kRMMaxLatitude || currentLongitude < kRMMinLongitude || currentLongitude > kRMMaxLongitude)
continue;
}
max.latitude = fmax(currentLatitude, max.latitude);
max.longitude = fmax(currentLongitude, max.longitude);
... ...
... ... @@ -27,7 +27,8 @@
#import "RMTile.h"
@interface RMCacheObject : NSObject {
@interface RMCacheObject : NSObject
{
id cachedObject;
NSString *cacheKey;
... ...
... ... @@ -34,9 +34,13 @@
#define kDefaultFillColor [UIColor blueColor]
@interface RMCircle ()
- (void)updateCirclePath;
@end
#pragma mark -
@implementation RMCircle
@synthesize shapeLayer;
... ... @@ -116,7 +120,8 @@
- (void)setLineColor:(UIColor *)newLineColor
{
if (lineColor != newLineColor) {
if (lineColor != newLineColor)
{
[lineColor release];
lineColor = [newLineColor retain];
[self updateCirclePath];
... ... @@ -125,7 +130,8 @@
- (void)setFillColor:(UIColor *)newFillColor
{
if (fillColor != newFillColor) {
if (fillColor != newFillColor)
{
[fillColor release];
fillColor = [newFillColor retain];
[self updateCirclePath];
... ...
... ... @@ -27,9 +27,7 @@
#import <UIKit/UIKit.h>
@interface RMConfiguration : NSObject {
id propertyList;
}
@interface RMConfiguration : NSObject
+ (RMConfiguration *)configuration;
... ...
... ... @@ -30,14 +30,19 @@
static RMConfiguration *RMConfigurationSharedInstance = nil;
@implementation RMConfiguration
{
id propertyList;
}
+ (RMConfiguration *)configuration
{
@synchronized (RMConfigurationSharedInstance) {
@synchronized (RMConfigurationSharedInstance)
{
if (RMConfigurationSharedInstance != nil)
return RMConfigurationSharedInstance;
RMConfigurationSharedInstance = [[RMConfiguration alloc] initWithPath:[[NSBundle mainBundle] pathForResource:@"routeme" ofType:@"plist"]];
return RMConfigurationSharedInstance;
}
... ... @@ -53,12 +58,14 @@ static RMConfiguration *RMConfigurationSharedInstance = nil;
NSString *error;
NSPropertyListFormat format;
if (path == nil) {
if (path == nil)
{
propertyList = nil;
return self;
}
RMLog(@"reading configuration from %@", path);
plistData = [NSData dataWithContentsOfFile:path];
propertyList = [[NSPropertyListSerialization propertyListFromData:plistData
... ... @@ -66,7 +73,8 @@ static RMConfiguration *RMConfigurationSharedInstance = nil;
format:&format
errorDescription:&error] retain];
if (!propertyList) {
if (!propertyList)
{
RMLog(@"problem reading from %@: %@", path, error);
[error release];
}
... ...
... ... @@ -75,9 +75,7 @@
#import "FMDatabase.h"
#import "FMDatabaseQueue.h"
#define kDefaultLatLonBoundingBox ((RMSphericalTrapezium){.northEast = {.latitude = 90, .longitude = 180}, .southWest = {.latitude = -90, .longitude = -180}})
#define FMDBErrorCheck(db) { if ([db hadError]) { NSLog(@"DB error %d on line %d: %@", [db lastErrorCode], __LINE__, [db lastErrorMessage]); } }
#pragma mark --- begin constants ----
// mandatory preference keys
#define kMinZoomKey @"map.minZoom"
... ... @@ -98,6 +96,7 @@
#define kShortAttributionKey @"map.shortAttribution"
#define kLongAttributionKey @"map.longAttribution"
#pragma mark --- end constants ----
@interface RMDBMapSource (Preferences)
... ... @@ -219,7 +218,8 @@
{
// fetch the image from the db
FMResultSet *result = [db executeQuery:@"SELECT image FROM tiles WHERE tilekey = ?", key];
FMDBErrorCheck(db);
if ([db hadError])
NSLog(@"DB error %d on line %d: %@", [db lastErrorCode], __LINE__, [db lastErrorMessage]);
if ([result next])
image = [[[UIImage alloc] initWithData:[result dataForColumnIndex:0]] autorelease];
... ...
... ... @@ -67,6 +67,7 @@ RMProjectedPoint RMScaleProjectedPointAboutPoint(RMProjectedPoint point, float f
{
point.x = (point.x - pivot.x) * factor + pivot.x;
point.y = (point.y - pivot.y) * factor + pivot.y;
return point;
}
... ... @@ -75,6 +76,7 @@ RMProjectedRect RMScaleProjectedRectAboutPoint(RMProjectedRect rect, float facto
rect.origin = RMScaleProjectedPointAboutPoint(rect.origin, factor, pivot);
rect.size.width *= factor;
rect.size.height *= factor;
return rect;
}
... ... @@ -82,18 +84,21 @@ RMProjectedPoint RMTranslateProjectedPointBy(RMProjectedPoint point, RMProjected
{
point.x += delta.width;
point.y += delta.height;
return point;
}
RMProjectedRect RMTranslateProjectedRectBy(RMProjectedRect rect, RMProjectedSize delta)
{
rect.origin = RMTranslateProjectedPointBy(rect.origin, delta);
return rect;
}
RMProjectedPoint RMProjectedPointMake(double x, double y)
{
RMProjectedPoint point = { x, y };
return point;
}
... ... @@ -103,6 +108,7 @@ RMProjectedRect RMProjectedRectMake(double x, double y, double width, double hei
{x, y},
{width, height}
};
return rect;
}
... ... @@ -111,6 +117,7 @@ RMProjectedSize RMProjectedSizeMake(double width, double heigth)
RMProjectedSize size = {
width, heigth
};
return size;
}
... ...
... ... @@ -32,7 +32,8 @@
@class RMProjection;
@interface RMFractalTileProjection : NSObject {
@interface RMFractalTileProjection : NSObject
{
// Maximum zoom for which our tile server stores images
NSUInteger maxZoom, minZoom;
... ...
... ... @@ -97,11 +97,10 @@
{
// The mask contains a 1 for every valid x-coordinate bit.
uint32_t mask = 1;
for (int i = 0; i < tile.zoom; i++)
{
mask <<= 1;
}
mask -= 1;
tile.x &= mask;
... ...
... ... @@ -24,12 +24,9 @@
@end
@interface RMMapOverlayView : UIView {
@interface RMMapOverlayView : UIView
{
id <RMMapOverlayViewDelegate> delegate;
BOOL _trackPanGesture;
CGPoint _lastTranslation;
RMAnnotation *_draggedAnnotation;
}
@property (nonatomic, assign) id <RMMapOverlayViewDelegate> delegate;
... ...
... ... @@ -19,10 +19,15 @@
@end
@implementation RMMapOverlayView
{
BOOL _trackPanGesture;
CGPoint _lastTranslation;
RMAnnotation *_draggedAnnotation;
}
@synthesize delegate;
+ + layerClass
+ (Class)layerClass
{
return [CAScrollLayer class];
}
... ... @@ -100,9 +105,9 @@
return NO;
CALayer *hit = [self.layer hitTest:point];
if (!hit || ![hit isKindOfClass:[RMMarker class]]) {
if (!hit || ![hit isKindOfClass:[RMMarker class]])
return NO;
}
return ((RMMarker *)hit).annotation.enabled;
}
... ... @@ -124,46 +129,54 @@
- (void)handleSingleTap:(UIGestureRecognizer *)recognizer
{
CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];
if (!hit) return;
if (!hit)
return;
CALayer *superlayer = [hit superlayer];
// See if tap was on a marker or marker label and send delegate protocol method
if ([hit isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnAnnotation:atPoint:)]) {
if ([hit isKindOfClass:[RMMarker class]])
{
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnAnnotation:atPoint:)])
[delegate mapOverlayView:self tapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
}
} else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)]) {
}
else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]])
{
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)])
[delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
}
} else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)]) {
}
else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]])
{
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)])
[delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
}
}
}
- (void)handleDoubleTap:(UIGestureRecognizer *)recognizer
{
CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];
if (!hit) return;
if (!hit)
return;
CALayer *superlayer = [hit superlayer];
// See if tap was on a marker or marker label and send delegate protocol method
if ([hit isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnAnnotation:atPoint:)]) {
if ([hit isKindOfClass:[RMMarker class]])
{
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnAnnotation:atPoint:)])
[delegate mapOverlayView:self doubleTapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
}
} else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)]) {
}
else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]])
{
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)])
[delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
}
} else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)]) {
}
else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]])
{
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)])
[delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
}
}
}
... ... @@ -172,8 +185,12 @@
if (recognizer.state == UIGestureRecognizerStateBegan)
{
CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];
if (!hit) return;
if ([hit respondsToSelector:@selector(enableDragging)] && ![(RMMarker *)hit enableDragging]) return;
if (!hit)
return;
if ([hit respondsToSelector:@selector(enableDragging)] && ![(RMMarker *)hit enableDragging])
return;
_lastTranslation = CGPointZero;
[_draggedAnnotation release];
... ... @@ -185,15 +202,18 @@
_trackPanGesture = NO;
}
if (!_trackPanGesture) return;
if (!_trackPanGesture)
return;
if (recognizer.state == UIGestureRecognizerStateChanged && [delegate respondsToSelector:@selector(mapOverlayView:didDragAnnotation:withDelta:)]) {
if (recognizer.state == UIGestureRecognizerStateChanged && [delegate respondsToSelector:@selector(mapOverlayView:didDragAnnotation:withDelta:)])
{
CGPoint translation = [recognizer translationInView:self];
CGPoint delta = CGPointMake(_lastTranslation.x - translation.x, _lastTranslation.y - translation.y);
_lastTranslation = translation;
[delegate mapOverlayView:self didDragAnnotation:_draggedAnnotation withDelta:delta];
} else if (recognizer.state == UIGestureRecognizerStateEnded && [delegate respondsToSelector:@selector(mapOverlayView:didEndDragAnnotation:)]) {
}
else if (recognizer.state == UIGestureRecognizerStateEnded && [delegate respondsToSelector:@selector(mapOverlayView:didEndDragAnnotation:)])
{
[delegate mapOverlayView:self didEndDragAnnotation:_draggedAnnotation];
_trackPanGesture = NO;
[_draggedAnnotation release]; _draggedAnnotation = nil;
... ...
... ... @@ -20,7 +20,8 @@
@end
@interface RMMapTiledLayerView : UIView {
@interface RMMapTiledLayerView : UIView
{
id <RMMapTiledLayerViewDelegate> delegate;
RMMapView *mapView;
}
... ...
... ... @@ -22,7 +22,7 @@
@synthesize delegate;
+ + layerClass
+ (Class)layerClass
{
return [CATiledLayer class];
}
... ...
//
// RMMapView.h
//
// Copyright (c) 2008-2009, Route-Me Contributors
// Copyright (c) 2008-2012, Route-Me Contributors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
... ... @@ -57,6 +57,7 @@ typedef enum {
@class RMMarker;
@class RMAnnotation;
@class RMQuadTree;
@protocol RMMercatorToTileProjection;
@protocol RMTileSource;
@protocol RMMapTiledLayerViewDelegate;
... ... @@ -94,34 +95,6 @@ typedef enum {
NSUInteger boundingMask;
RMProjectedRect tileSourceProjectedBounds;
@private
BOOL _delegateHasBeforeMapMove;
BOOL _delegateHasAfterMapMove;
BOOL _delegateHasBeforeMapZoom;
BOOL _delegateHasAfterMapZoom;
BOOL _delegateHasMapViewRegionDidChange;
BOOL _delegateHasDoubleTapOnMap;
BOOL _delegateHasDoubleTapTwoFingersOnMap;
BOOL _delegateHasSingleTapOnMap;
BOOL _delegateHasSingleTapTwoFingersOnMap;
BOOL _delegateHasLongSingleTapOnMap;
BOOL _delegateHasTapOnAnnotation;
BOOL _delegateHasDoubleTapOnAnnotation;
BOOL _delegateHasTapOnLabelForAnnotation;
BOOL _delegateHasDoubleTapOnLabelForAnnotation;
BOOL _delegateHasShouldDragMarker;
BOOL _delegateHasDidDragMarker;
BOOL _delegateHasDidEndDragMarker;
BOOL _delegateHasLayerForAnnotation;
BOOL _delegateHasWillHideLayerForAnnotation;
BOOL _delegateHasDidHideLayerForAnnotation;
BOOL _constrainMovement;
RMProjectedPoint _northEastConstraint, _southWestConstraint;
float _lastZoom;
CGPoint _lastContentOffset, _accumulatedDelta;
}
@property (nonatomic, assign) id <RMMapViewDelegate> delegate;
... ...
... ... @@ -73,6 +73,34 @@
#pragma mark -
@implementation RMMapView
{
BOOL _delegateHasBeforeMapMove;
BOOL _delegateHasAfterMapMove;
BOOL _delegateHasBeforeMapZoom;
BOOL _delegateHasAfterMapZoom;
BOOL _delegateHasMapViewRegionDidChange;
BOOL _delegateHasDoubleTapOnMap;
BOOL _delegateHasDoubleTapTwoFingersOnMap;
BOOL _delegateHasSingleTapOnMap;
BOOL _delegateHasSingleTapTwoFingersOnMap;
BOOL _delegateHasLongSingleTapOnMap;
BOOL _delegateHasTapOnAnnotation;
BOOL _delegateHasDoubleTapOnAnnotation;
BOOL _delegateHasTapOnLabelForAnnotation;
BOOL _delegateHasDoubleTapOnLabelForAnnotation;
BOOL _delegateHasShouldDragMarker;
BOOL _delegateHasDidDragMarker;
BOOL _delegateHasDidEndDragMarker;
BOOL _delegateHasLayerForAnnotation;
BOOL _delegateHasWillHideLayerForAnnotation;
BOOL _delegateHasDidHideLayerForAnnotation;
BOOL _constrainMovement;
RMProjectedPoint _northEastConstraint, _southWestConstraint;
float _lastZoom;
CGPoint _lastContentOffset, _accumulatedDelta;
}
@synthesize decelerationMode;
... ... @@ -147,6 +175,7 @@
- (id)initWithCoder:(NSCoder *)aDecoder
{
LogMethod();
if (!(self = [super initWithCoder:aDecoder]))
return nil;
... ... @@ -167,12 +196,14 @@
- (id)initWithFrame:(CGRect)frame
{
LogMethod();
return [self initWithFrame:frame andTilesource:[[RMOpenStreetMapSource new] autorelease]];
}
- (id)initWithFrame:(CGRect)frame andTilesource:(id <RMTileSource>)newTilesource
{
LogMethod();
CLLocationCoordinate2D coordinate;
coordinate.latitude = kDefaultInitialLatitude;
coordinate.longitude = kDefaultInitialLongitude;
... ... @@ -195,6 +226,7 @@
backgroundImage:(UIImage *)backgroundImage
{
LogMethod();
if (!(self = [super initWithFrame:frame]))
return nil;
... ... @@ -214,7 +246,8 @@
[super setFrame:frame];
// only change if the frame changes and not during initialization
if (!CGRectEqualToRect(r, frame)) {
if (!CGRectEqualToRect(r, frame))
{
CGRect bounds = CGRectMake(0, 0, frame.size.width, frame.size.height);
backgroundView.frame = bounds;
mapScrollView.frame = bounds;
... ... @@ -226,6 +259,7 @@
- (void)dealloc
{
LogMethod();
[self setDelegate:nil];
[self setBackgroundView:nil];
[self setQuadTree:nil];
... ... @@ -246,6 +280,7 @@
- (void)didReceiveMemoryWarning
{
LogMethod();
[tileSource didReceiveMemoryWarning];
[tileCache didReceiveMemoryWarning];
}
... ... @@ -258,6 +293,7 @@
- (NSString *)description
{
CGRect bounds = [self bounds];
return [NSString stringWithFormat:@"MapView at %.0f,%.0f-%.0f,%.0f", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height];
}
... ... @@ -346,6 +382,7 @@
// Default is with scale = 2.0 * mercators/pixel
zoomRect.size.width = self.bounds.size.width * 2.0;
zoomRect.size.height = self.bounds.size.height * 2.0;
if ((myPoint.x / self.bounds.size.width) < (myPoint.y / self.bounds.size.height))
{
if ((myPoint.y / (self.bounds.size.height - pixelBuffer)) > 1)
... ... @@ -362,6 +399,7 @@
zoomRect.size.height = self.bounds.size.height * (myPoint.x / (self.bounds.size.width - pixelBuffer));
}
}
myOrigin.x = myOrigin.x - (zoomRect.size.width / 2);
myOrigin.y = myOrigin.y - (zoomRect.size.height / 2);
... ... @@ -377,16 +415,20 @@
- (BOOL)tileSourceBoundsContainProjectedPoint:(RMProjectedPoint)point
{
RMSphericalTrapezium bounds = [self.tileSource latitudeLongitudeBoundingBox];
if (bounds.northEast.latitude == 90 && bounds.northEast.longitude == 180 &&
bounds.southWest.latitude == -90 && bounds.southWest.longitude == -180) {
bounds.southWest.latitude == -90 && bounds.southWest.longitude == -180)
{
return YES;
}
return [self projectedBounds:tileSourceProjectedBounds containsPoint:point];
}
- (BOOL)tileSourceBoundsContainScreenPoint:(CGPoint)pixelCoordinate
{
RMProjectedPoint projectedPoint = [self pixelToProjectedPoint:pixelCoordinate];
return [self tileSourceBoundsContainProjectedPoint:projectedPoint];
}
... ... @@ -451,7 +493,8 @@
if (![self tileSourceBoundsContainProjectedPoint:centerProjectedPoint])
return;
if (_delegateHasBeforeMapMove) [delegate beforeMapMove:self];
if (_delegateHasBeforeMapMove)
[delegate beforeMapMove:self];
// RMLog(@"Current contentSize: {%.0f,%.0f}, zoom: %f", mapScrollView.contentSize.width, mapScrollView.contentSize.height, self.zoom);
... ... @@ -466,7 +509,8 @@
// RMLog(@"setMapCenterProjectedPoint: {%f,%f} -> {%.0f,%.0f}", centerProjectedPoint.x, centerProjectedPoint.y, mapScrollView.contentOffset.x, mapScrollView.contentOffset.y);
if (_delegateHasAfterMapMove) [delegate afterMapMove:self];
if (_delegateHasAfterMapMove)
[delegate afterMapMove:self];
[self correctPositionOfAllAnnotations];
}
... ... @@ -490,19 +534,24 @@
// see if new bounds are within constrained bounds, and constrain if necessary
BOOL constrained = NO;
if (newBounds.origin.y < _southWestConstraint.y) {
if (newBounds.origin.y < _southWestConstraint.y)
{
newBounds.origin.y = _southWestConstraint.y;
constrained = YES;
}
if (newBounds.origin.y + newBounds.size.height > _northEastConstraint.y) {
if (newBounds.origin.y + newBounds.size.height > _northEastConstraint.y)
{
newBounds.origin.y = _northEastConstraint.y - newBounds.size.height;
constrained = YES;
}
if (newBounds.origin.x < _southWestConstraint.x) {
if (newBounds.origin.x < _southWestConstraint.x)
{
newBounds.origin.x = _southWestConstraint.x;
constrained = YES;
}
if (newBounds.origin.x + newBounds.size.width > _northEastConstraint.x) {
if (newBounds.origin.x + newBounds.size.width > _northEastConstraint.x)
{
newBounds.origin.x = _northEastConstraint.x - newBounds.size.width;
constrained = YES;
}
... ... @@ -517,12 +566,16 @@
}
}
if (_delegateHasBeforeMapMove) [delegate beforeMapMove:self];
if (_delegateHasBeforeMapMove)
[delegate beforeMapMove:self];
CGPoint contentOffset = mapScrollView.contentOffset;
contentOffset.x += delta.width;
contentOffset.y += delta.height;
mapScrollView.contentOffset = contentOffset;
if (_delegateHasAfterMapMove) [delegate afterMapMove:self];
if (_delegateHasAfterMapMove)
[delegate afterMapMove:self];
}
#pragma mark -
... ... @@ -614,11 +667,10 @@
//zooming in zoomFactor > 1
//zooming out zoomFactor < 1
if ((zoomGreaterMin && zoomLessMax) || (zoomAtMax && zoomFactor<1) || (zoomAtMin && zoomFactor>1)) {
if ((zoomGreaterMin && zoomLessMax) || (zoomAtMax && zoomFactor<1) || (zoomAtMin && zoomFactor>1))
return YES;
} else {
else
return NO;
}
}
- (void)zoomContentByFactor:(float)zoomFactor near:(CGPoint)pivot animated:(BOOL)animated
... ... @@ -635,14 +687,16 @@
// clamp zoom to remain below or equal to maxZoom after zoomAfter will be applied
// Set targetZoom to maxZoom so the map zooms to its maximum
if (targetZoom > [self maxZoom]) {
if (targetZoom > [self maxZoom])
{
zoomFactor = exp2f([self maxZoom] - [self zoom]);
targetZoom = [self maxZoom];
}
// clamp zoom to remain above or equal to minZoom after zoomAfter will be applied
// Set targetZoom to minZoom so the map zooms to its maximum
if (targetZoom < [self minZoom]) {
if (targetZoom < [self minZoom])
{
zoomFactor = 1/exp2f([self zoom] - [self minZoom]);
targetZoom = [self minZoom];
}
... ... @@ -672,12 +726,14 @@
- (float)nextNativeZoomFactor
{
float newZoom = fminf(floorf([self zoom] + 1.0), [self maxZoom]);
return exp2f(newZoom - [self zoom]);
}
- (float)previousNativeZoomFactor
{
float newZoom = fmaxf(floorf([self zoom] - 1.0), [self minZoom]);
return exp2f(newZoom - [self zoom]);
}
... ... @@ -690,10 +746,14 @@
{
// Calculate rounded zoom
float newZoom = fmin(ceilf([self zoom]) + 0.99, [self maxZoom]);
if (newZoom == self.zoom) return;
if (newZoom == self.zoom)
return;
float factor = exp2f(newZoom - [self zoom]);
if (factor > 2.25) {
if (factor > 2.25)
{
newZoom = fmin(ceilf([self zoom]) - 0.01, [self maxZoom]);
factor = exp2f(newZoom - [self zoom]);
}
... ... @@ -711,10 +771,14 @@
{
// Calculate rounded zoom
float newZoom = fmax(floorf([self zoom]) - 0.01, [self minZoom]);
if (newZoom == self.zoom) return;
if (newZoom == self.zoom)
return;
float factor = exp2f(newZoom - [self zoom]);
if (factor > 0.75) {
if (factor > 0.75)
{
newZoom = fmax(floorf([self zoom]) - 1.01, [self minZoom]);
factor = exp2f(newZoom - [self zoom]);
}
... ... @@ -731,20 +795,22 @@
float _zoomFactor = [self adjustedZoomForCurrentBoundingMask:zoomFactor];
float zoomDelta = log2f(_zoomFactor);
float targetZoom = zoomDelta + [self zoom];
BOOL canZoom = NO;
if (targetZoom == [self zoom]) {
if (targetZoom == [self zoom])
{
//OK... . I could even do a return here.. but it will hamper with future logic..
canZoom = YES;
}
// clamp zoom to remain below or equal to maxZoom after zoomAfter will be applied
if (targetZoom > [self maxZoom]) {
if (targetZoom > [self maxZoom])
zoomFactor = exp2f([self maxZoom] - [self zoom]);
}
// clamp zoom to remain above or equal to minZoom after zoomAfter will be applied
if (targetZoom < [self minZoom]) {
if (targetZoom < [self minZoom])
zoomFactor = 1/exp2f([self zoom] - [self minZoom]);
}
// bools for syntactical sugar to understand the logic in the if statement below
BOOL zoomAtMax = ([self zoom] == [self maxZoom]);
... ... @@ -784,7 +850,8 @@
zRect.origin.x < _southWestConstraint.x || zRect.origin.x+zRect.size.width > _northEastConstraint.x);
}
if (!canZoom) {
if (!canZoom)
{
RMLog(@"Zooming will move map out of bounds: no zoom");
return;
}
... ... @@ -832,6 +899,7 @@
// Default is with scale = 2.0 * mercators/pixel
zoomRect.size.width = self.bounds.size.width * 2.0;
zoomRect.size.height = self.bounds.size.height * 2.0;
if ((myPoint.x / self.bounds.size.width) < (myPoint.y / self.bounds.size.height))
{
if ((myPoint.y / (self.bounds.size.height - pixelBuffer)) > 1)
... ... @@ -848,6 +916,7 @@
zoomRect.size.height = self.bounds.size.height * (myPoint.x / (self.bounds.size.width - pixelBuffer));
}
}
myOrigin.x = myOrigin.x - (zoomRect.size.width / 2);
myOrigin.y = myOrigin.y - (zoomRect.size.height / 2);
zoomRect.origin = myOrigin;
... ... @@ -897,11 +966,17 @@
tiledLayerView = [[RMMapTiledLayerView alloc] initWithFrame:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) mapView:self];
tiledLayerView.delegate = self;
if (self.adjustTilesForRetinaDisplay && screenScale > 1.0) {
if (self.adjustTilesForRetinaDisplay && screenScale > 1.0)
{
RMLog(@"adjustTiles");
((CATiledLayer *)tiledLayerView.layer).tileSize = CGSizeMake(tileSideLength * 2.0, tileSideLength * 2.0);
} else
}
else
{
((CATiledLayer *)tiledLayerView.layer).tileSize = CGSizeMake(tileSideLength, tileSideLength);
}
[mapScrollView addSubview:tiledLayerView];
[mapScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
... ... @@ -918,6 +993,7 @@
overlayView = [[RMMapOverlayView alloc] initWithFrame:[self bounds]];
overlayView.delegate = self;
[self insertSubview:overlayView aboveSubview:mapScrollView];
}
... ... @@ -968,9 +1044,12 @@
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView tapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
{
if (_delegateHasTapOnAnnotation && anAnnotation) {
if (_delegateHasTapOnAnnotation && anAnnotation)
{
[delegate tapOnAnnotation:anAnnotation onMap:self];
} else {
}
else
{
if (_delegateHasSingleTapOnMap)
[delegate singleTapOnMap:self at:aPoint];
}
... ... @@ -978,9 +1057,12 @@
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView doubleTapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
{
if (_delegateHasDoubleTapOnAnnotation && anAnnotation) {
if (_delegateHasDoubleTapOnAnnotation && anAnnotation)
{
[delegate doubleTapOnAnnotation:anAnnotation onMap:self];
} else {
}
else
{
[self zoomInToNextNativeZoomAt:aPoint animated:YES];
if (_delegateHasDoubleTapOnMap)
... ... @@ -990,9 +1072,12 @@
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView tapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
{
if (_delegateHasTapOnLabelForAnnotation && anAnnotation) {
if (_delegateHasTapOnLabelForAnnotation && anAnnotation)
{
[delegate tapOnLabelForAnnotation:anAnnotation onMap:self];
} else {
}
else
{
if (_delegateHasSingleTapOnMap)
[delegate singleTapOnMap:self at:aPoint];
}
... ... @@ -1001,8 +1086,11 @@
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView doubleTapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
{
if (_delegateHasDoubleTapOnLabelForAnnotation && anAnnotation)
{
[delegate doubleTapOnLabelForAnnotation:anAnnotation onMap:self];
else {
}
else
{
[self zoomInToNextNativeZoomAt:aPoint animated:YES];
if (_delegateHasDoubleTapOnMap)
... ... @@ -1078,10 +1166,12 @@
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(correctPositionOfAllAnnotations) object:nil];
if (_constrainMovement && ![self projectedBounds:tileSourceProjectedBounds containsPoint:[self centerProjectedPoint]]) {
if (_constrainMovement && ![self projectedBounds:tileSourceProjectedBounds containsPoint:[self centerProjectedPoint]])
{
dispatch_async(dispatch_get_main_queue(), ^{
[mapScrollView setContentOffset:_lastContentOffset animated:NO];
});
return;
}
... ... @@ -1092,14 +1182,18 @@
_accumulatedDelta.x += delta.x;
_accumulatedDelta.y += delta.y;
if (fabsf(_accumulatedDelta.x) < kZoomRectPixelBuffer && fabsf(_accumulatedDelta.y) < kZoomRectPixelBuffer) {
if (fabsf(_accumulatedDelta.x) < kZoomRectPixelBuffer && fabsf(_accumulatedDelta.y) < kZoomRectPixelBuffer)
{
[overlayView moveLayersBy:_accumulatedDelta];
[self performSelector:@selector(correctPositionOfAllAnnotations) withObject:nil afterDelay:0.1];
} else {
}
else
{
[self correctPositionOfAllAnnotations];
}
} else {
}
else
{
[self correctPositionOfAllAnnotationsIncludingInvisibles:NO];
_lastZoom = zoom;
}
... ... @@ -1107,7 +1201,8 @@
_lastContentOffset = mapScrollView.contentOffset;
// Don't do anything stupid here or your scrolling experience will suck
if (_delegateHasMapViewRegionDidChange) [delegate mapViewRegionDidChange:self];
if (_delegateHasMapViewRegionDidChange)
[delegate mapViewRegionDidChange:self];
}
#pragma mark -
... ... @@ -1156,7 +1251,8 @@
if (backgroundView == aView)
return;
if (backgroundView != nil) {
if (backgroundView != nil)
{
[backgroundView removeFromSuperview];
[backgroundView release];
}
... ... @@ -1183,6 +1279,7 @@
- (void)setMetersPerPixel:(double)newMetersPerPixel animated:(BOOL)animated
{
double factor = self.metersPerPixel / newMetersPerPixel;
[self zoomContentByFactor:factor near:CGPointMake(self.bounds.size.width/2.0, self.bounds.size.height/2.0) animated:animated];
}
... ... @@ -1196,6 +1293,7 @@
double routemeMetersPerPixel = self.metersPerPixel;
double iphoneMillimetersPerPixel = kiPhoneMilimeteresPerPixel;
double truescaleDenominator = routemeMetersPerPixel / (0.001 * iphoneMillimetersPerPixel);
return truescaleDenominator;
}
... ... @@ -1236,6 +1334,7 @@
- (void)setEnableClustering:(BOOL)doEnableClustering
{
enableClustering = doEnableClustering;
[self correctPositionOfAllAnnotations];
}
... ... @@ -1244,8 +1343,12 @@
decelerationMode = aDecelerationMode;
float decelerationRate = 0.0;
if (aDecelerationMode == RMMapDecelerationNormal) decelerationRate = UIScrollViewDecelerationRateNormal;
else if (aDecelerationMode == RMMapDecelerationFast) decelerationRate = UIScrollViewDecelerationRateFast;
if (aDecelerationMode == RMMapDecelerationNormal)
decelerationRate = UIScrollViewDecelerationRateNormal;
else if (aDecelerationMode == RMMapDecelerationFast)
decelerationRate = UIScrollViewDecelerationRateFast;
[mapScrollView setDecelerationRate:decelerationRate];
}
... ... @@ -1261,9 +1364,11 @@
- (void)setAdjustTilesForRetinaDisplay:(BOOL)doAdjustTilesForRetinaDisplay
{
if (adjustTilesForRetinaDisplay == doAdjustTilesForRetinaDisplay) return;
if (adjustTilesForRetinaDisplay == doAdjustTilesForRetinaDisplay)
return;
adjustTilesForRetinaDisplay = doAdjustTilesForRetinaDisplay;
[self createMapView];
}
... ... @@ -1420,14 +1525,15 @@
if (self.quadTree)
{
if (!correctAllAnnotations) {
if (!correctAllAnnotations)
{
for (RMAnnotation *annotation in visibleAnnotations)
{
[self correctScreenPosition:annotation];
}
// RMLog(@"%d annotations corrected", [visibleAnnotations count]);
[CATransaction commit];
return;
}
... ... @@ -1451,26 +1557,33 @@
continue;
// Use the zPosition property to order the layer hierarchy
if (![visibleAnnotations containsObject:annotation]) {
if (![visibleAnnotations containsObject:annotation])
{
[overlayView addSublayer:annotation.layer];
[visibleAnnotations addObject:annotation];
}
[previousVisibleAnnotations removeObject:annotation];
}
for (RMAnnotation *annotation in previousVisibleAnnotations)
{
if (_delegateHasWillHideLayerForAnnotation) [delegate mapView:self willHideLayerForAnnotation:annotation];
if (_delegateHasWillHideLayerForAnnotation)
[delegate mapView:self willHideLayerForAnnotation:annotation];
annotation.layer = nil;
if (_delegateHasDidHideLayerForAnnotation) [delegate mapView:self didHideLayerForAnnotation:annotation];
if (_delegateHasDidHideLayerForAnnotation)
[delegate mapView:self didHideLayerForAnnotation:annotation];
[visibleAnnotations removeObject:annotation];
}
[previousVisibleAnnotations release];
// RMLog(@"%d annotations on screen, %d total", [overlayView sublayersCount], [annotations count]);
} else
}
else
{
CALayer *lastLayer = nil;
... ... @@ -1481,13 +1594,16 @@
for (RMAnnotation *annotation in annotations)
{
[self correctScreenPosition:annotation];
if ([annotation isAnnotationWithinBounds:[self bounds]]) {
if ([annotation isAnnotationWithinBounds:[self bounds]])
{
if (annotation.layer == nil && _delegateHasLayerForAnnotation)
annotation.layer = [delegate mapView:self layerForAnnotation:annotation];
if (annotation.layer == nil)
continue;
if (![visibleAnnotations containsObject:annotation]) {
if (![visibleAnnotations containsObject:annotation])
{
if (!lastLayer)
[overlayView insertSublayer:annotation.layer atIndex:0];
else
... ... @@ -1495,20 +1611,28 @@
[visibleAnnotations addObject:annotation];
}
lastLayer = annotation.layer;
} else {
if (_delegateHasWillHideLayerForAnnotation) [delegate mapView:self willHideLayerForAnnotation:annotation];
}
else
{
if (_delegateHasWillHideLayerForAnnotation)
[delegate mapView:self willHideLayerForAnnotation:annotation];
annotation.layer = nil;
[visibleAnnotations removeObject:annotation];
if (_delegateHasDidHideLayerForAnnotation) [delegate mapView:self didHideLayerForAnnotation:annotation];
if (_delegateHasDidHideLayerForAnnotation)
[delegate mapView:self didHideLayerForAnnotation:annotation];
}
}
// RMLog(@"%d annotations on screen, %d total", [overlayView sublayersCount], [annotations count]);
} else {
}
else
{
for (RMAnnotation *annotation in visibleAnnotations)
{
[self correctScreenPosition:annotation];
}
// RMLog(@"%d annotations corrected", [visibleAnnotations count]);
}
}
... ... @@ -1529,21 +1653,26 @@
- (void)addAnnotation:(RMAnnotation *)annotation
{
@synchronized (annotations) {
@synchronized (annotations)
{
[annotations addObject:annotation];
[self.quadTree addAnnotation:annotation];
}
if (enableClustering) {
if (enableClustering)
{
[self correctPositionOfAllAnnotations];
} else {
}
else
{
[self correctScreenPosition:annotation];
if ([annotation isAnnotationOnScreen] && [delegate respondsToSelector:@selector(mapView:layerForAnnotation:)])
{
annotation.layer = [delegate mapView:self layerForAnnotation:annotation];
if (annotation.layer) {
if (annotation.layer)
{
[overlayView addSublayer:annotation.layer];
[visibleAnnotations addObject:annotation];
}
... ... @@ -1553,22 +1682,26 @@
- (void)addAnnotations:(NSArray *)newAnnotations
{
@synchronized (annotations) {
@synchronized (annotations)
{
for (RMAnnotation *annotation in newAnnotations)
{
[annotations addObject:annotation];
[self.quadTree addAnnotation:annotation];
}
}
[self correctPositionOfAllAnnotationsIncludingInvisibles:YES];
}
- (void)removeAnnotation:(RMAnnotation *)annotation
{
@synchronized (annotations) {
@synchronized (annotations)
{
[annotations removeObject:annotation];
[visibleAnnotations removeObject:annotation];
}
[self.quadTree removeAnnotation:annotation];
// Remove the layer from the screen
... ... @@ -1577,7 +1710,8 @@
- (void)removeAnnotations:(NSArray *)annotationsToRemove
{
@synchronized (annotations) {
@synchronized (annotations)
{
for (RMAnnotation *annotation in annotationsToRemove)
{
[annotations removeObject:annotation];
... ... @@ -1592,7 +1726,8 @@
- (void)removeAllAnnotations
{
@synchronized (annotations) {
@synchronized (annotations)
{
for (RMAnnotation *annotation in annotations)
{
// Remove the layer from the screen
... ...
... ... @@ -103,12 +103,14 @@
if (label == aView)
return;
if (label != nil) {
if (label != nil)
{
[[label layer] removeFromSuperlayer];
[label release]; label = nil;
}
if (aView != nil) {
if (aView != nil)
{
label = [aView retain];
[self addSublayer:[label layer]];
}
... ... @@ -166,7 +168,8 @@
- (void)showLabel
{
if ([self.label isHidden]) {
if ([self.label isHidden])
{
// Using addSublayer will animate showing the label, whereas setHidden is not animated
[self addSublayer:[self.label layer]];
[self.label setHidden:NO];
... ... @@ -175,7 +178,8 @@
- (void)hideLabel
{
if (![self.label isHidden]) {
if (![self.label isHidden])
{
// Using removeFromSuperlayer will animate hiding the label, whereas setHidden is not animated
[[self.label layer] removeFromSuperlayer];
[self.label setHidden:YES];
... ...
... ... @@ -29,7 +29,8 @@
#import "RMTile.h"
#import "RMTileCache.h"
@interface RMMemoryCache : NSObject <RMTileCache> {
@interface RMMemoryCache : NSObject <RMTileCache>
{
NSMutableDictionary *cache;
NSUInteger capacity;
}
... ...
... ... @@ -41,6 +41,7 @@
if (aCapacity < 1)
aCapacity = 1;
capacity = aCapacity;
return self;
... ... @@ -53,24 +54,29 @@
- (void)dealloc
{
@synchronized (cache) {
@synchronized (cache)
{
[cache removeAllObjects];
[cache release]; cache = nil;
}
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
LogMethod();
@synchronized (cache) {
@synchronized (cache)
{
[cache removeAllObjects];
}
}
- (void)removeTile:(RMTile)tile
{
@synchronized (cache) {
@synchronized (cache)
{
[cache removeObjectForKey:[RMTileCache tileHash:tile]];
}
}
... ... @@ -81,13 +87,15 @@
RMCacheObject *cachedObject = nil;
NSNumber *tileHash = [RMTileCache tileHash:tile];
@synchronized (cache) {
@synchronized (cache)
{
cachedObject = [cache objectForKey:tileHash];
if (!cachedObject)
return nil;
if (![[cachedObject cacheKey] isEqualToString:aCacheKey]) {
if (![[cachedObject cacheKey] isEqualToString:aCacheKey])
{
[cache removeObjectForKey:tileHash];
return nil;
}
... ... @@ -103,7 +111,8 @@
/// Remove the least-recently used image from cache, if cache is at or over capacity. Removes only 1 image.
- (void)makeSpaceInCache
{
@synchronized (cache) {
@synchronized (cache)
{
while ([cache count] >= capacity)
{
// Rather than scanning I would really like to be using a priority queue
... ... @@ -126,7 +135,8 @@
}
}
if (oldestImage) {
if (oldestImage)
{
// RMLog(@"Memory cache delete tile %d %d %d (%@)", oldestImage.tile.x, oldestImage.tile.y, oldestImage.tile.zoom, [RMTileCache tileHash:oldestImage.tile]);
[cache removeObjectForKey:[RMTileCache tileHash:oldestImage.tile]];
}
... ... @@ -140,7 +150,8 @@
[self makeSpaceInCache];
@synchronized (cache) {
@synchronized (cache)
{
[cache setObject:[RMCacheObject cacheObject:image forTile:tile withCacheKey:aCacheKey] forKey:[RMTileCache tileHash:tile]];
}
}
... ... @@ -148,7 +159,9 @@
- (void)removeAllCachedImages
{
LogMethod();
@synchronized (cache) {
@synchronized (cache)
{
[cache removeAllObjects];
}
}
... ...
... ... @@ -32,7 +32,6 @@
Provides key-based access to tiles from the Open Cycle Map project.
*/
@interface RMOpenCycleMapSource : RMAbstractWebMapSource {
}
@interface RMOpenCycleMapSource : RMAbstractWebMapSource
@end
\ No newline at end of file
... ...
... ... @@ -46,6 +46,7 @@
NSAssert4(((tile.zoom >= self.minZoom) && (tile.zoom <= self.maxZoom)),
@"%@ tried to retrieve tile with zoomLevel %d, outside source's defined range %f to %f",
self, tile.zoom, self.minZoom, self.maxZoom);
return [NSURL URLWithString:[NSString stringWithFormat:@"http://andy.sandbox.cloudmade.com/tiles/cycle/%d/%d/%d.png", tile.zoom, tile.x, tile.y]];
}
... ...
... ... @@ -32,7 +32,6 @@
Provides key-based access to tiles from the Open Street Map project.
*/
@interface RMOpenStreetMapSource : RMAbstractWebMapSource {
}
@interface RMOpenStreetMapSource : RMAbstractWebMapSource
@end
... ...
... ... @@ -46,6 +46,7 @@
NSAssert4(((tile.zoom >= self.minZoom) && (tile.zoom <= self.maxZoom)),
@"%@ tried to retrieve tile with zoomLevel %d, outside source's defined range %f to %f",
self, tile.zoom, self.minZoom, self.maxZoom);
return [NSURL URLWithString:[NSString stringWithFormat:@"http://tile.openstreetmap.org/%d/%d/%d.png", tile.zoom, tile.x, tile.y]];
}
... ...
... ... @@ -95,7 +95,8 @@
- (void)recalculateGeometry
{
if (ignorePathUpdates) return;
if (ignorePathUpdates)
return;
CGPoint myPosition = self.annotation.position;
... ... @@ -108,7 +109,9 @@
// The bounds are actually in mercators...
/// \bug if "bounds are actually in mercators", shouldn't be using a CGRect
scaledLineWidth = lineWidth;
if (!scaleLineWidth) {
if (!scaleLineWidth)
{
renderedScale = [mapView metersPerPixel];
scaledLineWidth *= renderedScale;
}
... ... @@ -124,24 +127,31 @@
// Clip top
offset = myPosition.y + pixelBounds.origin.y - screenBounds.origin.y + outset;
if (offset < 0.0f) {
if (offset < 0.0f)
{
pixelBounds.origin.y -= offset;
pixelBounds.size.height += offset;
}
// Clip left
offset = myPosition.x + pixelBounds.origin.x - screenBounds.origin.x + outset;
if (offset < 0.0f) {
if (offset < 0.0f)
{
pixelBounds.origin.x -= offset;
pixelBounds.size.width += offset;
}
// Clip bottom
offset = myPosition.y + pixelBounds.origin.y + pixelBounds.size.height - screenBounds.origin.y - screenBounds.size.height - outset;
if (offset > 0.0f) {
if (offset > 0.0f)
{
pixelBounds.size.height -= offset;
}
// Clip right
offset = myPosition.x + pixelBounds.origin.x + pixelBounds.size.width - screenBounds.origin.x - screenBounds.size.width - outset;
if (offset > 0.0f) {
if (offset > 0.0f)
{
pixelBounds.size.width -= offset;
}
... ... @@ -154,6 +164,7 @@
pathBoundingBox = CGRectMake(myPosition.x + self.bounds.origin.x, myPosition.y + self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height);
self.anchorPoint = CGPointMake(-pixelBounds.origin.x / pixelBounds.size.width, -pixelBounds.origin.y / pixelBounds.size.height);
[self setNeedsDisplay];
}
... ... @@ -176,11 +187,9 @@
point.y = point.y - projectedLocation.y;
if (isDrawing)
{
CGPathAddLineToPoint(path, NULL, point.x, -point.y);
} else {
else
CGPathMoveToPoint(path, NULL, point.x, -point.y);
}
[self recalculateGeometry];
}
... ... @@ -238,16 +247,17 @@
float scale = 1.0f / [mapView metersPerPixel];
float scaledLineWidth = lineWidth;
if (!scaleLineWidth) {
if (!scaleLineWidth)
scaledLineWidth *= renderedScale;
}
// NSLog(@"line width = %f, content scale = %f", scaledLineWidth, renderedScale);
if (!scaleLineDash && _lineDashLengths) {
if (!scaleLineDash && _lineDashLengths)
{
dashLengths = _scaledLineDashLengths;
for (size_t dashIndex=0; dashIndex<_lineDashCount; dashIndex++) {
for (size_t dashIndex=0; dashIndex<_lineDashCount; dashIndex++)
dashLengths[dashIndex] = _lineDashLengths[dashIndex] * renderedScale;
}
}
CGContextScaleCTM(theContext, scale, scale);
... ... @@ -261,9 +271,8 @@
CGContextSetStrokeColorWithColor(theContext, [lineColor CGColor]);
CGContextSetFillColorWithColor(theContext, [fillColor CGColor]);
if (_lineDashLengths) {
if (_lineDashLengths)
CGContextSetLineDash(theContext, lineDashPhase, dashLengths, _lineDashCount);
}
// according to Apple's documentation, DrawPath closes the path if it's a filled style, so a call to ClosePath isn't necessary
CGContextDrawPath(theContext, drawingMode);
... ... @@ -325,7 +334,8 @@
- (void)setLineColor:(UIColor *)aLineColor
{
if (lineColor != aLineColor) {
if (lineColor != aLineColor)
{
[lineColor release];
lineColor = [aLineColor retain];
[self setNeedsDisplay];
... ... @@ -339,7 +349,8 @@
- (void)setFillColor:(UIColor *)aFillColor
{
if (fillColor != aFillColor) {
if (fillColor != aFillColor)
{
[fillColor release];
fillColor = [aFillColor retain];
[self setNeedsDisplay];
... ... @@ -349,42 +360,48 @@
- (NSArray *)lineDashLengths
{
NSMutableArray *lengths = [NSMutableArray arrayWithCapacity:_lineDashCount];
for (size_t dashIndex=0; dashIndex<_lineDashCount; dashIndex++) {
for (size_t dashIndex=0; dashIndex<_lineDashCount; dashIndex++)
[lengths addObject:(id)[NSNumber numberWithFloat:_lineDashLengths[dashIndex]]];
}
return lengths;
}
- (void)setLineDashLengths:(NSArray *)lengths
{
if (_lineDashLengths) {
if (_lineDashLengths)
{
free(_lineDashLengths);
_lineDashLengths = NULL;
}
if (_scaledLineDashLengths) {
if (_scaledLineDashLengths)
{
free(_scaledLineDashLengths);
_scaledLineDashLengths = NULL;
}
_lineDashCount = [lengths count];
if (!_lineDashCount) {
if (!_lineDashCount)
return;
}
_lineDashLengths = calloc(_lineDashCount, sizeof(CGFloat));
if (!scaleLineDash) {
if (!scaleLineDash)
_scaledLineDashLengths = calloc(_lineDashCount, sizeof(CGFloat));
}
NSEnumerator *lengthEnumerator = [lengths objectEnumerator];
id lenObj;
size_t dashIndex = 0;
while ((lenObj = [lengthEnumerator nextObject]))
{
if ([lenObj isKindOfClass:[NSNumber class]]) {
if ([lenObj isKindOfClass:[NSNumber class]])
{
_lineDashLengths[dashIndex] = [lenObj floatValue];
} else {
}
else
{
_lineDashLengths[dashIndex] = 0.0;
dashIndex++;
}
... ...
... ... @@ -31,6 +31,7 @@ CGPoint RMScaleCGPointAboutPoint(CGPoint point, float factor, CGPoint pivot)
{
point.x = (point.x - pivot.x) * factor + pivot.x;
point.y = (point.y - pivot.y) * factor + pivot.y;
return point;
}
... ... @@ -39,6 +40,7 @@ CGRect RMScaleCGRectAboutPoint(CGRect rect, float factor, CGPoint pivot)
rect.origin = RMScaleCGPointAboutPoint(rect.origin, factor, pivot);
rect.size.width *= factor;
rect.size.height *= factor;
return rect;
}
... ... @@ -46,11 +48,13 @@ CGPoint RMTranslateCGPointBy(CGPoint point, CGSize delta)
{
point.x += delta.width;
point.y += delta.height;
return point;
}
CGRect RMTranslateCGRectBy(CGRect rect, CGSize delta)
{
rect.origin = RMTranslateCGPointBy(rect.origin, delta);
return rect;
}
... ...
... ... @@ -58,6 +58,7 @@
{
RMProjectedRect theBounds;
theBounds = RMProjectedRectMake(0, 0, 0, 0);
return [self initWithString:params inBounds:theBounds];
}
... ... @@ -142,10 +143,12 @@ static RMProjection *_latlong = nil;
+ (RMProjection *)googleProjection
{
if (_google) {
if (_google)
{
return _google;
}
else {
else
{
RMProjectedRect theBounds = RMProjectedRectMake(-20037508.34, -20037508.34, 20037508.34 * 2, 20037508.34 * 2);
_google = [[RMProjection alloc] initWithString:@"+title= Google Mercator EPSG:900913 +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"
... ... @@ -156,10 +159,12 @@ static RMProjection *_latlong = nil;
+ (RMProjection *)EPSGLatLong
{
if (_latlong) {
if (_latlong)
{
return _latlong;
}
else {
else
{
RMProjectedRect theBounds = RMProjectedRectMake(-kMaxLong, -kMaxLat, 360, kMaxLong);
_latlong = [[RMProjection alloc] initWithString:@"+proj=latlong +ellps=WGS84"
... ...
... ... @@ -66,12 +66,14 @@
mapView = nil;
[cachedClusterAnnotation release]; cachedClusterAnnotation = nil;
@synchronized (annotations) {
@synchronized (annotations)
{
for (RMAnnotation *annotation in annotations)
{
annotation.quadTreeNode = nil;
}
}
[annotations release]; annotations = nil;
[northWest release]; northWest = nil;
... ... @@ -87,7 +89,8 @@
{
NSArray *immutableAnnotations = nil;
@synchronized (annotations) {
@synchronized (annotations)
{
immutableAnnotations = [NSArray arrayWithArray:annotations];
}
... ... @@ -97,26 +100,42 @@
- (void)addAnnotationToChildNodes:(RMAnnotation *)annotation
{
RMProjectedRect projectedRect = annotation.projectedBoundingBox;
if (RMProjectedRectContainsProjectedRect(northWestBoundingBox, projectedRect)) {
if (!northWest) northWest = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:northWestBoundingBox];
if (RMProjectedRectContainsProjectedRect(northWestBoundingBox, projectedRect))
{
if (!northWest)
northWest = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:northWestBoundingBox];
[northWest addAnnotation:annotation];
}
else if (RMProjectedRectContainsProjectedRect(northEastBoundingBox, projectedRect))
{
if (!northEast)
northEast = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:northEastBoundingBox];
} else if (RMProjectedRectContainsProjectedRect(northEastBoundingBox, projectedRect)) {
if (!northEast) northEast = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:northEastBoundingBox];
[northEast addAnnotation:annotation];
}
else if (RMProjectedRectContainsProjectedRect(southWestBoundingBox, projectedRect))
{
if (!southWest)
southWest = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:southWestBoundingBox];
} else if (RMProjectedRectContainsProjectedRect(southWestBoundingBox, projectedRect)) {
if (!southWest) southWest = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:southWestBoundingBox];
[southWest addAnnotation:annotation];
}
else if (RMProjectedRectContainsProjectedRect(southEastBoundingBox, projectedRect))
{
if (!southEast)
southEast = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:southEastBoundingBox];
} else if (RMProjectedRectContainsProjectedRect(southEastBoundingBox, projectedRect)) {
if (!southEast) southEast = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:self inBoundingBox:southEastBoundingBox];
[southEast addAnnotation:annotation];
} else {
@synchronized (annotations) {
}
else
{
@synchronized (annotations)
{
[annotations addObject:annotation];
}
annotation.quadTreeNode = self;
[self removeUpwardsAllCachedClusterAnnotations];
}
... ... @@ -126,12 +145,15 @@
{
if (nodeType == nodeTypeLeaf)
{
@synchronized (annotations) {
@synchronized (annotations)
{
[annotations addObject:annotation];
}
annotation.quadTreeNode = self;
if ([annotations count] <= kMaxAnnotationsPerLeaf || boundingBox.size.width < (kMinimumQuadTreeElementWidth * 2.0)) {
if ([annotations count] <= kMaxAnnotationsPerLeaf || boundingBox.size.width < (kMinimumQuadTreeElementWidth * 2.0))
{
[self removeUpwardsAllCachedClusterAnnotations];
return;
}
... ... @@ -142,7 +164,9 @@
// might be a problem depending on kMaxAnnotationsPerLeaf
NSArray *immutableAnnotations = nil;
@synchronized (annotations) {
@synchronized (annotations)
{
immutableAnnotations = [NSArray arrayWithArray:annotations];
[annotations removeAllObjects];
}
... ... @@ -160,10 +184,13 @@
- (void)removeAnnotation:(RMAnnotation *)annotation
{
if (!annotation.quadTreeNode) return;
if (!annotation.quadTreeNode)
return;
annotation.quadTreeNode = nil;
@synchronized (annotations) {
@synchronized (annotations)
{
[annotations removeObject:annotation];
}
... ... @@ -180,9 +207,11 @@
[self removeAnnotation:annotation];
RMQuadTreeNode *nextParentNode = self;
while ((nextParentNode = [nextParentNode parentNode]))
{
if (RMProjectedRectContainsProjectedRect(nextParentNode.boundingBox, annotation.projectedBoundingBox)) {
if (RMProjectedRectContainsProjectedRect(nextParentNode.boundingBox, annotation.projectedBoundingBox))
{
[nextParentNode addAnnotationToChildNodes:annotation];
break;
}
... ... @@ -217,7 +246,8 @@
{
NSMutableArray *unclusteredAnnotations = [NSMutableArray array];
@synchronized (annotations) {
@synchronized (annotations)
{
for (RMAnnotation *annotation in annotations)
{
if (!annotation.clusteringEnabled)
... ... @@ -245,33 +275,43 @@
{
NSArray *enclosedAnnotations = self.enclosedAnnotations;
NSUInteger enclosedAnnotationsCount = [enclosedAnnotations count];
if (enclosedAnnotationsCount < 2) {
if (enclosedAnnotationsCount < 2)
{
[someArray addObjectsFromArray:enclosedAnnotations];
return;
}
RMProjectedPoint clusterMarkerPosition;
if (findGravityCenter)
{
double averageX = 0.0, averageY = 0.0;
for (RMAnnotation *annotation in enclosedAnnotations)
{
averageX += annotation.projectedLocation.x;
averageY += annotation.projectedLocation.y;
}
averageX /= (double)enclosedAnnotationsCount;
averageY /= (double) enclosedAnnotationsCount;
double halfClusterWidth = clusterSize.width / 2.0, halfClusterHeight = clusterSize.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 - 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;
// TODO: anchorPoint
clusterMarkerPosition = RMProjectedPointMake(averageX, averageY);
} else
}
else
{
clusterMarkerPosition = RMProjectedPointMake(boundingBox.origin.x + halfWidth, boundingBox.origin.y + (boundingBox.size.height / 2.0));
}
... ... @@ -283,22 +323,30 @@
[someArray addObject:cachedClusterAnnotation];
[someArray addObjectsFromArray:[self unclusteredAnnotations]];
return;
}
// TODO: leaf clustering (necessary?)
if (nodeType == nodeTypeLeaf) {
@synchronized (annotations) {
if (nodeType == nodeTypeLeaf)
{
@synchronized (annotations)
{
[someArray addObjectsFromArray:annotations];
}
return;
}
} else {
if (nodeType == nodeTypeLeaf) {
@synchronized (annotations) {
}
else
{
if (nodeType == nodeTypeLeaf)
{
@synchronized (annotations)
{
[someArray addObjectsFromArray:annotations];
}
return;
}
}
... ... @@ -312,7 +360,8 @@
if (RMProjectedRectIntersectsProjectedRect(aBoundingBox, southEastBoundingBox))
[southEast addAnnotationsInBoundingBox:aBoundingBox toMutableArray:someArray createClusterAnnotations:createClusterAnnotations withClusterSize:clusterSize findGravityCenter:findGravityCenter];
@synchronized (annotations) {
@synchronized (annotations)
{
for (RMAnnotation *annotation in annotations)
{
if (RMProjectedRectIntersectsProjectedRect(aBoundingBox, annotation.projectedBoundingBox))
... ... @@ -323,7 +372,9 @@
- (void)removeUpwardsAllCachedClusterAnnotations
{
if (parentNode) [parentNode removeUpwardsAllCachedClusterAnnotations];
if (parentNode)
[parentNode removeUpwardsAllCachedClusterAnnotations];
[cachedClusterAnnotation release]; cachedClusterAnnotation = nil;
}
... ... @@ -354,21 +405,24 @@
- (void)addAnnotation:(RMAnnotation *)annotation
{
@synchronized (self) {
@synchronized (self)
{
[rootNode addAnnotation:annotation];
}
}
- (void)removeAnnotation:(RMAnnotation *)annotation
{
@synchronized (self) {
@synchronized (self)
{
[annotation.quadTreeNode removeAnnotation:annotation];
}
}
- (void)removeAllObjects
{
@synchronized (self) {
@synchronized (self)
{
[rootNode release];
rootNode = [[RMQuadTreeNode alloc] initWithMapView:mapView forParent:nil inBoundingBox:[[RMProjection googleProjection] planetBounds]];
}
... ... @@ -385,7 +439,8 @@
{
NSMutableArray *annotations = [NSMutableArray array];
@synchronized (self) {
@synchronized (self)
{
[rootNode addAnnotationsInBoundingBox:boundingBox toMutableArray:annotations createClusterAnnotations:createClusterAnnotations withClusterSize:clusterSize findGravityCenter:findGravityCenter];
}
... ...
... ... @@ -39,6 +39,7 @@ uint64_t RMTileHash(RMTile tile)
accumulator |= ((uint64_t)tile.x & (1LL<<i)) << i;
accumulator |= ((uint64_t)tile.y & (1LL<<i)) << (i+1);
}
accumulator |= 1LL<<(tile.zoom * 2);
return accumulator;
... ... @@ -61,6 +62,7 @@ RMTile RMTileDummy()
t.x = -1;
t.y = -1;
t.zoom = -1;
return t;
}
... ... @@ -80,6 +82,7 @@ RMTile RMTileMake(uint32_t x, uint32_t y, short zoom)
t.x = x;
t.y = y;
t.zoom = zoom;
return t;
}
... ... @@ -89,6 +92,7 @@ RMTileRect RMTileRectRound(RMTileRect rect)
rect.size.width = ceilf(rect.size.width + rect.origin.offset.x);
rect.size.height = ceilf(rect.size.height + rect.origin.offset.y);
rect.origin.offset = CGPointZero;
return rect;
}
... ...
... ... @@ -50,12 +50,11 @@
memoryCache = nil;
id cacheCfg = [[RMConfiguration configuration] cacheConfiguration];
if (!cacheCfg) {
if (!cacheCfg)
cacheCfg = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObject: @"memory-cache" forKey: @"type"],
[NSDictionary dictionaryWithObject: @"db-cache" forKey: @"type"],
nil];
}
for (id cfg in cacheCfg)
{
... ... @@ -65,7 +64,8 @@
NSString *type = [cfg valueForKey:@"type"];
if ([@"memory-cache" isEqualToString:type]) {
if ([@"memory-cache" isEqualToString:type])
{
memoryCache = [[self memoryCacheWithConfig:cfg] retain];
continue;
}
... ... @@ -73,11 +73,10 @@
if ([@"db-cache" isEqualToString:type])
newCache = [self databaseCacheWithConfig:cfg];
if (newCache) {
if (newCache)
[caches addObject:newCache];
} else {
else
RMLog(@"failed to create cache of type %@", type);
}
}
@catch (NSException * e) {
... ... @@ -97,7 +96,8 @@
- (void)addCache:(id <RMTileCache>)cache
{
@synchronized (caches) {
@synchronized (caches)
{
[caches addObject:cache];
}
}
... ... @@ -111,13 +111,18 @@
- (UIImage *)cachedImage:(RMTile)tile withCacheKey:(NSString *)aCacheKey
{
UIImage *image = [memoryCache cachedImage:tile withCacheKey:aCacheKey];
if (image) return image;
@synchronized (caches) {
if (image)
return image;
@synchronized (caches)
{
for (id <RMTileCache> cache in caches)
{
image = [cache cachedImage:tile withCacheKey:aCacheKey];
if (image != nil) {
if (image != nil)
{
[memoryCache addImage:image forTile:tile withCacheKey:aCacheKey];
return image;
}
... ... @@ -131,12 +136,12 @@
{
[memoryCache addImage:image forTile:tile withCacheKey:aCacheKey];
@synchronized (caches) {
@synchronized (caches)
{
for (id <RMTileCache> cache in caches)
{
if ([cache respondsToSelector:@selector(addImage:forTile:withCacheKey:)]) {
if ([cache respondsToSelector:@selector(addImage:forTile:withCacheKey:)])
[cache addImage:image forTile:tile withCacheKey:aCacheKey];
}
}
}
}
... ... @@ -146,7 +151,8 @@
LogMethod();
[memoryCache didReceiveMemoryWarning];
@synchronized (caches) {
@synchronized (caches)
{
for (id<RMTileCache> cache in caches)
{
[cache didReceiveMemoryWarning];
... ... @@ -158,7 +164,8 @@
{
[memoryCache removeAllCachedImages];
@synchronized (caches) {
@synchronized (caches)
{
for (id<RMTileCache> cache in caches)
{
[cache removeAllCachedImages];
... ...
//
// RouteMe.h
//
// Copyright (c) 2008-2011, Route-Me Contributors
// Copyright (c) 2008-2012, Route-Me Contributors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
... ...
... ... @@ -1047,6 +1047,7 @@
GCC_STRICT_ALIASING = YES;
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
... ... @@ -1080,6 +1081,7 @@
GCC_STRICT_ALIASING = YES;
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
... ...