0

In my Android application i need to get the traveled road with car and i check it with google android directions API and GPS.

But the problem is that some times the GPS location is not precise and i can get an error of 10Km for some lecture and that means that in a total travel of 150km my "distance traveled" can be 250km and it's wrong!

Yesterday i test it in highway and the problem is that when the marker is located out from highway, the calculation of distance traveled from my current position and the last marker located by road is very wrong (in this case out of the highway).

There is some best way for getting traveled distance with car using the phone? Maybe some better code for getting more precise GPS position? Here is my code:

private void getUserLocation() {

    Log.d(TAG, "getUserLocation()");
    checkLocationPermission();
    mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.
                    if (location != null) {
                        // Logic to handle location object
                        String stringStartLat, stringStartLng;

                        double lat = location.getLatitude();
                        double lng = location.getLongitude();

                        //Start position of device
                        if (travelInfo.getStartLat() == 0 && travelInfo.getStartLng() == 0) {
                            travelInfo.setStartLat(lat);
                            travelInfo.setStartLng(lng);
                            //Set lastcoordinates equals to start
                            travelInfo.setLastLat(lat);
                            travelInfo.setLastLng(lng);
                        }
                        //Current position of device
                        travelInfo.setCurrentLat(lat);
                        travelInfo.setCurrentLng(lng);

                        stringStartLat = Double.toString(travelInfo.getStartLat());
                        stringStartLng = Double.toString(travelInfo.getStartLng());
                        //Set the TextView in the fragment with start coordinates
                        Log.d(TAG,"LatitudeStart: " + stringStartLat);
                        Log.d(TAG,"LongitudeStart: " + stringStartLng);

                        if (startMarker == null) {
                            //Add the user location to the map with a marker
                            LatLng userLoction = new LatLng(travelInfo.getStartLat(), travelInfo.getStartLng());
                            startMarker = googleMap.addMarker(new MarkerOptions()
                                    .position(userLoction)
                                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))
                                    .title("Start Position")
                                    .snippet("Show the start position of user"));

                            // For zooming automatically to the location of the marker
                            CameraPosition cameraPosition = new CameraPosition.Builder().target(userLoction).zoom(9).build();
                            googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
                        } else {

                            LatLng currentLocation = new LatLng(travelInfo.getCurrentLat(), travelInfo.getCurrentLng());
                            currentPositionMarker = googleMap.addMarker(new MarkerOptions()
                                    .position(currentLocation)
                                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW))
                                    .title("Current Position")
                                    .snippet("Show the current position of user during travel"));

                            // For zooming automatically to the location of the marker
                            CameraPosition cameraPosition = new CameraPosition.Builder().target(currentLocation).zoom(11).build();
                            googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
                        }

                        if (travelInfo.getEndLat() != 0 && travelInfo.getEndLng() != 0) {
                            Log.i(TAG, "Dentro if userlocation");
                            //Get total distance of travel
                            getTotalDistanceTime(travelInfo);
                            //Get the percurred distance from last known coordinates
                            getPercurredDistance(travelInfo);
                        }
                    }
                }
            });
}

And getpercurredDistance use google direction API with this url

    String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + obj.getLastLat() + "," + obj.getLastLng() + "&destination=" + obj.getCurrentLat() + "," + obj.getCurrentLng() + "&mode=driving&key=AI*******************I";

For getting distance traveled from last marker and current position marker. But some times it put the localized position too far from real position... how avoid this?

EDIT

The method that i use is good for my work? mFusedLocationClient.getLastLocation()

Dario
  • 732
  • 7
  • 30

2 Answers2

2

There is no possibilities to get more precise GPS position from GPS sensor of android device, but you can filter "wrong" points this ways:

1) for each travel point get several values of Lat and Lng, discard the minimum and maximum and average the remaining ones;

2) log timestamps of each travel point and compare it for two neighboring points: speed (distance between that two points divided by time interval of that points) grater than max. car speed (e.g. 250 km/h) that means the second point is wrong (if first point is good of course).

3) use Google Maps Roads API to find best-fit road geometry for a given set of GPS coordinates.

Also take a look at this question.

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
  • How can get more geopoints in a same call? Just call more times the method mFusedLocationClient.getLastLocation()? Liket a for( . . .) { mFusedLocationClient.getLastLocation()} ? – Dario Nov 13 '17 at 15:40
  • Google maps roads can be enough it without other passage... i see that adapt the percurred road with the map street... and this can be very good for my issue! – Dario Nov 13 '17 at 15:43
  • 1
    @Dario Points 1 and 2 are for location updates logging via [LocationListener](https://developer.android.com/reference/android/location/LocationListener.html). – Andrii Omelchenko Nov 13 '17 at 16:22
  • 1
    @Dario Also take a look at [this](https://stackoverflow.com/q/40446956/6950238) question. – Andrii Omelchenko Nov 13 '17 at 17:50
  • So my method getUserLocation() doing the same thing that mFusedLocationClient.requestLocationUpdates :) ? – Dario Nov 13 '17 at 18:30
  • @Dario I think GPS data should be filtered :) – Andrii Omelchenko Nov 13 '17 at 18:37
  • i will try some change and let you know :) – Dario Nov 13 '17 at 21:20
  • did you have some suggestion about how get more geopoints and calculate average with them? How can i get more geopoints with a single call of the method getUserLocation()? – Dario Nov 14 '17 at 12:09
  • @Dario Seems, there are no possibilities to get more geopoints from single `getUserLocation()` call, but you can create custom [`GpsStatus.NmeaListener`](https://stackoverflow.com/a/47272873/6950238) and get and parse raw NMEA data manually every second. – Andrii Omelchenko Nov 14 '17 at 12:24
  • But if i put a for cycle (that cycle 5 times) inside the thread that call every 30 sec the method getUserLocation() i get 5 marker in a "same" position so can calculate the average of 5 markers and get only one marker. Or it's a bad idea? – Dario Nov 14 '17 at 16:24
  • Finally i got the traveld distance from speed and it's very precise, but anyway your answere is correct so i check it! Thanks. – Dario Nov 20 '17 at 23:22
1

For real-time location purposes, location updates allow you to request location updates at different intervals. See the android developer location documentation. The function you want is FusedLocationProviderClient.requestLocationUpdates.

There is no reason GPS (or any other widely used location technology) should ever give you 10km error for a single location estimate. If you are getting this, there is a large mismatch between when you the location estimate was made and when you are requesting it.

mattm
  • 5,851
  • 11
  • 47
  • 77
  • The error come out because if the marker is setted out of the highstreet (in italy is autostrada) the distance by road from the new and the old point is much long because the point is out of the highstreet! The result is good, but the wrong is that i'm in the highstreet and the point was setted out of this street :) – Dario Nov 13 '17 at 18:19