iPhone: calculate distance while walking using GPS - iphone

I want to calculate the distance that users cover while walking using GPS. For example a user taps the start button and starts to walk or run than when he done he taps stop. What will be the minimum distance user has to travel to get the different lat long?
How can we do it in IPhone, asume we take Lat, long after every 0.3 sec than in the last we have a list of points?

You could do this by calculating the distance between 2 points (latitude, longitude):
(I haven't tested it):
-(double)distanceBetweenCoordinate:(CLLocationCoordinate2D)c1 andCoordinate:(CLLocationCoordinate2D)c2 {
double long1 = degreesToRadians(c1.longitude);
double lat1 = degreesToRadians(90 - c1.latitude);
double long2 = degreesToRadians(c2.longitude);
double lat2 = degreesToRadians(90 - c2.latitude);
double gamma = fabs(long1 - long2);
if (gamma > M_PI) {
gamma = 2 * M_PI - gamma;
}
double result = cos(lat2) * cos(lat1) + sin(lat2) * sin(lat1) * cos(gamma);
return acos(result) * 6366.1977; // Kilometers
};
CGFloat degreesToRadians(CGFloat degrees) {
return degrees * M_PI / 180;
};
UPDATE: Use distanceFromLocation - Calculate distance between two points instead

Related

User is Inside or not Geofense Flutter

i am creating flutter attendance app where i want to check when user is marking attendance he/she is available in office area or not? if not show them how much distance they are away from radius.
i tried using this but not getting the appropriate result. i want to check 200m radius from lat long.
double geDistance(double lat1, double lon1, double lat2, double lon2) {
double theta = lon1 - lon2;
double dist = sin(toRadians(lat1)) * sin(toRadians(lat2)) +
cos(toRadians(lat1)) * cos(toRadians(lat2)) * cos(toRadians(theta));
dist = acos(dist);
dist = toDegrees(dist);
dist = dist * 60 * 1.1515;
dist = dist * 1000 * 1.609344;
///dist in meter
return dist;
}
double toRadians(double degree) {
return degree * pi / 180;
}
double toDegrees(double radian) {
return radian * 180 / pi;
}
i know geofense can resolve accurately this but i have no idea which method can help me to check user location is inside radius or not.

What is the size limit of the gameobjects?

I am building an AR application with unity and Mapbox. I have a point to represents a building. I can geolocate the point through Mapbox. I want to see this object everywhere. So, I change the size of objects according to distance.
Firstly, the code is working. But, I could not see the point really far away, 5 km away.
// Update is called once per frame
void Update()
{
// Get user location
// Latitude
x = getLocation.x1.ToString();
user_lat = Convert.ToDouble(x);
user_lat_rad = Math.PI * user_lat / 180.0; // Radian
// Longitude
y = getLocation.y1.ToString();
user_lon = Convert.ToDouble(y);
user_lon_rad = Math.PI * user_lon / 180.0; // Radian
// Change POIs sizes
distances = distance(user_lat_rad, user_lon_rad);
double s = 0.3; // size of the poi
double d = 50f; // specific distance to point (reference distance)
double size = (distances * s) / d;
float size2 = Convert.ToSingle(size);
temp = transform.localScale;
temp.x = size2;
temp.y = size2;
temp.z = size2;
transform.localScale = temp;
}
public double distance(double lat2, double lon2)
{
// Haversine Formula
// Lat2,Lon2 = User Location
// Lat1,Lon1 = POI Location
double dist1 = Sqrt((Pow(Sin((lat2 - lat1) / 2), 2)) + Cos(lat2) * Cos(lat2) * (Pow(Sin((lon2 - lon1) / 2), 2)));
double distance = 2 * r * Asin(dist1);
return distance;
}
Why I couldn't see the point far away even though object size is change? Is there any limitation for this?
As said in the comments the issue most probably is a too small value for the Camera's farClipPlane.
The furthest point relative to the camera that drawing will occur.
Any object/triangle that is further away from the Camera will not be rendered.
In the Inspector it is configured on the Camera component → Clipping Planes → Far
or using code
cameraReference.farClipPlane = XYZ;

Latitude / Longitude Distance Calculation

A quick question about a Lat / Long calculation.
I want to take a value set e.g. Lat: 55.123456 Long -6.123456 and work out the four points that are an arbitrary distance away.
As the given square, I want to work out the value for Latitude on the left and right side. Thus the red lines are 1.5km from the start point. Likewise for the longitude, the blue lines will be 1.5km from the start point. The output will be 4 points, all distances in kilometres.
In short: Latitude + Y = Latitude Value X kilometers away
Working with iPhone at the moment and its for a very rough database calculation.
EDIT: Just to clarify, the distance is so short that curvature (And hence accuracy) is not an issue.
In OBJ-C this should be a decent solution:
float r_earth = 6378 * 1000; //Work in meters for everything
float dy = 3000; //A point 3km away
float dx = 3000; //A point 3km away
float new_latitude = latitude + (dy / r_earth) * (180 / M_PI);
float new_longitude = longitude + (dx / r_earth) * (180 / M_PI) / cos(latitude * 180/M_PI);
Well, for rough calculation with relatively small distances (less than 100km) you may assume that there is 40_000_000/360=111 111 meters per degree of latitude and 111 111*cos(latitude) meters per degree of longitude. This is because a meter was defined as 1/40_000_000 part of the Paris meridian;).
Otherwise you should use great circle distances, as noted in the comments. For high precision you also need to take into account that Earth is slightly oblate spheroid rather than a sphere.
// parameter: offset in meters
float offsetM = 1500; // 1.5km
// degrees / earth circumfence
float degreesPerMeter = 360.0 / 40 000 000;
float toRad = 180 / M_PI;
float latOffsetMeters = offsetM * degreesPerMeter;
float lonOffsetMeters = offsetM * degreesPerMeter * cos (centerLatitude * toRad);
Now simply add +/- latOffsetMeters and +/- lonOffsetMeters to your centerLatitude/ centerLongitude.
Formula is usefull up to hundred kilometers.

iPhone Compass GPS Direction [duplicate]

I'm trying to develop an application that use the GPS and Compass of the iPhone in order to point some sort of pointer to a specific location (like the compass always point to the North). The location is fixed and I always need the pointer to point to that specific location no matter where the user is located. I have the Lat/Long coordinates of this location but not sure how can I point to that location using the Compass and the GPS... just like http://www.youtube.com/watch?v=iC0Xn8hY80w this link 1:20'
I write some code, however, it can't rotate right direction.
-(float) angleToRadians:(double) a {
return ((a/180)*M_PI);
}
-(void)updateArrow {
double alon=[longi doubleValue];//source
double alat=[lati doubleValue];//source
double blon=[pointlongi doubleValue];//destination
double blat=[pointlati doubleValue];//destination
float fLat = [self angleToRadians:alat];
float fLng = [self angleToRadians:alon];
float tLat = [self angleToRadians:blat];
float tLng = [self angleToRadians:blon];
float temp = atan2(sin(tLng-fLng)*cos(tLat),
cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng));
double temp2= previousHeading;
double temp1=temp-[self angleToRadians:temp2];
/*I using this,but it can't rotate by :point even i change the coordinate
in CGPointMake */
Compass2.layer.anchorPoint=CGPointMake(0, 0.5);
[Compass2 setTransform:CGAffineTransformMakeRotation(temp1)];
/* Compass2 is a UIImageView like below picture I want to rotate it around
: point in image
^
|
|
|
:
|
*/
There is a standard "heading" or "bearing" equation that you can use - if you are at lat1,lon1, and the point you are interested in is at lat2,lon2, then the equation is:
heading = atan2( sin(lon2-lon1)*cos(lat2), cos(lat1)*sin(lat2) - sin(lat1)*cos(lat2)*cos(lon2-lon1))
This gives you a bearing in radians, which you can convert to degrees by multiplying by 180/π. The value is then between -180 and 180 degrees, so to get a standard compass bearing add 360 to any negative answers.
atan2 is a standard function related to arctan, that does the right thing for the four possible quadrants that your destination point could be in compared to where you are.
1) Get your current location (from the GPS)
2) Get the differences in latitude and longitude
3) use the atan2 method to get the angle
i.e. (WARNING: untested code)
CLLocation *targetLocation = [CLLocation alloc] initWithLatitude:1 longitude:2];
CLLocation *sourceLocation = <get from GPS>
double dx = [targetLocation coordinate].latitude - [sourceLocation coordinate].latitude;
double dy = [targetLocation coordinate].longitude - [sourceLocation coordinate].longitude;
double angle = atan2(dx, dy);
You might have to tweak that to get it to compile but the idea is there!
I did this some time ago, here are two different implementations. The first is similar to your approach, the second is without the trig math. The first is what I used in my app, but the second seemed to work as well, though doesn't appear to be as clean. You will need to also remember to offset this bearing based on north in your UI.
- (double) toRadian: (double) val
{
return val * (M_PI / 180);
}
// Convert to degrees from radians
- (double) toDegrees: (double) val
{
return val * 180 / M_PI;
}
// convert from a radian to a 360 degree format.
- (double) toBearing: (double) val
{
return ( (int)([self toDegrees: val]) + 360 ) % 360; // use mod to get the degrees
}
// Calculate the bearing based off of the passed coordinates and destination.
//
- (double) calcBearingWithLatitude:(CLLocationDegrees)latSource
latitude:(CLLocationDegrees)latDest
longitude:(CLLocationDegrees)lonSrc
longitude:(CLLocationDegrees)lonDest
{
double lat1 = [self toRadian:latSource];
double lat2 = [self toRadian:latDest];
double dLon = [self toRadian:(lonDest - lonSrc)];
double y = sin(dLon) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
return [self toBearing:atan2(y, x)];
}
And the second.
// got this code from some forums and modified it, thanks for posting it coullis! Mostly here for reference on how to do this without sin and cos.
- (CLLocationDegrees) altCalcBearingWithLatitude:(CLLocationDegrees)latSource
latitude:(CLLocationDegrees)latDest
longitude:(CLLocationDegrees)lonSrc
longitude:(CLLocationDegrees)lonDest
{
CLLocationDegrees result;
// First You calculate Delta distances.
float dx = lonSrc - latSource;
float dy = lonDest - latDest;
// If x part is 0 we could get into division by zero problems, but in that case result can only be 90 or 270:
if (dx==0)
{
if (dy > 0)
result = 90;
else
result = 270;
}
else
{
result = [self toDegrees: atan(dy/dx)];
}
// This is only valid for two quadrants (for right side of the coordinate system) so modify result if necessary...
if (dx < 0)
result = result + 180;
// looks better if all numbers are positive (0 to 360 range)
if (result < 0)
result = result + 360;
// return our result.
return result;
}
Use this. You will have to subtract out your actual compass heading from the result of getHeadingForDirection to determine the proper relative heading. Return value is heading in radians.
-(float) angleToRadians:(float) a {
return ((a/180)*M_PI);
}
- (float) getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc
{
float fLat = [self angleToRadians:fromLoc.latitude];
float fLng = [self angleToRadians:fromLoc.longitude];
float tLat = [self angleToRadians:toLoc.latitude];
float tLng = [self angleToRadians:toLoc.longitude];
return atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng));
}

