如何在谷歌地图android中显示当前位置的平滑移动
我正在实现一个地图导航应用程序。我每1000毫秒获取一次设备的当前位置,并绘制一条从当前位置到固定标记点的多段线。但当在车内使用该设备时,多段线和当前位置的更新并不像优步或谷歌地图那样具有动画效果。从一个点到另一个点的变化是突然的如何在谷歌地图android中显示当前位置的平滑移动,android,google-maps,android-mapview,android-maps-v2,Android,Google Maps,Android Mapview,Android Maps V2,我正在实现一个地图导航应用程序。我每1000毫秒获取一次设备的当前位置,并绘制一条从当前位置到固定标记点的多段线。但当在车内使用该设备时,多段线和当前位置的更新并不像优步或谷歌地图那样具有动画效果。从一个点到另一个点的变化是突然的 如何获得当前位置更改的平滑动画。您必须尝试这种方法,它将帮助您 private void animateMarkerNew(final LatLng startPosition, final LatLng destination, final Marker marke
如何获得当前位置更改的平滑动画。您必须尝试这种方法,它将帮助您
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);
}
}
}
//求两点间方位角的方法
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 float getbeing(车床开始,车床结束){
double lat=Math.abs(begin.latitude-end.latitude);
double lng=Math.abs(begin.longitude-end.longitude);
if(begin.latitude=end.latitude&&begin.longitude=end.latitude&&begin.longitude>=end.longitude)
返回(浮动)(数学至度数(数学至度数(lng/lat))+180);
else if(begin.latitude=end.longitude)
返回(浮动)((90-数学到度数(数学到度数(lng/lat)))+270);
返回-1;
}
你必须尝试这种方法,它将帮助你
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);
}
}
}
//求两点间方位角的方法
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 float getbeing(车床开始,车床结束){
double lat=Math.abs(begin.latitude-end.latitude);
double lng=Math.abs(begin.longitude-end.longitude);
if(begin.latitude=end.latitude&&begin.longitude=end.latitude&&begin.longitude>=end.longitude)
返回(浮动)(数学至度数(数学至度数(lng/lat))+180);
else if(begin.latitude=end.longitude)
返回(浮动)((90-数学到度数(数学到度数(lng/lat)))+270);
返回-1;
}
您的显示精度不能超过1s。在您的情况下,您可能需要通过计算速度和方向来推断位置。它可能存在一个这样做的库。你不能比1更精确地显示。在您的情况下,您可能需要通过计算速度和方向来推断位置。它可能存在一个这样做的库。我认为这可以在任意一个方向上随机设置一个点到另一个点的动画,它不关心路径。。我想通过路径设置动画。有可能吗?你们说的路径是指多段线,对,多段线有一个长和宽,这里起始位置是你们的标记位置,终点是你们的下一条多段线,然后通过使用标记对象。希望会work@Raja我认为他是正确的,因为这个解决方案可能适用于直线多段线,但它不适用于hashmap路径或我们从google获得的显示两点之间路线的道路。在这个标记中,经过一段时间后会消失,如何解决this@M.Yogeshwaran-你解决了标记消失的问题了吗?我想这是动画一个点到另一个点在任意一个方向上随机移动,它与路径无关。。我想通过路径设置动画。有可能吗?你们说的路径是指多段线,对,多段线有一个长和宽,这里起始位置是你们的标记位置,终点是你们的下一条多段线,然后通过使用标记对象。希望会work@Raja我认为他是正确的,因为这个解决方案可能适用于直线多段线,但它不适用于hashmap路径或我们从google获得的显示两点之间路线的道路。在这个标记中,经过一段时间后会消失,如何解决this@M.Yogeshwaran-你解决了标记消失的问题了吗?