在“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度(如果你在意的)上做一个数学解决方案是很复杂的。 如果您使用地图,则全部内置。 你也可以明显地在你现有的地图上使用这个解决方案,但用户会看到一个反弹。
以下是你如何做到这一点:
- 按照上面的定义进入界限
- 使用map.getCameraPosition()获取缩放。
- 如果使用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))
- 不能在androidTest中使用Kotlin反向方法名称 – 描述符错误异常
- 如何在Kotlin中实现setOnClickListener?
- 测试Android Kotlin应用程序 – 用匕首Mockito注入null
- 运行Spek测试显示错误“空测试套件”
- AndroidInjector <android.app.Activity>不能提供@ Provide或者@ Produces注解的方法
- android – 运行应用程序失败,错误“com.android.builder.dexing.DexArchiveMergerException:无法合并dex’
- 使用DataBinding库设置背景颜色资源或null
- Kotlin webview崩溃
- 一些绘图不能被发现