How to measure Elevation using GPS technology for iPhone SDK? - iphone

There are few apps like Strava which records users movements using GPS. It also measures the elevation of the road on which they travelled.
I would like to know how can we measure elevation of the road using iPhone SDK?
Please let me know.

Use the Google Elevation API
Example here
Then use a JSON parser to retrieve the values

CoreLocation is what you want to use (although it is generally quite inaccurate I've found)
first import the core location framework in the .h:
#import <CoreLocation/CoreLocation.h>
followed by in the .m:
- (void)locationUpdate:(CLLocation *)location {
altitudeLabel.text = [NSString stringWithFormat:#"Altitude - %f", [location altitude]];
}
This is given in height from sea level

Related

Getting the Co-ordinatades of middle point of Map - iPhone sdk

I am making iPhone application in which i am using UIMapKit. I have a static pointer (Arrow) in the middle of screen of iPhone and behind that Pointer i am using iOS maps in which user interaction is enable , means user can move the map can zoom in or zoom out the map.
My task is to get the longitude and latitude of that location which comes under my Screen Pointer(Arrow)
Can anyone help me how can i do achieve this. I have very good command on UIMap i just need a idea
You can get middle point of screen using :
CGPoint screenCenterPoint = self.view.center;
and then convert it to coordinates using :
CLLocationCoordinate2D mapCenterPoint = [self.view convertPoint:screenCenterPoint toCoordinateFromView:self.view];
If you use Google maps then you can use this ,too :
CLLocationCoordinate2D mapCenterPoint = [self.mapView.projection coordinateForPoint: screenCenterPoint];
To learn more look at GMSProjection and GMSMapView.
The necessary functionality is built in to MapView.
CLLocationCoordinate2D pinCoordinate = [self.pickupLocationView convertPoint:CGPointMake(self.pickupLocationView.frame.size.width / 2, self.pickupLocationView.frame.size.height) toCoordinateFromView:self.view];
This is UIKit as the poster requested. I believe Akash's solution would work if the question was about Google's map.

Getting Altitude(height from sea level) of my location in iphone SDK

I am trying to get Altitude of my location in my application. But every time I try altitude property of CLLocation object I am getting 0.00 as result.
I googled for my query and I got a similar question here and here. This link is saying that if I access CLLocation with wifi or cell tower it will be null. Even if I try to set desireAccuracy to best than even it don't make sure that app will use GPS. It is also saying that if I am indoor that I won't be able to access GPS.
I many cases it its not sure that app will use GPS only. I want some way for getting Altitude from wifi or cell tower too. For that I googled more and I got Google Earth API but I think this is for Microsoft .net technology only.
Now according to this situation I think for a solution I can create a web service in Microsoft Technology and pass my location there and I can get altitude as response but I don't want to do this.
Can anyone suggest me how to get my location's altitude from ios. Is there any way available or not? If yes than please navigate me in right direction.
Thanks in advance.
Edit1
I used CLLocationManager for updating location and when I get my location I need altitude.
Edit2
According to #fishinear's answer I tried following code:
- (void)viewDidLoad
{
[super viewDidLoad];
manager = [[CLLocationManager alloc] init];
[manager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[manager setDistanceFilter:kCLDistanceFilterNone];
[manager setDelegate:self];
[manager startUpdatingLocation];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if ([newLocation verticalAccuracy] >= 0) {
NSLog(#"Altitude = %lf",newLocation.altitude);
}
NSLog(#"Vertical Accuracy : %lf",newLocation.verticalAccuracy);
}
verticalAccuracy is always -1. It is not changing even after running the app to last 30 Mins. I am runnin ios 4.3.2 on my 3GS. I am indoor so I think it is not accessing GPS using this code even.
To answer your original question:
GPS will always be used if you set desiredAccuracy to Best or BestForNavigation, and distanceFilter to kCLDistanceFilterNone when configuring the CLLocationManager. You will then also get altitude values in the CLLocation event.
However, it takes a short while before the GPS has "locked in" to enough satelites to be able to report the altitude. During that time it will report CLLocation events without altitude values. Therefore, you should ignore the first couple of events until the verticalAccuracy value is good enough for you. Also, check the timestamp, because sometimes the first CLLocation event is an old one.
See Android - Get Altitude By Longitude and Latitude? there is an Android solution but it is easily adaptable to iOS.
The answer is to use the USGS Elevation Query Web Service
From the top answer there, basically you just send an HTML Web request to:
http://gisdata.usgs.gov/xmlwebservices2/elevation_service.asmx/getElevation?X_Value=" +
String.valueOf(longitude) +
"&Y_Value=" + String.valueOf(latitude)
+ "&Elevation_Units=METERS&Source_Layer=-1&Elevation_Only=true";
Then you can parse out the response text from between the <double>...</double> tags
Edit:
It looks like you might be trying to get elevation outside the United States.
Google Maps API does provide an Elevation service and documentation at https://developers.google.com/maps/documentation/javascript/elevation

iPhone:Road Direction Map view

I am showing a map view using MapKit framework in my iPhone application. I am also showing the particular friends list Pin point in map view based on the location they are. I would like to enhance now to showing the road map direction from my location to a particular selected friend location. I know the lat and long for both source and destination, but i have draw route line in road direction, it should be road direction. Could someone help me on this?
Thank you!
MapKit does not expose a means of performing driving directions. So, it's not as simple as asking the map to display a course from location A to location B. You have two options:
1) Integrate with Google's API to get the driving directions, and overlay your own lines onto the MapKit map.
or
2) Simply direct your users out of app and delegate this functionality to the built in Map app.
I have no experience with the former, but the later is very easy. Simply:
CLLocationCoordinate2D location = [[map userLocation] location].coordinate;
double currentLat = location.latitude;
double currentLong = location.longitude;
NSString *googleUrl = [[NSString alloc] initWithFormat:#"http://maps.google.com/maps?saddr=%f,%f&daddr=%f,%f", currentLat, currentLong, item.latitude, item.longitude];
NSLog(#"%#", googleUrl);
[[UIApplication sharedApplication] openURL:[[NSURL alloc] initWithString:googleUrl]];
Actually there is no api supported by iPhone sdk to draw route on map. There a repo on github which is using google maps api to draw route on map by using map overlay. It has some limitation but you can take help from this repo - https://github.com/kishikawakatsumi/MapKit-Route-Directions

Compass True Heading in iPhone/iPad

I having some problem on the iPhone/iPad compass development.
The trueHeading taken from the CLHeading alway give me the '-1' value, I'm stuck here. Here is my code:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
self.locationManager.headingFilter = 0.5; //1 degrees
[self.locationManager startUpdatingHeading];
I also found out something, that is when I on the map app or the compass app which has use the location stuff, the trueHeading value suddenly read correct. I wonder what is the cause, any idea? It happen on both iPhone4 and on the iPad.
It also happen whenever I off the Location Services in settings and re-enable it, it will become unable to read the correct trueHeading value, i wonder because the location services cannot be enable by the app I creating?
anyway, thank in advance
---My Solution---
see below.
to avoid the heading keep returning -1.000000, not JUST run startUpdatingHeading but run startUpdatingLocation together, this helps.
Try using this...
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
// Start heading updates.
if (locationManager.headingAvailable && locationManager.locationServicesEnabled)
{
locationManager.headingFilter = kCLHeadingFilterNone;
[locationManager startUpdatingHeading];
}
and after doing this CLLocationManager delegate methods calls
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
// Use the true heading if it is valid.
[lblAccuracy setText:[NSString stringWithFormat:#"%.1fmi",newHeading.headingAccuracy]];
}
But this coding works on device not in simulator...
Happy coding..
---My Solution---
What I did was, add in the [self.locationManager startUpdatingLocation] to before or after the [self.locationManager startUpdatingHeading]; (when Location Services is off & re-enable from the Settings). I'm not sure this is a good solution, but this is what I did to make it work, if you have any better solution please share.
I had some trouble with the location manager myself and found out that for me it helped to unplug the iPhone from the computer when testing. Somehow the calibration alert only popped up after unplugging the iPhone.
I had this same problem. I moved startUpdatingHeading into a button action, then moved it back to where the CLLocationManager is allocated -- where it had been working fine -- and it started returning only -1.
I rebooted my iPad and it started working again. Hopefully it stays that way.
Edit: Nope, it didn't stay that way. I had to use startUpdatingLocation too. Won't this wear down the battery though? I set desiredAccuracy to kCLLocationAccuracyThreeKilometers, because I am not using location data anyway.
A TRUE reading requires knowing the magnetic variation for the place where you are using the compass. From the previous discussion, it appears to be that the function that corrects the true direction from magnetic direction needs your location for obtaining the variation value. If you don't like to use the location GPS information in your code, I suggest reading the magnetic reading and correct the value by yourself. You need to obtain the variation for the desired location first then apply the following formula: T=M ± V, where T is the true direction, M is the compass magnetic reading and V is the variation. Use "+" for East and "-" for West. I found the allowing web site provide the variation(magnetic declination) for any needed location: http://www.geomag.nrcan.gc.ca/calc/mdcal-eng.php.
When location services are off, the didUpdateHeading delegate method returns only the magnetic heading. You can use it according to your needs. According to Apple docs..
To begin the delivery of heading-related events, assign a delegate to
the location manager object and call its startUpdatingHeading method.
If location updates are also enabled, the location manager returns
both the true heading and magnetic heading values. If location updates
are not enabled, the location manager returns only the magnetic
heading value.
Working on this problem now. I can get updates from Core Motion when I use SpriteKit. It's about being able to call a function continuously like once a frame (1/60th of a second) or every few frames. Without using SpriteKit, the documentation says to invoke the updates within a closure, which I assume will be on their own thread and up to you to release.
There's an algorithm for converting the magnetometer readings to actual degrees relative to true north. Picture a graph that looks like the time domain function of alternating current and you'll see that interpolating the data is a simple matter of applying Maxwell's equations. Here's an example on honeywell

How to find the car speed on iPhone?

I want to find the car speed on my iPhone when driving so what should I use and how?
Core Motion or Core Location? Is there any documentation or sample code?
Hey - You'll want core location for this.
There is a really good tutorial here - http://www.vellios.com/2010/08/16/core-location-gps-tutorial/ that I followed once. There is a whole series but this one shows you how to calculate the position and speed of your device. There is a sample project to download too. Hope this helps!
CoreMotion would not help you much, because it is an abstraction of the device's accelerometer and the gyroscope. You could measure acceleration and deceleration and computing the speed from basic physics, but I would not do so.
I would use the CoreLocation frameworkd and rely on GPS positioning. There is a ton of sample code out there and a WWDC10 video as well, so go ahead and look it up.
Use CLLocationManager and speed property in CLLocation class
- (void) locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation{
NSLog("[Location Updated] \n Speed: %.2fm/s (%.1fkm/h)", newLocation.speed, newLocation.speed*3600/1000);
}