在“LatLngBounds”构建器上设置最大缩放级别

我在搜索中没有find答案,所以有几个答案,但他们并没有为我工作。

我在地图上有两个标记,我正在使用LatLngBounds构建器,以便让相机缩放到正确的缩放级别以将它们包括在内。 一切都按预期工作,除了一个事情,当两个标记彼此非常接近时,地图非常放大而且很好,具有这个缩放级别没有任何意义。

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。

我也有类似的情况,至少要有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); } 

我根据user2808624的答案实施了这个解决方案,但是使用Android Maps Utility Library中的SphericalUtil来进行计算。

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

来得迟,但也许有人有同样的问题,我有:我从一个地方,而不是从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中的最小距离定义的太小。您可以根据需要调整数字。

Google已经添加了一个API来限制最大/最小缩放级别。

 GoogleMap.setMaxZoomPreference() GoogleMap.setMinZoomPreference() 

下面是基于user2808624的答案的更短的版本。

  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行额外的代码。

你有没有考虑制作一个隐藏的地图片段,并用它来确定你的缩放/边界? 这显然不是最好的计算,但它可能是最简单/最准确的解决方案。 例如,在极点附近和经度0度(如果你在意的)上做一个数学解决方案是很复杂的。 如果您使用地图,则全部内置。 你也可以明显地在你现有的地图上使用这个解决方案,但用户会看到一个反弹。

以下是你如何做到这一点:

  1. 按照上面的定义进入界限
  2. 使用map.getCameraPosition()获取缩放。
  3. 如果使用CameraUpdateFactory.zoomTo(15)将zoom> 15缩小到15,

从4.0.30开始,无法限制缩放级别,但是您可能会跟踪此问题 。

简单的方法是像这个video强制缩放级别: http : //www.youtube.com/watch?v=-nCZ37HdheY
基本上,他们正在调用animateCamera达到一定的缩放级别。

这看起来有点奇怪,因为你有2个不是由用户启动的animation。

困难的方法是自己做数学。 尝试使用LatLng CameraUpdateFactory.newLatLngZoom作为这些点和最大缩放之间的中心,当您检测点彼此接近时。

快速修复是:

 gMap.setOnMapLoadedCallback(this); CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); gMap.setMaxZoomPreference(10); gMap.animateCamera(cu); @Override public void onMapLoaded() { gMap.resetMinMaxZoomPreference(); } 

要小心,它可以暂停缩放,直到地图完全重新加载。 但作为一个快速解决它的作品。

这只是简单的:

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

在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() } 

这通常在你的Util或Extensions文件中,然后你可以在任何地方使用它,就像这样:

 var bounds = builder.build() //To include all your existing points. bounds = builder.createBoundsWithZoomMaintained(bounds) //Updated bounds. mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10))