I started with objective-c programing, and now I can get one GPS location and send it to my server. this is my code:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[manager stopUpdatingLocation];
if(newLocation != nil){
float lat = newLocation.coordinate.latitude ;
float longt = newLocation.coordinate.longitude ;
uint8_t location[BUFFER_SIZE] ={0};
sprintf((char *)location, "(%f,%f)",lat , long) ;
[self writeToServer:location size:strlen((char *)location)] ;
}
}
When "writeToServer" is responsible for sending the data.
Now, how can I change this method to get two locations, in interval of 10 second, then send these two locations?
Many thans!
Related
I'm using CLLocation to get the current location as follows:
-(void)loadCurrentLocation{
if (manager==nil) {
manager=[[CLLocationManager alloc]init];
}
manager.delegate=self;
manager.desiredAccuracy=kCLLocationAccuracyBest;
[manager startUpdatingLocation];
}
- (void) viewDidLoad {
[super viewDidLoad];
[self loadCurrentLocation];
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
CLLocation *loc=newLocation;
if (loc!=nil) {
self.latitude=loc.coordinate.latitude; //1
self.longitude=loc.coordinate.longitude; //2
NSLog(#"Gained Latitude:%.f",self.latitude);
NSLog(#"Gained Longitude:%.f",self.longitude);
}
}
Given that latitude and longitude are declared as follows in the .h file:
#interface Prayers :UIViewController<CLLocationManagerDelegate>
#property double longitude;
#property double latitude;
#end
the problem is that the returned values at lines 1 & 2 are integers like 30 and 31 and i was expecting them like 31.377033600000004000 and 30.016893900000000000, so why the returned values are integers instead of double ? thanks in advance
If the types weren't what you expect, Xcode would likely be giving you conversion warnings. What makes you think they aren't doubles you are getting back? Maybe the framework is just rounding to the nearest degree and returning that as a double?
Another possibility. what if your log looked like
NSLog(#"Gained Latitude:%.2f",self.latitude);
Does that print more accuracy (note, the 2 in the format).
Maybe even trying boxing them as an NSNumber and see what that prints:
NSLog(#"Gained Latitude:%#", #(self.latitude));
I want to display the distance between a user's current location and another annotation (displayed on my MapView) in a label on my custom table cell.
Each cell displays the name of a cafe (nameLabel), and underneath, I want it to display their distance away from each cafe (distanceLabel).
My MapViewController.m uses this code to calculate the distance between a user's current location and the closest cafes:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
for (MapViewAnnotation *annotation in self.mapView.annotations) {
CLLocationCoordinate2D coord = [annotation coordinate];
CLLocation *userLocation = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
annotation.distance = [newLocation distanceFromLocation:userLocation];
CLLocationDistance calculatedDistance = [userLocation distanceFromLocation:userLocation];
annotation.distance = calculatedDistance;
}
I've already set up my custom cell, I just want to know what I should put into my TableView code (TableViewController.m) in order to display the Calculated Distance inside of my text label (called distanceLabel).
E.g. how do I finish this line?
cell.distanceLabel.text =
UPDATE
Just tried adding the reference to my TableViewController.h, but xcode keeps throwing me the error "Redefinition of 'CLLocationDistance' as different kind of symbol".
#class CLLocationDistance;
#property (nonatomic, strong) CLLocationDistance *calculatedDistance;
UPDATE
.h file
****UPDATE**
**.m file****
Make a forward reference for CLLocationDistance calculatedDistance in fx. Your .h . CLLocationDistance is typedef as a double, a prmitive data type, so don't use a pointer in your forward reference (CLLocationDistance calulatedDistance; or #property CLLocationDistance calulatedDistance;). Then do the following:
cell.distanceLabel.text = [NSString stringWithFormat:#"%f", calculatedDistance];
So infact you dont have to create another/new double and assign it to calculatedDistance. Sorry for any confusion..:)
I'm developing a location based app and I'm using the following code (which works perfectly) to retrieve the location of the user. However, I would like to set a default value to the longitude and latitude in case the user turned off location services.
I tried self.latitude = 0; but the app crashes. latitude and longitude are variables of type float. Ideally I want to set them to a default value of (0,0).
So basically: how can I set a default value for a variable of type float?
Thanks for your help.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.latitude = newLocation.coordinate.latitude;
self.longitude = newLocation.coordinate.longitude;
SVGeocoder *geocodeRequest = [[SVGeocoder alloc] initWithCoordinate:newLocation.coordinate];
[geocodeRequest setDelegate:self];
[geocodeRequest startAsynchronous];
// NSLog(#"lat:%f,long:%f",self.latitude,self.longitude);
[self.locationMgr stopUpdatingLocation];
}
I'm trying to build an iOS app that displays the total distance travelled when running or walking. I've read and re-read all the documentation I can find, but I'm having trouble coming up with something that gives me an accurate total distance.
When compared with Nike+ GPS or RunKeeper, my app consistently reports a shorter distance. They'll report the same at first, but as I keep moving, the values of my app vs other running apps gradually drift.
For example, if I walk .3 kilometers (verified by my car's odometer), Nike+ GPS and RunKeeper both report ~.3 kilometers every time, but my app will report ~.13 kilometers. newLocation.horizontalAccuracy is consistently 5.0 or 10.0.
Here's the code I'm using. Am I missing something obvious? Any thoughts on how I could improve this to get a more accurate reading?
#define kDistanceCalculationInterval 10 // the interval (seconds) at which we calculate the user's distance
#define kNumLocationHistoriesToKeep 5 // the number of locations to store in history so that we can look back at them and determine which is most accurate
#define kValidLocationHistoryDeltaInterval 3 // the maximum valid age in seconds of a location stored in the location history
#define kMinLocationsNeededToUpdateDistance 3 // the number of locations needed in history before we will even update the current distance
#define kRequiredHorizontalAccuracy 40.0f // the required accuracy in meters for a location. anything above this number will be discarded
- (id)init {
if ((self = [super init])) {
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = 5; // specified in meters
}
self.locationHistory = [NSMutableArray arrayWithCapacity:kNumLocationHistoriesToKeep];
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// since the oldLocation might be from some previous use of core location, we need to make sure we're getting data from this run
if (oldLocation == nil) return;
BOOL isStaleLocation = [oldLocation.timestamp compare:self.startTimestamp] == NSOrderedAscending;
[self.delegate locationManagerDebugText:[NSString stringWithFormat:#"accuracy: %.2f", newLocation.horizontalAccuracy]];
if (!isStaleLocation && newLocation.horizontalAccuracy >= 0.0f && newLocation.horizontalAccuracy < kRequiredHorizontalAccuracy) {
[self.locationHistory addObject:newLocation];
if ([self.locationHistory count] > kNumLocationHistoriesToKeep) {
[self.locationHistory removeObjectAtIndex:0];
}
BOOL canUpdateDistance = NO;
if ([self.locationHistory count] >= kMinLocationsNeededToUpdateDistance) {
canUpdateDistance = YES;
}
if ([NSDate timeIntervalSinceReferenceDate] - self.lastDistanceCalculation > kDistanceCalculationInterval) {
self.lastDistanceCalculation = [NSDate timeIntervalSinceReferenceDate];
CLLocation *lastLocation = (self.lastRecordedLocation != nil) ? self.lastRecordedLocation : oldLocation;
CLLocation *bestLocation = nil;
CGFloat bestAccuracy = kRequiredHorizontalAccuracy;
for (CLLocation *location in self.locationHistory) {
if ([NSDate timeIntervalSinceReferenceDate] - [location.timestamp timeIntervalSinceReferenceDate] <= kValidLocationHistoryDeltaInterval) {
if (location.horizontalAccuracy < bestAccuracy && location != lastLocation) {
bestAccuracy = location.horizontalAccuracy;
bestLocation = location;
}
}
}
if (bestLocation == nil) bestLocation = newLocation;
CLLocationDistance distance = [bestLocation distanceFromLocation:lastLocation];
if (canUpdateDistance) self.totalDistance += distance;
self.lastRecordedLocation = bestLocation;
}
}
}
As it turns out, the code I posted above works great. The problem happened to be in a different part of my app. I was accidentally converting the distance from meters to miles, instead of from meters to kilometers. Oops!
Anyway, hopefully my post will still have some merit, since I feel it's a pretty solid example of how to track a user's distance with Core Location.
You probably have set kRequiredHorizontalAccuracy too low. If there is no location in the history that has accuracy < kRequiredHorizontalAccuracy, then you ignore all those points and add 0 to the distance.
I´m following the http://www.switchonthecode.com/tutorials/getting-your-location-in-an-iphone-application tutorial, but I can´t not get mi latitude and longitude in my Xcode SDK.
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
int degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lat = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
//latLabel.text = lat;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longt = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
NSLog(#"%# %#",longt, lat);
}
It don´t show me the latitude and longitude in the Console.
Help me please.
Your code looks fine. If it does not work - the issue is not here.
Make sure:
You running it on a device (not emulator)
Your device has SIM installed and connected to cellular network
It's very good idea to have the device connected to WiFi with Internet access.
All these things will help GPS to fix the position faster using assisted GPS.
Also, take into account that Core Location returns last known position almost immediately. It's stale and may be wrong, but provided immediately. If do not getting anything at all - it looks like the issue with Core Location on your device, not with the application.
Also, it's good idea to implement locationManager:didFailWithError: method to catch possible errors. Like disabled GPS.
Here is example for this method:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"GPS Error: %#", [error localizedDescription]);
}
GPS position fixing may take few minutes for 3Gs and early, and about 10 seconds for 4 and 4S (assuming clear sky view in both cases)