2

我有以下代码:

 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);

我正在将这些转换为CLLocationCoordinate2Dwith MKCoordinateForMapPoint。例如:

    CLLocationCoordinate2D northCoords = MKCoordinateForMapPoint(northMapPoint);

除了northCoords,我还有centerCoords地图中心点的坐标。使用这两组坐标,我创建了一个数组,将这两组坐标CLLocationCoordinate2D coordinates[2]添加到其中...

接下来,我使用以下代码在两个坐标之间画一条线:

    MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:2];
    [_mapView addOverlay:polyLine];


- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay 
{
    MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
    polylineView.strokeColor = [UIColor redColor];
    polylineView.lineWidth = 5.0;
    return polylineView;
}

问题:

折线叠加起点(地图中心)始终从中心开始正确。然而,线的另一端(北/南/东/西)没有正确指向它应该在的位置。在下图中,我绘制了与上面的 4 MKMapPoint 相对应的所有四条线。

在此处输入图像描述

4

1 回答 1

6

总体思路是对的,但是有两个问题:

  1. 代码假定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职位。

  2. 代码假定用户位置将位于地图的中心。如果可以保证,那么您可以使用上述中点。然而,这是不必要的限制。即使用户位置不在中心,您也可以轻松调整代码以使其正常工作:

    //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并返回 anMKPolylineRenderer而不是MKPolylineView. 虽然 iOS 7 目前仍然可以工作,但如果你只实现viewForOverlay它,它在技术上已被弃用。您可以同时使用这两种委托方法,以便应用程序在任何 iOS 版本中运行(iOS 6 将使用它viewForOverlay,iOS 7 将使用rendererForOverlay它)。

于 2013-11-14T15:38:00.727 回答