2

How to animate Marker between Array with a specific velocity in kmph on Google Map Android.

I tried animateMarker method which is widely available in internet. Am able to move through set of LatLng points but not with a specific velocity.

Can someone help me in moving the object with a specific velocity in KMPH

Pavandroid
  • 1,586
  • 2
  • 15
  • 30

2 Answers2

1

You might have to use Physics here. Below is an algorithm-like-detail which may be helpful.

  1. Find out the time that should be consumed from first position to the last one. Let's say if the Velocity is 17 km/hr, and the distance between first and last position is 10 km then time would be 3600 sec or 3600000 ms.
  2. Now divide the time for each location in your Array. Let's say if you have 100 elements in an Array, time between each location would be 36 sec or 36000 ms
  3. Now define a Handler with duration set to 36 sec or 36000 ms and try to animate marker within this duration. For that you can use another Handler or default method provided by he API. Recall it the no of times you have elements in your array with next location every time.

NOTE

I found an example too. Refer here for original post.

public void animateMarker(final Marker marker, final LatLng toPosition,
        final boolean hideMarker) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    Projection proj = mGoogleMapObject.getProjection();
    Point startPoint = proj.toScreenLocation(marker.getPosition());
    final LatLng startLatLng = proj.fromScreenLocation(startPoint);
    final long duration = 500;

    final Interpolator interpolator = new LinearInterpolator();

    handler.post(new Runnable() {
        @Override
        public void run() {
            long elapsed = SystemClock.uptimeMillis() - start;
            float t = interpolator.getInterpolation((float) elapsed
                    / duration);
            double lng = t * toPosition.longitude + (1 - t)
                    * startLatLng.longitude;
            double lat = t * toPosition.latitude + (1 - t)
                    * startLatLng.latitude;
            marker.setPosition(new LatLng(lat, lng));

            if (t < 1.0) {
                // Post again 16ms later.
                handler.postDelayed(this, 16);
            } else {
                if (hideMarker) {
                    marker.setVisible(false);
                } else {
                    marker.setVisible(true);
                }
            }
        }
    });
}

Hope anyone of it helps.

Community
  • 1
  • 1
Waqas Ahmed Ansari
  • 1,683
  • 15
  • 30
0

I modified the same method to achieve this.

We need to call this method

animateMarker(googleMap, driver, arrayPoints, distance(arrayPoints.get(0), arrayPoints.get(1)) * msForKMTravel, 0);

arrayPoints is the LatLng array. msForKMTravel is the microSec for travlling a KM.

Method :::

public void animateMarker(final GoogleMap mMap, final Marker marker, final List<LatLng> arrayLications, final double duration, final int step) {
        Log.d(TAG, "Moving from:" + step + "To:" + (step + 1) + "duration" + duration);
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        LatLng startPosition = arrayLications.get(step);
        final LatLng toPosition = arrayLications.get(step + 1);
        Projection proj = mMap.getProjection();
        Point startPoint = proj.toScreenLocation(startPosition);
        final LatLng startLatLng = proj.fromScreenLocation(startPoint);

        final Interpolator interpolator = new LinearInterpolator();

        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) (elapsed
                        / duration));
                Log.d(TAG, "interpolator t:" + t + "start :" + start + " elapsed :" + elapsed);
                double lng = t * toPosition.longitude + (1 - t)
                        * startLatLng.longitude;
                double lat = t * toPosition.latitude + (1 - t)
                        * startLatLng.latitude;
                LatLng newLatLng = new LatLng(lat, lng);
                Log.d(TAG, "Moving to" + newLatLng);
                marker.setPosition(newLatLng);

                if (t < 1.0) {
                    handler.postDelayed(this, 100);
                } else {
                    if (arrayLications.size() > step + 2 && isVisible()) {
                        double distance = distance(arrayLications.get(step + 1), arrayLications.get(step + 2));
                        double time = distance * msForKMTravel;
                        Log.d(TAG, "Go for distance" + distance + " in time " + time);
                        animateMarker(mMap, marker, arrayLications, time, step + 1);
                    }
                }
            }
        });
    }
Pavandroid
  • 1,586
  • 2
  • 15
  • 30