web-dev-qa-db-ja.com

マーカーが画面の下部にくるようにカメラを中央に配置するにはどうすればよいですか? (GoogleマップAPI V2 Android)

マーカーをクリックすると、カメラのデフォルトの動作は画面の中央に配置されますが、通常は情報ウィンドウに長いテキストの説明があるため、実際にカメラの位置を変更してマーカーが下にくるようにすると便利です画面(画面の中央に情報ウィンドウを作成)。次のようにonMarkerClick関数をオーバーライドすることでそれができるはずだと思います(この関数がtrueを返すと、デフォルトの動作はキャンセルされます)

@Override

public boolean onMarkerClick(final Marker marker) {


    // Google sample code comment : We return false to indicate that we have not

    // consumed the event and that we wish
    // for the default behavior to occur (which is for the camera to move
    // such that the
    // marker is centered and for the marker's info window to open, if it
    // has one).

    marker.showInfoWindow();

            CameraUpdate center=
                CameraUpdateFactory.newLatLng(new LatLng(XXXX,
                                                         XXXX));
            mMap.moveCamera(center);//my question is how to get this center

            // return false;
    return true;
}

編集:

受け入れられた回答の手順、以下のコードを使用して問題を解決しました:

@Override

    public boolean onMarkerClick(final Marker marker) {

                //get the map container height
        LinearLayout mapContainer = (LinearLayout) findViewById(R.id.map_container);
        container_height = mapContainer.getHeight();

        Projection projection = mMap.getProjection();

        LatLng markerLatLng = new LatLng(marker.getPosition().latitude,
                marker.getPosition().longitude);
        Point markerScreenPosition = projection.toScreenLocation(markerLatLng);
        Point pointHalfScreenAbove = new Point(markerScreenPosition.x,
                markerScreenPosition.y - (container_height / 2));

        LatLng aboveMarkerLatLng = projection
                .fromScreenLocation(pointHalfScreenAbove);

        marker.showInfoWindow();
        CameraUpdate center = CameraUpdateFactory.newLatLng(aboveMarkerLatLng);
        mMap.moveCamera(center);
        return true;



    }

助けてくれてありがとう^ ^

42
Arch1tect

後でこの答えを編集してコードを提供することもありますが、うまくいくと思うのはこれです:

  1. クリックしたマーカーのLatLngLatLng M)を取得します。
  2. LatLng MPointPoint Mに変換) Projection.toScreenLocation(LatLng) メソッドを使用します。これにより、デバイスのディスプレイ上のマーカーの位置(ピクセル単位)がわかります。
  3. 上記のポイント(新しいポイント)の位置を計算ポイントMマップの高さの半分まで。
  4. New PointLatLngに戻し、地図を中央に配置します。

here を見て、マップの高さを取得する方法に関する私の答えを探してください。

    // googleMap is a GoogleMap object
    // view is a View object containing the inflated map
    // marker is a Marker object
    Projection projection = googleMap.getProjection();
    LatLng markerPosition = marker.getPosition();
    Point markerPoint = projection.toScreenLocation(markerPosition);
    Point targetPoint = new Point(markerPoint.x, markerPoint.y - view.getHeight() / 2);
    LatLng targetPosition = projection.fromScreenLocation(targetPoint);
    googleMap.animateCamera(CameraUpdateFactory.newLatLng(targetPosition), 1000, null);
48
zbr

はい、Projectionクラスを使用します。すなわち:

マップの投影を取得します。

 Projection projection = map.getProjection();

マーカーの位置を取得します。

 LatLng markerLocation = marker.getPosition();

Projection.toScreenLocation()メソッドに場所を渡します。

 Point screenPosition = projection.toScreenLocation(markerLocation);

このように、マーカーを画面の中心または画面の周りに相対的に移動できます

Point mappoint = googleMap.getProjection().toScreenLocation(new LatLng(latitude, longitude));
        mappoint.set(mappoint.x, mappoint.y-30);
        googleMap.animateCamera(CameraUpdateFactory.newLatLng(googleMap.getProjection().fromScreenLocation(mappoint)));
20
Sampath Kumar

スクリーン投影に依存しないLarry McKenzieの回答(mProjection.toScreenLocation()など)が好きです。地図のズームレベルが低いと投影解像度が低下し、正確に表示されないことがありますポジション。したがって、Googleマップの仕様に基づいた計算は間違いなく問題を解決します。

以下は、下から画面サイズの30%にマーカーを移動するコードの例です。

zoom_lvl = mMap.getCameraPosition().zoom;
double dpPerdegree = 256.0*Math.pow(2, zoom_lvl)/170.0;
double screen_height = (double) mapContainer.getHeight();
double screen_height_30p = 30.0*screen_height/100.0;
double degree_30p = screen_height_30p/dpPerdegree;      
LatLng centerlatlng = new LatLng( latlng.latitude + degree_30p, latlng.longitude );         
mMap.animateCamera( CameraUpdateFactory.newLatLngZoom( centerlatlng, 15 ), 1000, null);
6
chunyap

私は同じ問題を抱えていて、次の完全に機能するソリューションを試しました

