Device Location (ie latitude,longitude)
by Dave Young · in iTorque 2D · 02/03/2009 (12:24 pm) · 19 replies
I wrote up a handy way to grab the latitude and longitude info off the device when it comes in.
Ideally you make the call a few times to get the best positional data, but here is a one-off:
First, add CoreLocation framework to the project.
Next, extend the app delegate to respond to the location callback
TGBAppDelegate.h
Then the actual callbacks:
TGBAppDelegate.mm (the entire file)
Finally, some callbacks in the code, in iPhoneMain.mm
And the relative script callbacks:
It worked on the iPod, the app requests to use your location (via iPhoneSDK) and if you say yes then it should find you!
Again, the ideal way to do this is to initiate the call a few times, each time can take 10-15 seconds and can use one of 5 different location methods, so you might get better locations with more attempts, examining the accuracy when it comes in.
I got lucky implementing this: it worked the first time or so, so I thought I would share it! Struggling for a few months with the iPhone SDK ended up being useful after all.
Ideally you make the call a few times to get the best positional data, but here is a one-off:
First, add CoreLocation framework to the project.
Next, extend the app delegate to respond to the location callback
TGBAppDelegate.h
#import <CoreLocation/CoreLocation.h>
#import <CoreLocation/CLLocationManagerDelegate.h>
@interface TGBAppDelegate : NSObject <UIApplicationDelegate,CLLocationManagerDelegate> {
IBOutlet UIWindow *window;
CLLocationManager *locmanager;
}Then the actual callbacks:
TGBAppDelegate.mm (the entire file)
///-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#import "TGBAppDelegate.h"
#include "platform/platformInput.h"
extern void _iPhoneRunTorqueMain( id appID, UIView *Window, UIApplication *app );
extern void _iPhoneGameInnerLoop();
extern void _iPhoneGameResignActive();
extern void _iPhoneGameBecomeActive();
extern void _iPhoneGameWillTerminate();
extern void _iPhoneGameChangeOrientation();
extern void _iPhoneGameLogLocationFail();
extern void _iPhoneGameLogLocationSuccess(const char *coords,const char *accuracy);
@implementation TGBAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
locmanager = [[CLLocationManager alloc] init];
[locmanager setDelegate:self];
[locmanager setDesiredAccuracy:kCLLocationAccuracyBest];
[locmanager startUpdatingLocation];
_iPhoneRunTorqueMain( self, window, application );
}
- (void)applicationWillResignActive:(UIApplication *)application {
_iPhoneGameResignActive();
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
_iPhoneGameBecomeActive();
}
- (void)applicationWillTerminate:(UIApplication *)application {
_iPhoneGameWillTerminate();
}
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation{
_iPhoneGameChangeOrientation();
}
- (void) runMainLoop {
_iPhoneGameInnerLoop();
}
- (void) getDeviceLocation {
[locmanager startUpdatingLocation];
}
- (void) locationManager:(CLLocationManager *) manager didUpdateToLocation:(CLLocation *) newLocation fromLocation:(CLLocation *)oldLocation
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
CLLocationAccuracy hAccuracy = [newLocation horizontalAccuracy];
CLLocationAccuracy vAccuracy = [newLocation verticalAccuracy];
NSString *accuracyString = [NSString stringWithFormat:@"%f %f",hAccuracy,vAccuracy];
const char *strAccuracyString = [accuracyString UTF8String ];
CLLocationCoordinate2D loc = [newLocation coordinate];
NSString *coordString = [NSString stringWithFormat:@"%f %f",loc.latitude,loc.longitude];
const char *strCoordString = [coordString UTF8String ];
_iPhoneGameLogLocationSuccess(strCoordString,strAccuracyString);
[pool release];
}
- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"Error establishing location");
_iPhoneGameLogLocationFail();
}
- (void)dealloc {
[locmanager release];
[window release];
[super dealloc];
}
@endFinally, some callbacks in the code, in iPhoneMain.mm
void _iPhoneGameLogLocationFail()
{
Con::errorf("Location Fail");
Con::executef( 1, "oniPhoneLogLocationFail" );
}
void _iPhoneGameLogLocationSuccess(const char *coords, const char *accuracy)
{
char argBuffer1[64];
dSprintf(argBuffer1, 64, coords);
char argBuffer2[64];
dSprintf(argBuffer2, 64, accuracy);
Con::executef( 3, "oniPhoneLogLocationSuccess",argBuffer1, argBuffer2 );
}And the relative script callbacks:
function oniPhoneLogLocationSuccess(%loc,%accuracy)
{
MessageBoxOK("Location Log Success","Success:" @ %loc,"");
$DeviceLocation = %loc; //This is a latitude SPC longitude format
}
function oniPhoneLogLocationFail()
{
MessageBoxOK("Location Log Fail","Fail","");
}It worked on the iPod, the app requests to use your location (via iPhoneSDK) and if you say yes then it should find you!
Again, the ideal way to do this is to initiate the call a few times, each time can take 10-15 seconds and can use one of 5 different location methods, so you might get better locations with more attempts, examining the accuracy when it comes in.
I got lucky implementing this: it worked the first time or so, so I thought I would share it! Struggling for a few months with the iPhone SDK ended up being useful after all.
#2
It would be nice to have a high score board with names, scores, and the country of origin, automatically populated.
06/11/2009 (10:50 am)
Does anyone have ready-made method of converting a location to a name, specifically a country?It would be nice to have a high score board with names, scores, and the country of origin, automatically populated.
#3
06/11/2009 (11:42 am)
There should be a simple test for whether the location is valid, also. I live in a secret cave on a mountain top where my iPod doesn't have enough known wi-fi access points for reference to the CoreLocation API.
#4
Then everything compiles and works correctly!
Thanks for sharing this code, Dave!!
11/30/2009 (4:52 pm)
Quick bugfix.In the iPhoneMain.mm code, it should read..char argBuffer1[64];
dSprintf(argBuffer1, 64, coords); //Bug was in this line. It used argBuffer2
char argBuffer2[64];
dSprintf(argBuffer2, 64, accuracy);Then everything compiles and works correctly!
Thanks for sharing this code, Dave!!
#5
Was fun to work on this stuff :)
11/30/2009 (5:04 pm)
Thanks Dave, code edited above. It's funny, but sometimes when posting code I will change a var name to be more clear, or take out some fluff/debug code, and therefore introduce typos and errors. My apologies!Was fun to work on this stuff :)
#6
This gives the error: 'locmanager' was not declared in this scope.
The error makes sense, though I'm not entirely sure how to declare locmanager within the scope that it requires. Any hints?
12/14/2009 (7:44 pm)
I'm trying to modify this resource so I can control when the game starts pinging the GPS, rather than it happening the second the application starts. To do this, I've moved the init command into a ConsoleFunction, however I appear to be lacking in something in my Objective-C here. This is what I'm doing:ConsoleFunction( startUpdatingGPSLocation, void, 2, 2, "" )
{
[locmanager startUpdatingLocation];
}This gives the error: 'locmanager' was not declared in this scope.
The error makes sense, though I'm not entirely sure how to declare locmanager within the scope that it requires. Any hints?
#7
But it's this line that would do the trick:
@synthesize locmanager;
Don't forget to #import "TGBAppDelegate.h"
good luck :)
12/14/2009 (9:18 pm)
locmanager is declared in TGBAppDelegate.h in my example above. And it worked because the function referencing it was in the implementation file.But it's this line that would do the trick:
@synthesize locmanager;
Don't forget to #import "TGBAppDelegate.h"
good luck :)
#8
I've added @synthesize locmanager; at the top of the file, just underneath @synthesize window;. #import "TGBAppDelegate.h" is already in there. I now get an error on the @synthesize locmanager; line which reads:
"No declaration of locmanager found in this interface"
12/14/2009 (11:03 pm)
Hrm... I'm suspecting I'm missing something crucial in Objective-C here.I've added @synthesize locmanager; at the top of the file, just underneath @synthesize window;. #import "TGBAppDelegate.h" is already in there. I now get an error on the @synthesize locmanager; line which reads:
"No declaration of locmanager found in this interface"
#9
So that's all well and good... buuut... I'm still receiving my original problem, with the error "'locmanager' was not declared in this scope" for this block of code:
12/15/2009 (2:03 pm)
Ok... I managed to get rid of the error with the @synthesize line by adding this to the header file:@property (nonatomic, retain) CLLocationManager *locmanager;
So that's all well and good... buuut... I'm still receiving my original problem, with the error "'locmanager' was not declared in this scope" for this block of code:
ConsoleFunction( startUpdatingGPSLocation, void, 2, 2, "" )
{
[locmanager startUpdatingLocation];
}
#10
Stick that anywhere below getDeviceLocation, in TGBAppDelegate.mm .
No need for the extra @property and @synthesize.
Since getDeviceLocation doesn't actually return anything, it shouldn't start with the word 'get', it should be renamed. Probably to 'startUpdatingGPSLocation'.
Don't forget to remove or comment out the line "[locmanager startUpdatingLocation];" in applicationDidFinishLaunching. It's around line 29, above.
share and enjoy!
12/15/2009 (4:55 pm)
ConsoleFunction( startUpdatingGPSLocation, void, 2, 2, "" )
{
TGBAppDelegate* delegate = (TGBAppDelegate*)[UIApplication sharedApplication].delegate;
[delegate getDeviceLocation];
}Stick that anywhere below getDeviceLocation, in TGBAppDelegate.mm .
No need for the extra @property and @synthesize.
Since getDeviceLocation doesn't actually return anything, it shouldn't start with the word 'get', it should be renamed. Probably to 'startUpdatingGPSLocation'.
Don't forget to remove or comment out the line "[locmanager startUpdatingLocation];" in applicationDidFinishLaunching. It's around line 29, above.
share and enjoy!
#11
Also, a quick change to the ConsoleFunction syntax, otherwise it gives errors about not having enough arguments:
Voila! Controllable initializing of GPS searching. All hail your new iPhone overlords.
12/15/2009 (6:19 pm)
Thanks, Paul - that did it! :)Also, a quick change to the ConsoleFunction syntax, otherwise it gives errors about not having enough arguments:
ConsoleFunction( startUpdatingGPSLocation, void, 1, 1, "" )
{
TGBAppDelegate* appDelegate = (TGBAppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate startUpdatingGPSLocation];
}Voila! Controllable initializing of GPS searching. All hail your new iPhone overlords.
#12
(PS: My apologies if something is clearly typoed... I read this from one monitor and typed it back out. The code gives no errors or warnings though when compiled and ran.)
12/19/2009 (3:42 pm)
Any idea how we can get the device to stop polling the location? In the case of my game, we only need to poll the location at certain points, and I want to make sure we aren't using those resources when we don't need to poll. It seems like just doing the following would work, but it doesn't seem to shut it off:- (void) stopUpdatingGPSLocation
{
[locmanager release];
}
ConsoleFunction( stopUpdatingGPSLocation, void, 1, 1, "" )
{
TGBAppDelegate* appDelegate = (TGBAppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate stopUpdatingGPSLocation);
}(PS: My apologies if something is clearly typoed... I read this from one monitor and typed it back out. The code gives no errors or warnings though when compiled and ran.)
#13
12/31/2009 (9:06 am)
For anyone following this thread: I got the code working. Was a rather silly mistake on my part. Gotta do this for it to work:- (void) stopUpdatingGPSLocation {
[locmanager stopUpdatingLocation];
}
ConsoleFunction( stopUpdatingGPSLocation, void, 1, 1, "" )
{
TGBAppDelegate* appDelegate = (TGBAppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate stopUpdatingGPSLocation];
}
#14
"function_name", refrence from -[viewname functionname:] in viewname.o symbol(s) not found collect2: ld returned 1 exit status.
Any help is appreciated.
06/08/2010 (8:34 am)
I have tried the above concept to send data typed in a view to torque script. But when i compile it I get errors when linking. The error is as follows:"function_name", refrence from -[viewname functionname:] in viewname.o symbol(s) not found collect2: ld returned 1 exit status.
Any help is appreciated.
#15
06/08/2010 (8:58 am)
Hitesh, could you please post your code so we can double check it for you?
#16
In my header file i have the following code:
In my implementation file I have the following code:
And this is the code for the c++ method in .mm file
06/08/2010 (11:21 am)
Thanks for the quick response. In my header file i have the following code:
..... ..... -(IBAction) loginpressed:(id)sender; ..... ..... @end
In my implementation file I have the following code:
.....
.....
#import "LoginView.h"
extern void _sendlogindetails (const char *usr, const char *pwd);
.....
.....
-(IBAction) loginpressed:(id)sender{
NSString *usernamestring = username.text;
NSString *passwordstring = password.text;
const char *strusername = [usernamestring UTF8String];
const char *strpassword = [passwordstring UTF8String];
_sendlogindetails(strusername, strpassword);
}
.....
.....And this is the code for the c++ method in .mm file
#include "console/console.h"
void _sendlogindetails (const char *usr, const char *pwd)
{
char argBuffer1[64];
dSprintf(argBuffer1, 64, usr);
char argBuffer2[64];
dSprintf(argBuffer2, 64, pwd);
Con::executef(3, "TCPLogin", argBuffer1, argBuffer2);
}
#17
06/08/2010 (11:23 am)
What line of code is the error on?
#18
06/09/2010 (3:38 am)
The error happens when linking. The exact error is "_sendlogindetails", reference from: -[LoginView loginpressed:] in LoginView.o symbol(s) not found collect2: ld returned exit status
#19
06/09/2010 (2:19 pm)
I figured it out. My implementation file was named with a .m extension. I changed it to .mm and it compiled fine.
Torque 3D Owner Dave Young
Dave Young Games
CLLocationDistance altitude
which could also be pumped through as well.
The difference would be something like: