Ios 如何将由NE和SW坐标组成的特定边界拟合到可见地图视图中?

Ios 如何将由NE和SW坐标组成的特定边界拟合到可见地图视图中?,ios,mkmapview,mapkit,Ios,Mkmapview,Mapkit,我需要在一张地图上确定一个界限。通过调用google geocoder并读取viewport属性,我得到了如下界限: { northeast = { lat = "30.4212235"; lng = "-97.486942"; }; southwest = { lat = "30.1128403"; lng = "-97.99917959999999"; }; } 然后我将它们转换

我需要在一张地图上确定一个界限。通过调用google geocoder并读取viewport属性,我得到了如下界限:

{
    northeast =     {
        lat = "30.4212235";
        lng = "-97.486942";
    };
    southwest =     {
        lat = "30.1128403";
        lng = "-97.99917959999999";
    };
}
然后我将它们转换为CLLocationCoordinate2D

NSDictionary *viewport = [[[results objectAtIndex:0] objectForKey:@"geometry"] 
                                                     objectForKey:@"viewport"];
NSDictionary *NEDictionary = [viewport objectForKey:@"northeast"];
NSDictionary *SWDictionary = [viewport objectForKey:@"southwest"];

CLLocationCoordinate2D SWCoordinate = 
    CLLocationCoordinate2DMake(
        [[SWDictionary objectForKey:@"lat"] floatValue], 
        [[SWDictionary objectForKey:@"lng"] floatValue]
    );
CLLocationCoordinate2D NECoordinate = 
    CLLocationCoordinate2DMake(
        [[NEDictionary objectForKey:@"lat"] floatValue], 
        [[NEDictionary objectForKey:@"lng"] floatValue]
    );    
我知道我需要从这些坐标生成一个MKMapRect(或mkmaprection,以较容易的为准),然后[mapView setVisibleRect:newRect animated:YES](或[mapView setRegion:newRegion animated:YES]),但我不太确定如何实现。我需要一种方法将边界转换为正确的数据结构,例如:

- (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                   NE:(CLLocationCoordinate2D)ne {
    // CGFloat x = ??
    // CGFloat y = ??
    // CGFloat width = ??
    // CGFloat height = ??
    MKMapRect mapRectFromBounds = MKMapRectMake(x,y,width,height);
    return mapRectFromBounds;
}

有什么想法吗?

有几种方法可以做到这一点

您可以通过计算出
中心
点来创建
MKCoordinateRegion
,然后
span
是角点之间的绝对度数差

或者,您可以使用MapKit函数
MKMapPointForCoordinate
创建
MKMapRect
。若要获取
原点
,请算出西北坐标并将其转换为
MKMapPoint
。若要获取
宽度
高度
,请获取mappoints之间的绝对差值een角点(首先使用函数将角点从坐标转换为
MKMapPoint
s)

另一种快速方法是使用
MKMapRectUnion
函数的小技巧。从每个坐标创建一个零大小
MKMapRect
,然后使用该函数将两个矩形合并为一个大矩形:

MKMapPoint swPoint = MKMapPointForCoordinate(SWCoordinate);
MKMapRect swRect = MKMapRectMake(swPoint.x, swPoint.y, 0, 0);

MKMapPoint nePoint = MKMapPointForCoordinate(NECoordinate);
MKMapRect neRect = MKMapRectMake(nePoint.x, nePoint.y, 0, 0);

MKMapRect rect = MKMapRectUnion(swRect, neRect);

请记住,地图视图仍将根据地图视图的比例和所需的缩放比例对您请求的矩形进行自己的调整。(如果您想知道调整后的矩形是什么,请调用地图视图的
maprectthatthafits:
方法。)

我发现了一些有效的方法。我最终选择了以下方法:

- (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                   NE:(CLLocationCoordinate2D)ne {
    MKMapPoint nePoint = MKMapPointForCoordinate(ne);
    MKMapPoint swPoint = MKMapPointForCoordinate(sw);
    CGFloat width = ABS(nePoint.x - swPoint.x);
    CGFloat height = ABS(nePoint.y - swPoint.y);
    MKMapRect newMapRect = MKMapRectMake(
        MIN(swPoint.x, nePoint.x), 
        MIN(swPoint.y, nePoint.y), 
        width, 
        height
    );

    // if (!MKMapRectSpans180thMeridian(newMapRect)) {
        return newMapRect;
    // } else {
        // ????
    // }
}

如果您的边界可以跨越180子午线,则必须在转换中考虑:

- (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                   NE:(CLLocationCoordinate2D)ne 
{
    MKMapPoint pSW = MKMapPointForCoordinate(sw);
    MKMapPoint pNE = MKMapPointForCoordinate(ne);

    double antimeridianOveflow = 
      (ne.longitude > sw.longitude) ? 0 : MKMapSizeWorld.width;    

    return MKMapRectMake(pSW.x, pNE.y, 
                        (pNE.x - pSW.x) + antimeridianOveflow, 
                        (pSW.y - pNE.y));
}
但是要小心那些跨越地球的
MKMapRect
s,因为它们来自龙居住的土地。如果你想了解那里存在的一些危险,请查看
。您已收到警告!

如果您确信NE和SW点正确(且未切换为NW和SE或其他位置)然后你不需要ABS。如果你不确定它们是否是正确的角,那么你需要得到两个可能的x坐标中的最小值作为MKMapRectMake的第一个参数。y也是一样。当然,这一切都取决于你没有任何穿过反子午线的盒子。我可以理解为什么不担心哪个坐标是好的纵坐标是NE或SW,以防它们意外交换,所以我将MIN添加到MKMapRect x和y。我们如何处理反子午线问题?因为MKMapView不越过日期线,所以您也无法绘制一个穿过日期线的框。要确定给定的坐标是否真的越过了日期线,您需要确定h为NE,方框中为SW,然后检查NE是否比SW更“西”(在-180和+180之间)如果是这样的话,那么框就过了线。如果你不知道哪个坐标属于右上/左下角,那么就得到它们的经度值的绝对差值。>180意味着绕地球的另一边走会更短。@jmcopeland查看我关于“我们如何处理反经度问题”的答案.这真是一个巧妙的把戏。作为最不懂数学的人,应该得到更多的选票。