我的搜索中没有找到答案,有几个答案,但它们对我不起作用。
我在地图上有2个标记,我正在使用LatLngBounds构建器,以便让相机缩放到正确的缩放级别以包含它们。一切都按预期工作,除了一件事,当2个标记彼此非常接近时,地图非常放大,很好,这种缩放水平没有任何意义。
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(firstMarker.getPosition());
builder.include(secondMarker.getPosition());
LatLngBounds bounds = builder.build();
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, markerPadding);
有没有办法强制进行一定程度的变焦,之后相机不会变焦?这样可以避免地图放大/缩小。基本上我使用15.0f作为缩放级别。如果点太远,我希望变焦适合它们。如果点越来越近,我不希望缩放级别超过15.0f。
答案 0 :(得分:44)
我有一个类似的情况,我想要至少2公里的地图对角线。 因此,我只是在建造者身上增加了两个点:原始边界中心西北面的前1公里和中心东南面的第二个1公里。如果它们在界限内,它们不会改变任何东西。如果它们超出原始边界,则会将边界增加到有意义的大小。
以下是完整的代码示例:
public LatLngBounds createBoundsWithMinDiagonal(MarkerOptions firstMarker, MarkerOptions secondMarker) {
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(firstMarker.getPosition());
builder.include(secondMarker.getPosition());
LatLngBounds tmpBounds = builder.build();
/** Add 2 points 1000m northEast and southWest of the center.
* They increase the bounds only, if they are not already larger
* than this.
* 1000m on the diagonal translates into about 709m to each direction. */
LatLng center = tmpBounds.getCenter();
LatLng northEast = move(center, 709, 709);
LatLng southWest = move(center, -709, -709);
builder.include(southWest);
builder.include(northEast);
return builder.build();
}
private static final double EARTHRADIUS = 6366198;
/**
* Create a new LatLng which lies toNorth meters north and toEast meters
* east of startLL
*/
private static LatLng move(LatLng startLL, double toNorth, double toEast) {
double lonDiff = meterToLongitude(toEast, startLL.latitude);
double latDiff = meterToLatitude(toNorth);
return new LatLng(startLL.latitude + latDiff, startLL.longitude
+ lonDiff);
}
private static double meterToLongitude(double meterToEast, double latitude) {
double latArc = Math.toRadians(latitude);
double radius = Math.cos(latArc) * EARTHRADIUS;
double rad = meterToEast / radius;
return Math.toDegrees(rad);
}
private static double meterToLatitude(double meterToNorth) {
double rad = meterToNorth / EARTHRADIUS;
return Math.toDegrees(rad);
}
答案 1 :(得分:10)
我根据user2808624的答案实施了此解决方案,但使用SphericalUtil中的Android Maps Utility Library进行了计算。
final double HEADING_NORTH_EAST = 45;
final double HEADING_SOUTH_WEST = 215;
LatLng center = tmpBounds.getCenter();
LatLng norhtEast = SphericalUtil.computeOffset(center, 709,HEADING_NORTH_EAST);
LatLng southWest = SphericalUtil.computeOffset(center, 709,HEADING_SOUTH_WEST );
答案 2 :(得分:3)
迟到但也许某人有同样的问题:我收到了一个地方的界限,而不是来自LatLngBounds.Builder:
我使用Location.distanceBetween(...)来查明边界是否太小,然后使用边界中心的最小缩放级别:
if (areBoundsTooSmall(bounds, 300)) {
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(bounds.getCenter(), 17));
} else {
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20));
}
检查方法是:
private boolean areBoundsTooSmall(LatLngBounds bounds, int minDistanceInMeter) {
float[] result = new float[1];
Location.distanceBetween(bounds.southwest.latitude, bounds.southwest.longitude, bounds.northeast.latitude, bounds.northeast.longitude, result);
return result[0] < minDistanceInMeter;
}
我使用最小缩放级别17和填充20来获得太小的边界,这里的最小距离是300米。您可以根据需要调整数字。
答案 3 :(得分:2)
Google添加了一个用于限制最大/最小缩放级别的API。
GoogleMap.setMaxZoomPreference()
GoogleMap.setMinZoomPreference()
答案 4 :(得分:2)
这是一个基于user2808624的answer的更短的版本。
LatLngBounds bounds = builder.build();
LatLng center = bounds.getCenter();
builder.include(new LatLng(center.latitude-0.001f,center.longitude-0.001f));
builder.include(new LatLng(center.latitude+0.001f,center.longitude+0.001f));
bounds = builder.build();
它有点草率,但你可以使用0.001来放大不小于城市街区,0.01不低于城市景观。唯一的优势是它只有4行额外代码。
答案 5 :(得分:1)
您是否考虑制作隐藏的地图片段,并使用它来确定缩放/界限?它显然不是最好的计算,但它可能是最简单/最准确的解决方案。例如,制作一个在极点和0度经度附近工作的数学解决方案很复杂(如果你愿意的话)。如果您使用地图,那就已经内置了。您显然也可以在现有地图上使用此解决方案,但用户会看到反弹。
以下是你的表现:
答案 6 :(得分:1)
快速修复:
gMap.setOnMapLoadedCallback(this);
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
gMap.setMaxZoomPreference(10);
gMap.animateCamera(cu);
@Override
public void onMapLoaded() {
gMap.resetMinMaxZoomPreference();
}
请注意,在完全重新加载地图之前,它可以暂停缩放。但作为一个快速修复它的工作原理。
答案 7 :(得分:1)
这很简单:
LatLngBounds.Builder latlngBuilder = new LatLngBounds.Builder();
LatLng sydney1 = new LatLng(57.149651, -2.099075);
LatLng sydney2 = new LatLng(51.621441, -3.943646);
latlngBuilder.include(sydney1);
latlngBuilder.include(sydney2);
googlemap.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBuilder.build(), 100));
答案 8 :(得分:1)
根据user2808624和dvdrlee的回答,我在Kotlin写了一个扩展名:
fun LatLngBounds.Builder.createBoundsWithZoomMaintained(bounds: LatLngBounds) : LatLngBounds {
val HEADING_NORTH_EAST = 45.0 //NorthEast angle
val HEADING_SOUTH_WEST = 215.0 //SouthWest angle
val center = bounds.center
val northEast = SphericalUtil.computeOffset(center, 709.0, HEADING_NORTH_EAST) //1000 metres on the diagonal translates to 709 metres on either side.
val southWest = SphericalUtil.computeOffset(center, 709.0, HEADING_SOUTH_WEST)
this.include(northEast).include(southWest)
return this.build()
}
这通常位于您的Utils或Extensions文件中,然后您可以在任何地方使用它,就像这样:
var bounds = builder.build() //To include all your existing points.
bounds = builder.createBoundsWithZoomMaintained(bounds) //Updated bounds.
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10))
答案 9 :(得分:0)
自4.0.30起无法限制缩放级别,但您可以跟踪this issue。
简单的方法是像这个视频一样强制缩放级别:http://www.youtube.com/watch?v=-nCZ37HdheY
基本上,当达到某个缩放级别时,他们会调用animateCamera
。
这看起来有点奇怪,因为你有2个不是由用户启动的动画。
艰难的方法就是自己做数学。尝试使用CameraUpdateFactory.newLatLngZoom
LatLng
作为这些点之间的中心,并在检测到点彼此接近时进行最大缩放。