私はドキュメントに何かが欠けているに違いありません、これは簡単なはずだと思いました...
座標が1つあり、ある方向にxメートル離れた新しい座標を取得したい場合。どうすればよいですか?
私はのようなものを探しています
-(CLLocationCoordinate2D) translateCoordinate:(CLLocationCoordinate2D)coordinate translateMeters:(int)meters translateDegrees:(double)degrees;
ありがとう!
残念ながら、そのような関数はAPIで提供されていないため、独自に作成する必要があります。
このサイト 緯度/経度とサンプルJavaScriptコードを含むいくつかの計算を提供します。具体的には、「始点からの距離と方位を指定した目的地」というタイトルのセクションに、求めているものを計算する方法を示します。
JavaScriptコードはそのページの下部にあり、Objective-Cに変換する1つの可能な方法は次のとおりです。
- (double)radiansFromDegrees:(double)degrees
{
return degrees * (M_PI/180.0);
}
- (double)degreesFromRadians:(double)radians
{
return radians * (180.0/M_PI);
}
- (CLLocationCoordinate2D)coordinateFromCoord:
(CLLocationCoordinate2D)fromCoord
atDistanceKm:(double)distanceKm
atBearingDegrees:(double)bearingDegrees
{
double distanceRadians = distanceKm / 6371.0;
//6,371 = Earth's radius in km
double bearingRadians = [self radiansFromDegrees:bearingDegrees];
double fromLatRadians = [self radiansFromDegrees:fromCoord.latitude];
double fromLonRadians = [self radiansFromDegrees:fromCoord.longitude];
double toLatRadians = asin( sin(fromLatRadians) * cos(distanceRadians)
+ cos(fromLatRadians) * sin(distanceRadians) * cos(bearingRadians) );
double toLonRadians = fromLonRadians + atan2(sin(bearingRadians)
* sin(distanceRadians) * cos(fromLatRadians), cos(distanceRadians)
- sin(fromLatRadians) * sin(toLatRadians));
// adjust toLonRadians to be in the range -180 to +180...
toLonRadians = fmod((toLonRadians + 3*M_PI), (2*M_PI)) - M_PI;
CLLocationCoordinate2D result;
result.latitude = [self degreesFromRadians:toLatRadians];
result.longitude = [self degreesFromRadians:toLonRadians];
return result;
}
JSコードには、 このリンク が含まれています。これは、地球の円周の1/4を超える距離のより正確な計算を示しています。
また、上記のコードはkm単位の距離を受け入れるため、通過する前に必ずメートルを1000.0で割ってください。
私はそれを行う1つの方法を見つけ、正しい構造体と関数を見つけるために掘らなければなりませんでした。結局、度ではなくメートルを緯度と経度に使用することになりました。
これが私がそれをした方法です:
-(CLLocationCoordinate2D)translateCoord:(CLLocationCoordinate2D)coord MetersLat:(double)metersLat MetersLong:(double)metersLong{
CLLocationCoordinate2D tempCoord;
MKCoordinateRegion tempRegion = MKCoordinateRegionMakeWithDistance(coord, metersLat, metersLong);
MKCoordinateSpan tempSpan = tempRegion.span;
tempCoord.latitude = coord.latitude + tempSpan.latitudeDelta;
tempCoord.longitude = coord.longitude + tempSpan.longitudeDelta;
return tempCoord;
}
そしてもちろん、将来本当に学位を使用する必要がある場合は、実際に要求したように機能させるために、上記にいくつかの変更を加えるのは非常に簡単です(私は思う...)。
MKCoordinateRegion
の使用にはいくつかの問題があります。運が悪い軸のいずれかにゼロのデルタが必要な場合、2つのデルタがその緯度の投影に正確にマッピングされない可能性があるため、返される領域を調整して適合させることができます。 、など。
この関数は、MKMapPoint
を使用して座標変換を実行します。これにより、地図投影の座標空間内でポイントを移動し、そこから座標を抽出できます。
CLLocationCoordinate2D MKCoordinateOffsetFromCoordinate(CLLocationCoordinate2D coordinate, CLLocationDistance offsetLatMeters, CLLocationDistance offsetLongMeters) {
MKMapPoint offsetPoint = MKMapPointForCoordinate(coordinate);
CLLocationDistance metersPerPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude);
double latPoints = offsetLatMeters / metersPerPoint;
offsetPoint.y += latPoints;
double longPoints = offsetLongMeters / metersPerPoint;
offsetPoint.x += longPoints;
CLLocationCoordinate2D offsetCoordinate = MKCoordinateForMapPoint(offsetPoint);
return offsetCoordinate;
}
Nicsoftの答えは素晴らしく、まさに私が必要としていたものです。 Swift 3-yバージョンを作成しました。これはもう少し簡潔で、CLLocationCoordinate2D
インスタンスで直接呼び出すことができます。
public extension CLLocationCoordinate2D {
public func transform(using latitudinalMeters: CLLocationDistance, longitudinalMeters: CLLocationDistance) -> CLLocationCoordinate2D {
let region = MKCoordinateRegionMakeWithDistance(self, latitudinalMeters, longitudinalMeters)
return CLLocationCoordinate2D(latitude: latitude + region.span.latitudeDelta, longitude: longitude + region.span.longitudeDelta)
}
}