web-dev-qa-db-ja.com

GoogleマップV2のユーザーの指示に従ってマーカーを回転させるAndroid

加速度計から受け取った方位またはセンサー値に従ってマーカーを回転させて、実際に動いている場所をユーザーに表示します。マーカーアイコンとフラット値を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);

私はこれを使いました marker マーカーとして。

ユーザーの指示に従って回転しない理由がわかりません。誰かが何か考えを持っているなら、私が間違っているところを親切に助けてください。

LocationUtils.sBearingは、onLocationChangedまたは加速度計から受け取ったBearingの値です。

基本的に、自分のマーカーを、ユーザーが移動または回転している方向を示すGoogleマップマーカーと同じにしたいと思います。

18
Scorpion

これは古い質問であり、それ以来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);
_

これは、マーカーアイコンの上部が前方向であることを前提としています。マーカーが図のように回転している場合は、マーカーに設定する前に、方位を調整して補正する必要があります。単純なsetRotation(bearing - 45)だけで実行できます。

18
Breavyn

上記の質問に関連する解決策を探している私のような人々はそれが役に立つかもしれないので、この回答を投稿します。

だからここで私はそれをどのようにしたか。

@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.上記の方位角を使用してマーカーを回転するには、このコードを使用しました

ここでisMarkerRotatingはブール値です。追加 isMarkerRotating = false in OnCreateメソッド

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

3.上記のコードを使用する

LatLng oldLocation, newLocaation;

float bearing = (float) bearingBetweenLocations(oldLocation, newLocaation);
rotateMarker(start_marker, bearing);
9
satti8893

Kotlinでは、Google SphericalUtilクラスを使用して、次のようにソースと宛先のLatLngを渡すことでベアリングを取得できます。

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)

リファレンス: https://developers.google.com/maps/documentation/Android-sdk/utility/#spherical

2
Shylendra Madda