获取MKMapvIew的界限
为了设置一个查询到外部服务器,我想在我正在构build的iPhone应用程序中获取当前地图视图的边界。 UIView应该回应界限,但似乎MKMapView不。 设置一个区域并放大地图后,我尝试获取边界。 我被困在第一步,即尝试获取代表地图SE和NWangular的CGPoint。 之后,我要使用:
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view
将点转换为地图坐标。 但是我连那个都没有
//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);
代码编译没有警告但是se和nw都是空的。 看self.mapView.bounds.origin.xvariables是0.试图直接NSLog直接self.mapView.bounds.size.width给我一个“程序接收到的信号:”EXC_BAD_ACCESS“。” 这似乎来自NSLog。
任何人都知道从MKMapView的可见区域获取东南angular和西北angular(在地图坐标中)的正确方法吗?
编辑:这似乎每当你问这里的答案就来到你的权利。 我正在使用%@而不是@f打印NSLog中的每个variables,在那里抛出错误。 我也发现了MKMapview的annotationVisibleRect属性。 看来虽然annotationVisibleRect是基于父视图的坐标。
好吧,我正式回答了我自己的问题,但因为我没有find它的任何地方,我会在这里发布答案:
//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];
另一个select是在MKMapView实例上使用visibleMapRect属性,并使用MKCoordinateForMapPoint()转换为经纬度。
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);
迅速离开…(基于@ 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) } }
我能够得到这个Parse GeoBox查询:
//Calculate the corners of the map to get the points CGPoint nePoint = CGPointMake(self.mapView.bounds.origin.x + self.mapView.bounds.size.width, self.mapView.bounds.origin.y); CGPoint swPoint = CGPointMake((self.mapView.bounds.origin.x),(self.mapView.bounds.origin.y+ self.mapView.bounds.size.height)); //Transform points into lat/long values CLLocationCoordinate2D NECoordinate = [self.mapView convertPoint:nePoint toCoordinateFromView:self.mapView]; CLLocationCoordinate2D SWCoordinate = [self.mapView convertPoint:swPoint toCoordinateFromView:self.mapView]; //Convert to Parse GeoPoints PFGeoPoint *Southwest = [PFGeoPoint geoPointWithLatitude:SWCoordinate.latitude longitude:SWCoordinate.longitude]; PFGeoPoint *Northeast = [PFGeoPoint geoPointWithLatitude:NECoordinate.latitude longitude:NECoordinate.longitude];
此代码适用于像90/180度旋转的地图。 设置mapView.pitchEnabled = NO; 为更less的错误。
CLLocationDirection heading = mapView.camera.heading; float mapWidth = mapView.frame.size.width; float mapHeight = mapView.frame.size.height; float neX = mapWidth; float neY = 0.0; float swX = 0.0; float swY = mapHeight; if (heading >= 0 && heading <= 90) { //println("Q1") float ratio = heading / 90; neX = (1-ratio) * mapWidth; swX = (mapWidth*ratio); } else if (heading >= 90 && heading <= 180) { //println("Q2") float ratio = (heading - 90) / 90; neX = 0; neY = (mapHeight*ratio); swY = (1-ratio) * mapHeight; swX = mapWidth; } else if (heading >= 180 && heading <= 270) { //println("Q3") float ratio = (heading - 180) / 90; neX = mapWidth*ratio; neY = mapHeight; swX = (1-ratio) * mapWidth; swY = 0; } else if (heading >= 270 && heading <= 360) { //println("Q4"); float ratio = (heading - 270) / 90; neX = mapWidth; neY = (1-ratio) * mapHeight; swY = ratio * mapHeight; } CGPoint swPoint = CGPointMake(swX, swY); CGPoint nePoint = CGPointMake(neX, neY); CLLocationCoordinate2D swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView]; CLLocationCoordinate2D neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView];
这个http://wiki.openstreetmap.org/wiki/Bounding_Box是边界框的文件;
bbox = left,bottom,right,top bbox = min Longitude , min Latitude , max Longitude , max Latitude
你可以有一个代表这个的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.longitude, min.latitude, max.longitude, max.latitude ] } }
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)
请注意,在元组(long,lat)