Oblicz drugi punkt znając punkt początkowy i odległość

Używając wartości szerokości i długości geograficznej (punkt A), staram się obliczyć inny punkt B, X metrów z dala o 0 radianów od punktu A. następnie Wyświetl wartości szerokości i długości geograficznej punktu B.

Przykład (Pseudo kod):

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

new_PointB = PointA-Distance;

Udało mi się obliczyć odległość między dwoma punktami, ale chcę znaleźć drugi punkt, znając odległość i położenie.

Najlepiej w PHP lub Javascript.

Dziękuję

Author: pppglowacki, 2010-02-02

4 answers

Wygląda na to, że mierzysz odległość (R) w metrach i łożysko (theta) w kierunku przeciwnym do ruchu wskazówek zegara z kierunku wschodniego. A dla Twoich celów (hundereds metrów), geometria płaszczyzny powinna być wystarczająco dokładna. W takim przypadku

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

Jeśli theta jest mierzona zgodnie z ruchem wskazówek zegara z północy (na przykład łożyska kompasu), obliczenia dla dx I dy są nieco inne:

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

W obu przypadkach zmiana stopni długości i szerokości geograficznej wynosi:

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

Różnica między stałe 110540 i 111320 wynika z obłędu ziemi (obwody polarne i równikowe są różne).

Oto wypracowany przykład, używając parametrów z późniejszego pytania:

Podano miejsce startu na długości -87.62788 stopni, szerokość 41.88592 stopni, znajdź współrzędne punktu 500 metrów na północny zachód od miejsca startu.

Jeśli mierzymy kąty w kierunku przeciwnym do ruchu wskazówek zegara ze wschodu," północny zachód " odpowiada do theta=135 stopni. R jest 500 metrów.

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
 41
Author: Jim Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-30 17:00:21

Mogłoby pomóc, gdybyś wiedział, że 3600 sekund łuku wynosi 1 stopień (lat. albo długo.), że w milie morskiej znajduje się 1852 m, a mila morska to 1 sekunda łuku. Oczywiście zależy ci na relatywnie krótkich odległościach, inaczej musiałbyś użyć trygonometrii sferycznej.

 3
Author: Arthur Kalliokoski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-02 21:18:54

Oto zaktualizowana wersja za pomocą 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

Użycie tego rozszerzenia:

extension Double {
    var degreesToRadians : CGFloat {
        return CGFloat(self) * CGFloat(M_PI) / 180.0
    }
}
 2
Author: SteffenK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-25 15:20:47

Dx = sin (łożysko)
dy = cos (bearing)
/ align = "center" / 3x + dist dx;
y = center.y + dist
dy;

 -1
Author: Chris H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-02 21:09:18