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

jmc*_*and 5 mapkit mkmapview ios

我需要在地图中适应某些边界.我得到了调用谷歌地理编码器和阅读视口属性的界限,如下所示:

{
    northeast =     {
        lat = "30.4212235";
        lng = "-97.486942";
    };
    southwest =     {
        lat = "30.1128403";
        lng = "-97.99917959999999";
    };
}
Run Code Online (Sandbox Code Playgroud)

然后我将它们转换为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]
    );    
Run Code Online (Sandbox Code Playgroud)

我知道我需要从这些坐标生成MKMapRect(或MKMapRegion,哪个更容易)然后[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;
}
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

小智 10

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

您可以MKCoordinateRegion通过计算出center点来创建一个,然后span是角点之间的绝对度差.

或者您可以MKMapRect使用MapKit函数创建一个MKMapPointForCoordinate.为了获得origin,找出西北坐标并将其转换为MKMapPoint.获得widthheight,获得角之间的mappoints的绝对差异(MKMapPoint首先使用函数将角从坐标转换为s).

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

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);
Run Code Online (Sandbox Code Playgroud)

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


Pal*_*ndo 2

如果您的边界可以跨越 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));
}
Run Code Online (Sandbox Code Playgroud)

但要小心那些MKMapRect跨越子午线的东西,因为它们来自龙居住的土地。如果您想了解那里存在的一些危险,请查看 MKMapRect 并显示跨越 180 度子午线的地图叠加层。你被警告了!