0

I am building a car navigation application in Xamarin.Android (native not forms). I had read a lot, and follow instructions I found on how to add the map in the application and also how to use the location services, either with the FusedLocationProvider or the NavigationManager. I decided to use the NavigationManager since it looks more accurate because of the number of decimal digits (14) in the LatLng. All good up to now. I am testing my app and while the marker and the map are moving, in order to follow the car's direction, the map is blurred (see the attached pictures), it looks like it does not have the appropriate time to get refreshed.

What I am doing in order to move the camera and the marker? 1. OnLocationChanged from the LocationManager I am calling the UpdateCameraBearing function

internal static void UpdateCameraBearing(float bearing, Location newLocation)
    {
        if (Map == null)
            return;

        // Save current zoom
        int originalZoom = (int)Map.CameraPosition.Zoom;
        if (!startingZoom.HasValue)
        {
            startingZoom = originalZoom = MapZoomDef;
        }

        LastLocation = newLocation;
        LatLng newPosition = new LatLng(newLocation.Latitude, newLocation.Longitude);
        CameraPosition camPos = new CameraPosition(newPosition, originalZoom != MapZoomDef ? originalZoom : MapZoomDef, 0, bearing);
        try
        {
            Map.AnimateCamera(CameraUpdateFactory.NewCameraPosition(camPos));
            UpdateMarkerPosition(newPosition);
        }
        catch (Exception ex)
        {
            Log.Error(TAG, ex.Message);
        }
    }

This function animates the camera to the new position and also updates the marker position using the UpdateMarkerPosition function as follows

    private static void UpdateMarkerPosition(LatLng newPosition)
    {
        if (null == MapMarker)
        {
            SetNewMarker(newPosition);
        }
        else
        {
            //positionMarker.Visible = true;
            //positionMarker.Position = newPosition;
            AnimateMarker(newPosition, new LatLngInterpolatorSpherical());
        }
    }

    private static void SetNewMarker(LatLng myPosition)
    {
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.SetPosition(myPosition);
        markerOptions.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Mipmap.ic_car));
        MapMarker = Map.AddMarker(markerOptions);
    }

    private static void AnimateMarker(LatLng finalPosition, LatLngInterpolatorSpherical latLngInterpolator)
    {
        Android.OS.Handler handler = new Android.OS.Handler();
        long start = Android.OS.SystemClock.UptimeMillis();
        LatLng startPosition = MapMarker.Position;
        Android.Views.Animations.AccelerateDecelerateInterpolator interpolator = new Android.Views.Animations.AccelerateDecelerateInterpolator();
        float durationInMs = 1000;

        Java.Lang.Runnable mUpdateGeneration = null;
        mUpdateGeneration = new Java.Lang.Runnable(() => {
            long elapsed;
            float t;
            float v;

            // Calculate progress using interpolator
            elapsed = Android.OS.SystemClock.UptimeMillis() - start;
            t = elapsed / durationInMs;
            v = interpolator.GetInterpolation(t);
            MapMarker.Position = latLngInterpolator.Interpolate(v, startPosition, finalPosition);
            // Repeat till progress is complete.
            if (t < 1)
            {
                // Post again 16ms later.
                handler.PostDelayed(mUpdateGeneration, 16);
            }
        });

        handler.Post(mUpdateGeneration);
    }

The UpdateMarkerPosition function checks if the marker exists and if not (this is the first time) it creates it, otherwise it calls the AnimateMarker function where I am using an Interpolator in order to simulate a smooth marker movement.

Last but not least the LocationManager.RequestLocationUpdates is configured with 1-second minimum time and 1-meter minimum Distance.

I will appreciate any suggestions on how to solve the problem...

enter image description here enter image description here

FreakyAli
  • 13,349
  • 3
  • 23
  • 63
  • My first suggestion would be to use FusedLocationProvider instead of LocationManager since its more accurate a good explanation for this can be found https://stackoverflow.com/questions/30144480/are-there-any-advantages-of-using-fusedlocationproviderapi-over-locationmanager – FreakyAli May 27 '20 at 08:07
  • The Google Maps api provides the `animateCamera (CameraUpdate update, int durationMs, GoogleMap.CancelableCallback callback)` method which may help you to update the map with an animation over a specified duration. Check the tutorial:https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap#public-void-animatecamera-cameraupdate-update,-int-durationms,-googlemap.cancelablecallback-callback – Jarvan Zhang May 27 '20 at 09:41
  • Also are you sure you have a good internet connection? – FreakyAli May 28 '20 at 05:22

0 Answers0