考虑到视图位于其之上,如何专注于谷歌地图上的位置?

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(),我认为它不能一步完成...:/

以上是关于考虑到视图位于其之上,如何专注于谷歌地图上的位置?的主要内容,如果未能解决你的问题,请参考以下文章

动画相机以定位和设置谷歌地图中的平移

java中jpeg的地理定位

如何在谷歌地图应用程序中从另一个位置显示当前位置?

GPS不准确时如何计算可能位置的面积(如在谷歌地图中)

计算在鼠标光标位置放大的视图偏移

swift - 如何在应用程序运行时顺利加载谷歌地图视图