iPhone SDK Point to a specific location [duplicate]

I'm trying to develop an application that use the GPS and Compass of the iPhone in order to point some sort of pointer to a specific location (like the compass always point to the North). The location is fixed and I always need the pointer to point to that specific location no matter where the user is located. I have the Lat/Long coordinates of this location but not sure how can I point to that location using the Compass and the GPS... just like http://www.youtube.com/watch?v=iC0Xn8hY80w this link 1:20'
I write some code, however, it can't rotate right direction.
-(float) angleToRadians:(double) a {
return ((a/180)*M_PI);
}
-(void)updateArrow {
double alon=[longi doubleValue];//source
double alat=[lati doubleValue];//source
double blon=[pointlongi doubleValue];//destination
double blat=[pointlati doubleValue];//destination
float fLat = [self angleToRadians:alat];
float fLng = [self angleToRadians:alon];
float tLat = [self angleToRadians:blat];
float tLng = [self angleToRadians:blon];
float temp = atan2(sin(tLng-fLng)*cos(tLat),
cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng));
double temp2= previousHeading;
double temp1=temp-[self angleToRadians:temp2];
/*I using this,but it can't rotate by :point even i change the coordinate
in CGPointMake */
Compass2.layer.anchorPoint=CGPointMake(0, 0.5);
[Compass2 setTransform:CGAffineTransformMakeRotation(temp1)];
/* Compass2 is a UIImageView like below picture I want to rotate it around
: point in image
^
|
|
|
:
|
*/
There is a standard "heading" or "bearing" equation that you can use - if you are at lat1,lon1, and the point you are interested in is at lat2,lon2, then the equation is:
heading = atan2( sin(lon2-lon1)*cos(lat2), cos(lat1)*sin(lat2) - sin(lat1)*cos(lat2)*cos(lon2-lon1))
This gives you a bearing in radians, which you can convert to degrees by multiplying by 180/π. The value is then between -180 and 180 degrees, so to get a standard compass bearing add 360 to any negative answers.
atan2 is a standard function related to arctan, that does the right thing for the four possible quadrants that your destination point could be in compared to where you are.
1) Get your current location (from the GPS)
2) Get the differences in latitude and longitude
3) use the atan2 method to get the angle
i.e. (WARNING: untested code)
CLLocation *targetLocation = [CLLocation alloc] initWithLatitude:1 longitude:2];
CLLocation *sourceLocation = <get from GPS>
double dx = [targetLocation coordinate].latitude - [sourceLocation coordinate].latitude;
double dy = [targetLocation coordinate].longitude - [sourceLocation coordinate].longitude;
double angle = atan2(dx, dy);
You might have to tweak that to get it to compile but the idea is there!
I did this some time ago, here are two different implementations. The first is similar to your approach, the second is without the trig math. The first is what I used in my app, but the second seemed to work as well, though doesn't appear to be as clean. You will need to also remember to offset this bearing based on north in your UI.
- (double) toRadian: (double) val
{
return val * (M_PI / 180);
}
// Convert to degrees from radians
- (double) toDegrees: (double) val
{
return val * 180 / M_PI;
}
// convert from a radian to a 360 degree format.
- (double) toBearing: (double) val
{
return ( (int)([self toDegrees: val]) + 360 ) % 360; // use mod to get the degrees
}
// Calculate the bearing based off of the passed coordinates and destination.
//
- (double) calcBearingWithLatitude:(CLLocationDegrees)latSource
latitude:(CLLocationDegrees)latDest
longitude:(CLLocationDegrees)lonSrc
longitude:(CLLocationDegrees)lonDest
{
double lat1 = [self toRadian:latSource];
double lat2 = [self toRadian:latDest];
double dLon = [self toRadian:(lonDest - lonSrc)];
double y = sin(dLon) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
return [self toBearing:atan2(y, x)];
}
And the second.
// got this code from some forums and modified it, thanks for posting it coullis! Mostly here for reference on how to do this without sin and cos.
- (CLLocationDegrees) altCalcBearingWithLatitude:(CLLocationDegrees)latSource
latitude:(CLLocationDegrees)latDest
longitude:(CLLocationDegrees)lonSrc
longitude:(CLLocationDegrees)lonDest
{
CLLocationDegrees result;
// First You calculate Delta distances.
float dx = lonSrc - latSource;
float dy = lonDest - latDest;
// If x part is 0 we could get into division by zero problems, but in that case result can only be 90 or 270:
if (dx==0)
{
if (dy > 0)
result = 90;
else
result = 270;
}
else
{
result = [self toDegrees: atan(dy/dx)];
}
// This is only valid for two quadrants (for right side of the coordinate system) so modify result if necessary...
if (dx < 0)
result = result + 180;
// looks better if all numbers are positive (0 to 360 range)
if (result < 0)
result = result + 360;
// return our result.
return result;
}
Use this. You will have to subtract out your actual compass heading from the result of getHeadingForDirection to determine the proper relative heading. Return value is heading in radians.
-(float) angleToRadians:(float) a {
return ((a/180)*M_PI);
}
- (float) getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc
{
float fLat = [self angleToRadians:fromLoc.latitude];
float fLng = [self angleToRadians:fromLoc.longitude];
float tLat = [self angleToRadians:toLoc.latitude];
float tLng = [self angleToRadians:toLoc.longitude];
return atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng));
}