将Android GoogleMap居中放置在一个点上,同时缩放到足以包含另一个点

将Android GoogleMap居中放置在一个点上,同时缩放到足以包含另一个点,android,google-maps-android-api-2,Android,Google Maps Android Api 2,我想有一个像雷达屏幕一样的东西,它以用户所在的位置为中心,同时缩放到足以包含v2api的目标点。现在我正在使用 bounds = new LatLngBounds.Builder().include(destPos) .include(yourPos).build(); map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); 但这会集中在两点之间的某个点,并缩放以同时

我想有一个像雷达屏幕一样的东西,它以用户所在的位置为中心,同时缩放到足以包含v2api的目标点。现在我正在使用

bounds = new LatLngBounds.Builder().include(destPos)
                .include(yourPos).build();
        map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
但这会集中在两点之间的某个点,并缩放以同时包含这两个点。有没有这么简单的方法来做我想做的事?或者我必须或多或少地从头开始做一些数学计算(例如,计算两点之间的距离,计算LatLngBounds的lat/lng,以便用户位于定义矩形的中心,矩形的边缘包括目的地——考虑地图/屏幕尺寸)

以下是我所拥有的:

以下是我想要的:


我想出了如上所述的艰难方法。我为LatLngBounds设置了一个正方形区域,以简化获取方位编号的过程(这对我来说是可以的,只要它适合屏幕:您可以通过更多的三角来计算从非正方形矩形的中心到角的方位)。我还添加了一些填充,因为点之间的距离将与从中心到东北角的对角线相同,并且这将大于从中心到上边缘的距离,这意味着第二个点可能位于上边缘之上,并且不可见(如果它位于正北)。我从和那里借了很多钱

以下是我获取LatLngBounds的方法:

public LatLngBounds getBounds(double lat1, double lng1, double lat2,
        double lng2) {

    // defines a square area with point lat1,lng1 at center and includes
    // point
    // lat2, long2 with a buffer between edge and second point

    // get distance between two points
    float[] results = new float[1];

    Location.distanceBetween(lat1, lng1, lat2, lng2, results);
    double d = results[0];

    d = (d * 1.5); // add padding. The shortest distance to an edge of the
//square box is d * cos(45 degrees). Thus it's possible that the second point will be out of the box. To compensate I make the radius larger (d * 1/cos(45) = d * 1.41). I put a bit extra so that the second point isn't right on the edge of the screen. 

    long R = 6371000; // distance of earth's radius in meters

    d = d /(double) R;

    lat1 = Math.toRadians(lat1); // Current lat point converted to radians
    lng1 = Math.toRadians(lng1); // Current long point converted to radians

    // calculate northeast corner of LatLngBounds

    double brng = Math.toRadians(45); // bearing from center to northeast in
                                        // radians

    double resultLat1 = Math.asin(Math.sin(lat1) * Math.cos(d)
            + Math.cos(lat1) * Math.sin(d) * Math.cos(brng));

    double resultLng1 = lng1
            + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat1),
                    Math.cos(d) - Math.sin(lat1) * Math.sin(resultLat1));

    resultLat1 = Math.toDegrees(resultLat1);
    resultLng1 = Math.toDegrees(resultLng1);

    Log.i("My Code", "resultLat1: " + resultLat1 + " resultLng1: " + resultLng1);

    LatLng northEast = new LatLng(resultLat1, resultLng1);

    // calculate southwest corner of LatLngBounds. Everything is the same
    // except the bearing value

    brng = Math.toRadians(225); // bearing from center to southwest corner
                                // in radians
    double resultLat2 = Math.asin(Math.sin(lat1) * Math.cos(d)
            + Math.cos(lat1) * Math.sin(d) * Math.cos(brng));

    double resultLng2 = lng1
            + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat1),
                    Math.cos(d) - Math.sin(lat1) * Math.sin(resultLat2));

    resultLat2 = Math.toDegrees(resultLat2);
    resultLng2 = Math.toDegrees(resultLng2);

    Log.i("My Code", "resultLat2: " + resultLat2 + " resultLng2: " + resultLng2);

    LatLng southWest = new LatLng(resultLat2, resultLng2);

    LatLngBounds bounds = new LatLngBounds(southWest, northEast);

    return bounds;
}

你自己的答案太复杂了

您需要计算位置另一侧的点,并将其包含在
LatLngBounds

LatLng otherSidePos = new LatLng(2 * yourPos.latitude - destPos.latitude, 2 * yourPos.longitude - destPos.longitude);
bounds = new LatLngBounds.Builder().include(destPos)
                .include(otherSidePos).build();
        map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, padding));

注意:您不希望硬编码50像素作为填充。它在不同的设备上看起来会不同。改为使用与密度无关的像素。

用于缩放以包括所有标记,而无需更改相机目标(地图中心)

LatLngBounds.Builder=new LatLngBounds.Builder();
用于(标记:标记){
include(marker.getPosition());
}
LatLngBounds bounds=builder.build();
LatLng currentLoc=\u googleMapView.getCameraPosition().target;
//确保中心位置不变
double deltaLat=数学最大值(数学绝对值(bounds.southwest.latitude-CurrentLocal.latitude),
Math.abs(bounds.northeast.latitude-currentLoc.latitude);
double deltaLon=Math.max(Math.abs(bounds.soutwest.longitude-currentLoc.longitude),
abs(bounds.northeast.longitude-currentLoc.longitude);
LatLngBounds.Builder displayBuilder=新的LatLngBounds.Builder();
displayBuilder.include(当前位置)//没必要,但是嘿
displayBuilder.include(新LatLng(当前位置纬度+三角洲,当前位置经度+三角洲));
displayBuilder.include(新板条(当前位置纬度-三角洲,当前位置经度-三角洲));
_moveCamera(CameraUpdateFactory.newLatLngBounds(displayBuilder.build(),0));

@MES请尽可能添加屏幕截图。您可以将地图居中放置在第一个点,然后缩小,直到第二个点可见。我自己还没有试过,但也许你可以使用
GoogleMap#getProjection().getVisibleRegion().latLngBounds
获取地图的当前可见区域,然后使用
latLngBounds#contains()
询问第二个点是否在边界内。如果第二个点不可见,则可以缩小并再次检查,直到该点可见。我将在我的一个项目中尝试这个方法,如果它有效,我将发布一个答案。我确实尝试过。但是,当相机改变时,投影不会更新。绝对更优雅;我用这个代替。顺便说一句,我不是在填充50像素,而是在latlngbounds中填充1.5米的距离。我建议(因为对我来说,你的解决方案因为map还没有布局而崩溃)使用另一种方法来设置动画:
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,metrics.widthPixels,metrics.heightPixels,padding))
获取度量可以使用:
DisplayMetrics metrics=newdisplaymetrics()
getWindowManager().getDefaultDisplay().getMetrics(度量)@Vive如果在布局完成之前调用2个参数版本,它将崩溃。你可以自由使用4参数版本,或者在布局完成后调用它。是的,我知道,我已经读过了。我想提供解决方案,以防像我这样学习的人也会遇到类似的问题——他不必搜索。这就是为什么答案不是写给你的——我知道你知道这个问题,是写给像我这样的新手的。