【问题标题】:Rotating Marker in Google Maps API v2Google Maps API v2 中的旋转标记
【发布时间】:2016-12-17 08:24:55
【问题描述】:

我已遵循此答案,并且效果很好。 https://stackoverflow.com/a/37048987/4209417

但我现在面临的问题是:

  1. 当我停在任何位置时,它都不稳定。即使我不动,我也会得到随机方位值
  2. 当我轮流逆时针旋转时,这是错误的。它应该是短暂的。

这是我正在使用的代码:

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

【问题讨论】:

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


    【解决方案1】:

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

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

     double oldLat = oldLocation.getLatitude();
     double oldLng = oldLocation.getLongitude();
    
     double newLat = newLocation.getLatitude();
     double newLng = newLocation.getLongitude();
    
     if (oldLat != newLat && oldLng != newLng){
          updateMyLocation(toLatLng(oldLocation), toLatLng(mCurrentLocation));
     }
    

    我还更新了我的标记轮换代码。这会旋转标记并以流畅的动画移动到新位置。 (调整持续时间以获得流畅的动画)。

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

    【讨论】:

    猜你喜欢
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 2013-03-22
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多