背景及问题分析
在 MeshKit 中,用户在规划好飞行区域后,进入到设置航线参数的页面,因为所规划的区域大小不尽相同,仅仅靠单一的 zoomLevel 配置,往往无法在地图上一目了然地看到整个航线区域,导致在用户体验上差强人意。

实现该需求的基本思路就是划定一个矩形区域,该矩形区域刚好可以容纳整个多边形区域,然后把地图的显示中心设置为该矩形区域就行了。
这里计算这个矩形区域非常简单,只需要把多边形的坐标顶点求极值,即可组合出矩形区域的四个顶点坐标。关键在于如何利用 MapKit 和 MapBox 的接口把地图显示中心设置为该矩形区域。
MapKit 设置中心区域
在 计算MKMapView的zoomLevel(地图缩放等级) 一文中有提到 MapKit 上的 MKCoordinateRegion ,这个对象定义了在地图上的一块区域。
可以通过 MapKit 提供的下面这个方法,来把此区域显示在地图中心。
/// Changes the currently visible region and optionally animates the change./// Declarationfunc setRegion(_ region: MKCoordinateRegion, animated: Bool)
如上图,我们只需求出 右上角(NorthEastPoint)  和 左下角(SouthWestPoint) 即可定义出这个矩形。
具体设置代码如下:
let polygonCoordinates: [CLLocationCoordinate2D] = [...] // 多边形顶点坐标let latitudes = coordinates.map { $0.latitude }let longtitudes = coordinates.map { $0.longitude }// 求坐标点极值guard let minLat = latitudes.min(), let maxLat = latitudes.max(), let minLng = longtitudes.min(), let maxLng = longtitudes.max() else { return }// 求出 NorthEast(右上角点) 和 SouthWest(左下角点) 坐标点let southWestCoordinate = CLLocationCoordinate2D(latitude: minLat, longitude: minLng)let northEastCoordinate = CLLocationCoordinate2D(latitude: maxLat, longitude: maxLng)// 根据 NorthEast(右上角点) 和 SouthWest(左下角点) 求出 经纬度跨度,即 MKCoordinateSpanlet latDelta = northEastCoordinate.latitude - southWestCoordinate.latitudelet lngDelta = northEastCoordinate.longitude - southWestCoordinate.longitude// 根据 NorthEast(右上角点) 和 SouthWest(左下角点)求出 中心点let centerLat = (northEastCoordinate.latitude + southWestCoordinate.latitude) / 2let centerlng = (northEastCoordinate.longitude + southWestCoordinate.longitude) / 2let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lngDelta)let center = CLLocationCoordinate2D(latitude: centerLat, longitude: centerlng)let region = MKCoordinateRegion(center: center, span: span)mapView.setRegion(region, animated: true)
MapBox 设置中心区域
在 MapBox 中有 setVisibleCoordinateBounds 这样一个方法,它的作用同样可以把一片区域显示在地图中心。它需要传入的是 MGLCoordinateBounds 对象。
/**Changes the receiver’s viewport to fit the given coordinate bounds,optionally animating the change.@param bounds The bounds that the viewport will show in its entirety.*/- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds animated:(BOOL)animated;
 MGLCoordinateBounds 对象,正是由我们上面所说的 右上角(NorthEastPoint)  和 左下角(SouthWestPoint) 组成:
/** A rectangular area as measured on a two-dimensional map projection. */typedef struct __attribute__((objc_boxable)) MGLCoordinateBounds {/** Coordinate at the southwest corner. */CLLocationCoordinate2D sw;/** Coordinate at the northeast corner. */CLLocationCoordinate2D ne;} MGLCoordinateBounds;
所以这里就很简单了,只需要构建  MGLCoordinateBounds 对象,然后调用 setVisibleCoordinateBound 方法即可:
let polygonCoordinates: [CLLocationCoordinate2D] = [...] // 多边形顶点坐标let latitudes = coordinates.map { $0.latitude }let longtitudes = coordinates.map { $0.longitude }// 求坐标点极值guard let minLat = latitudes.min(), let maxLat = latitudes.max(), let minLng = longtitudes.min(), let maxLng = longtitudes.max() else { return }// 求出 NorthEast(右上角点) 和 SouthWest(左下角点) 坐标点let southWestCoordinate = CLLocationCoordinate2D(latitude: minLat, longitude: minLng)let northEastCoordinate = CLLocationCoordinate2D(latitude: maxLat, longitude: maxLng)let coordinateBound = MGLCoordinateBounds(sw: southWestCoordinate, ne: northEastCoordinate)mapbox.setVisibleCoordinateBounds(coordinateBound, animated: true)
