Permalink
Browse files

CompassController & GeekPoint

  • Loading branch information...
1 parent b5117c2 commit 6ba3242c1f3a4102c1ce6b2a523047f986d9099a Krzysiek committed Feb 10, 2012
@@ -14,6 +14,8 @@
80A7823514E4560E0008E31D /* HKCompassViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 80A7823414E4560E0008E31D /* HKCompassViewController.m */; };
95A6B88814E48A3F00752178 /* spiral.png in Resources */ = {isa = PBXBuildFile; fileRef = 95A6B88714E48A3F00752178 /* spiral.png */; };
95A6B88A14E4914100752178 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95A6B88914E4914000752178 /* QuartzCore.framework */; };
+ 80A7823114E455B10008E31D /* HKCompassGeekPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 80A7823014E455B10008E31D /* HKCompassGeekPoint.m */; };
+ 80A7823514E4560E0008E31D /* HKCompassViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 80A7823414E4560E0008E31D /* HKCompassViewController.m */; };
A20B50F514E45810009C0BB0 /* HKDetectorClient.m in Sources */ = {isa = PBXBuildFile; fileRef = A20B50F414E45810009C0BB0 /* HKDetectorClient.m */; };
A278841814E4480400D0476B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A278841714E4480400D0476B /* UIKit.framework */; };
A278841A14E4480400D0476B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A278841914E4480400D0476B /* Foundation.framework */; };
@@ -51,6 +53,10 @@
80A7823414E4560E0008E31D /* HKCompassViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HKCompassViewController.m; path = Controllers/HKCompassViewController.m; sourceTree = "<group>"; };
95A6B88714E48A3F00752178 /* spiral.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = spiral.png; sourceTree = "<group>"; };
95A6B88914E4914000752178 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ 80A7822F14E455B10008E31D /* HKCompassGeekPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; path = HKCompassGeekPoint.h; sourceTree = "<group>"; };
+ 80A7823014E455B10008E31D /* HKCompassGeekPoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HKCompassGeekPoint.m; sourceTree = "<group>"; };
+ 80A7823314E4560E0008E31D /* HKCompassViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HKCompassViewController.h; path = Controllers/HKCompassViewController.h; sourceTree = "<group>"; };
+ 80A7823414E4560E0008E31D /* HKCompassViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HKCompassViewController.m; path = Controllers/HKCompassViewController.m; sourceTree = "<group>"; };
A20B50F314E45810009C0BB0 /* HKDetectorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HKDetectorClient.h; path = Models/HKDetectorClient.h; sourceTree = "<group>"; };
A20B50F414E45810009C0BB0 /* HKDetectorClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HKDetectorClient.m; path = Models/HKDetectorClient.m; sourceTree = "<group>"; };
A278841314E4480400D0476B /* GitHubDetector.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GitHubDetector.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -184,8 +190,8 @@
A278843714E44BC600D0476B /* extern */ = {
isa = PBXGroup;
children = (
- 80A7822F14E455B10008E31D /* GeoCoordinate.h */,
- 80A7823014E455B10008E31D /* GeoCoordinate.m */,
+ 80A7822F14E455B10008E31D /* HKCompassGeekPoint.h */,
+ 80A7823014E455B10008E31D /* HKCompassGeekPoint.m */,
A278845614E44D3200D0476B /* JSONKit */,
A278843814E44CB400D0476B /* AFNetworking */,
);
@@ -343,7 +349,7 @@
52D2B34014E4527A00855A1F /* MapViewController.m in Sources */,
80A7822614E451B50008E31D /* HKCompassGeekView.m in Sources */,
A20B50F514E45810009C0BB0 /* HKDetectorClient.m in Sources */,
- 80A7823114E455B10008E31D /* GeoCoordinate.m in Sources */,
+ 80A7823114E455B10008E31D /* HKCompassGeekPoint.m in Sources */,
80A7823514E4560E0008E31D /* HKCompassViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -7,7 +7,10 @@
//
#import "HKCompassViewController.h"
-#import "GeoCoordinate.h"
+#import "HKCompassGeekPoint.h"
+#import "HKGeek.h"
+#import "HKCheckIn.h"
+#import "HKCompassGeekView.h"
#import <QuartzCore/QuartzCore.h>
NSComparisonResult AngleSortASC(GeoCoordinate *s1, GeoCoordinate *s2, void *ignore);
@@ -18,20 +21,88 @@ @interface HKCompassViewController()
@property (nonatomic, assign) double currentHeadingAngle;
@property (nonatomic, assign) double sonarRadius; /**< sonar radius in points */
@property (nonatomic, readwrite, strong) CLLocation * currentLocation; /**< most up to date user location */
-@property (nonatomic, readonly) CLLocationManager * locationManager;
+@property (nonatomic, readwrite, strong) CLLocationManager * locationManager;
+
+@property (nonatomic, readwrite, strong) NSMutableArray * geekPoints;
@end
@implementation HKCompassViewController
-@synthesize sonarRange=_sonarRange, pointsContainer=_pointsContainer, pointsIndex=_pointsIndex, currentHeadingAngle = _currentHeadingAngle, sonarRadius=_sonarRadius, currentLocation=_currentLocation;
+@synthesize sonarRange=_sonarRange, pointsContainer=_pointsContainer, pointsIndex=_pointsIndex, currentHeadingAngle = _currentHeadingAngle, sonarRadius=_sonarRadius, currentLocation=_currentLocation, geekPoints=_geekPoints;
// TODO proper use of shared app location manager
-(CLLocationManager *)locationManager {
return [[CLLocationManager alloc] init];
}
--(void)setLocations:(NSMutableArray *) loc {
+-(id)init {
+ self = [super init];
+ if (self != nil){
+ self.geekPoints = [[NSMutableArray alloc] init];
+
+ self.pointsIndex = 0;
+ self.sonarRadius = 150;
+ self.sonarRange = 2000; // 2 km
+ self.currentHeadingAngle = 0;
+
+ self.pointsContainer = [[UIView alloc] initWithFrame:self.view.frame];
+ self.locationManager = [[CLLocationManager alloc] init];
+ self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
+ self.locationManager.delegate = self;
+ [self.locationManager startUpdatingLocation];
+ [self.locationManager stopUpdatingHeading];
+ self.currentLocation = nil;
+ self.geekPoints = [[NSMutableArray alloc] init];
+ }
+ return self;
+}
+
+
+-(void)viewWillAppear:(BOOL)animated{
+ [super viewWillAppear:animated];
+
+ [self.locationManager startUpdatingLocation];
+ [self.locationManager startUpdatingHeading];
+}
+
+-(void)viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+ [self.locationManager stopUpdatingLocation];
+ [self.locationManager startUpdatingHeading];
+}
+
+-(void)viewDidLoad {
+ [super viewDidLoad];
+ [self.view addSubview:self.pointsContainer];
+}
+
+-(void)setLocations:(NSMutableArray *) geeks {
+ @autoreleasepool {
+ for (HKCompassGeekPoint * gp in self.geekPoints) {
+ [gp.view removeFromSuperview];
+ }
+ [self.geekPoints removeAllObjects];
+
+ for (HKGeek * geek in geeks) {
+ //NSLog(@"set location...");
+ CLLocation * l = [geek lastCheckIn].location;
+
+ HKCompassGeekView * gv = [[HKCompassGeekView alloc] init]; //WithGeek: geek];
+
+ HKCompassGeekPoint * p = [[HKCompassGeekPoint alloc] initWithLocation:l andPointView:gv andSonarRadius:self.sonarRadius];
+ [self.geekPoints addObject:p];
+
+
+ [self.pointsContainer addSubview: p.view];
+ p.view.center = self.pointsContainer.center;
+
+ if (self.currentLocation != nil) {
+ NSLog(@"!= nil");
+ [p calibrateUsingOrigin:self.currentLocation andSonarRange:self.sonarRange];
+ }
+ }
+ }
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
@@ -51,8 +122,8 @@ - (void)viewDidUnload {
#pragma mark CLLocationManager Delegate Methods
-
-NSComparisonResult AngleSortASC(GeoCoordinate *s1, GeoCoordinate *s2, void *ignore) {
+NSComparisonResult AngleSortASC(HKCompassGeekPoint *s1, HKCompassGeekPoint *s2, void *ignore);
+NSComparisonResult AngleSortASC(HKCompassGeekPoint *s1, HKCompassGeekPoint *s2, void *ignore) {
if (s1.azimuth < s2.azimuth) {
return NSOrderedAscending;
} else if (s1.azimuth > s2.azimuth) {
@@ -62,4 +133,36 @@ NSComparisonResult AngleSortASC(GeoCoordinate *s1, GeoCoordinate *s2, void *igno
}
}
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
+ if (newLocation.horizontalAccuracy > 0 && newLocation != oldLocation) {
+ self.currentLocation = newLocation;
+ NSLog(@"new location %f %f", self.currentLocation.coordinate.latitude, self.currentLocation.coordinate.longitude);
+
+ for (HKCompassGeekPoint* sp in self.geekPoints) {
+ [sp calibrateUsingOrigin:self.currentLocation andSonarRange:self.sonarRange];
+ }
+ [self.geekPoints sortUsingFunction:AngleSortASC context:NULL]; /**< sortujemy elementy wmierze łukowej kąta */
+ }
+}
+
+- (void) locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
+ if (newHeading.headingAccuracy > 0) {
+ self.currentHeadingAngle = newHeading.trueHeading;
+ [UIView beginAnimations:@"SonarScreenAnimation" context:NULL];
+ [UIView setAnimationBeginsFromCurrentState: YES];
+ [UIView setAnimationDuration:0.2];
+ [UIView setAnimationCurve: UIViewAnimationCurveLinear];
+ [UIView setAnimationRepeatAutoreverses:NO];
+ self.pointsContainer.transform = CGAffineTransformMakeRotation(degreesToRadians(-newHeading.trueHeading));
+ [UIView commitAnimations];
+ }
+}
+
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
+ NSLog(@"Received Core Location error %@", error);
+}
+
+
+
@end
@@ -4,6 +4,10 @@
#import <Availability.h>
+#define degreesToRadians(x) (M_PI * (x) / 180.0)
+#define radiansToDegrees(x) ((x) * 180.0/M_PI)
+
+
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif
@@ -0,0 +1,23 @@
+//
+// GeoCoordinate.h
+//
+// Created by Krzysztof Profic on 11-03-02.
+// Copyright 2011 Krzysztof Profic. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <CoreLocation/CoreLocation.h>
+
+@interface HKCompassGeekPoint : NSObject;
+
+@property (nonatomic) double distance;
+@property (nonatomic) double inclination;
+@property (nonatomic) double azimuth;
+@property (nonatomic, readwrite, strong) CLLocation * location;
+@property (nonatomic, readwrite, strong) UIView* view;
+
+- (id) initWithLocation:(CLLocation *)loc andPointView: (UIView *) pointView andSonarRadius: (double) radiusInPoints;
+
+- (void) calibrateUsingOrigin:(CLLocation *)origin andSonarRange: (double) sonarRange;
+- (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second;
+@end
@@ -0,0 +1,94 @@
+//
+// GeoCoordinate.m
+//
+// Created by Krzysztof Profic on 11-03-02.
+// Copyright 2011 Krzysztof Profic. All rights reserved.
+//
+
+#import "HKCompassGeekPoint.h"
+
+@interface HKCompassGeekPoint()
+@property (nonatomic, strong) UIView *pointView;
+- (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second;
+@end
+
+
+@implementation HKCompassGeekPoint
+@synthesize distance, inclination, azimuth, view, pointView=_pointView, location=_location;
+
+// Override the azimuth accessor method
+- (double)azimuth {
+ if ( azimuth < 0.0 ) {
+ azimuth = (M_PI * 2.0) + azimuth;
+ } else if ( azimuth > (M_PI * 2.0) ) {
+ azimuth = azimuth - (M_PI * 2.0);
+ }
+ return azimuth;
+}
+
+- (id)initWithLocation:(CLLocation *)loc {
+ self = [super init];
+ if ( self != nil ) {
+ self.location = loc;
+ }
+ return self;
+}
+
+- (id)initWithCoordiante:(CLLocation *)loc andOrigin:(CLLocation *)origin {
+ self = [super init];
+ if ( self != nil ) {
+ }
+ return self;
+}
+- (id) initWithLocation:(CLLocation *)loc andPointView: (UIView *) pointView andSonarRadius: (double) radiusInPoints {
+
+ self = [super init];
+ if (self != nil){
+ self.location = loc;
+ self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, radiusInPoints, radiusInPoints)];
+ self.pointView = pointView;
+ [self.view addSubview:pointView];
+ self.view.backgroundColor = [UIColor blueColor];
+ }
+ return self;
+}
+
+//returns the angle between north -> first <- second
+- (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second {
+ float longitudinalDifference = second.longitude - first.longitude;
+ float latitudinalDifference = second.latitude - first.latitude;
+ float possibleAzimuth = (M_PI_2) - atan(latitudinalDifference / longitudinalDifference); // arc ctan
+
+ if (longitudinalDifference > 0)
+ return possibleAzimuth;
+ else if (longitudinalDifference < 0)
+ return possibleAzimuth + M_PI;
+ else if (latitudinalDifference < 0)
+ return M_PI;
+
+ return 0.0f;
+}
+
+// calculating GeoCoordinate's distance
+- (void) calibrateUsingOrigin:(CLLocation *)origin andSonarRange: (double) sonarRange {
+ double baseDistance = [origin distanceFromLocation:self.location];
+ self.distance = baseDistance; // sqrt( pow( [origin altitude] - [self.location altitude], 2) + pow(baseDistance, 2));
+
+ //calculating GeoCoorginate's inclination
+ float angle = asin( ABS([origin altitude] - [self.location altitude]) / self.distance);
+ if ([origin altitude] > [self.location altitude]) {
+ angle = -angle;
+ }
+ self.inclination = angle;
+
+ // calculating GeoCoordinate's azimuth
+ self.azimuth = [self angleFromCoordinate:[origin coordinate] toCoordinate:[self.location coordinate]];
+
+ //calibrate view
+ dispatch_async(dispatch_get_main_queue(), ^{
+ self.pointView.center = CGPointMake(view.bounds.size.width/2, view.bounds.size.height/2 - (view.bounds.size.height/2)*(self.distance/sonarRange));
+ view.transform = CGAffineTransformMakeRotation(self.azimuth);
+ });
+}
+
+@end

0 comments on commit 6ba3242

Please sign in to comment.