Authored by Hal Mueller

fixed unit tests for marker coordinate projection

@@ -39,12 +39,8 @@ extern NSString * const RMMarkerRedKey; @@ -39,12 +39,8 @@ extern NSString * const RMMarkerRedKey;
39 39
40 /// one marker drawn on the map. Note that RMMarker ultimately descends from CALayer, and has an image contents. 40 /// one marker drawn on the map. Note that RMMarker ultimately descends from CALayer, and has an image contents.
41 @interface RMMarker : RMMapLayer <RMMovingMapLayer> { 41 @interface RMMarker : RMMapLayer <RMMovingMapLayer> {
42 - /// expressed in projected meters. The anchorPoint of the image is plotted here. 42 + /// expressed in projected meters. The anchorPoint of the image is plotted here. \deprecated "location" (meters) is confusingly vague, doesn't convey units.
43 RMXYPoint location; 43 RMXYPoint location;
44 -#ifdef DEBUG  
45 - // to see if projection really works correctly  
46 - CLLocationCoordinate2D latlon;  
47 -#endif  
48 /// provided for storage of arbitrary user data 44 /// provided for storage of arbitrary user data
49 NSObject* data; 45 NSObject* data;
50 46
@@ -54,9 +50,6 @@ extern NSString * const RMMarkerRedKey; @@ -54,9 +50,6 @@ extern NSString * const RMMarkerRedKey;
54 UIColor *textBackgroundColor; 50 UIColor *textBackgroundColor;
55 } 51 }
56 @property (assign, nonatomic) RMXYPoint location; 52 @property (assign, nonatomic) RMXYPoint location;
57 -#ifdef DEBUG  
58 -@property (assign, nonatomic) CLLocationCoordinate2D latlon;  
59 -#endif  
60 53
61 @property (nonatomic, retain) NSObject* data; 54 @property (nonatomic, retain) NSObject* data;
62 @property (nonatomic, retain) UIView* labelView; 55 @property (nonatomic, retain) UIView* labelView;
@@ -40,9 +40,6 @@ static CGImageRef _markerBlue = nil; @@ -40,9 +40,6 @@ static CGImageRef _markerBlue = nil;
40 @implementation RMMarker 40 @implementation RMMarker
41 41
42 @synthesize location; 42 @synthesize location;
43 -#ifdef DEBUG  
44 -@synthesize latlon;  
45 -#endif  
46 @synthesize data; 43 @synthesize data;
47 @synthesize labelView; 44 @synthesize labelView;
48 @synthesize textForegroundColor; 45 @synthesize textForegroundColor;
@@ -44,6 +44,9 @@ @@ -44,6 +44,9 @@
44 2B246AA20F8AD9D400A7D55D /* RouteMeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B246AA10F8AD9D400A7D55D /* RouteMeTests.m */; }; 44 2B246AA20F8AD9D400A7D55D /* RouteMeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B246AA10F8AD9D400A7D55D /* RouteMeTests.m */; };
45 2B5682720F68E36000E8DF40 /* RMOpenAerialMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */; }; 45 2B5682720F68E36000E8DF40 /* RMOpenAerialMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */; };
46 2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */; }; 46 2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */; };
  47 + 2B580E2C0F8D201200D495B2 /* marker-red.png in Resources */ = {isa = PBXBuildFile; fileRef = B8474C6F0EB53A41006A0BC1 /* marker-red.png */; };
  48 + 2B580E820F8D26F200D495B2 /* RMTestableMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B580E810F8D26F200D495B2 /* RMTestableMarker.m */; };
  49 + 2B580F160F8D2E9C00D495B2 /* RMTestableMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B580E810F8D26F200D495B2 /* RMTestableMarker.m */; };
