/MapView/Map/RMCoreAnimationRenderer.m
Objective C | 197 lines | 96 code | 29 blank | 72 comment | 11 complexity | fb5b072269ad636665b65bb7858fe51e MD5 | raw file
1// 2// RMCoreAnimationRenderer.m 3// 4// Copyright (c) 2008-2009, Route-Me Contributors 5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions are met: 9// 10// * Redistributions of source code must retain the above copyright notice, this 11// list of conditions and the following disclaimer. 12// * Redistributions in binary form must reproduce the above copyright notice, 13// this list of conditions and the following disclaimer in the documentation 14// and/or other materials provided with the distribution. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26// POSSIBILITY OF SUCH DAMAGE. 27#import "RMGlobalConstants.h" 28#import "RMCoreAnimationRenderer.h" 29#import <QuartzCore/QuartzCore.h> 30#import "RMTile.h" 31#import "RMTileLoader.h" 32#import "RMPixel.h" 33#import "RMTileImage.h" 34#import "RMTileImageSet.h" 35 36@implementation RMCoreAnimationRenderer 37 38- (id) initWithContent: (RMMapContents *)_contents 39{ 40 if (![super initWithContent:_contents]) 41 return nil; 42 43 // NOTE: RMMapContents may still be initialising when this function 44 // is called. Be careful using any of methods - they might return 45 // strange data. 46 47 layer = [[CAScrollLayer layer] retain]; 48 layer.anchorPoint = CGPointZero; 49 layer.masksToBounds = YES; 50 // If the frame is set incorrectly here, it will be fixed when setRenderer is called in RMMapContents 51 layer.frame = [content screenBounds]; 52 53 NSMutableDictionary *customActions = [NSMutableDictionary dictionaryWithDictionary:[layer actions]]; 54 [customActions setObject:[NSNull null] forKey:@"sublayers"]; 55 layer.actions = customActions; 56 57 layer.delegate = self; 58 59 tiles = [[NSMutableArray alloc] init]; 60 61 return self; 62} 63 64-(void) dealloc 65{ 66 for ( RMTileImage *image in tiles ) { 67 [image layer].delegate = nil; 68 } 69 layer.delegate = nil; 70 [tiles release]; 71 [layer release]; 72 [super dealloc]; 73} 74 75/// \bug this is a no-op 76-(void)mapImageLoaded: (NSNotification*)notification 77{ 78} 79 80- (id<CAAction>)actionForLayer:(CALayer *)theLayer 81 forKey:(NSString *)key 82{ 83 if (theLayer == layer) 84 { 85// RMLog(@"base layer key: %@", key); 86 return nil; 87 } 88 89 // || [key isEqualToString:@"onLayout"] 90 if ([key isEqualToString:@"position"] 91 || [key isEqualToString:@"bounds"]) 92 return nil; 93// return (id<CAAction>)[NSNull null]; 94 else 95 { 96// RMLog(@"key: %@", key); 97 98 return nil; 99 } 100} 101 102- (void)tileAdded: (RMTile) tile WithImage: (RMTileImage*) image 103{ 104// RMLog(@"tileAdded: %d %d %d at %f %f %f %f", tile.x, tile.y, tile.zoom, image.screenLocation.origin.x, image.screenLocation.origin.y, 105// image.screenLocation.size.width, image.screenLocation.size.height); 106 107// RMLog(@"tileAdded"); 108 109 NSUInteger min = 0, max = [tiles count]; 110 CALayer *sublayer = [image layer]; 111 112 sublayer.delegate = self; 113 114 while (min < max) { 115 // Binary search for insertion point 116 NSUInteger pivot = (min + max) / 2; 117 RMTileImage *other = [tiles objectAtIndex:pivot]; 118 RMTile otherTile = other.tile; 119 120 if (otherTile.zoom <= tile.zoom) { 121 min = pivot + 1; 122 } 123 if (otherTile.zoom > tile.zoom) { 124 max = pivot; 125 } 126 } 127 128 [tiles insertObject:image atIndex:min]; 129 [layer insertSublayer:sublayer atIndex:min]; 130} 131 132-(void) tileRemoved: (RMTile) tile 133{ 134 RMTileImage *image = nil; 135 136 NSUInteger i = [tiles count]; 137 while (i--) 138 { 139 RMTileImage *potential = [tiles objectAtIndex:i]; 140 141 if (RMTilesEqual(tile, potential.tile)) 142 { 143 [tiles removeObjectAtIndex:i]; 144 image = potential; 145 break; 146 } 147 } 148 149// RMLog(@"tileRemoved: %d %d %d at %f %f %f %f", tile.x, tile.y, tile.zoom, image.screenLocation.origin.x, image.screenLocation.origin.y, 150// image.screenLocation.size.width, image.screenLocation.size.height); 151 152 [[image layer] removeFromSuperlayer]; 153} 154 155- (void)setFrame:(CGRect)frame 156{ 157 layer.frame = [content screenBounds]; 158} 159 160- (CALayer*) layer 161{ 162 return layer; 163} 164 165/* 166- (void)moveBy: (CGSize) delta 167{ 168 [CATransaction begin]; 169 [CATransaction setValue:[NSNumber numberWithFloat:0.0f] 170 forKey:kCATransactionAnimationDuration]; 171 172 [CATransaction setValue:(id)kCFBooleanTrue 173 forKey:kCATransactionDisableActions]; 174 175 [super moveBy:delta]; 176 [tileLoader moveBy:delta]; 177 178 [CATransaction commit]; 179} 180 181- (void)zoomByFactor: (float) zoomFactor Near:(CGPoint) center 182{ 183 [CATransaction begin]; 184 [CATransaction setValue:[NSNumber numberWithFloat:0.0f] 185 forKey:kCATransactionAnimationDuration]; 186 187 [CATransaction setValue:(id)kCFBooleanTrue 188 forKey:kCATransactionDisableActions]; 189 190 [super zoomByFactor:zoomFactor Near:center]; 191 [tileLoader zoomByFactor:zoomFactor Near:center]; 192 193 [CATransaction commit]; 194} 195*/ 196 197@end