web-dev-qa-db-ja.com

開始点と距離がわかっている2番目の点を計算する

緯度と経度の値(ポイントA)を使用して、ポイントAから0ラジアンの方向にXメートル離れた別のポイントBを計算しようとしています。次に、ポイントBの緯度と経度の値を表示します。

例(疑似コード):

PointA_Lat = x.xxxx;
PointA_Lng = x.xxxx;
Distance = 3; //Meters
bearing = 0; //radians

new_PointB = PointA-Distance;

2点間の距離を計算できましたが、検索したいのは、距離と方位を知っている2番目の点です。

できればPHPまたはJavaScript。

ありがとうございました

28
pppglowacki

距離(R)をメートルで測定し、方位(シータ)を真東から反時計回りに測定しているようです。そして、あなたの目的(数十メートルの数)のために、平面形状は十分に正確でなければなりません。その場合、

dx = R*cos(theta) ; theta measured counterclockwise from due east
dy = R*sin(theta) ; dx, dy same units as R

シータが真北から時計回りに測定される場合(たとえば、コンパス方位)、dxとdyの計算はわずかに異なります。

dx = R*sin(theta)  ; theta measured clockwise from due north
dy = R*cos(theta)  ; dx, dy same units as R

どちらの場合も、経度と緯度の度数の変化は次のとおりです。

delta_longitude = dx/(111320*cos(latitude))  ; dx, dy in meters
delta_latitude = dy/110540                   ; result in degrees long/lat

定数110540と111320の違いは、地球の偏平によるものです(極と赤道の円周は異なります)。

これは、後のあなたの質問のパラメータを使用した実際の例です。

経度-87.62788度、緯度41.88592度の開始位置を指定して、開始位置から北西500メートルの点の座標を見つけます。

真東から反時計回りに角度を測定している場合、「北西」はtheta = 135度に対応します。 Rは500メートルです。

dx = R*cos(theta) 
   = 500 * cos(135 deg) 
   = -353.55 meters

dy = R*sin(theta) 
   = 500 * sin(135 deg) 
   = +353.55 meters

delta_longitude = dx/(111320*cos(latitude)) 
                = -353.55/(111320*cos(41.88592 deg))
                = -.004266 deg (approx -15.36 arcsec)

delta_latitude = dy/110540
               = 353.55/110540
               =  .003198 deg (approx 11.51 arcsec)

Final longitude = start_longitude + delta_longitude
                = -87.62788 - .004266
                = -87.632146

Final latitude = start_latitude + delta_latitude
               = 41.88592 + .003198
               = 41.889118
46
Jim Lewis

3600秒の弧は1度(緯度または長さ)であり、海里は1852メートルあり、海里は1秒の弧であることを知っている場合に役立ちます。もちろん、比較的短い距離に依存しています。それ以外の場合は、球面三角法を使用する必要があります。

3

Swiftを使用した更新バージョンは次のとおりです。

let location = CLLocation(latitude: 41.88592 as CLLocationDegrees, longitude: -87.62788 as CLLocationDegrees)

let distanceInMeter : Int = 500
let directionInDegrees : Int = 135

let lat = location.coordinate.latitude
let long = location.coordinate.longitude

let radDirection : CGFloat = Double(directionInDegrees).degreesToRadians

let dx = Double(distanceInMeter) * cos(Double(radDirection)) 
let dy = Double(distanceInMeter) * sin(Double(radDirection))

let radLat : CGFloat = Double(lat).degreesToRadians

let deltaLongitude = dx/(111320 * Double(cos(radLat)))  
let deltaLatitude = dy/110540                   

let endLat = lat + deltaLatitude
let endLong = long + deltaLongitude

この拡張機能を使用する:

extension Double {
    var degreesToRadians : CGFloat {
        return CGFloat(self) * CGFloat(M_PI) / 180.0
    }
}
2
SteffenK