将 MKCooperativeRegion 转换为 MKMapRect

问题描述 投票:0回答:11

我的应用程序中有一个方形 MKMapView,我希望设置一个中心点和视图的确切高度/宽度(以米为单位)。

创建一个 MKCooperativeRegion 并将地图设置到它(如这段代码中......

MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(center_coord, 1000.0, 1000.0);
[self.mapView setRegion:region animated:YES];

..)无法正常工作,因为在这里使用区域仅意味着至少显示该区域,通常比该区域显示的更多。


我计划改用 setVisibleMapRect:animated: 方法,因为我相信这会缩放到实际传递的 MKMapRect

那么,有没有一种简单的方法可以在 MKcoordinateRegion 和 MKMapRect 之间进行转换?也许获取该区域的左上角和右下角坐标,并使用它们来制作 MKMapRect?

我在地图套件功能参考中看不到任何方便的东西。

(使用iOS 5,Xcode 4.2)

ios mkmapview mkcoordinateregion mkmaprect
11个回答
62
投票

向堆中添加另一个实现:

- (MKMapRect)MKMapRectForCoordinateRegion:(MKCoordinateRegion)region
{
    MKMapPoint a = MKMapPointForCoordinate(CLLocationCoordinate2DMake(
        region.center.latitude + region.span.latitudeDelta / 2, 
        region.center.longitude - region.span.longitudeDelta / 2));
    MKMapPoint b = MKMapPointForCoordinate(CLLocationCoordinate2DMake(
        region.center.latitude - region.span.latitudeDelta / 2, 
        region.center.longitude + region.span.longitudeDelta / 2));
    return MKMapRectMake(MIN(a.x,b.x), MIN(a.y,b.y), ABS(a.x-b.x), ABS(a.y-b.y));
}

注意:

MKMapRect
MKCoordinateRegion
之间的转换方法有很多种。这当然不是 MKCoordinateRegionMakeWithDistance() 的精确逆,但相当接近它。因此,来回转换时要小心,因为信息可能会丢失。
    


49
投票

func MKMapRectForCoordinateRegion(region:MKCoordinateRegion) -> MKMapRect { let topLeft = CLLocationCoordinate2D(latitude: region.center.latitude + (region.span.latitudeDelta/2), longitude: region.center.longitude - (region.span.longitudeDelta/2)) let bottomRight = CLLocationCoordinate2D(latitude: region.center.latitude - (region.span.latitudeDelta/2), longitude: region.center.longitude + (region.span.longitudeDelta/2)) let a = MKMapPoint(topLeft) let b = MKMapPoint(bottomRight) return MKMapRect(origin: MKMapPoint(x:min(a.x,b.x), y:min(a.y,b.y)), size: MKMapSize(width: abs(a.x-b.x), height: abs(a.y-b.y))) }



13
投票

CLLocationCoordinate2D coordinateOrigin = CLLocationCoordinate2DMake(latitude, longitude); CLLocationCoordinate2D coordinateMax = CLLocationCoordinate2DMake(latitude + cellSize, longitude + cellSize); MKMapPoint upperLeft = MKMapPointForCoordinate(coordinateOrigin); MKMapPoint lowerRight = MKMapPointForCoordinate(coordinateMax); MKMapRect mapRect = MKMapRectMake(upperLeft.x, upperLeft.y, lowerRight.x - upperLeft.x, lowerRight.y - upperLeft.y);



9
投票
MKCoordinateRegion

转换为

CGRect

- (CGRect)convertRegion:(MKCoordinateRegion)region toRectToView:(UIView *)view

并使用 
- (MKMapRect)mapRectForRect:(CGRect)rect


或者使用

MKMapPointForCoordinate

方法首先将坐标转换为

MKPoint
并使用它形成
MKMapRect
最终使用
setVisibleMapRect:animated:
    


9
投票

我想应该是:

CLLocationCoordinate2D topLeftCoordinate = CLLocationCoordinate2DMake(coordinateRegion.center.latitude + (coordinateRegion.span.latitudeDelta/2.0), coordinateRegion.center.longitude - (coordinateRegion.span.longitudeDelta/2.0)); MKMapPoint topLeftMapPoint = MKMapPointForCoordinate(topLeftCoordinate); CLLocationCoordinate2D bottomRightCoordinate = CLLocationCoordinate2DMake(coordinateRegion.center.latitude - (coordinateRegion.span.latitudeDelta/2.0), coordinateRegion.center.longitude + (coordinateRegion.span.longitudeDelta/2.0)); MKMapPoint bottomRightMapPoint = MKMapPointForCoordinate(bottomRightCoordinate); MKMapRect mapRect = MKMapRectMake(topLeftMapPoint.x, topLeftMapPoint.y, fabs(bottomRightMapPoint.x-topLeftMapPoint.x), fabs(bottomRightMapPoint.y-topLeftMapPoint.y));

