it-swarm.com.ru

Анимация маркеров в Google Maps v2

Как лучше всего анимировать маркеры на Картах Google с помощью API версии 2?

Я работаю над игрой, ориентированной на карты, где я отслеживаю местоположение людей и показываю их на карте, чтобы они могли видеть друг друга. Когда люди двигаются, я хочу анимировать маркер от его текущей позиции до последней. У каждого человека есть направление, поэтому мне нужно правильно повернуть маркер.

Каков наилучший способ сделать это с помощью нового API Карт Google?

26
Maksim Golivkin

Некоторые инженеры Google предоставили демонстрационное видео Nice с элегантным примером кода о том, как анимировать маркеры от начальной до конечной точки для всех различных версий Android:

Соответствующий код здесь:

https://Gist.github.com/broady/6314689

И хорошее демо-видео всего этого в действии.

http://youtu.be/WKfZsCKSXVQ

СТАРЫЙ УСТАРЕВШИЙ ОТВЕТ НИЖЕ

В документации упоминается, что значки маркеров не могут быть изменены:

Значок

Растровое изображение, которое отображается для маркера. Если значок не установлен, отображается значок по умолчанию. Вы можете указать альтернативный цвет значка по умолчанию, используя defaultMarker (float). Вы не можете изменить значок после создания маркера.

Документация Google Maps API v2

Вам нужно будет отслеживать конкретные маркеры, возможно, используя метод, аналогичный описанному здесь: Свяжите маркер с объектом , затем выясните, какой маркер вам нужно обновить. Вызовите .remove() для маркера, затем создайте повернутое изображение в зависимости от желаемого «направления», создайте новый маркер с этим изображением и добавьте новый маркер на карту.

Вам не нужно «очищать» карту, просто удалите маркер, который вы хотите изменить, создайте новый и добавьте его обратно на карту.

К сожалению, новый API Карт пока не очень гибок. Надеюсь, Google продолжает улучшать его.

55
DiscDev

Пример использования для Ответ DiscDev (выше):

LatLng fromLocation = new LatLng(38.5, -100.4); // Whatever Origin coordinates
LatLng toLocation = new LatLng(37.7, -107.7); // Whatever destination coordinates
Marker marker = mMap.addMarker(new MarkerOptions().position(firstLocation));
MarkerAnimation.animateMarkerToICS(marker, toLocation, new LatLngInterpolator.Spherical());

А для тех из вас, кто использует GPS/или любого другого поставщика местоположения, который получает обновления местоположения:

Marker ourGlobalMarker;
// We've got a location from some provider of ours, now we can call:
private void updateMarkerPosition(Location newLocation) {

    LatLng newLatLng = new LatLng(newLocation.getLatitude(), newLocation.getLongitude());

    if(ourGlobalMarker == null) { // First time adding marker to map
        ourGlobalMarker = mMap.addMarker(new MarkerOptions().position(newLatLng));
    }
    else {
        MarkerAnimation.animateMarkerToICS(ourGlobalMarker, newLatLng, new LatLngInterpolator.Spherical());
    }         
}

ВАЖНЫЙ:

В 1MarkerAnimation.Java Если длительность анимации установлена ​​на X, , И вы получаете обновления местоположения со скоростью, меньшей X, будет запущено несколько анимаций, и вы можете увидеть, как анимация маркера немного мерцает (что не является пользователем Nice). опыт).

Чтобы избежать этого, метод animationMarkerToICS (например, animationMarkerToICS) должен выглядеть примерно так:

полная реализация метода:

private static Animator animator; // MAKING ANIMATOR GLOBAL INSTEAD OF LOCAL TO THE STATIC FUNCTION

...

// Ice cream sandwich compatible
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public static void animateMarkerToICS(Marker marker, LatLng finalPosition, final LatLngInterpolator latLngInterpolator) {

    TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() {
        @Override
        public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
            return latLngInterpolator.interpolate(fraction, startValue, endValue);
        }
    };
    Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position");

    // ADD THIS TO STOP ANIMATION IF ALREADY ANIMATING TO AN OBSOLETE LOCATION
    if(animator != null && animator.isRunning()) {
        animator.cancel();
        animator = null;
    }
    animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);
    animator.setDuration((long) ANIMATION_DURATION);
    animator.start();
}

Наслаждаться.

7
Mercury

Маркер имеет новую функцию, добавленную в версии 7 API v2. Marker.setIcon , так что вы можете использовать несколько значков, чтобы показать направление.

5
MaciejGórski
    //Your code         
    double bearing = 0.0;
             bearing = getBearing(new LatLng(
                                                currentPosition.latitude
                                                ,currentPosition.longitude),
                                        new LatLng(
                                                nextPosition.latitude,
                                                nextPosition.longitude));  

          bearing -= 90;
                            CameraPosition cameraPosition = new CameraPosition
                                    .Builder()
                                    .target(new LatLng(nextPosition.latitude, nextPosition.longitude))
                                    .bearing((float) bearing)
                                    .zoom(ZOOM_LEVEL).build();


                            mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000, null);

                 animatedMarker(currentPosition,nextPosition,busMarker);



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

   private void animatedMarker(final LatLng startPosition,final LatLng nextPosition,final Marker mMarker)
    {

        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final Interpolator interpolator = new AccelerateDecelerateInterpolator();
        final float durationInMs = 3000;
        final boolean hideMarker = false;

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

                LatLng currentPosition = new LatLng(
                        startPosition.latitude * (1 - t) + nextPosition.latitude * t,
                        startPosition.longitude * (1 - t) + nextPosition.longitude * t);

                mMarker.setPosition(currentPosition);

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

    }
0
kailash barochiya