47 2B5BDCDB0F8C17A500848078 /* GTMCALayer+UnitTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCCC0F8C17A500848078 /* GTMCALayer+UnitTesting.m */; }; 50 2B5BDCDB0F8C17A500848078 /* GTMCALayer+UnitTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCCC0F8C17A500848078 /* GTMCALayer+UnitTesting.m */; };
48 2B5BDCDC0F8C17A500848078 /* GTMIPhoneUnitTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCD00F8C17A500848078 /* GTMIPhoneUnitTestDelegate.m */; }; 51 2B5BDCDC0F8C17A500848078 /* GTMIPhoneUnitTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCD00F8C17A500848078 /* GTMIPhoneUnitTestDelegate.m */; };
49 2B5BDCDD0F8C17A500848078 /* GTMIPhoneUnitTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCD10F8C17A500848078 /* GTMIPhoneUnitTestMain.m */; }; 52 2B5BDCDD0F8C17A500848078 /* GTMIPhoneUnitTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCD10F8C17A500848078 /* GTMIPhoneUnitTestMain.m */; };
@@ -229,6 +232,8 @@ @@ -229,6 +232,8 @@
229 2B2BD41E0F79A95500B8B9A7 /* routeme.doxygen */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = routeme.doxygen; sourceTree = "<group>"; }; 232 2B2BD41E0F79A95500B8B9A7 /* routeme.doxygen */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = routeme.doxygen; sourceTree = "<group>"; };
230 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMOpenAerialMapSource.h; sourceTree = "<group>"; }; 233 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMOpenAerialMapSource.h; sourceTree = "<group>"; };
231 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMOpenAerialMapSource.m; sourceTree = "<group>"; }; 234 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMOpenAerialMapSource.m; sourceTree = "<group>"; };
  235 + 2B580E800F8D26F200D495B2 /* RMTestableMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMTestableMarker.h; sourceTree = "<group>"; };
  236 + 2B580E810F8D26F200D495B2 /* RMTestableMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMTestableMarker.m; sourceTree = "<group>"; };
232 2B5BDCCB0F8C17A500848078 /* GTMCALayer+UnitTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "GTMCALayer+UnitTesting.h"; path = "GTM/GTMCALayer+UnitTesting.h"; sourceTree = "<group>"; }; 237 2B5BDCCB0F8C17A500848078 /* GTMCALayer+UnitTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "GTMCALayer+UnitTesting.h"; path = "GTM/GTMCALayer+UnitTesting.h"; sourceTree = "<group>"; };
233 2B5BDCCC0F8C17A500848078 /* GTMCALayer+UnitTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "GTMCALayer+UnitTesting.m"; path = "GTM/GTMCALayer+UnitTesting.m"; sourceTree = "<group>"; }; 238 2B5BDCCC0F8C17A500848078 /* GTMCALayer+UnitTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "GTMCALayer+UnitTesting.m"; path = "GTM/GTMCALayer+UnitTesting.m"; sourceTree = "<group>"; };
234 2B5BDCCD0F8C17A500848078 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMDefines.h; path = GTM/GTMDefines.h; sourceTree = "<group>"; }; 239 2B5BDCCD0F8C17A500848078 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMDefines.h; path = GTM/GTMDefines.h; sourceTree = "<group>"; };
@@ -427,6 +432,8 @@ @@ -427,6 +432,8 @@
427 isa = PBXGroup; 432 isa = PBXGroup;
428 children = ( 433 children = (
429 2BF306BF0F8ABC35007014EE /* Google Toolbox for Mac (unit testing) */, 434 2BF306BF0F8ABC35007014EE /* Google Toolbox for Mac (unit testing) */,
  435 + 2B580E800F8D26F200D495B2 /* RMTestableMarker.h */,
  436 + 2B580E810F8D26F200D495B2 /* RMTestableMarker.m */,
430 2B246AA00F8AD9D400A7D55D /* RouteMeTests.h */, 437 2B246AA00F8AD9D400A7D55D /* RouteMeTests.h */,
431 2B246AA10F8AD9D400A7D55D /* RouteMeTests.m */, 438 2B246AA10F8AD9D400A7D55D /* RouteMeTests.m */,
432 ); 439 );
@@ -833,6 +840,7 @@ @@ -833,6 +840,7 @@
833 isa = PBXResourcesBuildPhase; 840 isa = PBXResourcesBuildPhase;
834 buildActionMask = 2147483647; 841 buildActionMask = 2147483647;
835 files = ( 842 files = (
  843 + 2B580E2C0F8D201200D495B2 /* marker-red.png in Resources */,
836 ); 844 );
837 runOnlyForDeploymentPostprocessing = 0; 845 runOnlyForDeploymentPostprocessing = 0;
838 }; 846 };
@@ -933,6 +941,7 @@ @@ -933,6 +941,7 @@
933 2B5BDCDF0F8C17A500848078 /* GTMSenTestCase.m in Sources */, 941 2B5BDCDF0F8C17A500848078 /* GTMSenTestCase.m in Sources */,
934 2B5BDCE00F8C17A500848078 /* GTMSystemVersion.m in Sources */, 942 2B5BDCE00F8C17A500848078 /* GTMSystemVersion.m in Sources */,
935 2B5BDCE10F8C17A500848078 /* GTMUIKit+UnitTesting.m in Sources */, 943 2B5BDCE10F8C17A500848078 /* GTMUIKit+UnitTesting.m in Sources */,
  944 + 2B580E820F8D26F200D495B2 /* RMTestableMarker.m in Sources */,
936 ); 945 );
937 runOnlyForDeploymentPostprocessing = 0; 946 runOnlyForDeploymentPostprocessing = 0;
938 }; 947 };
@@ -980,6 +989,7 @@ @@ -980,6 +989,7 @@
980 2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */, 989 2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */,
981 96FE8E370F72D01B00A11CF0 /* RMYahooMapSource.m in Sources */, 990 96FE8E370F72D01B00A11CF0 /* RMYahooMapSource.m in Sources */,
982 F5C12D2B0F8A86CA00A894D2 /* RMGeoHash.m in Sources */, 991 F5C12D2B0F8A86CA00A894D2 /* RMGeoHash.m in Sources */,
  992 + 2B580F160F8D2E9C00D495B2 /* RMTestableMarker.m in Sources */,
983 ); 993 );
984 runOnlyForDeploymentPostprocessing = 0; 994 runOnlyForDeploymentPostprocessing = 0;
985 }; 995 };
@@ -1062,6 +1072,7 @@ @@ -1062,6 +1072,7 @@
1062 GCC_ENABLE_SYMBOL_SEPARATION = YES; 1072 GCC_ENABLE_SYMBOL_SEPARATION = YES;
1063 GCC_PRECOMPILE_PREFIX_HEADER = YES; 1073 GCC_PRECOMPILE_PREFIX_HEADER = YES;
1064 GCC_PREFIX_HEADER = MapView_Prefix.pch; 1074 GCC_PREFIX_HEADER = MapView_Prefix.pch;
  1075 + GCC_PREPROCESSOR_DEFINITIONS = "NS_BLOCK_ASSERTIONS=1";
1065 HEADER_SEARCH_PATHS = ../Proj4; 1076 HEADER_SEARCH_PATHS = ../Proj4;
1066 INFOPLIST_FILE = "RM Unit Tests-Info.plist"; 1077 INFOPLIST_FILE = "RM Unit Tests-Info.plist";
1067 INSTALL_PATH = "$(HOME)/Applications"; 1078 INSTALL_PATH = "$(HOME)/Applications";
  1 +//
  2 +// RMTestableMarker.h
  3 +// MapView
  4 +//
  5 +// Created by Hal Mueller on 4/8/09.
  6 +// Copyright 2009 Route-Me Contributors. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import <UIKit/UIKit.h>
  11 +#import <CoreLocation/CoreLocation.h>
  12 +
  13 +@class RMMarker;
  14 +
  15 +/// Subclass of RMMarker with lat/lon coordinates added, to verify correct projection calculations
  16 +@interface RMTestableMarker : RMMarker {
  17 + /// original location in lat/lon, to see if projection really works correctly
  18 + CLLocationCoordinate2D coordinate;
  19 +}
  20 +
  21 +@property (assign, nonatomic) CLLocationCoordinate2D coordinate;
  22 +
  23 +@end
  1 +//
  2 +// RMTestableMarker.m
  3 +// MapView
  4 +//
  5 +// Created by Hal Mueller on 4/8/09.
  6 +// Copyright 2009 Route-Me Contributors. All rights reserved.
  7 +//
  8 +
  9 +#import "RMMarker.h"
  10 +#import "RMTestableMarker.h"
  11 +#import "RMMarker.h"
  12 +
  13 +@implementation RMTestableMarker
  14 +@synthesize coordinate;
  15 +
  16 +@end
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 #import "RMCloudMadeMapSource.h" 11 #import "RMCloudMadeMapSource.h"
12 #import "RMGeoHash.h" 12 #import "RMGeoHash.h"
13 #import "RMMarker.h" 13 #import "RMMarker.h"
  14 +#import "RMTestableMarker.h"
