折线路径上的动画标记

时间:2017-09-06 19:25:22

标签: android google-maps google-maps-android-api-2 android-maps-v2

我在Google地图上有3 markers

  1. Two Markers 以显示starting and ending points
  2. 以下是使用在这两点之间绘制折线的代码:

    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 以显示current Location [HUE_ROSE]
    2. animate marker to current location 使用:

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

      问题:

      Getting Animating Marker, but right side of Polyline

      SOLUTION:

      How Can I show Animated Marker on Polyline Path

      尝试了很多来为这个 solution 找到 did not find ,但suggestions任何事情,都要分享你的https://mmg-fna.whatsapp.net/d/f/Agli1Cej_5hAtjpKhGZ3xl2TKU9dWRXcOE_k0KLvJOWZ.enc 。< / p>

3 个答案:

答案 0 :(得分:1)

尝试设置锚点,如下所示

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

并确保您的图标没有任何填充或边距。避免图标图像中不必要的空间,而不是下面显示的内容。

enter image description here

答案 1 :(得分:1)

我假设你有3个标记 1.来源​​点 2.目的地点 3.移动标记

你必须尝试这种方式它会帮助你

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

注意:标记是指您想要为该标记设置动画的标记。

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

答案 2 :(得分:0)

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

在onLocationChange方法中调用此方法并传递位置lat和lang然后你会看到一个魔法;)