Authored by Hal Mueller

fixed unit tests for marker coordinate projection

... ... @@ -39,12 +39,8 @@ extern NSString * const RMMarkerRedKey;
/// one marker drawn on the map. Note that RMMarker ultimately descends from CALayer, and has an image contents.
@interface RMMarker : RMMapLayer <RMMovingMapLayer> {
/// expressed in projected meters. The anchorPoint of the image is plotted here.
/// expressed in projected meters. The anchorPoint of the image is plotted here. \deprecated "location" (meters) is confusingly vague, doesn't convey units.
RMXYPoint location;
#ifdef DEBUG
// to see if projection really works correctly
CLLocationCoordinate2D latlon;
#endif
/// provided for storage of arbitrary user data
NSObject* data;
... ... @@ -54,9 +50,6 @@ extern NSString * const RMMarkerRedKey;
UIColor *textBackgroundColor;
}
@property (assign, nonatomic) RMXYPoint location;
#ifdef DEBUG
@property (assign, nonatomic) CLLocationCoordinate2D latlon;
#endif
@property (nonatomic, retain) NSObject* data;
@property (nonatomic, retain) UIView* labelView;
... ...
... ... @@ -40,9 +40,6 @@ static CGImageRef _markerBlue = nil;
@implementation RMMarker
@synthesize location;
#ifdef DEBUG
@synthesize latlon;
#endif
@synthesize data;
@synthesize labelView;
@synthesize textForegroundColor;
... ...
... ... @@ -44,6 +44,9 @@
2B246AA20F8AD9D400A7D55D /* RouteMeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B246AA10F8AD9D400A7D55D /* RouteMeTests.m */; };
2B5682720F68E36000E8DF40 /* RMOpenAerialMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */; };
2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */; };
2B580E2C0F8D201200D495B2 /* marker-red.png in Resources */ = {isa = PBXBuildFile; fileRef = B8474C6F0EB53A41006A0BC1 /* marker-red.png */; };
2B580E820F8D26F200D495B2 /* RMTestableMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B580E810F8D26F200D495B2 /* RMTestableMarker.m */; };
2B580F160F8D2E9C00D495B2 /* RMTestableMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B580E810F8D26F200D495B2 /* RMTestableMarker.m */; };
2B5BDCDB0F8C17A500848078 /* GTMCALayer+UnitTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCCC0F8C17A500848078 /* GTMCALayer+UnitTesting.m */; };
2B5BDCDC0F8C17A500848078 /* GTMIPhoneUnitTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCD00F8C17A500848078 /* GTMIPhoneUnitTestDelegate.m */; };
2B5BDCDD0F8C17A500848078 /* GTMIPhoneUnitTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5BDCD10F8C17A500848078 /* GTMIPhoneUnitTestMain.m */; };
... ... @@ -229,6 +232,8 @@
2B2BD41E0F79A95500B8B9A7 /* routeme.doxygen */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = routeme.doxygen; sourceTree = "<group>"; };
2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMOpenAerialMapSource.h; sourceTree = "<group>"; };
2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMOpenAerialMapSource.m; sourceTree = "<group>"; };
2B580E800F8D26F200D495B2 /* RMTestableMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMTestableMarker.h; sourceTree = "<group>"; };
2B580E810F8D26F200D495B2 /* RMTestableMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMTestableMarker.m; sourceTree = "<group>"; };
2B5BDCCB0F8C17A500848078 /* GTMCALayer+UnitTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "GTMCALayer+UnitTesting.h"; path = "GTM/GTMCALayer+UnitTesting.h"; sourceTree = "<group>"; };
2B5BDCCC0F8C17A500848078 /* GTMCALayer+UnitTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "GTMCALayer+UnitTesting.m"; path = "GTM/GTMCALayer+UnitTesting.m"; sourceTree = "<group>"; };
2B5BDCCD0F8C17A500848078 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMDefines.h; path = GTM/GTMDefines.h; sourceTree = "<group>"; };
... ... @@ -427,6 +432,8 @@
isa = PBXGroup;
children = (
2BF306BF0F8ABC35007014EE /* Google Toolbox for Mac (unit testing) */,
2B580E800F8D26F200D495B2 /* RMTestableMarker.h */,
2B580E810F8D26F200D495B2 /* RMTestableMarker.m */,
2B246AA00F8AD9D400A7D55D /* RouteMeTests.h */,
2B246AA10F8AD9D400A7D55D /* RouteMeTests.m */,
);
... ... @@ -833,6 +840,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2B580E2C0F8D201200D495B2 /* marker-red.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
... ... @@ -933,6 +941,7 @@
2B5BDCDF0F8C17A500848078 /* GTMSenTestCase.m in Sources */,
2B5BDCE00F8C17A500848078 /* GTMSystemVersion.m in Sources */,
2B5BDCE10F8C17A500848078 /* GTMUIKit+UnitTesting.m in Sources */,
2B580E820F8D26F200D495B2 /* RMTestableMarker.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
... ... @@ -980,6 +989,7 @@
2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */,
96FE8E370F72D01B00A11CF0 /* RMYahooMapSource.m in Sources */,
F5C12D2B0F8A86CA00A894D2 /* RMGeoHash.m in Sources */,
2B580F160F8D2E9C00D495B2 /* RMTestableMarker.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
... ... @@ -1062,6 +1072,7 @@
GCC_ENABLE_SYMBOL_SEPARATION = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = MapView_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = "NS_BLOCK_ASSERTIONS=1";
HEADER_SEARCH_PATHS = ../Proj4;
INFOPLIST_FILE = "RM Unit Tests-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
... ...
//
// RMTestableMarker.h
// MapView
//
// Created by Hal Mueller on 4/8/09.
// Copyright 2009 Route-Me Contributors. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@class RMMarker;
/// Subclass of RMMarker with lat/lon coordinates added, to verify correct projection calculations
@interface RMTestableMarker : RMMarker {
/// original location in lat/lon, to see if projection really works correctly
CLLocationCoordinate2D coordinate;
}
@property (assign, nonatomic) CLLocationCoordinate2D coordinate;
@end
... ...
//
// RMTestableMarker.m
// MapView
//
// Created by Hal Mueller on 4/8/09.
// Copyright 2009 Route-Me Contributors. All rights reserved.
//
#import "RMMarker.h"
#import "RMTestableMarker.h"
#import "RMMarker.h"
@implementation RMTestableMarker
@synthesize coordinate;
@end
... ...
... ... @@ -11,6 +11,7 @@
#import "RMCloudMadeMapSource.h"
#import "RMGeoHash.h"
#import "RMMarker.h"
#import "RMTestableMarker.h"
#import "RMMarkerManager.h"
@implementation RouteMeTests
... ... @@ -22,13 +23,11 @@
contentView = [[UIView alloc] initWithFrame:appRect];
contentView.backgroundColor = [UIColor greenColor];
NSLog(@"%@", [UIScreen mainScreen]);
initialCenter.latitude = 66.44;
initialCenter.longitude = -178.0;
mapView = [[RMMapView alloc] initWithFrame:CGRectMake(10,20,200,300)
WithLocation:initialCenter];
NSLog(@"contentView %@ mapView %@", contentView, mapView);
[contentView addSubview:mapView];
}
... ... @@ -75,12 +74,13 @@
{
STAssertNotNil(mapView, @"mapview creation failed");
STAssertNotNil([mapView contents], @"mapView contents should not be nil");
NSLog(@"%@", [mapView contents]);
}
- (void)testMarkerCreation
{
// create markers from -183 to -169 longitude
initialCenter.longitude = -178.0;
CLLocationCoordinate2D markerPosition;
NSUInteger nRows = 1;
NSUInteger nColumns = 8;
... ... @@ -94,37 +94,38 @@
markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing);
for (j = 0; j < nColumns; j++) {
markerPosition.longitude += columnSpacing;
NSLog(@"%f %f", markerPosition.latitude, markerPosition.longitude);
RMMarker *newMarker = [[RMMarker alloc] initWithUIImage:markerImage];
RMTestableMarker *newMarker = [[RMTestableMarker alloc] initWithUIImage:markerImage];
STAssertNotNil(newMarker, @"testMarkerCreation marker creation failed");
#ifdef DEBUG
[newMarker setLatlon:markerPosition];
#endif
[newMarker setCoordinate:markerPosition];
[mapView.contents.markerManager addMarker:newMarker
AtLatLong:markerPosition];
}
markerPosition.latitude += columnSpacing;
}
#ifdef DEBUG
RMMarkerManager *mangler = [[mapView contents] markerManager];
for (RMMarker *theMarker in [mangler getMarkers]) {
for (RMTestableMarker *theMarker in [mangler getMarkers]) {
CGPoint screenPosition = [mangler getMarkerScreenCoordinate:theMarker];
NSLog(@"%@ %3.1f %3.1f %f %f", theMarker,
theMarker.latlon.latitude, theMarker.latlon.longitude,
RMLog(@"%@ %3.1f %3.1f %f %f", theMarker,
theMarker.coordinate.latitude, theMarker.coordinate.longitude,
screenPosition.y, screenPosition.x);
}
#endif
}
- (void)testMarkerCoordinates
- (void)testMarkerCoordinatesFarEast
{
[mapView.contents setZoom:3.0];
// create markers from +177 to +191 longitude
initialCenter.longitude = +176.0;
CLLocationCoordinate2D markerPosition;
NSUInteger nColumns = 8;
double columnSpacing = 2.0;
UIImage *markerImage = [UIImage imageNamed:@"marker-red.png"];
markerPosition.latitude = initialCenter.latitude;
markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing);
... ... @@ -132,32 +133,86 @@
NSMutableArray *testMarkers = [NSMutableArray arrayWithCapacity:nColumns];
for (j = 0; j < nColumns; j++) {
markerPosition.longitude += columnSpacing;
NSLog(@"%f %f", markerPosition.latitude, markerPosition.longitude);
RMMarker *newMarker = [[RMMarker alloc] initWithUIImage:markerImage];
RMTestableMarker *newMarker = [[RMTestableMarker alloc] initWithUIImage:markerImage];
[testMarkers addObject:newMarker];
[newMarker setCoordinate:markerPosition];
[mapView.contents.markerManager addMarker:newMarker
AtLatLong:markerPosition];
}
STAssertGreaterThan(columnSpacing, 0.0, @"this test requires positive columnSpacing");
RMMarkerManager *mangler = [[mapView contents] markerManager];
[[mapView contents] moveBy:CGSizeMake(-5.0, 0.0)];
#ifdef DEBUG
[newMarker setLatlon:markerPosition];
RMLatLongBounds screenLimitsDegrees = [[mapView contents] getScreenCoordinateBounds];
RMLog(@"screen limits west: %4.1f east %4.1f", screenLimitsDegrees.northWest.longitude, screenLimitsDegrees.southEast.longitude);
RMLog(@"screen limits south: %4.1f north %4.1f", screenLimitsDegrees.southEast.latitude, screenLimitsDegrees.northWest.latitude);
#endif
for (j = 1; j < nColumns; j++) {
RMTestableMarker *leftMarker = [testMarkers objectAtIndex:j - 1];
RMTestableMarker *rightMarker = [testMarkers objectAtIndex:j];
CGPoint leftScreenPosition = [mangler getMarkerScreenCoordinate:leftMarker];
CGPoint rightScreenPosition = [mangler getMarkerScreenCoordinate:rightMarker];
STAssertLessThan(leftScreenPosition.x, rightScreenPosition.x,
@"screen position calculation failed (markers %d, %d): left (%f, %f) right (%f, %f) mapped to left (%f, %f) right (%f, %f)",
j-1, j,
// write these out as longitude/latitude instead of standard latitude/longitude to make comparisons easier
leftMarker.coordinate.longitude, leftMarker.coordinate.latitude,
rightMarker.coordinate.longitude, rightMarker.coordinate.latitude,
leftScreenPosition.x, leftScreenPosition.y, rightScreenPosition.x, rightScreenPosition.y);
}
}
- (void)testMarkerCoordinatesFarWest
{
[mapView.contents setZoom:3.0];
// create markers from -177 to -169 longitude
initialCenter.longitude = -178.0;
CLLocationCoordinate2D markerPosition;
NSUInteger nColumns = 8;
double columnSpacing = 2.0;
UIImage *markerImage = [UIImage imageNamed:@"marker-red.png"];
markerPosition.latitude = initialCenter.latitude;
markerPosition.longitude = initialCenter.longitude - ((nColumns - 1)/2.0 * columnSpacing);
int j;
NSMutableArray *testMarkers = [NSMutableArray arrayWithCapacity:nColumns];
for (j = 0; j < nColumns; j++) {
markerPosition.longitude += columnSpacing;
RMTestableMarker *newMarker = [[RMTestableMarker alloc] initWithUIImage:markerImage];
[testMarkers addObject:newMarker];
[newMarker setCoordinate:markerPosition];
[mapView.contents.markerManager addMarker:newMarker
AtLatLong:markerPosition];
}
STAssertGreaterThan(columnSpacing, 0.0, @"this test requires positive columnSpacing");
#ifdef DEBUG
RMMarkerManager *mangler = [[mapView contents] markerManager];
[[mapView contents] moveBy:CGSizeMake(-5.0, 0.0)];
#ifdef DEBUG
RMLatLongBounds screenLimitsDegrees = [[mapView contents] getScreenCoordinateBounds];
RMLog(@"screen limits west: %4.1f east %4.1f", screenLimitsDegrees.northWest.longitude, screenLimitsDegrees.southEast.longitude);
RMLog(@"screen limits south: %4.1f north %4.1f", screenLimitsDegrees.southEast.latitude, screenLimitsDegrees.northWest.latitude);
#endif
for (j = 1; j < nColumns; j++) {
RMMarker *leftMarker = [testMarkers objectAtIndex:j - 1];
RMMarker *rightMarker = [testMarkers objectAtIndex:j];
RMTestableMarker *leftMarker = [testMarkers objectAtIndex:j - 1];
RMTestableMarker *rightMarker = [testMarkers objectAtIndex:j];
CGPoint leftScreenPosition = [mangler getMarkerScreenCoordinate:leftMarker];
CGPoint rightScreenPosition = [mangler getMarkerScreenCoordinate:rightMarker];
STAssertLessThan(leftScreenPosition.x, rightScreenPosition.x,
@"screen position calculation failed: left (%f, %f) right (%f, %f) mapped to left (%f, %f) right (%f, %f)",
leftMarker.latlon.longitude, leftMarker.latlon.latitude,
rightMarker.latlon.longitude, rightMarker.latlon.latitude,
@"screen position calculation failed (markers %d, %d): left (%f, %f) right (%f, %f) mapped to left (%f, %f) right (%f, %f)",
j-1, j,
leftMarker.coordinate.longitude, leftMarker.coordinate.latitude,
rightMarker.coordinate.longitude, rightMarker.coordinate.latitude,
leftScreenPosition.x, leftScreenPosition.y, rightScreenPosition.x, rightScreenPosition.y);
}
#endif
}
@end
... ...