2016-12-17 149 views
4

我遵循這個答案,它的工作很棒。 https://stackoverflow.com/a/37048987/4209417Google Maps API v2中的旋轉標記

但我現在面臨的問題是:

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

回答

2

所以,終於找到了我自己的答案,我會張貼在這裏,所以其他人可以發現它有用。

每當我的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; 
} 
+0

嘿,對不起,重新審視這個老問題,但你介意發佈你的LatLngInterpolator代碼? –

+1

@VasiliFedotov這裏是鏈接https://gist.github.com/hardikbhalodi/671ab28c81d3392fba45bc72fa549be2 LatLngInterpolator – satti8893