Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate marker on Polyline path

I have 3 markers on a Google Map.

  1. Two Markers to show starting and ending points

Here is the code using to draw a Polyline between these two points:

private void polyLine() {

    LatLng starting = new LatLng(##.######, ##.######);
    LatLng ending = new LatLng(##.######, ##.######);

    PolylineOptions line = new PolylineOptions().add(starting, ending);

    mGoogleMap.addMarker(new MarkerOptions().position(starting).title("Start"));
    mGoogleMap.addMarker(new MarkerOptions().position(ending).title("End"));

    mGoogleMap.addPolyline(line);

}
  1. One Marker to show current Location [HUE_ROSE]

And to animate marker to current location using:

@Override
public void onLocationChanged(Location location)
{
    Toast.makeText(this, "Location Changed " + location.getLatitude()
            + location.getLongitude(), Toast.LENGTH_LONG).show();

    mLastLocation = location;

    if (mCurrLocationMarker != null) {
        mCurrLocationMarker.remove();
    }

    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

    if(ourGlobalMarker == null) { // First time adding marker to map
        ourGlobalMarker = mGoogleMap.addMarker(new MarkerOptions().position(latLng)
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE)));
        MarkerAnimation.animateMarkerToICS(ourGlobalMarker, latLng, new LatLngInterpolator.Spherical());
        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18));
    } else {
        MarkerAnimation.animateMarkerToICS(ourGlobalMarker, latLng, new LatLngInterpolator.Spherical());
        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18));
    }

}

PROBLEM:

Getting Animating Marker, but right side of Polyline

SOLUTION:

How Can I show Animated Marker on Polyline Path

I tried a lot to find solution for this one, but did not find any thing, share your suggestions.

like image 569
Sophie Avatar asked Sep 06 '17 19:09

Sophie


People also ask

How do you move a marker in maps?

Use a long press to activate the ability to move the marker. By default, when a user taps a marker, the map toolbar appears at the bottom right of the map, giving the user quick access to the Google Maps mobile app.


Video Answer


2 Answers

Try out with setting anchor like follows

mDetailPositionMarker = mDetailGoogleMap.addMarker(new MarkerOptions()
                    .position(newLatLonValue)
                    .anchor(0.5f, 0.5f)
                    .rotation(bearingValue)
                    .flat(true)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.biketopicon)));

And make sure your icon will not be having any padding or margin. Avoid unnecessary space in icon image than the content like shown below.

enter image description here

like image 109
Sreehari Avatar answered Oct 05 '22 00:10

Sreehari


I am assuming you have 3 marker 1. Source point 2. Destination Point 3. Moving marker

you have to try this way it will help you

private void animateMarkerNew(final LatLng startPosition, final LatLng destination, final Marker marker) {

        if (marker != null) {

            final LatLng endPosition = new LatLng(destination.latitude, destination.longitude);

            final float startRotation = marker.getRotation();
            final LatLngInterpolatorNew latLngInterpolator = new LatLngInterpolatorNew.LinearFixed();

            ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
            valueAnimator.setDuration(2000); // duration 3 second
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    try {
                        float v = animation.getAnimatedFraction();
                        LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, endPosition);
                        marker.setPosition(newPosition);
                        googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
                                .target(newPosition)
                                .zoom(18f)
                                .build()));

                        marker.setRotation(getBearing(startPosition, new LatLng(destination.latitude, destination.longitude)));
                    } catch (Exception ex) {
                        //I don't care atm..
                    }
                }
            });
            valueAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);

                    // if (mMarker != null) {
                    // mMarker.remove();
                    // }
                    // mMarker = googleMap.addMarker(new MarkerOptions().position(endPosition).icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_car)));

                }
            });
            valueAnimator.start();
        }
    }

Note: marker is mean which marker you want to animate that one.

 private interface LatLngInterpolatorNew {
        LatLng interpolate(float fraction, LatLng a, LatLng b);

        class LinearFixed implements LatLngInterpolatorNew {
            @Override
            public LatLng interpolate(float fraction, LatLng a, LatLng b) {
                double lat = (b.latitude - a.latitude) * fraction + a.latitude;
                double lngDelta = b.longitude - a.longitude;
                // Take the shortest path across the 180th meridian.
                if (Math.abs(lngDelta) > 180) {
                    lngDelta -= Math.signum(lngDelta) * 360;
                }
                double lng = lngDelta * fraction + a.longitude;
                return new LatLng(lat, lng);
            }
        }
    }


//Method for finding bearing between two points
private float getBearing(LatLng begin, LatLng end) {
    double lat = Math.abs(begin.latitude - end.latitude);
    double lng = Math.abs(begin.longitude - end.longitude);

    if (begin.latitude < end.latitude && begin.longitude < end.longitude)
        return (float) (Math.toDegrees(Math.atan(lng / lat)));
    else if (begin.latitude >= end.latitude && begin.longitude < end.longitude)
        return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 90);
    else if (begin.latitude >= end.latitude && begin.longitude >= end.longitude)
        return (float) (Math.toDegrees(Math.atan(lng / lat)) + 180);
    else if (begin.latitude < end.latitude && begin.longitude >= end.longitude)
        return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 270);
    return -1;
}
like image 30
Raja Avatar answered Oct 05 '22 00:10

Raja