Animate marker on Polyline path

纵饮孤独 提交于 2019-12-07 01:00:59

问题


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.


回答1:


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.




回答2:


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;
}



回答3:


    // Animation handler for old APIs without animation support
private void animateMarkerTo(final Marker marker, final double lat, final double lng) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    final long DURATION_MS = 3000;
    final Interpolator interpolator = new AccelerateDecelerateInterpolator();
    final LatLng startPosition = marker.getPosition();
    handler.post(new Runnable() {
        @Override
        public void run() {
            float elapsed = SystemClock.uptimeMillis() - start;
            float t = elapsed/DURATION_MS;
            float v = interpolator.getInterpolation(t);

            double currentLat = (lat - startPosition.latitude) * v + startPosition.latitude;
            double currentLng = (lng - startPosition.longitude) * v + startPosition.longitude;
            marker.setPosition(new LatLng(currentLat, currentLng));

            // if animation is not finished yet, repeat
            if (t < 1) {
                handler.postDelayed(this, 16);
            }
        }
    });
}

call this method inside onLocationChange method and pass location lat and lang then you will see a magic ;)



来源:https://stackoverflow.com/questions/46082918/animate-marker-on-polyline-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!