【问题标题】:MKMapView setRegion: crashes at edge of worldMKMapView setRegion:在世界边缘崩溃
【发布时间】:2014-05-31 11:06:44
【问题描述】:

我正在使用此代码设置MKMapView 的区域,使其以pin 为中心并缩放以显示大约 10 公里的区域。

CLLocationAccuracy accuracy = kCLLocationAccuracyKilometer;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(pin.coordinate, accuracy * 10.0f, accuracy * 10.0f);
[self.mapSubView setRegion:region animated:NO];

当使用纬度 -90、经度 -58.359001159667969 的 pin 坐标运行代码时,将生成 region,如下所示:

绘制mapSubView时发生崩溃:-

由于未捕获的异常而终止应用 'NSInvalidArgumentException',原因:'无效区域 '

我第一次尝试解决这个问题是检查“边缘”纬度/经度(-90、+90、-180、+180),这解决了问题。但是,如果纬度变为 -89.99999,问题就会再次出现。

我猜这是由于纬度为 -90 和/或区域跨度的经度增量如此之大导致该区域实际上“脱离了这个世界”:p

任何关于如何将地图围绕在任何坐标上的大头针居中的建议,显示约 10 公里的区域,而不会发生这种崩溃,我们将不胜感激。

【问题讨论】:

    标签: objective-c mkmapview mapkit core-location


    【解决方案1】:

    根据 Sergey 和 supp-f 的回答,您还必须检查最大跨度值。

    纬度跨度最大值为180.0,经度跨度最大值为360.0

    func safeSetRegion(_ region: MKCoordinateRegion) {
        let myRegion = self.mapView.regionThatFits(region)
        if !(myRegion.span.latitudeDelta.isNaN || myRegion.span.longitudeDelta.isNaN) {
    
            // check for maximum span values (otherwise the setRegion(myRegion) call will crash)
            let deltaLat = min(180.0, myRegion.span.latitudeDelta)
            let deltaLong = min(360.0, myRegion.span.longitudeDelta)
    
            // now build a nice and easy span ...
            let coordinatesRegionWithSpan =  MKCoordinateSpan(
                         latitudeDelta: deltaLat,
                         longitudeDelta: deltaLong)
    
            // ... to use for an adjusted region
            let adjustedCoordinateRegion = MKCoordinateRegion(
                center: region.center,
                span: coordinatesRegionWithSpan)
    
            // and now it's safe to call
            self.mapView.setRegion(adjustedCoordinateRegion, animated: true)
        }
    }
    

    【讨论】:

      【解决方案2】:

      @supp-f 答案是正确的

      Swift 3解决方案:

      func safeSetRegion(_ region: MKCoordinateRegion) {
          let myRegion = self.mapView.regionThatFits(region)
          if !(myRegion.span.latitudeDelta.isNaN || myRegion.span.longitudeDelta.isNaN) {
              self.mapView.setRegion(myRegion, animated: true)
          }
      }
      

      【讨论】:

      • 文档中至少应该有一个“这个函数偶尔会在没有明显原因的情况下为 span 返回 NaN”
      【解决方案3】:

      首先,使用regionThatFits:方法调整地图区域。然后,将结果跨度增量与 nan 值进行比较。你应该有这样的东西:

      region = [self.mapView regionThatFits:region];
      if (!isnan(region.span.latitudeDelta) && !isnan(region.span.longitudeDelta)) {
        [self.mapView setRegion:region animated:YES];
      }
      

      【讨论】:

        【解决方案4】:

        我能够重现崩溃。我认为这是 SDK 中的错误。

        而且这个测试也会失败,但不会崩溃:

        MKCoordinateRegion region;
        region.center.longitude = coord.longitude;
        region.center.latitude = 90.f;//coord.latitude;
        region.span.longitudeDelta = 0.02f;
        region.span.latitudeDelta = 0.02f;
        
        [self.mapView setRegion:region animated:NO];
        

        那将是一个稳定的版本。只有在这里,该区域才非常大。如果有 NSNotFound,您可以测试 delta 值

        【讨论】:

        • 对照NSNotFound检查增量值不起作用,请参阅此控制台输出:-Longitude span: 1462142065660629.000000 vs NSNotFound: 2147483647
        • 是的,你是对的。我的错误,但我认为这也是某个地方定义的 MAX 值。一轮非常糟糕的工作是测试跨度是否是一个荒谬的值。我在 Apple 开发者论坛中搜索过这个问题,但我一无所获。抱歉,现在我知道更多了。
        猜你喜欢
        • 1970-01-01
        • 2020-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-17
        • 2014-11-20
        相关资源
        最近更新 更多