PageRenderTime 27ms CodeModel.GetById 2ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/MapView/Map/RMTileLoader.m

http://github.com/route-me/route-me
Objective C | 225 lines | 113 code | 41 blank | 71 comment | 21 complexity | d187ea07c5858bf7fc5dd43fc0ad46e1 MD5 | raw file
  1//
  2//  RMTimeImageSet.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 "RMTileLoader.h"
 29
 30#import "RMTileImage.h"
 31#import "RMTileSource.h"
 32#import "RMPixel.h"
 33#import "RMMercatorToScreenProjection.h"
 34#import "RMFractalTileProjection.h"
 35#import "RMTileImageSet.h"
 36
 37#import "RMTileCache.h"
 38
 39@implementation RMTileLoader
 40
 41@synthesize loadedBounds, loadedZoom;
 42
 43-(id) init
 44{
 45	if (![self initWithContent: nil])
 46		return nil;
 47	
 48	return self;
 49}
 50
 51-(id) initWithContent: (RMMapContents *)_contents
 52{
 53	if (![super init])
 54		return nil;
 55	
 56	content = _contents;
 57	
 58	[self clearLoadedBounds];
 59	loadedTiles.origin.tile = RMTileDummy();
 60	
 61	suppressLoading = NO;
 62	
 63	return self;
 64}
 65
 66-(void) dealloc
 67{
 68	[[NSNotificationCenter defaultCenter] removeObserver:self];
 69	[super dealloc];
 70}
 71
 72-(void) clearLoadedBounds
 73{
 74	loadedBounds = CGRectZero;
 75}
 76
 77-(BOOL) screenIsLoaded
 78{
 79	//	RMTileRect targetRect = [content tileBounds];
 80	BOOL contained = CGRectContainsRect(loadedBounds, [content screenBounds]);
 81	
 82	int targetZoom = (int)([[content mercatorToTileProjection] calculateNormalisedZoomFromScale:[content scaledMetersPerPixel]]);
 83	if((targetZoom > content.maxZoom) || (targetZoom < content.minZoom))
 84          RMLog(@"target zoom %d is outside of RMMapContents limits %f to %f",
 85			  targetZoom, content.minZoom, content.maxZoom);
 86	if (contained == NO)
 87	{
 88		//		RMLog(@"reassembling because its not contained");
 89	}
 90	
 91	if (targetZoom != loadedZoom)
 92	{
 93		//		RMLog(@"reassembling because target zoom = %f, loaded zoom = %d", targetZoom, loadedZoom);
 94	}
 95	
 96	return contained && targetZoom == loadedZoom;
 97}
 98
 99
100-(void) updateLoadedImages
101{
102	if (suppressLoading)
103		return;
104	
105	if ([content mercatorToTileProjection] == nil || [content  
106													  mercatorToScreenProjection] == nil)
107		return;
108	
109	// delay display of new images until expensive operations are  
110	//allowed
111	[[NSNotificationCenter defaultCenter] removeObserver:self  
112													name:RMResumeExpensiveOperations object:nil];
113	if ([RMMapContents performExpensiveOperations] == NO)
114	{
115        [[NSNotificationCenter defaultCenter] addObserver:self  
116												 selector:@selector(updateLoadedImages)  
117													 name:RMResumeExpensiveOperations object:nil];
118        return;
119	}
120	
121	if ([self screenIsLoaded])
122		return;
123	
124	//RMLog(@"updateLoadedImages initial count = %d", [[content imagesOnScreen] count]);
125	
126	RMTileRect newTileRect = [content tileBounds];
127	
128	RMTileImageSet *images = [content imagesOnScreen];
129	images.zoom = newTileRect.origin.tile.zoom;
130	CGRect newLoadedBounds = [images addTiles:newTileRect ToDisplayIn:
131							  [content screenBounds]];
132	//RMLog(@"updateLoadedImages added count = %d", [images count]);
133	
134	
135	if (!RMTileIsDummy(loadedTiles.origin.tile))
136	{
137		[images removeTilesOutsideOf:newTileRect];
138	}
139	
140	//RMLog(@"updateLoadedImages final count = %d", [images count]);
141	
142	loadedBounds = newLoadedBounds;
143	loadedZoom = newTileRect.origin.tile.zoom;
144	loadedTiles = newTileRect;
145	
146	[content tilesUpdatedRegion:newLoadedBounds];
147	
148} 
149
150/*
151 -(void) updateLoadedImages
152 {
153 if (suppressLoading)
154 return;
155 
156 if ([content mercatorToTileProjection] == nil || [content mercatorToScreenProjection] == nil)
157 return;
158 
159 if ([self screenIsLoaded])
160 return;
161 
162 RMLog(@"assemble count = %d", [[content imagesOnScreen] count]);
163 
164 RMTileRect newTileRect = [content tileBounds];
165 
166 RMTileImageSet *images = [content imagesOnScreen];
167 CGRect newLoadedBounds = [images addTiles:newTileRect ToDisplayIn:[content screenBounds]];
168 RMLog(@"-> mid count = %d", [images count]);
169 
170 if (!RMTileIsDummy(loadedTiles.origin.tile))
171 [images removeTiles:loadedTiles];
172 
173 RMLog(@"-> count = %d", [images count]);
174 
175 loadedBounds = newLoadedBounds;
176 loadedZoom = newTileRect.origin.tile.zoom;
177 loadedTiles = newTileRect;
178 
179 [content tilesUpdatedRegion:newLoadedBounds];
180 }*/
181
182- (void)moveBy: (CGSize) delta
183{
184	//	RMLog(@"loadedBounds %f %f %f %f -> ", loadedBounds.origin.x, loadedBounds.origin.y, loadedBounds.size.width, loadedBounds.size.height);
185	loadedBounds = RMTranslateCGRectBy(loadedBounds, delta);
186	//	RMLog(@" -> %f %f %f %f", loadedBounds.origin.x, loadedBounds.origin.y, loadedBounds.size.width, loadedBounds.size.height);
187	[self updateLoadedImages];
188}
189
190- (void)zoomByFactor: (float) zoomFactor near:(CGPoint) center
191{
192	loadedBounds = RMScaleCGRectAboutPoint(loadedBounds, zoomFactor, center);
193	[self updateLoadedImages];
194}
195
196- (BOOL) suppressLoading
197{
198	return suppressLoading;
199}
200
201- (void) setSuppressLoading: (BOOL) suppress
202{
203	suppressLoading = suppress;
204	
205	if (suppress == NO)
206		[self updateLoadedImages];
207}
208
209- (void)reset
210{
211	loadedTiles.origin.tile = RMTileDummy();
212}
213
214- (void)reload
215{
216	[self clearLoadedBounds];
217	[self updateLoadedImages];
218}
219
220//-(BOOL) containsRect: (CGRect)bounds
221//{
222//	return CGRectContainsRect(loadedBounds, bounds);
223//}
224
225@end