根据
apple api参考

,MKCooperativeRegion.center代表区域的中心点; MKCoordinateSpan.latitudeDelta 表示要在地图上显示的南北距离(以度为单位); MKCoordinateSpan.longitudeDelta 表示要为地图区域显示的东西距离(以度为单位)。


4
投票

public func MKMapRectForCoordinateRegion(region:MKCoordinateRegion) -> MKMapRect { var topLeft = CLLocationCoordinate2D( latitude: min(region.center.latitude + (region.span.latitudeDelta/2.0), 90), longitude: region.center.longitude - (region.span.longitudeDelta/2.0) ) if topLeft.longitude < -180 { // We wrapped around the meridian topLeft.longitude += 360 } var bottomRight = CLLocationCoordinate2D( latitude: max(region.center.latitude - (region.span.latitudeDelta/2.0), -90), longitude: region.center.longitude + (region.span.longitudeDelta/2.0) ) if bottomRight.longitude > 180 { // We wrapped around the medridian bottomRight.longitude -= 360 } let topLeftMapPoint = MKMapPointForCoordinate(topLeft) let bottomRightMapPoint = MKMapPointForCoordinate(bottomRight) var width = bottomRightMapPoint.x - topLeftMapPoint.x if width < 0.0 { // Rect crosses meridian width += MKMapPointForCoordinate(CLLocationCoordinate2D(latitude: 0.0, longitude: 180.0)).x } let height = bottomRightMapPoint.y - topLeftMapPoint.y let size = MKMapSize(width: width, height: height) return MKMapRect(origin: topLeftMapPoint, size: size) }

一些测试用例代码(使用 Nimble):

func testMKMapRectForCoordinateRegion() { let northWesternRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(45.0, -90.0), MKCoordinateSpanMake(20.0, 20.0)) let northWesternMapRect = MKMapRectForCoordinateRegion(region: northWesternRegion) let convertedNWRegion = MKCoordinateRegionForMapRect(northWesternMapRect) expect(self.equivalentRegions(northWesternRegion, convertedNWRegion)).to(beTrue()) let northEasternRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(45.0, 90.0), MKCoordinateSpanMake(20.0, 20.0)) let northEasternMapRect = MKMapRectForCoordinateRegion(region: northEasternRegion) let convertedNERegion = MKCoordinateRegionForMapRect(northEasternMapRect) expect(self.equivalentRegions(northEasternRegion, convertedNERegion)).to(beTrue()) let southWesternRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(-45.0, -90.0), MKCoordinateSpanMake(20.0, 20.0)) let southWesternMapRect = MKMapRectForCoordinateRegion(region: southWesternRegion) let convertedSWRegion = MKCoordinateRegionForMapRect(southWesternMapRect) expect(self.equivalentRegions(southWesternRegion, convertedSWRegion)).to(beTrue()) let southEasternRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(-45.0, 90.0), MKCoordinateSpanMake(20.0, 20.0)) let southEasternMapRect = MKMapRectForCoordinateRegion(region: southEasternRegion) let convertedSERegion = MKCoordinateRegionForMapRect(southEasternMapRect) expect(self.equivalentRegions(southEasternRegion, convertedSERegion)).to(beTrue()) let meridianSpanEastRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(0.0, 170.0), MKCoordinateSpanMake(20.0, 20.0)) let meridianSpanEastMapRect = MKMapRectForCoordinateRegion(region: meridianSpanEastRegion) let convertedMeridianSpanEastRegion = MKCoordinateRegionForMapRect(meridianSpanEastMapRect) expect(self.equivalentRegions(meridianSpanEastRegion, convertedMeridianSpanEastRegion)).to(beTrue()) let meridianSpanWestRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(0.0, -170.0), MKCoordinateSpanMake(20.0, 20.0)) let meridianSpanWestMapRect = MKMapRectForCoordinateRegion(region: meridianSpanWestRegion) let convertedMeridianSpanWestRegion = MKCoordinateRegionForMapRect(meridianSpanWestMapRect) expect(self.equivalentRegions(meridianSpanWestRegion, convertedMeridianSpanWestRegion)).to(beTrue()) } fileprivate func equivalentRegions(_ regionA: MKCoordinateRegion, _ regionB: MKCoordinateRegion) -> Bool { // Allow a small delta between values let deltaAllowed: Double = 1.0 return (fabs(regionA.center.latitude - regionB.center.latitude) < deltaAllowed) && (fabs(regionA.center.longitude - regionB.center.longitude) < deltaAllowed) && (fabs(regionA.span.latitudeDelta - regionB.span.latitudeDelta) < deltaAllowed) && (fabs(regionA.span.longitudeDelta - regionB.span.longitudeDelta) < deltaAllowed) }



2
投票

大)。 这里是修复(针对 Swift 3 代码):

