在Google Maps V2 Android上根据用户方向旋转标记

在Google Maps V2 Android上根据用户方向旋转标记,android,google-maps-markers,accelerometer,marker,bearing,Android,Google Maps Markers,Accelerometer,Marker,Bearing,我想根据从加速计接收到的轴承或传感器值旋转标记,以显示用户实际移动的位置。我已将标记图标和平面值设置为true,但它未按要求工作 mCurrentLocationMarker.position(new LatLng( LocationUtils.sLatitude, LocationUtils.sLongitude)); mCurrentLocationMarker.icon(icon);

我想根据从加速计接收到的轴承或传感器值旋转标记,以显示用户实际移动的位置。我已将标记图标和平面值设置为true,但它未按要求工作

mCurrentLocationMarker.position(new LatLng(
                            LocationUtils.sLatitude, LocationUtils.sLongitude));
                    mCurrentLocationMarker.icon(icon);
                    mCurrentLocationMarker.flat(true);
                    mCurrentLocationMarker.rotation(LocationUtils.sBearing);

                    if (currentMarker != null) {
                        currentMarker.setPosition(new LatLng(
                                LocationUtils.sLatitude,
                                LocationUtils.sLongitude));
                    } else {
                        currentMarker = mGoogleMap
                                .addMarker(mCurrentLocationMarker);
                    }
                    animateCameraTo(true);
我用这个做记号

我不知道为什么它不按照用户的方向旋转。如果有人有任何想法,请帮助我哪里出错

LocationUtils.sBearing是我从onLocationChanged或Accelerator收到的轴承值


基本上,我想让我的标记与google maps标记相同,google maps标记向用户显示他们移动或转向的方向。

这是一个老问题,从那以后API似乎发生了变化

我想你能拿到这些设备。如果不是,这里有一个

第一件事是创建一个可以用于轴承更新的标记

private Marker marker;

// Create this marker only once; probably in your onMapReady() method
marker = mGoogleMap.addMarker(new MarkerOptions()
        .position(new LatLng(myLatitude, myLongitude))
        .flat(true));
注意
.flat(true)
部分。确保我们的标记是北对齐的,这样即使用户旋转地图,我们的方位也能正常工作

现在,当您获得轴承更新时,您可以执行以下操作

marker.setRotation(bearing);
// or if following the linked tutorial
// marker.setRotation((float) azimuth);

这假设您的标记图标在顶部具有前进方向。如果您的标记旋转如图所示,则在将其设置为标记之前,您必须调整轴承以进行补偿。只要一个简单的
设置旋转(轴承-45)
就可以了。

我发布了这个答案,因为像我这样正在寻找与上述问题相关的解决方案的人可能会发现它很有用

我是怎么做到的

正如@colin所说,您必须启用
.flat(true)
来旋转标记

1.对于轴承角度,我使用了以下代码

这里latLng1-我的旧位置和latLng2-我的新位置

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;
    }
2.要使用上述方位角旋转标记,我使用了此代码

这里的
ismarkerroting
是一个布尔值。在
OnCreate
方法中添加
ismarkerroting=false

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

                    if (t < 1.0) {
                        // Post again 16ms later.
                        handler.postDelayed(this, 16);
                    } else {
                        isMarkerRotating = false;
                    }
                }
            });
        }
    }

在Kotlin中,通过使用Google SphereCalutil类,我们可以通过传递源和目标LatLngs获得方位,如:

fun calculateBearing(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Float {
        val sourceLatLng = LatLng(lat1, lng1)
        val destinationLatLng = LatLng(lat2, lng2)
        return SphericalUtil.computeHeading(sourceLatLng, destinationLatLng).toFloat()
    }
然后将此结果“轴承”设置为标记,如

Val bearing  = calculateBearing(lat1, lng1, lat2, lng2)
marker.rotation(bearing)

参考资料:

boo!!!这个问题有什么答案吗?或者如果(mLastLocation.hasBearing()){marker.setRotation(bearing);}对吗?@Stella如果你是从那里得到方向的, sure@Stella汽车标记器正朝着正确的方向移动,但标记器/图像感觉到它在向后/反向移动。如何解决它?如何借助您的答案旋转卡车?我尝试了这个解决方案,但卡车的图像垂直翻转@SATTI8893如果
旧的
新的
位置有点远,这可能不起作用。例如,如果您在30秒内更新地图,且车速为90英里/小时,则新旧位置之间的差异将为0.75英里,如果是曲线,则无法提供完美的方向。@satti8893 bearingBetweenLocations()返回0.0
Val bearing  = calculateBearing(lat1, lng1, lat2, lng2)
marker.rotation(bearing)