7

アプリに、マップとして使用する画像があるアクティビティがあります。画像がGoogleマップに「グリッド整列」されている場合、オンラインのGoogleマップから取得したマップの左上隅と右下隅を使用すると、ユーザーのGPSを画面上のxとyに変えることができます。ただし、マップが「グリッドに整列」しておらず、数学が返す値よりも角度がある場合、ユーザーの位置が画面から外れます。明らかに、マップの角度を処理する方法の一部が欠けているので、誰かがそれを行う方法に光を当てることができれば、それは非常に役立ちます.

ラジアンで角度を計算し、何らかの変換を行う必要があることはわかっていますが、どこから始めればよいかわかりません。これは、これまでキャンバスにプロットする x と y を取得するために使用したものです。

public double[] getPositionGPS(Location upperLeft, Location lowerRight, Location current){

    try{

        double hypotenuse = upperLeft.distanceTo(current);
        double bearing = upperLeft.bearingTo(current);
        double currentDistanceY = Math.cos(bearing * Math.PI / OneEightyDeg) * hypotenuse;
        //                           "percentage to mark the position"
        double totalHypotenuse = upperLeft.distanceTo(lowerRight);
        double totalDistanceY = totalHypotenuse * Math.cos(upperLeft.bearingTo(lowerRight) * Math.PI / OneEightyDeg);
        double currentPixelY = currentDistanceY / totalDistanceY * ImageSizeH;

        double hypotenuse2 = upperLeft.distanceTo(current);
        double bearing2 = upperLeft.bearingTo(current);
        double currentDistanceX = Math.sin(bearing2 * Math.PI / OneEightyDeg) * hypotenuse2;
        //                           "percentage to mark the position"
        double totalHypotenuse2 = upperLeft.distanceTo(lowerRight);
        double totalDistanceX = totalHypotenuse2 * Math.sin(upperLeft.bearingTo(lowerRight) * Math.PI / OneEightyDeg);
        double currentPixelX = currentDistanceX / totalDistanceX * ImageSizeW;

        return new double[]{currentPixelX, currentPixelY};

    }catch(Exception e){

        e.printStackTrace();
        return new double[]{0,0};

    }
4

5 に答える 5

2

まず、画像が斜めになっていないかのように、Google マップの座標をカスタム画像にマップします。ここでは、基本的にスケーリングとオフセットを扱っています。得られた座標が であると仮定します(x, y)

次に、次のマトリックスに従って座標を回転させます: Rotate a point around origin . 角度は既にわかっているので、カスタム マップが回転している中心点の座標を知ることができます。だとし(a, b)ます。具体的には:

1) マップの座標(x, y)(0,0)ベースの座標に変えます(x-a, y-b)

2) その行列を使用して回転すると、新しい coord が得られます(x', y')

(a, b)3)ベース座標に戻し(x'+a, y'+b)ます。

于 2013-11-04T13:21:28.547 に答える
1

私は完全に間違っているかもしれませんが、これは回転角度 (またはおそらく 4 つのコーナー) を取得する方法だと思います。

  1. lowerRight と upperLeft の間の角度アルファを取得します。私はこれが等しいと思います180 - lowerRight.bearingTo(upperLeft) 編集(この方程式は画面の象限に依存する必要があります)
  2. X、Y (画面) 座標を使用して、斜辺と下端の間の角度シータを取得します。(再び) この角度のサインは次のようになると思います:(height) / ((height^2) + (width^2))^1/2
  3. これで、回転角度は次のようになりますtheta - alpha

これを視覚化したい場合:

ブラ

于 2013-11-08T10:58:03.657 に答える
0

あなたの質問を理解できたかどうかわかりませんが、このように API から (X, Y) の位置を取得することはできませんか?

// myMap is a GoogleMap instance and location is a Location instance
Projection projection = myMap.getProjection();
LatLng latlng = new LatLng(location.getLatitude(), location.getLongitude());
Point pointInTheScreen = projection.toScreenLocation(latlng);

詳細については、GoogleMap API を参照してください。

于 2013-11-04T12:45:10.137 に答える
0

はい、表示されているマップにないポイントを描くことができます。LatLngBounds を設定して、これを回避します。次に、LatLngBounds のマップを表示します。マップを移動して LatLngBounds を表示することもできます。ここには、地球の接線や傾斜、双曲曲率など、難しいことは何もありません。すべては度単位で処理されるので、解決策を考えすぎないでください。地図を回転させると、ポイントも一緒に回転します。マップにポイントを追加して境界を見つけ、カメラを傾けます。カメラを後ろに傾けても、すべてのポイントが画面に表示されます! これにより、画面上のすべてのポイントから始めることができます。

サンプルと同じように、Google マップへの参照を取得します。

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the
    // map.

    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        // mMap = mMapFragment.getMap();
        // // Check if we were successful in obtaining the map.

        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();
        // use the settings maptype

        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

地図の境界を見つけ始めましょう。

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;

LatLngBounds および LatLngBounds.Builder のフィールド

private LatLngBounds bounds;
private LatLngBounds.Builder myLatLngBuilder;

LatLngBounds.Builder を初期化します

myLatLngBuilder = new LatLngBounds.Builder();

マップ上の各ポイント。

LatLng myLatLng = new LatLng(latitude, longitude);
myLatLngBuilder.include(myLatLng);

次に、ポイントの追加が終了したら、境界を構築します。

bounds = myLatLngBuilder.build();

これで、マップ上のすべてのポイントの境界がわかり、マップのその領域だけを表示できます。このコードは、マップ サンプルから取り出したものです。

final View mapView = getSupportFragmentManager().findFragmentById(
            R.id.map).getView();
    if (mapView.getViewTreeObserver().isAlive()) {
        mapView.getViewTreeObserver().addOnGlobalLayoutListener(
                new OnGlobalLayoutListener() {
                    @SuppressWarnings("deprecation")
                    // We use the new method when supported
                    @SuppressLint("NewApi")
                    // We check which build version we are using.
                    @Override
                    public void onGlobalLayout() {
                        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                            mapView.getViewTreeObserver()
                                    .removeGlobalOnLayoutListener(this);
                        } else {
                            mapView.getViewTreeObserver()
                                    .removeOnGlobalLayoutListener(this);
                        }
                        mMap.moveCamera(CameraUpdateFactory
                                .newLatLngBounds(bounds, 50));
                    }
                });
    }

これは基本的に、私のアプリBestrides KML Readerがマップを表示する方法であり、ポイントが画面外に表示されることはありません。

グッドラックダニー117

于 2013-11-08T02:03:43.457 に答える
-1

磁場センサー(別名コンパス) を使用してデバイスの向きを取得し、それを使用してカスタム ビューをマップに「グリッド整列」することができます。

于 2013-11-07T12:56:58.930 に答える