PageRenderTime 45ms CodeModel.GetById 15ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 0ms

/MapView/Map/RMMarkerManager.m

http://github.com/route-me/route-me
Objective C | 205 lines | 130 code | 34 blank | 41 comment | 19 complexity | eb7c2aeebd887e8a1b67cfeac0a08829 MD5 | raw file
  1//
  2//  RMMarkerManager.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
 28#import "RMMarkerManager.h"
 29#import "RMMercatorToScreenProjection.h"
 30#import "RMProjection.h"
 31#import "RMLayerCollection.h"
 32
 33@implementation RMMarkerManager
 34
 35@synthesize contents;
 36
 37- (id)initWithContents:(RMMapContents *)mapContents
 38{
 39	if (![super init])
 40		return nil;
 41	
 42	contents = mapContents;
 43	
 44	rotationTransform = CGAffineTransformIdentity; 
 45	
 46	return self;
 47}
 48
 49- (void)dealloc
 50{
 51	contents = nil;
 52	[super dealloc];
 53}
 54
 55///////////////////////////////////////////////////////////////////////////////////////////////////
 56#pragma mark 
 57#pragma mark Adding / Removing / Displaying Markers
 58
 59/// place the (new created) marker onto the map at projected point and take ownership of it
 60- (void)addMarker:(RMMarker *)marker atProjectedPoint:(RMProjectedPoint)projectedPoint {
 61
 62	// only set the AffineTransform if the marker has rotation enabled
 63	if (marker.enableRotation) {
 64	[marker setAffineTransform:rotationTransform];
 65	} else {
 66		[marker setAffineTransform:CGAffineTransformMakeRotation(0.0f)];
 67	}
 68	[marker setProjectedLocation:projectedPoint];
 69	[marker setPosition:[[contents mercatorToScreenProjection] projectXYPoint:projectedPoint]];
 70	[[contents overlay] addSublayer:marker];
 71}
 72
 73/// place the (newly created) marker onto the map and take ownership of it
 74/// \bug should return the marker
 75- (void) addMarker: (RMMarker*)marker AtLatLong:(CLLocationCoordinate2D)point
 76{
 77	[self addMarker:marker atProjectedPoint:[[contents projection] latLongToPoint:point]];
 78}
 79
 80/// \bug see http://code.google.com/p/route-me/issues/detail?id=75
 81/// (halmueller): I am skeptical about interactions of this code with paths
 82- (void) removeMarkers
 83{
 84	[[contents overlay] setSublayers:[NSArray arrayWithObjects:nil]]; 
 85}
 86
 87/// \bug this will hide path overlays too?
 88/// \deprecated syntactic sugar. Might have a place on RMMapView, but not on RMMarkerManager.
 89- (void) hideAllMarkers 
 90{
 91	[[contents overlay] setHidden:YES];
 92}
 93
 94/// \bug this will hide path overlays too?
 95/// \deprecated syntactic sugar. Might have a place on RMMapView, but not on RMMarkerManager.
 96- (void) unhideAllMarkers
 97{
 98	[[contents overlay] setHidden:NO];
 99}
100
101///////////////////////////////////////////////////////////////////////////////////////////////////
102#pragma mark 
103#pragma mark Marker information
104
105- (NSArray *)markers
106{
107	return [[contents overlay] sublayers];
108}
109
110- (void) removeMarker:(RMMarker *)marker
111{
112	[[contents overlay] removeSublayer:marker];
113}
114
115- (void) removeMarkers:(NSArray *)markers
116{
117	[[contents overlay] removeSublayers:markers];
118}
119
120- (CGPoint) screenCoordinatesForMarker: (RMMarker *)marker
121{
122	return [[contents mercatorToScreenProjection] projectXYPoint:[marker projectedLocation]];
123}
124
125- (CLLocationCoordinate2D) latitudeLongitudeForMarker: (RMMarker *) marker
126{
127	return [contents pixelToLatLong:[self screenCoordinatesForMarker:marker]];
128}
129
130- (NSArray *) markersWithinScreenBounds
131{
132	NSMutableArray *markersInScreenBounds = [NSMutableArray array];
133	CGRect rect = [[contents mercatorToScreenProjection] screenBounds];
134	
135	for (RMMarker *marker in [self markers]) {
136		if ([self isMarker:marker withinBounds:rect]) {
137			[markersInScreenBounds addObject:marker];
138		}
139	}
140	
141	return markersInScreenBounds;
142}
143
144- (BOOL) isMarkerWithinScreenBounds:(RMMarker*)marker
145{
146	return [self isMarker:marker withinBounds:[[contents mercatorToScreenProjection] screenBounds]];
147}
148
149/// \deprecated violates Objective-C naming rules
150- (BOOL) isMarker:(RMMarker*)marker withinBounds:(CGRect)rect
151{
152	if (![self managingMarker:marker]) {
153		return NO;
154	}
155	
156	CGPoint markerCoord = [self screenCoordinatesForMarker:marker];
157	
158	if (   markerCoord.x > rect.origin.x
159		&& markerCoord.x < rect.origin.x + rect.size.width
160		&& markerCoord.y > rect.origin.y
161		&& markerCoord.y < rect.origin.y + rect.size.height)
162	{
163		return YES;
164	}
165	return NO;
166}
167
168/// \deprecated violates Objective-C naming rules
169- (BOOL) managingMarker:(RMMarker*)marker
170{
171    NSArray *markers = [self markers];
172	if (marker != nil && markers != nil && [markers indexOfObject:marker] != NSNotFound) {
173		return YES;
174	}
175	return NO;
176}
177
178- (void) moveMarker:(RMMarker *)marker AtLatLon:(RMLatLong)point
179{
180	[marker setProjectedLocation:[[contents projection]latLongToPoint:point]];
181	[marker setPosition:[[contents mercatorToScreenProjection] projectXYPoint:[[contents projection] latLongToPoint:point]]];
182}
183
184- (void) moveMarker:(RMMarker *)marker AtXY:(CGPoint)point
185{
186	[marker setProjectedLocation:[[contents mercatorToScreenProjection] projectScreenPointToXY:point]];
187	[marker setPosition:point];
188}
189
190- (void)setRotation:(float)angle
191{
192  rotationTransform = CGAffineTransformMakeRotation(angle); // store rotation transform for subsequent markers
193
194  for (RMMarker *marker in [self markers]) 
195  {
196	  // only apply rotation if the marker has it enabled
197	  if (marker.enableRotation) {
198	  [marker setAffineTransform:rotationTransform];
199	  } else {
200		  [marker setAffineTransform:CGAffineTransformMakeRotation(0.0f)];
201	  }
202  }
203}
204
205@end