我正在使用 GoogleMaps SDK,目前我正在尝试将 GMSVisibleRegion 转换为 CLRegion。

GMSVisibleRegion 定义为:

typedef struct {
  CLLocationCoordinate2D nearLeft;
  CLLocationCoordinate2D nearRight;
  CLLocationCoordinate2D farLeft;
  CLLocationCoordinate2D farRight;
} GMSVisibleRegion;

这样做的最快方法是什么?

不幸的是,很难理解开发人员命名“near”和“far”的含义。我认为这个评论也很有用:
/**
 * Returns the region (four location coordinates) that is visible according to
 * the projection.
 *
 * The visible region can be non-rectangular. The result is undefined if the
 * projection includes points that do not map to anywhere on the map (e.g.,
 * camera sees outer space).
 */
 - (GMSVisibleRegion)visibleRegion;

非常感谢!

编辑:
好的,我的第一步是创建一个 GMSVisibleRegion 的 MKCoordinateRegion。

我建议使用以下代码将 GMSVisibleRegion 转换为 MKCoordinateRegion。任何异议。

+ (MKCoordinateRegion)regionForCenter:(CLLocationCoordinate2D)center andGMSVisibleRegion:(GMSVisibleRegion)visibleRegion
{
    CLLocationDegrees latitudeDelta = visibleRegion.farLeft.latitude - visibleRegion.nearLeft.latitude;
    CLLocationDegrees longitudeDelta = visibleRegion.farRight.longitude - visibleRegion.farLeft.longitude;
    MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);

    return MKCoordinateRegionMake(center, span);
}

最佳答案

我的猜测是“near”是屏幕底部 View 的角落,而“far”是屏幕顶部的角落。这是因为如果你倾斜了 View ,那么底角离相机最近,顶角离相机最远。

将其转换为 CLRegion 的一种方法可能是使用相机的目标作为中心,然后计算从最大距离到四个角的半径。这可能不是该区域上最紧密的拟合圆,但由于圆无论如何都无法拟合 View 的四边形,因此它可能足够接近。

这是一个辅助函数,用于计算两个 CLLocationCoordinate 值之间的距离(以米为单位):

double getDistanceMetresBetweenLocationCoordinates(
    CLLocationCoordinate2D coord1,
    CLLocationCoordinate2D coord2)
{
    CLLocation* location1 =
        [[CLLocation alloc]
            initWithLatitude: coord1.latitude
            longitude: coord1.longitude];
    CLLocation* location2 =
        [[CLLocation alloc]
            initWithLatitude: coord2.latitude
            longitude: coord2.longitude];

    return [location1 distanceFromLocation: location2];
}

然后 CLRegion 可以这样计算:
GMSMapView* mapView = ...;
...
CLLocationCoordinate2D centre = mapView.camera.target;
GMSVisibleRegion* visibleRegion = mapView.projection.visibleRegion;

double nearLeftDistanceMetres =
    getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.nearLeft);
double nearRightDistanceMetres =
    getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.nearRight);
double farLeftDistanceMetres =
    getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.farLeft);
double farRightDistanceMetres =
    getDistanceMetresBetweenLocationCoordinates(centre, visibleRegion.farRight);
double radiusMetres =
    MAX(nearLeftDistanceMetres,
    MAX(nearRightDistanceMetres,
    MAX(farLeftDistanceMetres, farRightDistanceMetres)));

CLRegion region = [[CLRegion alloc]
    initCircularRegionWithCenter: centre radius: radius identifier: @"id"];

更新:

关于 MKCoordinateRegion 的更新,您的示例代码可能不起作用。如果 map 已旋转90度,则farLeftnearLeft将具有相同的纬度,而farRightfarLeft将具有相同的经度,因此您的纬度和经度增量将为零。

您需要遍历所有四个 farLeftfarRightnearLeftnearRight ,计算每个的纬度和经度的最小值和最大值,然后从中计算增量。

适用于 iOS 的 Google Maps SDK 包含一个帮助类,它已经为您完成了其中的一些工作 - GMSCoordinateBounds 。它可以用 GMSVisibleRegion 初始化:
GMSMapView* mapView = ...;
....
GMSVisibleRegion visibleRegion = mapView.projection.visibleRegion;
GMSCoordinateBounds bounds =
    [[GMSCoordinateBounds alloc] initWithRegion: visibleRegion];
GMSCoordinateBounds 然后有定义边界的 northEastsouthWest 属性。因此,您可以按以下方式计算增量:
CLLocationDegrees latitudeDelta =
    bounds.northEast.latitude - bounds.southWest.latitude;
CLLocationDegrees longitudeDelta =
    bounds.northEast.longitude - bounds.southWest.longitude;

您还可以从边界计算中心,因此 MKCoordinateRegion :
CLLocationCoordinate2D centre = CLLocationCoordinate2DMake(
    (bounds.southWest.latitude + bounds.northEast.latitude) / 2,
    (bounds.southWest.longitude + bounds.northEast.longitude) / 2);
MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
return MKCoordinateRegionMake(centre, span);

10-08 15:36