I need to calculate distance as the user moves in android. I have the starting point coordinates and can get the user's current location. How should I calculate distance.
I don't think I can call GoogleDistance Api as my application would be a real time application and calling this API would be extremely overhead or should calling GoogleDirectionsAPI would work fine.
Also I would like to test the distance travelled. How should I do it? Is there some way of sampling the data or do I really need to go out in the real world and actually travel and then test my application?
Edited: I want the distance travelled by the user and not the straight line distance between the points
I hope following will help:
In my app i started collecting lat longs after every 3fts (I set 3ft just for testing). I collected lat longs as follows:
Now I started calculating distance from point 1 to 2 and then 2 to 3 and then 3 to 4 and so on. After summing up I got total distance from 1 to 5.
I used following functions to calculate distance:
public double GetDistanceFromLatLonInKm(double lat1, double lon1, double lat2, double lon2)
{
final int R = 6371;
// Radius of the earth in km
double dLat = deg2rad(lat2 - lat1);
// deg2rad below
double dLon = deg2rad(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = R * c;
// Distance in km
return d;
}
private double deg2rad(double deg)
{
return deg * (Math.PI / 180);
}
This method is calculating exact distance for me.
You can calculate the distance between two point using the following function
double distanceBetweenTwoPoint(double srcLat, double srcLng, double desLat, double desLng) {
double earthRadius = 3958.75;
double dLat = Math.toRadians(desLat - srcLat);
double dLng = Math.toRadians(desLng - srcLng);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(srcLat))
* Math.cos(Math.toRadians(desLat)) * Math.sin(dLng / 2)
* Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double dist = earthRadius * c;
double meterConversion = 1609;
return (int) (dist * meterConversion);
}
For the second Part: To use mock or sample data you can use "Fake GPS" app from the play store, which will generate mock location in your device.
Happy Coding
There are basically three ways to check the traveled distance -
By using GPS, check the coordinate between two points using distanceTo of Location class.
Using Accelerometer , you can check the movement of device using Accelerometer.
Using Step detector - this is recently updated by Android.
Hope this helps you to achieve your goal :)
For the first question . You have origin coordinates and the present user location coordinates so what you can do is google api v3 library provides a method that takes origin LatLng and destination LatLng and gives the distance . Add api v3 jar to your android build path.
For the second one goto google maps and give the location details it is accurate..
Related
I want to create an app in which I want to show how much distance does the user has been traveled.
I have tried using float distance = locationA.distanceTo(locationB); but it just draws a simple straight line from start to end and then calculates the distance.
I want to calculate the traveled distance based on the traveled route. Is it possible to do so using any Google maps API?
you just need service to continuously observer that user change it's location then you can use these function to calculate the distance.
public double GetDistanceInKm(double lat1, double lon1, double lat2, double lon2)
{
final int R = 6371;
// Radius of the earth in km
double dLat = deg2rad(lat2 - lat1);
// deg2rad below
double dLon = deg2rad(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = R * c;
// Distance in km
return d;
}
private double deg2rad(double deg)
{
return deg * (Math.PI / 180);
}
Assuming you have a bunch of lat long points making up a route. You have to take the distance from the previous point to the next point for all points and keep a total of that. In other words you need a-lot of lat lon data in between the route or you are just going to get a straight line.
You can use google maps api to get the distance
use this link to understand how to use it.
I want to restrict map to specific distance as example 15 km from my current location to restrict user navigate to another locations.
I can calculate the distance between 2 points correctly based on the following function
public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 6371.0; // earth radius in km
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double sindLat = Math.sin(dLat / 2);
double sindLng = Math.sin(dLng / 2);
double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
* Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double dist = earthRadius * c;
return dist;
}
but cannot get possible latitude and longitude from my location in all sides based on specific distance because user can navigate in any side in map.
I tried this example but not give my accurate result.
Check this answer here:
https://stackoverflow.com/a/7478827/1397821
Now put all angles 0-360 in the equations mentioned in the above answer to get all the Lat Longs.
Hope this helps
I'm developing an application where user can set multiple locations. I get succeed to show notifications when user get Enter or Leave specific region using GeoFencing.
Now, there is situation that i need to provide monitoring for all saved locations and it can be hundreds and more. I've read at the given link "You can have multiple active geofences, with a limit of 100 per device user."
Is there any way add more then 100 geofences per device user ?
Thanks!
Have an ArrayList with all the geofences you want to monitor +100.
Listen to location updates.
When you get a location update, if the ArrayList of all your geofences is more than 100, remove all geofences been monitored and then calculate the 100 nearest geofences using the harvesine formula:
public static final double R = 6372.8; // In kilometers
public static double haversine(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return R * c;
}
That will give you the distance between the two locations. After that you could compare that distance with the geofence region radius to know if is inside the region.
Note: This distance will be in kilometers if your radius is on meters then just multiply the haversine method result with 1000 so that it's converted to meters.
Reference
Start monitoring the result list of the 100 nearest geofences.
This will allow you to always monitor the 100 nearest geofences based on your location. Been able to monitor more than 100 since it will change the monitoring geofence regions always to the 100 nearest geofence regions.
I have an android application with a map of google.
Can anybody tell me how we rotate the map according user current direction walking? I have read a lot of information but still a litle bit confused.
Thanks
You can calculate bearing by comparing two points. You said that your user will be walking so that shouldn't be too hard to get two points a distance apart from each other.
When you have the two points do some math like so
lon1 = degToRad(lon1);
lon2 = degToRad(lon2);
lat1 = degToRad(lat1);
lat2 = degToRad(lat2);
double a = Math.Sin(lon2 - lon1) * Math.Cos(lat2);
double b = Math.Cos(lat1) * Math.Sin(lat2) - Math.Sin(lat1) * Math.Cos(lat2) * Math.Cos(lon2 - lon1);
double c = radToDeg(Math.Atan2(a, b)); // c is our bearing //
These are our conversion functions
public static double degToRad(double deg){
return deg * Math.PI / 180.0;
}
public static double radToDeg(double rad){
rad = rad * (180.0 / Math.PI);
if (rad < 0) rad = 360.0 + rad;
return rad;
}
Once you have the bearing you can pass it to your map using the CameraUpdateFactory.
map.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(LatLng, zoom, tilt, bearing)));
in my app i am trying to calculate the distance a person traveling from one place to the other. For that i am using the Haversine formula,
R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
getting the latitude and longitude of starting place and reaching place i am calculating the distance in kms. But others say that this distance calculation works only if travelled by airways and get varies if user travels by roadways.
If it is so how can i get a correct distance while traveling through road ways.
please help me friends
This method is in standard API (Location.distanceBetween method))
http://developer.android.com/reference/android/location/Location.html
Use the following formula to find the distance between two lat-longs:
private double calculateDistance(double lat1, double lon1, double lat2, double lon2, String unit)
{
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
if (unit == "K") {
dist = dist * 1.609344;
} else if (unit == "M") {
dist = dist * 0.8684;
}
return (dist);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:: This function converts decimal degrees to radians :*/
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
private double deg2rad(double deg)
{
return (deg * Math.PI / 180.0);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:: This function converts radians to decimal degrees :*/
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
private double rad2deg(double rad)
{
return (rad * 180.0 / Math.PI);
}
Pass lat,longs with the function and unit in which you want distance ("K" for kilometer and "M" for Miles).
Hope this will help you.
Location.distanceBetween() will do this for two Latitude Longitude coordinate points.
When you travel by road (Even via air-travel too), bearing of the Earth comes into play since the Earth is not flat. but this Haversine formula should already take care of it. Secondly, what people might have been saying, is that, when you travel via road, you don't go just straight between two points. you take quite a number of turns. And to "precisely" tell the distance between two points, you might want to take those turns into consideration too.
i found the sample code in the following link to calculate the distance going through roads.
http://code.google.com/p/krvarma-android-samples/source/browse/#svn/trunk/GPSSample%253Fstate%253Dclosed
Its seems distance trough radways bigger, because trains and trucks moves not along straight line but airplances do.
You need road map to occurate compute distance