0

I have implemented a function that tracks a user's location every second, and adds the tracked location to a polyline, drawing the user's path. The trouble is the data I have picked up and the resulting line is imprecise.

Below is a link to an image of a test run I did on a drive on a nearby street. The black line is the data received, notice how the line jumps from point to point sporadically. The red line is roughly what path the polyline should've followed, as it follows the road I took while driving and tracking location data from my Android phone.

https://i.imgur.com/9nWEfna.png

Below is the code related to the pathtracing functionality I have implemented. Every time the "track" button is pressed, a new polyline is created and a thread starts executing every second to report the user's location. Once received, the latlng of the location is added to the polyline and the polyline is redrawn to reflect the addition of the new point.

public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        return;
    }
    mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.
                    if (location == null) return;
                    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                    mMap.addMarker(new MarkerOptions().position(latLng).title("Current Location"));
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f));
                }
            });
    trackButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                final ArrayList currpath = new ArrayList<LatLng>();
                paths.add(currpath);
                PolylineOptions currpathlineoptions = new PolylineOptions();
                final Polyline currpathline = mMap.addPolyline(currpathlineoptions);
                tracking = true;
                MapsActivity.this.runOnUiThread(new Runnable() {
                    @SuppressLint("MissingPermission")
                    public void run() {
                        mFusedLocationClient.getLastLocation()
                                .addOnSuccessListener(MapsActivity.this, new OnSuccessListener<Location>() {
                                    @Override
                                    public void onSuccess(Location location) {
                                        // Got last known location. In some rare situations this can be null.
                                        if (location == null) return;
                                        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f));
                                        currpath.add(latLng);
                                        currpathline.setPoints(currpath);
                                    }
                                });
                        if(tracking){
                            Handler h = new Handler();
                            h.postDelayed(this, 1000);
                        }
                    }
                });

            } else {
                tracking = false;
            }
        }
    });
}

}

Could someone with more experience in handling Google Maps tell me why the LatLngs reported jump from point to point and imprecisely trace the route I drove?

Ace Zhang
  • 81
  • 1
  • 8
  • From the picture it appears you have 6 position updates over the course of the route. 5 of the 6 were good reckoning relative to referenced truth. But there is the 6th point (4th in the sequence) which is inaccurate. Just because you sample every second doesn't mean there is an update every second. From the code you specified you are not requesting location update but merely sampling location as a result of something else requesting it. I'd recommend requesting location updates at an interval consistent with your polling. –  Apr 10 '18 at 23:10
  • You need to actually request a location using `requestLocationUpdates()`. Take a look at the code in the answer here: https://stackoverflow.com/questions/44992014/how-to-get-current-location-in-googlemap-using-fusedlocationproviderclient – Daniel Nugent Apr 11 '18 at 00:43

1 Answers1

0

So you are using https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient.html#getLastLocation() which states:

It is particularly well suited for applications that do not require an accurate location and that do not want to maintain extra logic for location updates.

Also note that each Location has Accuracy so that will vary on local conditions.

Morrison Chang
  • 11,691
  • 3
  • 41
  • 77