Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MArker Animation #145

Open
juliocotta opened this issue Aug 24, 2015 · 0 comments
Open

MArker Animation #145

juliocotta opened this issue Aug 24, 2015 · 0 comments

Comments

@juliocotta
Copy link

Hi, I would like to contribute with this source. It is a variation of the Google Maps gist https://gist.github.com/broady/6314689
PS:The infowindows need to be close and open again to update the window position.

public class OSMarkerAnimation {
    public void animate(final MapView mapView, final Marker marker, final GeoPoint finalPosition, final long duration) {
        LatLngInterpolator interpolator = new LatLngInterpolator.LinearFixed();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
            animateMarkerToGB(mapView, marker, finalPosition, interpolator, duration);
        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            animateMarkerToHC(mapView, marker, finalPosition, interpolator, duration);
        } else {
            animateMarkerToICS(mapView, marker, finalPosition, interpolator, duration);
        }
    }

    static void animateMarkerToGB(final MapView mapView, final Marker marker, final GeoPoint finalPosition, final LatLngInterpolator latlngInterpolator, final long durationInMs) {
        final GeoPoint startPosition = marker.getPosition();
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final Interpolator interpolator = new AccelerateDecelerateInterpolator();

        handler.post(new Runnable() {
            long elapsed;
            float t;
            float v;

            @Override
            public void run() {
                // Calculate progress using interpolator
                elapsed = SystemClock.uptimeMillis() - start;
                t = elapsed / durationInMs;
                v = interpolator.getInterpolation(t);

                marker.setPosition(latlngInterpolator.interpolate(v, startPosition, finalPosition));
                if (marker.isInfoWindowOpen()) {
                    marker.closeInfoWindow();
                    marker.showInfoWindow();
                }
                mapView.invalidate();

                // Repeat till progress is complete.
                if (t < 1) {
                    // Post again 16ms later.
                    handler.postDelayed(this, 16);
                }
            }
        });
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
    static void animateMarkerToHC(final MapView mapView, final Marker marker, final GeoPoint finalPosition, final LatLngInterpolator latlngInterpolator, final long durationInMs) {
        final GeoPoint startPosition = marker.getPosition();

        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float v = animation.getAnimatedFraction();
                GeoPoint newPosition = latlngInterpolator.interpolate(v, startPosition, finalPosition);
                marker.setPosition(newPosition);
                if (marker.isInfoWindowOpen()) {
                    marker.closeInfoWindow();
                    marker.showInfoWindow();
                }
                mapView.invalidate();
            }
        });
        valueAnimator.setFloatValues(0, 1); // Ignored.
        valueAnimator.setDuration(durationInMs);
        valueAnimator.start();
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    static void animateMarkerToICS(final MapView mapView, final Marker marker, GeoPoint finalPosition, final LatLngInterpolator latlngInterpolator, final long durationInMs) {
        TypeEvaluator<GeoPoint> typeEvaluator = new TypeEvaluator<GeoPoint>() {
            @Override
            public GeoPoint evaluate(float fraction, GeoPoint startValue, GeoPoint endValue) {
                if (marker.isInfoWindowOpen()) {
                    marker.closeInfoWindow();
                    marker.showInfoWindow();
                }
                mapView.invalidate();
                return latlngInterpolator.interpolate(fraction, startValue, endValue);
            }
        };
        Property<Marker, GeoPoint> property = Property.of(Marker.class, GeoPoint.class, "position");
        ObjectAnimator animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);
        animator.setDuration(durationInMs);
        animator.start();
    }
}
/* Copyright 2013 Google Inc.
   Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0.html */

package br.com.wappa.appmobilecolaborador.ui.animation;

import org.osmdroid.util.GeoPoint;

import static java.lang.Math.asin;
import static java.lang.Math.atan2;
import static java.lang.Math.cos;
import static java.lang.Math.pow;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;

public interface LatLngInterpolator {
    public GeoPoint interpolate(float fraction, GeoPoint a, GeoPoint b);

    public class Linear implements LatLngInterpolator {
        @Override
        public GeoPoint interpolate(float fraction, GeoPoint a, GeoPoint b) {
            double lat = (b.getLatitude() - a.getLatitude() * fraction + a.getLatitude());
            double lng = (b.getLongitude() - a.getLongitude()) * fraction + a.getLongitude();
            return new GeoPoint(lat, lng);
        }
    }

    public class LinearFixed implements LatLngInterpolator {
        @Override
        public GeoPoint interpolate(float fraction, GeoPoint a, GeoPoint b) {
            double lat = (b.getLatitude() - a.getLatitude()) * fraction + a.getLatitude();
            double lngDelta = b.getLongitude() - a.getLongitude();

            // Take the shortest path across the 180th meridian.
            if (Math.abs(lngDelta) > 180) {
                lngDelta -= Math.signum(lngDelta) * 360;
            }
            double lng = lngDelta * fraction + a.getLongitude();
            return new GeoPoint(lat, lng);
        }
    }

    public class Spherical implements LatLngInterpolator {

        /* From github.com/googlemaps/android-maps-utils */
        @Override
        public GeoPoint interpolate(float fraction, GeoPoint from, GeoPoint to) {
            // http://en.wikipedia.org/wiki/Slerp
            double fromLat = toRadians(from.getLatitude());
            double fromLng = toRadians(from.getLongitude());
            double toLat = toRadians(to.getLatitude());
            double toLng = toRadians(to.getLongitude());
            double cosFromLat = cos(fromLat);
            double cosToLat = cos(toLat);

            // Computes Spherical interpolation coefficients.
            double angle = computeAngleBetween(fromLat, fromLng, toLat, toLng);
            double sinAngle = sin(angle);
            if (sinAngle < 1E-6) {
                return from;
            }
            double a = sin((1 - fraction) * angle) / sinAngle;
            double b = sin(fraction * angle) / sinAngle;

            // Converts from polar to vector and interpolate.
            double x = a * cosFromLat * cos(fromLng) + b * cosToLat * cos(toLng);
            double y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng);
            double z = a * sin(fromLat) + b * sin(toLat);

            // Converts interpolated vector back to polar.
            double lat = atan2(z, sqrt(x * x + y * y));
            double lng = atan2(y, x);
            return new GeoPoint(toDegrees(lat), toDegrees(lng));
        }

        private double computeAngleBetween(double fromLat, double fromLng, double toLat, double toLng) {
            // Haversine's formula
            double dLat = fromLat - toLat;
            double dLng = fromLng - toLng;
            return 2 * asin(sqrt(pow(sin(dLat / 2), 2) +
                    cos(fromLat) * cos(toLat) * pow(sin(dLng / 2), 2)));
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants