获得MKMapView的界限

dea*_*oxy 31 iphone cocoa-touch mapkit bounds mkmapview

为了设置外部服务器的查询,我想在我正在构建的iPhone应用程序中获取当前Map View的边界.UIView应该响应边界,但似乎MKMapView没有.设置区域并放大地图后,我尝试获取边界.我坚持第一步,试图获得代表地图SE和NW角落的CGPoints.之后我打算用:

- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view
Run Code Online (Sandbox Code Playgroud)

将点转换为地图坐标.但我甚至无法做到那么远......

//Recenter and zoom map in on search location
MKCoordinateRegion region =  {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = mySearchLocation.searchLocation.coordinate;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[self.mapView setRegion:region animated:YES];


//After the new search location has been added to the map, and the map zoomed, we need to update the search bounds
//First we need to calculate the corners of the map
CGPoint se = CGPointMake(self.mapView.bounds.origin.x, mapView.bounds.origin.y);
CGPoint nw = CGPointMake((self.mapView.bounds.origin.x + mapView.bounds.size.width), (mapView.bounds.origin.y + mapView.bounds.size.height));
NSLog(@"points are: se %@, nw %@", se, nw);
Run Code Online (Sandbox Code Playgroud)

代码编译时没有警告,但se和nw都是null.查看self.mapView.bounds.origin.x变量为0.尝试直接使用NS.LogView.bounds.size.width给我一个"程序接收信号:"EXC_BAD_ACCESS"." 这似乎来自NSLog.

有人知道从MKMapView的可见区域获取东南角和西北角(在地图坐标中)的正确方法吗?

编辑:似乎每当你在这里问一些问题时,答案就会立刻传到你身上.我使用%@而不是@f来打印NSLog中的每个变量,这些变量在那里抛出错误.我还发现了MKMapview的annotationVisibleRect属性.虽然annotationVisibleRect似乎是基于父视图坐标.

dea*_*oxy 75

好吧,我正式回答了我自己的问题,但由于我没有在任何地方找到它,所以我会在这里发布答案:

//To calculate the search bounds...
//First we need to calculate the corners of the map so we get the points
CGPoint nePoint = CGPointMake(self.mapView.bounds.origin.x + mapView.bounds.size.width, mapView.bounds.origin.y);
CGPoint swPoint = CGPointMake((self.mapView.bounds.origin.x), (mapView.bounds.origin.y + mapView.bounds.size.height));

//Then transform those point into lat,lng values
CLLocationCoordinate2D neCoord;
neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView];

CLLocationCoordinate2D swCoord;
swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView];
Run Code Online (Sandbox Code Playgroud)


afa*_*ham 41

另一种选择是在MKMapView实例上使用visibleMapRect属性,并使用MKCoordinateForMapPoint()转换为lat/lon.

MKMapRect mRect = self.mapView.visibleMapRect;
MKMapPoint neMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), mRect.origin.y);
MKMapPoint swMapPoint = MKMapPointMake(mRect.origin.x, MKMapRectGetMaxY(mRect));
CLLocationCoordinate2D neCoord = MKCoordinateForMapPoint(neMapPoint);
CLLocationCoordinate2D swCoord = MKCoordinateForMapPoint(swMapPoint);
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,visibleMapRect的名称是真的,只返回地图的可见部分.在我们的应用程序中,我们有一个幻灯片UIView,当选择一个项目时,它会通过MapView.当它出来时,visibleMapRect只返回仍然可见的地图部分.在我们的实例中,我们需要整个界限,因此@deadroxy解决方案对我们更有效. (3认同)
  • 此解决方案存在一些限制.好在2010年,但现在地图的性质发生了变化.以下是重要的区别; a)如果用户旋转视图,坐标没有意义,b)如果地图进入3D模式,则可见区域可能是梯形而不是矩形. (3认同)

Avi*_*oss 9

迅速离开...(根据@ deadroxy的回答...)

typealias Edges = (ne: CLLocationCoordinate2D, sw: CLLocationCoordinate2D)

extension MKMapView {
    func edgePoints() -> Edges {
        let nePoint = CGPoint(x: self.bounds.maxX, y: self.bounds.origin.y)
        let swPoint = CGPoint(x: self.bounds.minX, y: self.bounds.maxY)
        let neCoord = self.convertPoint(nePoint, toCoordinateFromView: self)
        let swCoord = self.convertPoint(swPoint, toCoordinateFromView: self)
        return (ne: neCoord, sw: swCoord)
    }
}
Run Code Online (Sandbox Code Playgroud)


Rod*_*ici 8

这个扩展解决了这个问题并保持了centerCoordinateSwift 5 中的语法

extension MKMapView {
    var northWestCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.minX, y: visibleMapRect.minY).coordinate
    }

    var northEastCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.maxX, y: visibleMapRect.minY).coordinate
    }

    var southEastCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.maxX, y: visibleMapRect.maxY).coordinate
    }

    var southWestCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.minX, y: visibleMapRect.maxY).coordinate
    }
}
Run Code Online (Sandbox Code Playgroud)


onm*_*133 6

这个http://wiki.openstreetmap.org/wiki/Bounding_Box是一个边界框的文档

bbox = left,bottom,right,top
bbox = min Longitude , min Latitude , max Longitude , max Latitude
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

你可以有一个BoundingBox代表这个的结构

struct BoundingBox {
  let min: CLLocationCoordinate2D
  let max: CLLocationCoordinate2D

  init(rect: MKMapRect) {
    let bottomLeft = MKMapPointMake(rect.origin.x, MKMapRectGetMaxY(rect))
    let topRight = MKMapPointMake(MKMapRectGetMaxX(rect), rect.origin.y)

    min = MKCoordinateForMapPoint(bottomLeft)
    max = MKCoordinateForMapPoint(topRight)
  }

  var points: [CLLocationDegrees] {
    return [
      min.latitude,
      min.longitude,
      max.latitude
      max.longitude,
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

visibleMapRect是一样的region.span

let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 320, height: 640))
XCTAssertEqual(mapView.userLocation.coordinate.latitude, 0)
XCTAssertEqual(mapView.userLocation.coordinate.longitude, 0)

let boundingBox = BoundingBox(rect: mapView.visibleMapRect)
XCTAssertEqual(boundingBox.max.longitude-boundingBox.min.longitude, mapView.region.span.longitudeDelta)
XCTAssertEqual(boundingBox.max.latitude-boundingBox.min.latitude, mapView.region.span.latitudeDelta)
Run Code Online (Sandbox Code Playgroud)