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

CLLocationCoordinate2Dこれらをwithに変換していMKCoordinateForMapPointます。例えば:

    CLLocationCoordinate2D northCoords = MKCoordinateForMapPoint(northMapPoint);

とともに、地図の中心にある点の座標northCoordsを持っています。centerCoordsこれら 2 つの座標セットを使用して、これら 2 つのセットを追加する配列を作成しCLLocationCoordinate2D coordinates[2]ます...

次に、次のコードを使用して 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 つの線すべてを描画しています。

ここに画像の説明を入力

4

1 に答える 1

6

全体的な考え方は正しいですが、2 つの問題があります。

  1. visibleMapRectコードは、の境界が 0,0 からであると想定していますが、通常はそうではありません。visibleMapRect.originプロパティには開始オフセットがあります。これは、中間点を計算する際に考慮する必要があります。

    現在のコードでは、境界が 80 から 100 の場合、MKMapRectGetMaxX(mRect)/250 を返しますが、表示されるマップの四角形は 80 から 100 であるため、行は最小値より前のどこかで終了します (終了を 90xに設定するのではなく)。x

    したがって、代わりに、またはさらに単純MKMapRectGetMaxX(mRect)/2にする必要があります。(MKMapRectGetMinX(mRect) + MKMapRectGetMaxX(mRect))/2MKMapRectGetMidX(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];


rendererForOverlayまた、iOS 7 では、 の代わりにデリゲート メソッドを実装し、 の代わりにをviewForOverlay返す 必要があることにも注意してください。iOS 7 は現在、実装するだけで動作しますが、技術的には推奨されていません。アプリが任意の iOS バージョンで動作するように、両方のデリゲート メソッドを使用できます (iOS 6 が使用し、iOS 7 が使用します)。MKPolylineRendererMKPolylineViewviewForOverlayviewForOverlayrendererForOverlay

于 2013-11-14T15:38:00.727 に答える