DISABLE ADBLOCK

ADBlock is blocking some content on the site

ADBlock errore

DistanceTo() doesn't give me stable measurements

StackOverflow https://stackoverflow.com/questions/20301765
 Checked

Question

I am working on an android app that fetch user's Location and calculate the distance between him and another location.

The problem is that DistanceTo function give me different measurements each time I pressed the button although that I don't move the device.

Sometimes it gives me perfect measurement (give me 18 M) and sometimes it gives me too bad measurements(53 M) while the real distance 15 M ! Hint : I need very accurate measurements accuracy < 4M

this is the code of get the location

LM = (LocationManager) getApplicationContext().getSystemService(
            LOCATION_SERVICE);

    Criteria criteria = new Criteria();
    provider = LM.getBestProvider(criteria, false);
    try {

        LM.requestLocationUpdates(provider, 100000, 1, this);

        if (LM != null) {
            Loc = LM.getLastKnownLocation(provider);
            LM.removeUpdates(this);
            if (Loc != null) {
                   //set the location

            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

and the code of claculate the distance is so easy Location1.distanceTo(Location2);

No correct solution

OTHER TIPS

I have the exact same problem. In my app, I get the current location from any provider and then compute distances from a set of LatLng. This is done in a timer loop of 10 seconds.

lat01, lng01, lat02 and lng02 are fixed and I have verified that they don't change. However in each timer loop, I get different values.

                            grep "in for" mymap.log  | sort | uniq 
                                in for loop dist 18.917835 <lat01> <lng01> <lat02> <lng02>
                                in for loop dist 324.48648 <lat01> <lng01> <lat02> <lng02>
                                in for loop dist 325.92554 <lat01> <lng01> <lat02> <lng02>

The logic is like this:

                    if(testtimer==null)
                    {
                        testtimer = new Timer();
                        testtimer.scheduleAtFixedRate(new TimerTask() {
                            @Override
                            public void run() {
                                Location loc1 = new Location("test");
                                loc1.setLatitude(lat01);
                                loc1.setLatitude(lng01);

                                Location loc2 = new Location("test");
                                loc2.setLatitude(lat02);
                                loc2.setLatitude(lng02);

                                for(int i=0;i<30;i++)
                                {
                                    log_write("distance loc1 to loc2 "+loc1.distanceTo(loc2));
                                }

                            }
                        },1000,10000);
                    }

Update/Fix: Stop using google's Location.distancebetween & location.distanceto functions. They don't work.

Instead use the direct formula to calculate the distance:

double distance_between(Location l1, Location l2)
{
    //float results[] = new float[1];
    /* Doesn't work. returns inconsistent results
    Location.distanceBetween(
            l1.getLatitude(),
            l1.getLongitude(),
            l2.getLatitude(),
            l2.getLongitude(),
            results);
            */
    double lat1=l1.getLatitude();
    double lon1=l1.getLongitude();
    double lat2=l2.getLatitude();
    double lon2=l2.getLongitude();
    double R = 6371; // km
    double dLat = (lat2-lat1)*Math.PI/180;
    double dLon = (lon2-lon1)*Math.PI/180;
    lat1 = lat1*Math.PI/180;
    lat2 = lat2*Math.PI/180;

    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.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double d = R * c * 1000;

    log_write("dist betn "+
            d + " " +
            l1.getLatitude()+ " " +
            l1.getLongitude() + " " +
            l2.getLatitude() + " " +
            l2.getLongitude()
            );

    return d;
}

The distanceTo function works, but your app has no filter to detect the situation when you are not moving. Some smartphones like iphones have built in to deliver a GPS position only when moving. What you are see is, so called static movement.

(Nearly all GPS reciver can be optionally be configured to supress the delivery of differnet positions while not moving. But as an App developper you can not change that fixed configuration.)

You have to write such a filter, to avoid different measures at the same position.

As far as i know "gps is lying" about the exact position about a "feew" meters. comercial apps that need more precision have a gps receiver at a known exact position and transmit the diference to the "lying gps" on a seperate channel so the gps position on the mobile can be corrected accordingly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow