在Google Maps V2 Android上按用户指示旋转标记

Sco*_*ion 18 android accelerometer bearing marker google-maps-markers

我想根据从Accelerometer接收的轴承或传感器值来旋转标记,以向用户显示他实际移动的位置.我已将标记图标和平面值设置为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);
Run Code Online (Sandbox Code Playgroud)

我用过这个 标记 作为标记.

我不知道为什么它不按照用户的指示旋转.如果有任何人有任何想法,请在我犯错的地方帮助我.

LocationUtils.sBearing是我从onLocationChanged或accelerometer收到的Bearing的值.

基本上我想让我的标记与谷歌地图标记一样,向用户显示他们正在移动或转向的方向.

Bre*_*vyn 19

这是一个老问题,从那时起,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));
Run Code Online (Sandbox Code Playgroud)

注意.flat(true)部分.确保我们的标记向北对齐,以便即使用户旋转地图,我们的轴承也能正常工作.

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

marker.setRotation(bearing);
// or if following the linked tutorial
// marker.setRotation((float) azimuth);
Run Code Online (Sandbox Code Playgroud)

这假设您的标记图标在顶部具有向前方向.如果您的标记旋转如图所示,则必须先调整轴承以进行补偿,然后再将其设置为标记.只是一个简单的setRotation(bearing - 45)应该这样做.


sat*_*893 9

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

所以在这里我是如何做到的.

正如@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;
    }
Run Code Online (Sandbox Code Playgroud)

2.要使用上述轴承角度旋转标记,我已使用此代码

isMarkerRotating是一个布尔值.添加isMarkerRotating = falseOnCreate方法

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;
                    }
                }
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

3.使用上面的代码

LatLng oldLocation, newLocaation;

float bearing = (float) bearingBetweenLocations(oldLocation, newLocaation);
rotateMarker(start_marker, bearing);
Run Code Online (Sandbox Code Playgroud)