let topLeftMapPoint = MKMapPointForCoordinate(topLeft) let bottomRightMapPoint = MKMapPointForCoordinate(bottomRight) var width = bottomRightMapPoint.x - topLeftMapPoint.x if width < 0.0 { // Rect crosses from the Eastern Hemisphere to the Western Hemisphere width += MKMapPointForCoordinate(CLLocationCoordinate2D(latitude: 0.0, longitude: 180.0)).x } let height = bottomRightMapPoint.y - topLeftMapPoint.y let size = MKMapSize(width: width, height: height) return MKMapRect(origin: topLeftMapPoint, size: size)

使用上面的代码将 MKCooperativeRegion 转换为 MKMapRect,然后使用 MKCooperativeRegionForMapRect() 将其转换回 MKCooperativeRegion,这使我在地图上任何位置的输入区域和输出区域之间都具有良好的一致性。


2
投票

func mapRect(region: MKCoordinateRegion) -> MKMapRect { let topLeft = CLLocationCoordinate2D( latitude: region.center.latitude + (region.span.latitudeDelta/2.0), longitude: region.center.longitude - (region.span.longitudeDelta/2.0) ) let bottomRight = CLLocationCoordinate2D( latitude: region.center.latitude - (region.span.latitudeDelta/2.0), longitude: region.center.longitude + (region.span.longitudeDelta/2.0) ) let topLeftMapPoint = MKMapPointForCoordinate(topLeft) let bottomRightMapPoint = MKMapPointForCoordinate(bottomRight) let origin = MKMapPoint(x: topLeftMapPoint.x, y: topLeftMapPoint.y) let size = MKMapSize(width: fabs(bottomRightMapPoint.x - topLeftMapPoint.x), height: fabs(bottomRightMapPoint.y - topLeftMapPoint.y)) return MKMapRect(origin: origin, size: size) }



1
投票

func mapRectForCoordinateRegion(_ region: MKCoordinateRegion) -> MKMapRect { let topLeftCoordinate = CLLocationCoordinate2DMake(region.center.latitude + (region.span.latitudeDelta / 2.0), region.center.longitude - (region.span.longitudeDelta / 2.0)) let topLeftMapPoint = MKMapPoint(topLeftCoordinate) let bottomRightCoordinate = CLLocationCoordinate2DMake(region.center.latitude - (region.span.latitudeDelta / 2.0), region.center.longitude + (region.span.longitudeDelta / 2.0)) let bottomRightMapPoint = MKMapPoint(bottomRightCoordinate) return MKMapRect(x: topLeftMapPoint.x, y: topLeftMapPoint.y, width: fabs(bottomRightMapPoint.x - topLeftMapPoint.x), height: fabs(bottomRightMapPoint.y - topLeftMapPoint.y)) }



0
投票

extension MKCoordinateRegion { public var rect : MKMapRect { let topLeft = CLLocationCoordinate2D(latitude: self.center.latitude + (self.span.latitudeDelta/2), longitude: self.center.longitude - (self.span.longitudeDelta/2)) let bottomRight = CLLocationCoordinate2D(latitude: self.center.latitude - (self.span.latitudeDelta/2), longitude: self.center.longitude + (self.span.longitudeDelta/2)) let a = MKMapPoint(topLeft) let b = MKMapPoint(bottomRight) return MKMapRect(origin: MKMapPoint(x:min(a.x,b.x), y:min(a.y,b.y)), size: MKMapSize(width: abs(a.x-b.x), height: abs(a.y-b.y))) } }

这允许:
region.rect

正常工作:)

    


-1
投票
MKCoordinateRegionForMapRect


MKCoordinateRegion region = MKCoordinateRegionForMapRect(rect);

	
© www.soinside.com 2019 - 2024. All rights reserved.