我已经实现了一个基于安全目的的应用程序。此应用程序适用于两个角色,即 A 和 B。两个用户都可以跟踪彼此的位置。对于用户A,我已经实现了Mapbox,对于用户B,我已经实现了谷歌地图。
对于 A,Mapbox 提供默认的实时导航,对于 B,我使用了提供用户 A 位置的信号 R。所以我可以将标记导航到 A 的特定位置。
我在从 SignalR 获取位置时遇到问题。但马克在闪烁。
我使用代码来移动标记,如下所示。
private val mMoveCarLocation = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent != null) {
val handler = Handler()
//Code to move car along latitude and longitude
handler.postDelayed(object : Runnable {
override fun run() {
try {
//post again
Log.d("tess", "inside run ")
val targetLocation = Location(LocationManager.GPS_PROVIDER)
val latitude = java.lang.Double.valueOf(
intent.getStringExtra(
GlobalVariables.PROVIDE_A_LATITUDE
)
)
val longitude =
java.lang.Double.valueOf(intent.getStringExtra(GlobalVariables.PROVIDE_A_LONGITUDE))
targetLocation.latitude = latitude
targetLocation.longitude = longitude
animateMarkerNew(targetLocation)
mActivityUserMapBinding!!.txtTime.setText(
intent.getStringExtra(
REMAINING_TIME
)
)
} catch (e: java.lang.Exception) {
Log.d("tess", "call back removed")
//removed callbacks
handler.removeCallbacks(this)
}
}
}, 3000)
}
}
}
为标记添加动画效果
fun animateMarkerNew(destination: Location) {
if (viewModel.mMarker != null) {
val startPosition = viewModel.mMarker.position
val endPosition = LatLng(destination.latitude, destination.longitude)
val startRotation = viewModel.mMarker.rotation
val latLngInterpolator = UserMapViewModel.LatLngInterpolatorNew.LinearFixed()
val valueAnimator = ValueAnimator.ofFloat(0F, 1F)
valueAnimator.duration = 3000 // duration 3 second
valueAnimator.interpolator = LinearInterpolator()
valueAnimator.addUpdateListener { animation ->
try {
val v = animation.animatedFraction
val newPosition =
latLngInterpolator.interpolate(v, startPosition, endPosition)
viewModel.mMarker.setPosition(newPosition)
handler = Handler()
handler!!.postDelayed(Runnable {
viewModel.googleMap!!.moveCamera(
CameraUpdateFactory.newCameraPosition(
CameraPosition.Builder()
.target(newPosition)
// .zoom(15.5f)
.zoom(17.5f)
.build()
)
)
viewModel.mMarker.rotation = viewModel.getBearing(
startPosition,
LatLng(destination.latitude, destination.longitude)
)
}, 800)
} catch (ex: Exception) {
//I don't care atm..
}
}
valueAnimator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
}
})
valueAnimator.start()
}
}
public static void animateMarker(LocationInfo destination, Marker marker, float bearning) {
if (marker != null) {
LatLng startPosition = marker.getPosition();
LatLng endPosition = new LatLng(destination.getLatitude(), destination.getLongitude());
float startRotation = marker.getRotation();
LatLngInterpolator latLngInterpolator = new LatLngInterpolator.LinearFixed();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(1000); // duration 1 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);
// marker.setRotation(computeRotation(v, startRotation, bearning));
} catch (Exception ex) {
// I don't care atm..
}
}
});
valueAnimator.start();
}
}
interface LatLngInterpolator {
LatLng interpolate(float fraction, LatLng a, LatLng b);
class LinearFixed implements LatLngInterpolator {
@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);
}
}
}