14 #import "RMMarkerManager.h" 15 #import "RMMarkerManager.h"
15 16
16 @implementation RouteMeTests 17 @implementation RouteMeTests
@@ -22,13 +23,11 @@ @@ -22,13 +23,11 @@
22 contentView = [[UIView alloc] initWithFrame:appRect]; 23 contentView = [[UIView alloc] initWithFrame:appRect];
23 contentView.backgroundColor = [UIColor greenColor]; 24 contentView.backgroundColor = [UIColor greenColor];
24 25
25 - NSLog(@"%@", [UIScreen mainScreen]);  
26 initialCenter.latitude = 66.44; 26 initialCenter.latitude = 66.44;
27 initialCenter.longitude = -178.0; 27 initialCenter.longitude = -178.0;
28 28
29 mapView = [[RMMapView alloc] initWithFrame:CGRectMake(10,20,200,300) 29 mapView = [[RMMapView alloc] initWithFrame:CGRectMake(10,20,200,300)
30 WithLocation:initialCenter]; 30 WithLocation:initialCenter];
31 - NSLog(@"contentView %@ mapView %@", contentView, mapView);  
32 [contentView addSubview:mapView]; 31 [contentView addSubview:mapView];
33 } 32 }
34 33
@@ -75,12 +74,13 @@ @@ -75,12 +74,13 @@
75 { 74 {
76 STAssertNotNil(mapView, @"mapview creation failed"); 75 STAssertNotNil(mapView, @"mapview creation failed");
77 STAssertNotNil([mapView contents], @"mapView contents should not be nil"); 76 STAssertNotNil([mapView contents], @"mapView contents should not be nil");
78 - NSLog(@"%@", [mapView contents]);  
79 -  
80 } 77 }
81 78
82 - (void)testMarkerCreation 79 - (void)testMarkerCreation
83 { 80 {
  81 + // create markers from -183 to -169 longitude
  82 + initialCenter.longitude = -178.0;
  83 +
84 CLLocationCoordinate2D markerPosition; 84 CLLocationCoordinate2D markerPosition;
85 NSUInteger nRows = 1; 85 NSUInteger nRows = 1;
86 NSUInteger nColumns = 8; 86 NSUInteger nColumns = 8;
@@ -94,37 +94,38 @@ @@ -94,37 +94,38 @@
94 markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing); 94 markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing);
95 for (j = 0; j < nColumns; j++) { 95 for (j = 0; j < nColumns; j++) {
96 markerPosition.longitude += columnSpacing; 96 markerPosition.longitude += columnSpacing;
97 - NSLog(@"%f %f", markerPosition.latitude, markerPosition.longitude);  
98 - RMMarker *newMarker = [[RMMarker alloc] initWithUIImage:markerImage]; 97 + RMTestableMarker *newMarker = [[RMTestableMarker alloc] initWithUIImage:markerImage];
99 STAssertNotNil(newMarker, @"testMarkerCreation marker creation failed"); 98 STAssertNotNil(newMarker, @"testMarkerCreation marker creation failed");
100 -#ifdef DEBUG  
101 - [newMarker setLatlon:markerPosition];  
102 -#endif 99 + [newMarker setCoordinate:markerPosition];
103 [mapView.contents.markerManager addMarker:newMarker 100 [mapView.contents.markerManager addMarker:newMarker
104 AtLatLong:markerPosition]; 101 AtLatLong:markerPosition];
105 } 102 }
106 markerPosition.latitude += columnSpacing; 103 markerPosition.latitude += columnSpacing;
107 } 104 }
108 105
  106 +
