考虑到视图位于其之上,如何专注于谷歌地图上的位置?
Posted
技术标签:
【中文标题】考虑到视图位于其之上,如何专注于谷歌地图上的位置?【英文标题】:How to focus on location on Google maps, considering a view is on top of it? 【发布时间】:2016-10-25 12:41:46 【问题描述】:背景
假设我有一个谷歌地图视图,在它上面还有另一个视图,它覆盖了它的一部分,隐藏了地图的一些内容。
问题
我需要制作地图的“相机”,聚焦并在坐标上标记,但让它全部位于地图可见部分的中间。
类似这样的:
原始代码专注于(大约)整个屏幕的中心,使标记几乎不可见(因为底部视图覆盖了它)。
问题是,我找不到正确的方法将正确的值设置为地图本身的 Y 坐标(意思是纬度)。
我尝试过的
我试过,给定底部视图的高度,以及我放置标记的坐标,来计算增量(当然不会改变标记本身):
final float neededZoom = 6.5f;
int bottomViewHeight = bottomView.getHeight();
LatLng posToFocusOn = ...;
final Point point = mMap.getProjection().toScreenLocation(posToFocusOn);
final float curZoom = mMap.getCameraPosition().zoom;
point.y += bottomViewHeight * curZoom / neededZoom;
posToFocusOn = mMap.getProjection().fromScreenLocation(point);
final CameraUpdate cameraPosition = CameraUpdateFactory.newCameraPosition(new Builder().target(posToFocusOn).zoom(neededZoom).build());
遗憾的是,这聚焦在标记之上。
问题
我写的有什么问题吗?我能做些什么来解决它?
【问题讨论】:
【参考方案1】:好的,我找到了一种解决方法,我认为它适用于所有设备(在 3 台设备上进行了测试,每个设备都有不同的屏幕分辨率和尺寸):
我已经测量了标记本身有多少像素(然后转换为 DP)。
据此,我测量了每个视图的高度,并计算了移动相机所需的增量。
在我的情况下,是这样的(假设变焦是 6.5f):
//measured as 223 pixels on Nexus 5, which has xxhdpi, so divide by 3
final float oneDegreeInPixels = convertDpToPixels( 223.0f / 3.0f);
final float mapViewCenter = mapViewHeight / 2.0f;
final float bottomViewHeight = ...;
final float posToFocusInPixelsFromTop = (mapViewHeight - bottomViewHeight) / 2.0f ;// can optionally add the height of the view on the top area
final float deltaLatDegreesToMove = (mapViewCenter - posToFocusInPixelsFromTop) / oneDegreeInPixels;
LatLng posToFocusOn = new LatLng(latitude - deltaLatDegreesToMove, longitude);
final CameraUpdate cameraPosition = CameraUpdateFactory.newCameraPosition(new Builder().target(posToFocusOn).zoom(neededZoom).build());
它奏效了。
我想知道是否可以调整它以支持任何缩放值。
【讨论】:
【参考方案2】:您的代码几乎是正确的,但是它超出了标记,因为您在计算 point.y
而不是 bottomViewHeight/2
时考虑了 bottomViewHeight
(当您的视图大小为 200px 时,您只需将地图位移 100px重新定位):
point.y += (bottomViewHeight / 2) * curZoom / neededZoom;
更新:
这是一种更通用的方法,它考虑了地图边界并根据您的bottomView
的高度计算新的地图边界。这是独立于缩放的。
public void recenter()
LatLngBounds mapBounds = mMap.getProjection().getVisibleRegion().latLngBounds;
Point nothEastPoint = mMap.getProjection().toScreenLocation(mapBounds.northeast);
Point souhWestPoint = mMap.getProjection().toScreenLocation(mapBounds.southwest);
Point newNorthEast = new Point(nothEastPoint.x, nothEastPoint.y + bottomView.getHeight() / 2);
Point newSouhWestPoint = new Point(souhWestPoint.x, souhWestPoint.y + bottomView.getHeight() / 2);
LatLngBounds newBounds = LatLngBounds.builder()
.include(mMap.getProjection().fromScreenLocation(newNorthEast))
.include(mMap.getProjection().fromScreenLocation(newSouhWestPoint))
.build();
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(newBounds, 0));
请注意,每次您拨打 recenter()
时,地图都会移动。
【讨论】:
这是正确的,但出于某种原因,它只有在当前缩放与所需缩放相同时才能正常工作(否则如果当前缩放小于新的缩放。我认为缩放也有问题。删除缩放计算并没有帮助,以及更改它们的顺序(因为我认为我可能有错误的方法)。 关于“重新居中”,我不明白。该怎么办?我提到的各种变量呢?它如何考虑顶部的视图和要前往的坐标? 当您显示您的bottomView
时,您可以致电recenter
。它考虑了当前的缩放级别(因为它取代了地图边界)。顶部的视图被考虑在内,因为它使用bottomView.getHeight()
重新计算边界。该方法自动将当前缩放的地图当前中心移动到“新”中心(考虑到顶部的视图)
我在哪里提供输入坐标,标记在哪里(关注它)?我在哪里可以设置缩放?这些是输入参数......我不明白这个函数应该做什么,没有任何参数。重新以什么为中心?毕竟,地图显示的每个点都是某物的中心...... :)
recenter
居中 当前目标 和 当前缩放 考虑到bottomView
大小,所以你需要做mMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().target(posToFocusOn).zoom(neededZoom).build()));
先打电话给recenter()
。由于我们使用的是使用当前地图边界的mMap.getProjection()
,我认为它不能一步完成...:/以上是关于考虑到视图位于其之上,如何专注于谷歌地图上的位置?的主要内容,如果未能解决你的问题,请参考以下文章