Google Maps API v2中的旋转标记

时间:2016-12-17 08:24:56

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

我已经按照这个答案而且工作得很好。 https://stackoverflow.com/a/37048987/4209417

但我现在面临的问题是:

  1. 当我在任何地方停留时,它不稳定。即使我没有移动
  2. ,我也会获得随机承载价值
  3. 当我轮流逆时针转动这是错误的。它应该短暂转弯。
  4. 这是我使用的代码:

    private double bearingBetweenLocations(LatLng latLng1,LatLng latLng2) {
    
            double PI = 3.14159;
            double lat1 = latLng1.latitude * PI / 180;
            double long1 = latLng1.longitude * PI / 180;
            double lat2 = latLng2.latitude * PI / 180;
            double long2 = latLng2.longitude * PI / 180;
    
            double dLon = (long2 - long1);
    
            double y = Math.sin(dLon) * Math.cos(lat2);
            double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
                    * Math.cos(lat2) * Math.cos(dLon);
    
            double brng = Math.atan2(y, x);
    
            brng = Math.toDegrees(brng);
            brng = (brng + 360) % 360;
    
            return brng;
        }
    
    private void rotateMarker(final Marker marker, final float toRotation) {
            if(!isMarkerRotating) {
                final Handler handler = new Handler();
                final long start = SystemClock.uptimeMillis();
                final float startRotation = marker.getRotation();
                final long duration = 2000;
    
                final Interpolator interpolator = new LinearInterpolator();
    
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        isMarkerRotating = true;
    
                        long elapsed = SystemClock.uptimeMillis() - start;
                        float t = interpolator.getInterpolation((float) elapsed / duration);
    
                        float rot = t * toRotation + (1 - t) * startRotation;
    
                        float bearing =  -rot > 180 ? rot / 2 : rot;
    
                        marker.setRotation(bearing);
    
                        CameraPosition camPos = CameraPosition
                                .builder(mMap.getCameraPosition())
                                .bearing(bearing)
                                .target(marker.getPosition())
                                .build();
                        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPos));
    
                        if (t < 1.0) {
                            // Post again 16ms later.
                            handler.postDelayed(this, 16);
                        } else {
                            isMarkerRotating = false;
                        }
                    }
                });
            }
        }
    

    onLocationChanged()

    float toRotation = (float) bearingBetweenLocations(toLatLng(oldLocation), toLatLng(newLocation));
    rotateMarker(my_marker, toRotation);
    

1 个答案:

答案 0 :(得分:4)

所以终于找到了我自己的答案,我将在这里发布,所以其他人可以发现它很有用。

每当我的onLocationChanged更新时,我都会检查我的旧版和版本。然后我更新标记。如下所示。

float rotation = (float) SphericalUtil.computeHeading(old, new);
rotateMarker(bus_marker, new, rotation);

private void rotateMarker(final Marker marker, final LatLng destination, final float rotation) {

    if (marker != null) {

        final LatLng startPosition = marker.getPosition();
        final float startRotation = marker.getRotation();

        final LatLngInterpolator latLngInterpolator = new LatLngInterpolator.Spherical();
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.setDuration(3000); // 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, destination);
                    float bearing = computeRotation(v, startRotation, rotation);

                    marker.setRotation(bearing);
                    marker.setPosition(newPosition);

                }
                catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
        valueAnimator.start();
    }
}
private static float computeRotation(float fraction, float start, float end) {
    float normalizeEnd = end - start; // rotate start to 0
    float normalizedEndAbs = (normalizeEnd + 360) % 360;

    float direction = (normalizedEndAbs > 180) ? -1 : 1; // -1 = anticlockwise, 1 = clockwise
    float rotation;
    if (direction > 0) {
        rotation = normalizedEndAbs;
    } else {
        rotation = normalizedEndAbs - 360;
    }

    float result = fraction * rotation + start;
    return (result + 360) % 360;
}

我也更新了我的标记旋转代码。这使标记旋转。以平滑的动画移动到新位置。 (调整平滑动画的持续时间)。

id