109 #ifdef DEBUG 107 #ifdef DEBUG
110 RMMarkerManager *mangler = [[mapView contents] markerManager]; 108 RMMarkerManager *mangler = [[mapView contents] markerManager];
111 -  
112 - for (RMMarker *theMarker in [mangler getMarkers]) { 109 + for (RMTestableMarker *theMarker in [mangler getMarkers]) {
113 CGPoint screenPosition = [mangler getMarkerScreenCoordinate:theMarker]; 110 CGPoint screenPosition = [mangler getMarkerScreenCoordinate:theMarker];
114 - NSLog(@"%@ %3.1f %3.1f %f %f", theMarker,  
115 - theMarker.latlon.latitude, theMarker.latlon.longitude, 111 + RMLog(@"%@ %3.1f %3.1f %f %f", theMarker,
  112 + theMarker.coordinate.latitude, theMarker.coordinate.longitude,
116 screenPosition.y, screenPosition.x); 113 screenPosition.y, screenPosition.x);
117 } 114 }
118 #endif 115 #endif
119 } 116 }
120 117
121 -- (void)testMarkerCoordinates 118 +- (void)testMarkerCoordinatesFarEast
122 { 119 {
  120 + [mapView.contents setZoom:3.0];
  121 +
  122 + // create markers from +177 to +191 longitude
  123 + initialCenter.longitude = +176.0;
123 CLLocationCoordinate2D markerPosition; 124 CLLocationCoordinate2D markerPosition;
124 125
125 NSUInteger nColumns = 8; 126 NSUInteger nColumns = 8;
126 double columnSpacing = 2.0; 127 double columnSpacing = 2.0;
127 - 128 +
128 UIImage *markerImage = [UIImage imageNamed:@"marker-red.png"]; 129 UIImage *markerImage = [UIImage imageNamed:@"marker-red.png"];
129 markerPosition.latitude = initialCenter.latitude; 130 markerPosition.latitude = initialCenter.latitude;
130 markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing); 131 markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing);
@@ -132,32 +133,86 @@ @@ -132,32 +133,86 @@
132 NSMutableArray *testMarkers = [NSMutableArray arrayWithCapacity:nColumns]; 133 NSMutableArray *testMarkers = [NSMutableArray arrayWithCapacity:nColumns];
133 for (j = 0; j < nColumns; j++) { 134 for (j = 0; j < nColumns; j++) {
134 markerPosition.longitude += columnSpacing; 135 markerPosition.longitude += columnSpacing;
135 - NSLog(@"%f %f", markerPosition.latitude, markerPosition.longitude);  
136 - RMMarker *newMarker = [[RMMarker alloc] initWithUIImage:markerImage]; 136 + RMTestableMarker *newMarker = [[RMTestableMarker alloc] initWithUIImage:markerImage];
137 [testMarkers addObject:newMarker]; 137 [testMarkers addObject:newMarker];
  138 + [newMarker setCoordinate:markerPosition];
  139 + [mapView.contents.markerManager addMarker:newMarker
  140 + AtLatLong:markerPosition];
  141 + }
  142 + STAssertGreaterThan(columnSpacing, 0.0, @"this test requires positive columnSpacing");
  143 +
  144 + RMMarkerManager *mangler = [[mapView contents] markerManager];
  145 +
  146 + [[mapView contents] moveBy:CGSizeMake(-5.0, 0.0)];
138 #ifdef DEBUG 147 #ifdef DEBUG
139 - [newMarker setLatlon:markerPosition]; 148 + RMLatLongBounds screenLimitsDegrees = [[mapView contents] getScreenCoordinateBounds];
  149 + RMLog(@"screen limits west: %4.1f east %4.1f", screenLimitsDegrees.northWest.longitude, screenLimitsDegrees.southEast.longitude);
  150 + RMLog(@"screen limits south: %4.1f north %4.1f", screenLimitsDegrees.southEast.latitude, screenLimitsDegrees.northWest.latitude);
140 #endif 151 #endif
  152 +
  153 + for (j = 1; j < nColumns; j++) {
  154 + RMTestableMarker *leftMarker = [testMarkers objectAtIndex:j - 1];
  155 + RMTestableMarker *rightMarker = [testMarkers objectAtIndex:j];
  156 + CGPoint leftScreenPosition = [mangler getMarkerScreenCoordinate:leftMarker];
  157 + CGPoint rightScreenPosition = [mangler getMarkerScreenCoordinate:rightMarker];
  158 + STAssertLessThan(leftScreenPosition.x, rightScreenPosition.x,
  159 + @"screen position calculation failed (markers %d, %d): left (%f, %f) right (%f, %f) mapped to left (%f, %f) right (%f, %f)",
  160 + j-1, j,
  161 +// write these out as longitude/latitude instead of standard latitude/longitude to make comparisons easier
  162 + leftMarker.coordinate.longitude, leftMarker.coordinate.latitude,
  163 + rightMarker.coordinate.longitude, rightMarker.coordinate.latitude,
  164 + leftScreenPosition.x, leftScreenPosition.y, rightScreenPosition.x, rightScreenPosition.y);
  165 + }
  166 +
  167 +}
  168 +
  169 +- (void)testMarkerCoordinatesFarWest
  170 +{
  171 + [mapView.contents setZoom:3.0];
  172 +
  173 + // create markers from -177 to -169 longitude
  174 + initialCenter.longitude = -178.0;
  175 + CLLocationCoordinate2D markerPosition;
  176 +
  177 + NSUInteger nColumns = 8;
  178 + double columnSpacing = 2.0;
  179 +
  180 + UIImage *markerImage = [UIImage imageNamed:@"marker-red.png"];
  181 + markerPosition.latitude = initialCenter.latitude;
  182 + markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing);
  183 + int j;
  184 + NSMutableArray *testMarkers = [NSMutableArray arrayWithCapacity:nColumns];
  185 + for (j = 0; j < nColumns; j++) {
  186 + markerPosition.longitude += columnSpacing;
  187 + RMTestableMarker *newMarker = [[RMTestableMarker alloc] initWithUIImage:markerImage];
  188 + [testMarkers addObject:newMarker];
  189 + [newMarker setCoordinate:markerPosition];
141 [mapView.contents.markerManager addMarker:newMarker 190 [mapView.contents.markerManager addMarker:newMarker
142 AtLatLong:markerPosition]; 191 AtLatLong:markerPosition];
143 } 192 }
144 STAssertGreaterThan(columnSpacing, 0.0, @"this test requires positive columnSpacing"); 193 STAssertGreaterThan(columnSpacing, 0.0, @"this test requires positive columnSpacing");
145 -#ifdef DEBUG 194 +
146 RMMarkerManager *mangler = [[mapView contents] markerManager]; 195 RMMarkerManager *mangler = [[mapView contents] markerManager];
147 196
148 [[mapView contents] moveBy:CGSizeMake(-5.0, 0.0)]; 197 [[mapView contents] moveBy:CGSizeMake(-5.0, 0.0)];
  198 +#ifdef DEBUG
  199 + RMLatLongBounds screenLimitsDegrees = [[mapView contents] getScreenCoordinateBounds];
  200 + RMLog(@"screen limits west: %4.1f east %4.1f", screenLimitsDegrees.northWest.longitude, screenLimitsDegrees.southEast.longitude);
  201 + RMLog(@"screen limits south: %4.1f north %4.1f", screenLimitsDegrees.southEast.latitude, screenLimitsDegrees.northWest.latitude);
  202 +#endif
  203 +
149 for (j = 1; j < nColumns; j++) { 204 for (j = 1; j < nColumns; j++) {
150 - RMMarker *leftMarker = [testMarkers objectAtIndex:j - 1];  
151 - RMMarker *rightMarker = [testMarkers objectAtIndex:j]; 205 + RMTestableMarker *leftMarker = [testMarkers objectAtIndex:j - 1];
  206 + RMTestableMarker *rightMarker = [testMarkers objectAtIndex:j];
152 CGPoint leftScreenPosition = [mangler getMarkerScreenCoordinate:leftMarker]; 207 CGPoint leftScreenPosition = [mangler getMarkerScreenCoordinate:leftMarker];
153 CGPoint rightScreenPosition = [mangler getMarkerScreenCoordinate:rightMarker]; 208 CGPoint rightScreenPosition = [mangler getMarkerScreenCoordinate:rightMarker];
154 STAssertLessThan(leftScreenPosition.x, rightScreenPosition.x, 209 STAssertLessThan(leftScreenPosition.x, rightScreenPosition.x,
155 - @"screen position calculation failed: left (%f, %f) right (%f, %f) mapped to left (%f, %f) right (%f, %f)",  
156 - leftMarker.latlon.longitude, leftMarker.latlon.latitude,  
157 - rightMarker.latlon.longitude, rightMarker.latlon.latitude, 210 + @"screen position calculation failed (markers %d, %d): left (%f, %f) right (%f, %f) mapped to left (%f, %f) right (%f, %f)",
  211 + j-1, j,
  212 + leftMarker.coordinate.longitude, leftMarker.coordinate.latitude,
  213 + rightMarker.coordinate.longitude, rightMarker.coordinate.latitude,
158 leftScreenPosition.x, leftScreenPosition.y, rightScreenPosition.x, rightScreenPosition.y); 214 leftScreenPosition.x, leftScreenPosition.y, rightScreenPosition.x, rightScreenPosition.y);
159 } 215 }
160 -#endif  
161 216
162 } 217 }
163 @end 218 @end