Trying to create a running gps in android, using this code to calculate the distance between two points every second (at least that's what I think it's doing):
gps = new GPSTracker(AndroidGPSTrackingActivity.this);
// check if GPS enabled
if (gps.canGetLocation()) {
final Handler h = new Handler();
final int delay = 1000; //milliseconds
h.postDelayed(new Runnable() {
public void run() {
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Location locationA = new Location("point A");
final Location locationB = new Location("point B");
locationA.setLatitude(latitude);
locationA.setLongitude(longitude);
Timer t = new Timer();
h.postDelayed(new Runnable() {
public void run() {
double latitude1 = gps.getLatitude();
double longitude2 = gps.getLongitude();
locationB.setLatitude(latitude1);
locationB.setLongitude(longitude2);
}
}, delay);
float distance = locationA.distanceTo(locationB);
finalDistance[0] = (finalDistance[0] + distance);
displayDistance.setText(String.valueOf(finalDistance[0]));
h.postDelayed(this, delay);
}
}, delay);
The distance changes more or less by the same increment whether I'm walking or not walking.
The distance I get is also a weird value, e.g.: 6.47875890357E9
My questions: 1)What unit is this distance in?
2)Am I getting some random gobbledigook because of crap programming skills?
1) The units are meters (see distanceTo()).
2) Yes. But like all programmers, you're still learning, so to be more helpful I won't just leave it there! The reason you are getting a huge distance is because your code is getting the distance between locationA and locationB, and you haven't set locationB at the time you execute the line:
float distance = locationA.distanceTo(locationB);
So you're getting the distance between locationA and lat/long 0,0.
You're only setting the latitude and longitude of locationB in your Runnable which will be executed after distance has been set. So, you probably need to move your distance calculation and the code that outputs it to within your Runnable that sets the latitude and longitude for locationB. You'll also have to make locationA final to do that.
Related
I am trying to calculate the distance between your current location and three markers.
Everything is working fine, but if I change my position the distance is equal to the distance before, I dont get the new coordinates. Here is my code:
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location current = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));
latng = String.valueOf(current.getLatitude());
lngon = String.valueOf(current.getLongitude());
Location club = new Location("clubloc");
club.setLatitude(Double.parseDouble(marker_data.get("lat")));
club.setLongitude(Double.parseDouble(marker_data.get("lng")));
double distance = current.distanceTo(club);
distance = distance / 1000;
distance = Math.round(distance * 100);
distance = distance / 100;
TextView dis = (TextView) findViewById(R.id.distance);
dis.setText(String.valueOf(distance) + "KM");
}
So my question is how can I update my coordinates so I always get the right distance?
You are always getting the last known location of the user (using getLastKnownLocation). You are not actively asking for location updates. You can read more about this here.
I am just trying to figure out what can I do to ensure I get precise GPS Coordinates from the mobile device. When I add the distances together, I get a crazy reading that I have gone 8m when the phone has not moved from my table. I do not know if it is because of the way I have set up my LocationRequest. I was reading on google something about GPS coordinates being 68% accurate, and some readings may fall out of the 68%... perhaps I should do something to remove the inaccurate readings??
Here is the location request I have created, so I can receive the location updates:
private void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(2000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//Some other code below which checks location settings
}
This is my onLocationChanged... this is where I get updates of the new location, and then calculate the distance between the two points:
#Override
public void onLocationChanged(Location location) {
//For the first location update, we will assume this is the starting point
if (currentLocation == null) {
currentLocation = location;
}
float distance = 0L;
double height = 0;
double speed = 0;
height = location.getAltitude();
if (runStarted && !runPaused) {
locationsList.add(location); //This adds the current location to the list
runnerLocations.add(location); //This adds the current route the runner is running (without pauses)
} else {
locationsList.add(location);
}
//Calculate the distance from the last recorded gps point
if (currentLocation != null && runStarted && !runPaused){
distance = currentLocation.distanceTo(location);
}
currentLocation = location;
//move the map view to the user's current location, regardless of their running state (paused or run)
mapObject.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 18));
if (runStarted && !runPaused) {
if (location.getSpeed() > 0) {
speed = location.getSpeed() * 3.6;// convert m/sec to km/h
}
DecimalFormat format = new DecimalFormat("###.##");
speed = Double.valueOf(format.format(speed));
recordedSpeeds.add(speed);
totalDistance = totalDistance + distance;
updateUI(speed, location, distance);
if (height > 0) {
height = Double.valueOf(format.format(height));
}
calculateCurrentCaloriesBurnt(height, speed);
}
}
I was thinking of calculating the distances manually, with some formula. What else can I try, to get accurate distance calculations?
In my Android application I am trying to calculate the distance between two locations but the values I am getting is in tens of Millions 11Million+. The actual distance between the two point/location is just 1.1km - 1.3Km. Why is this so? Even if the value the .distanceTo method returns is in meters 11M meters is still a very big value.
Here is my code:
Location locationA = new Location("LocationA");
locationA.setLatitude(lat);
locationA.setLongitude(lang);
Location locationB = new Location("LocationB");
locationB.setLatitude(14.575224);
locationB.setLongitude(121.042475);
float distance = locationA.distanceTo(locationB);
BigDecimal _bdDistance;
_bdDistance = round(distance,2);
String _strDistance = _bdDistance.toString();
Toast.makeText(this, "distance between two locations = "+_strDistance, Toast.LENGTH_SHORT).show();
public static BigDecimal round(float d, int decimalPlace) {
BigDecimal bd = new BigDecimal(Float.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd;
}
Your approximation is right. It returns the distance in meters.
You can convert it to KM by dividing it by 1000 like so;
float distance = locationA.distanceTo(locationB)/1000;
Read more about distanceTo here.
here in my screenshot you can see, if we take location from double latitude, longitude i.e. 6 digit after decimal but actually Location hold latitude value till 8 digits. The main difference is here. So don't use double for storing latitude, longitude. Try to use anotherway
I am developing an Android application.
I am getting a list of latitudes and longitudes from the server.
I have to arrange those values based on my location. I mean the nearest latitude/longitude first and then the next one etc.
I have my latitude and longitude and the list of latitude and longitudes. How can I find the nearest one?
This might not be the best way but it works :)
public static final double PI = 3.14159265;
public static final double deg2radians = PI/180.0;
public static final double miles = 0.000621371192;
public static final double kms = 0.001;
public static double getDistance(double latitude1, double longitude1, double latitude2,double longitude2) {
double distance;
Location locationA = new Location("point A");
locationA.setLatitude(latitude1);
locationA.setLongitude(longitude1);
Location locationB = new Location("point B");
locationB.setLatitude(latitude2);
locationB.setLongitude(longitude2);
distance = locationA.distanceTo(locationB);
double radd = distance * kms;
return radd;
}
pseudo code :
location.distanceTo(locFromServer);
and for the sorting
Colection.sort(listOfLocations;new Comparator(){
compareTo(){
// location.distanceTo(locFromServer)
}
}
You can simply calculate the distances of the user's position to the downloaded locations, and select the smallest one.
Have a look here: Quicker way to calculate geographic distance between two points.
I have trouble with the tracking of a driven distance.
I tried it like in this article: Source-Code is completely also there
The SUM of the driven distance is not the real driven distance that is displayed in my car.
After 2-3 km, I have a difference between my displayed distance in my car and the app of 200-800 meters. In this short distance :o)
What I also recognized is that the distance, e.g. while driving curves, is decrementing.
I have also tried several values for minTime and minDistance for the listener, but no success.
What I am doing wrong?
When I use the "MyTracks" app, the driven distance is caculated really, really fine and correct.
I only need a way to sum the completely driven way from start to end, without displaying it in google maps. Is this really so complicated?
kind regards
Frank
OK, the interesting part of the code:
public void startListening(final Activity activity)
{
if (locationManager == null)
{
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
}
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
final String bestProvider = locationManager.getBestProvider(criteria, true);
if (bestProvider != null && bestProvider.length() > 0)
{
locationManager.requestLocationUpdates(bestProvider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
else
{
final List<String> providers = locationManager.getProviders(true);
for (final String provider : providers)
{
locationManager.requestLocationUpdates(provider, GPSManager.gpsMinTime,
GPSManager.gpsMinDistance, locationListener);
}
}
}
and:
private double calcGeoDistance(final double lat1, final double lon1, final double lat2, final double lon2)
{
double distance = 0.0;
try
{
final float[] results = new float[3];
Location.distanceBetween(lat1, lon1, lat2, lon2, results);
distance = results[0];
}
catch (final Exception ex)
{
distance = 0.0;
}
return distance;
}
and:
private void updateMeasurement(){
double distance = calcGeoDistance(startLat,startLon,currentLat,currentLon) * multipliers[unitindex];
String distanceText = "" + RoundDecimal(distance,2) + " " + unitstrings[unitindex];
((TextView)findViewById(R.id.distance)).setText(distanceText);
}
and:
public double RoundDecimal(double value, int decimalPlace)
{
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(decimalPlace, 6);
return bd.doubleValue();
}
Ohhh, and as I am writing this down it seems that the distance is caculated between the start point and the current point. Not between the last two measurements with the sum of all values, right?
With the Criteria that you specify, you're likely to get innacurate locations. Increase the power requirement. Also, pay attention to the name of the provider being returned. If you want accuracy, then you're going to want the GPS provider.
See the following link for more information:
I keep getting an inaccurate location in Android