来自MKMapRect的MKMapPoint与MKMapPointMake
我有以下代码:
MKMapRect mRect = self.mapView.visibleMapRect; MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMaxY(mRect)/2); MKMapPoint northMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect)/2, 0); MKMapPoint southMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect)/2, MKMapRectGetMaxY(mRect)); MKMapPoint westMapPoint = MKMapPointMake(0, MKMapRectGetMaxY(mRect)/2);
我正在使用MKCoordinateForMapPoint
将这些转换为CLLocationCoordinate2D
。 例如:
CLLocationCoordinate2D northCoords = MKCoordinateForMapPoint(northMapPoint);
与northCoords
,我有northCoords
,它是地图中心点的坐标。 使用这两组坐标,我创建了一个数组CLLocationCoordinate2D coordinates[2]
,我将这两个CLLocationCoordinate2D coordinates[2]
添加到…
接下来,我使用以下代码在两个坐标之间绘制一条线:
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:2]; [_mapView addOverlay:polyLine]; - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay { MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay]; polylineView.strokeColor = [UIColor redColor]; polylineView.lineWidth = 5.0; return polylineView; }
问题:
折线叠加起点(地图的中心)始终从中心开始是正确的。 然而,该线的另一端(北/南/东/西)并未正确指向它应该的位置。 在下面的图像中,我绘制了与上面的4个MKMapPoint相对应的所有四条线。
总体思路是正确的,但有两个问题:
-
代码假定
visibleMapRect
的边界是0,0,它们通常不是。visibleMapRect.origin
属性具有起始偏移量。 计算中点时必须考虑到这一点。使用当前代码,如果边界从80到100,
MKMapRectGetMaxX(mRect)/2
返回50,但可见地图rect从80到100,因此该行在最小x
之前的某处结束(而不是将结尾x
设置为90)。因此,而不是
MKMapRectGetMaxX(mRect)/2
,它应该是(MKMapRectGetMinX(mRect) + MKMapRectGetMaxX(mRect))/2
甚至更简单的MKMapRectGetMidX(mRect)
。同样适用于
y
位置。 -
代码假定用户位置将位于地图的中心。 如果这是有保证的,那么您可以使用上述中点。 但是,这是一个不必要的限制。 您可以轻松调整代码,以便即使用户位置不在中心也能正常工作:
//first convert userLocation to map points... MKMapPoint userLocationMapPoint = MKMapPointForCoordinate(mapView.userLocation.coordinate); MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), userLocationMapPoint.y); MKMapPoint northMapPoint = MKMapPointMake(userLocationMapPoint.x, MKMapRectGetMinY(mRect)); MKMapPoint southMapPoint = MKMapPointMake(userLocationMapPoint.x, MKMapRectGetMaxY(mRect)); MKMapPoint westMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), userLocationMapPoint.y);
以上应适用于0(N),90(E),180(S)和270(W)位置,但这可以使用某些三角函数推广到任何角度:
//radiusMapPoints will be the length of the line (max of width or height). double radiusMapPoints = MAX(mRect.size.width, mRect.size.height); //thetaRadians is the heading of the line in radians. //Example below is for 45.0 degrees. double thetaRadians = 45.0 * (M_PI/180.0); //endMapPoint is end of line starting from user location. MKMapPoint endMapPoint; endMapPoint.x = userLocationMapPoint.x + (radiusMapPoints * sin(thetaRadians)); endMapPoint.y = userLocationMapPoint.y - (radiusMapPoints * cos(thetaRadians)); CLLocationCoordinate2D lineCoords[2]; lineCoords[0] = mapView.userLocation.coordinate; lineCoords[1] = MKCoordinateForMapPoint(endMapPoint); MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:lineCoords count:2]; //can also use polylineWithPoints and pass MKMapPoints instead [mapView addOverlay:polyLine];
另请注意,对于iOS 7,您应该实现rendererForOverlay
委托方法而不是viewForOverlay
并返回MKPolylineRenderer
而不是MKPolylineView
。 虽然iOS 7目前仍然有效,如果你只实现viewForOverlay
它在技术上已被弃用。 您可以使用两种委托方法,以便应用程序适用于任何iOS版本(iOS 6将使用viewForOverlay
,iOS 7将使用rendererForOverlay
它就在那里)。