mMap.setOnMarkerClickListener(new OnMarkerClickListener() 
        {
            @Override
            public boolean onMarkerClick(Marker marker)
            {
                int yMatrix = 200, xMatrix =40;

                DisplayMetrics metrics1 = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(metrics1);
                switch(metrics1.densityDpi)
                {
                case DisplayMetrics.DENSITY_LOW:
                    yMatrix = 80;
                    xMatrix = 20;
                    break;
                case DisplayMetrics.DENSITY_MEDIUM:
                    yMatrix = 100;
                    xMatrix = 25;
                    break;
                case DisplayMetrics.DENSITY_HIGH:
                    yMatrix = 150;
                    xMatrix = 30;
                    break;
                case DisplayMetrics.DENSITY_XHIGH:
                    yMatrix = 200;
                    xMatrix = 40;
                    break;
                case DisplayMetrics.DENSITY_XXHIGH:
                    yMatrix = 200;
                    xMatrix = 50;
                    break;
                }

                Projection projection = mMap.getProjection();
                LatLng latLng = marker.getPosition();
                Point point = projection.toScreenLocation(latLng);
                Point point2 = new Point(point.x+xMatrix,point.y-yMatrix);

                LatLng point3 = projection.fromScreenLocation(point2);
                CameraUpdate zoom1 = CameraUpdateFactory.newLatLng(point3);
                mMap.animateCamera(zoom1);
                marker.showInfoWindow();
                return true;
            }
        });
3
Samadhan Medge

地図のズームインを気にせず、マーカーを下に表示したい場合は、以下を参照してください、私はそれがより簡単な解決策だと思います

double center = mMap.getCameraPosition().target.latitude;
double southMap = mMap.getProjection().getVisibleRegion().latLngBounds.southwest.latitude;

double diff = (center - southMap);

double newLat = marker.getPosition().latitude + diff;

CameraUpdate centerCam = CameraUpdateFactory.newLatLng(new LatLng(newLat, marker.getPosition().longitude));

mMap.animateCamera(centerCam);
3
Cam Connor

私は少し調査しましたが、ドキュメントによると、マップは正方形で、ズームレベルがゼロの場合、幅と高さは256dpおよび+/- 85度N/Sです。マップの幅はズームレベルで増加するため、幅と高さは256 * 2N dpになります。 Nはズームレベルです。したがって、理論的には、マップの高さを取得し、それを合計170度で除算して1度あたりのdpを取得することにより、新しい場所を決定できます。次に、dpで画面の高さ(またはマップビューの高さ)を2で割って取得し、ビューの半分のサイズを緯度に変換します。次に、新しいカメラポイントを南の緯度に設定します。必要に応じてコードを追加できますが、現時点では電話を使用しています。

1
Larry McKenzie

ここで提案されているすべてのソリューションを試し、それらを組み合わせて実装しました。マップ投影、傾斜、ズーム、情報ウィンドウの高さを考慮します。

マーカーを実際に「カメラビュー」の下部に配置するわけではありませんが、ほとんどの場合、情報ウィンドウとマーカーの中央にうまく収まると思います。

@Override
public boolean onMarkerClick(Marker marker) {
    mIsMarkerClick = true;
    mHandler.removeCallbacks(mUpdateTimeTask);
    mLoadTask.cancel(true);
    getActivity().setProgressBarIndeterminateVisibility(false);
    marker.showInfoWindow();
    Projection projection = getMap().getProjection();
    Point marketCenter = projection.toScreenLocation(marker.getPosition());
    float tiltFactor = (90 - getMap().getCameraPosition().tilt) / 90;
    marketCenter.y -= mInfoWindowAdapter.getInfoWindowHeight() / 2 * tiltFactor;
    LatLng fixLatLng = projection.fromScreenLocation(marketCenter);

    mMap.animateCamera(CameraUpdateFactory.newLatLng(fixLatLng), null);

    return true;
}

そして、カスタムアダプターは、情報ウィンドウの拡大表示のインスタンスを保持して、その高さを取得できるようにする必要があります。

public int getInfoWindowHeight(){
    if (mLastInfoWindoView != null){
        return mLastInfoWindoView.getMeasuredHeight();
    }
    return 0;
}
0
mdelolmo

いくつかの経験の後、私はそのソリューションを実装してきました。

DisplayMetrics metrics = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(metrics);

Point targetPoint = new Point(metrics.widthPixels / 2, metrics.heightPixels - metrics.heightPixels / 9);
LatLng targetLatlng = map.getProjection().fromScreenLocation(targetPoint);
double fromCenterToTarget = SphericalUtil.computeDistanceBetween(map.getCameraPosition().target, targetLatlng);

LatLng center = SphericalUtil.computeOffset(new LatLng(location.latitude, location.longitude), fromCenterToTarget/1.2, location.bearing);
CameraUpdate camera = CameraUpdateFactory.newLatLng(center);
map.animateCamera(camera, 1000, null);

ここに。まず、画面上のマーカーを移動する物理的なポイントを選択します。次に、それをLatLngに変換します。次のステップ-現在のマーカー位置(中心)からターゲットまでの距離を計算します。最後に、マップの中心をマーカーから計算された距離までまっすぐに移動します。

0
Edward

まだ位置座標に従ってカメラの中心を探している人

CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(Lat, Lon))
        .zoom(15) 
        .bearing(0)
        .tilt(45)
        .build();
    map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

クレジット

0
user3354265