我正在从事类似于 UBER、Lyft 或 OLA 的项目,即。用可用的移动汽车在房屋上绘制 map 。 我正在寻找某种图书馆,它可以让汽车像 UBER 一样平稳地移动和转弯。现在,我可以使用下面的代码将汽车从一个经纬平稳地移动到另一个。但棘手的部分是转弯并确保汽车在向方向移动时面向前方。
顺滑车代号:
final LatLng SomePos = new LatLng(12.7796354, 77.4159606);
try {
if (googleMap == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
}
}
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.setMyLocationEnabled(true);
googleMap.setTrafficEnabled(false);
googleMap.setIndoorEnabled(false);
googleMap.setBuildingsEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(SomePos));
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(googleMap.getCameraPosition().target)
.zoom(17)
.bearing(30)
.tilt(45)
.build()));
myMarker = googleMap.addMarker(new MarkerOptions()
.position(SomePos)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher))
.title("Hello world"));
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker arg0) {
final LatLng startPosition = myMarker.getPosition();
final LatLng finalPosition = new LatLng(12.7801569, 77.4148528);
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;
LatLng currentPosition = new LatLng(
startPosition.latitude * (1 - t) + finalPosition.latitude * t,
startPosition.longitude * (1 - t) + finalPosition.longitude * t);
myMarker.setPosition(currentPosition);
// Repeat till progress is complete.
if (t < 1) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
if (hideMarker) {
myMarker.setVisible(false);
} else {
myMarker.setVisible(true);
}
}
}
});
return true;
}
});
} catch (Exception e) {
e.printStackTrace();
}
最佳答案
我最近遇到了同样的用例。这是我的解决方案。
首先,感谢@VipiN 分享“平稳行驶的汽车代码”。它运行顺利。
第二部分是将汽车标记放置在正确的方向并根据转弯旋转。为了实现这一点,我计算了两个连续点之间的方位角或航向角(即您从设备/服务器收到的位置更新)。这个link将帮助您了解其背后的数学原理。
以下代码将为您提供两个位置之间的方位:
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 = 1000;
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;
marker.setRotation(-rot > 180 ? rot / 2 : rot);
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
isMarkerRotating = false;
}
}
});
}
}
干杯!
关于java - 像 Uber Android 一样在 map 上旋转标记和移动动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35554796/