使用v2 API在Google地圖上標記動畫的最佳方式是什麼?在Google地圖v2上設置動畫標記
我正在研究一個以地圖爲中心的遊戲,我跟蹤人的位置並將它們顯示在地圖上以供彼此查看。隨着人們的移動,我想創建一個標記,從現在到最新的位置。每個人都有一個方向,所以我需要適當地旋轉標記。
使用新的Google Maps API來完成此操作的最佳方法是什麼?
使用v2 API在Google地圖上標記動畫的最佳方式是什麼?在Google地圖v2上設置動畫標記
我正在研究一個以地圖爲中心的遊戲,我跟蹤人的位置並將它們顯示在地圖上以供彼此查看。隨着人們的移動,我想創建一個標記,從現在到最新的位置。每個人都有一個方向,所以我需要適當地旋轉標記。
使用新的Google Maps API來完成此操作的最佳方法是什麼?
一些谷歌工程師們提供了一個很好的演示視頻有關如何從起點動畫標記到終點,所有的各種版本的Android的一些優雅的示例代碼:
相關的代碼是在這裏:
https://gist.github.com/broady/6314689
這是一個很好的演示視頻,
OLD DEPRECATED回答以下
在文檔中提到,標記圖標不能改變:
圖標
在隨即出現的位圖爲標記。如果圖標未設置,則顯示默認圖標。您可以使用defaultMarker(float)指定默認圖標的替代顏色。 創建標記後,無法更改圖標。
Google Maps API v2 Documentation
你將不得不跟蹤特定的標記,可能使用類似於這裏所描述的方法:Link a Marker to an Object,然後找出哪些標記需要更新。在標記上調用.remove()
,然後根據所需的「方向」創建一個旋轉的圖像,使用該圖像創建一個新標記,然後將新標記添加到地圖。
您不需要「清除」地圖,只需刪除要修改的標記,創建一個新標記,然後將其添加回地圖。
不幸的是,新的Maps API還不夠靈活。希望谷歌繼續改進它。
標記具有API v2修訂版7中新增的新功能。 Marker.setIcon,所以你可以使用多個圖標來顯示方向。
用法示例爲DiscDev's ansrwer(上圖):
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
如果動畫durat ion設置爲X, ,並且您正在以小於X的速率接收位置更新,將運行多個動畫,並且您可能會看到標記閃爍。
爲了避免這種情況,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();
}
享受。
//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);
}
}
}
});
}
可能[duplicate](http://stackoverflow.com/questions/13972401/google-map-v2-marker-animation)?如果在你選擇的解決方案中,你需要插入經度,密切關注第180次子午線上的符號翻轉。 – hleinone 2013-02-13 23:58:38
@hleinone不完全。您提到的那個解決方案可以:a)移動相機b)將標記移動到不同的位置。 我需要b),它可以簡單地通過做Marker.setPosition()來完成。但是,更改標記的圖標(我將沿着運動方向顯示旋轉的圖像)不起作用。看來,需要清除地圖上的所有標記以使圖標發生變化。 – 2013-02-14 00:09:45
用於動畫折線路線https://github.com/amalChandran/google-maps-route-animation – amalBit 2017-01-13 05:06:38