Find the final latitude longitude after a movement on the globeCalculate second point knowing the starting point and distanceCalculate distance between two latitude-longitude points? (Haversine formula)Get New Co-Ordinate based on degrees and distanceAdd radius to Longitude and Latitude with C#SQlite Getting nearest locations (with latitude and longitude)Area of a latitude-longitude rectangle looks wrongI need to find possible values of latitude and longitude around a geometric position( with known distance )How do I calculate and get the next latitude-longitude estimated by time between two points every 10 minutes having the start and end point?Distance between two geolocations in java: NaNCalculate point between two coordinates based on a percentageHow to calculate all gps distance using haversine formula?
How did medieval manors handle population growth? Were there room for more fields to be ploughed?
Can a network vulnerability be exploited locally?
Find feasible point in polynomial time in linear programming
Find most "academic" implementation of doubly linked list
Are sweatpants frowned upon on flights?
What is the name of this plot that has rows with two connected dots?
To what extent should we fear giving offense?
Why is the Grievance Studies affair considered to be research requiring IRB approval?
Number of Fingers for a Math Oriented Race
Group riding etiquette
Would it be better to write a trilogy over a much longer series?
Should I ask for a raise one month before the end of an internship?
Why do we need geometry for pure math?
Spicing up a moment of peace
If the UK Gov. has authority to cancel article 50 notification, why do they have to agree an extension with the EU
Why is 3/4 a simple meter while 6/8 is a compound meter?
How many petaflops does it take to land on the moon? What does Artemis need with an Aitken?
Why does a sticker slowly peel off, but if it is pulled quickly it tears?
Is there any problem with a full installation on a USB drive?
Half filled water bottle
Printing a list as "a, b, c." using Python
Did the Apollo Guidance Computer really use 60% of the world's ICs in 1963?
Heat output from a 200W electric radiator?
Modifing a GFF3 file and writting to a new file
Find the final latitude longitude after a movement on the globe
Calculate second point knowing the starting point and distanceCalculate distance between two latitude-longitude points? (Haversine formula)Get New Co-Ordinate based on degrees and distanceAdd radius to Longitude and Latitude with C#SQlite Getting nearest locations (with latitude and longitude)Area of a latitude-longitude rectangle looks wrongI need to find possible values of latitude and longitude around a geometric position( with known distance )How do I calculate and get the next latitude-longitude estimated by time between two points every 10 minutes having the start and end point?Distance between two geolocations in java: NaNCalculate point between two coordinates based on a percentageHow to calculate all gps distance using haversine formula?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I am using the Haversine formula to calculate the distance from two latitude-longitude pairs.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2)
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1);
var dLon = deg2rad(lon2-lon1);
var lat1 = deg2rad(lat1);
var lat2 = deg2rad(lat2);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) *
Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
Given a starting point (lat1, lat2), the distance required to move on a straight line and the angle, I need to determine the endpoint (as in lat2 and lon2).
See my attempt below:
function getFinalLatLon(lat1, lon1, distance, angle)
var R = 6371; // Radius of the earth in km
var c = distance/R;
// Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) = c/2
var a = // stuck here
// looking for this part of the code
return [lat2, lon2];
javascript math geolocation haversine earthdistance
add a comment |
I am using the Haversine formula to calculate the distance from two latitude-longitude pairs.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2)
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1);
var dLon = deg2rad(lon2-lon1);
var lat1 = deg2rad(lat1);
var lat2 = deg2rad(lat2);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) *
Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
Given a starting point (lat1, lat2), the distance required to move on a straight line and the angle, I need to determine the endpoint (as in lat2 and lon2).
See my attempt below:
function getFinalLatLon(lat1, lon1, distance, angle)
var R = 6371; // Radius of the earth in km
var c = distance/R;
// Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) = c/2
var a = // stuck here
// looking for this part of the code
return [lat2, lon2];
javascript math geolocation haversine earthdistance
Inverse ofMath.atan2
? You mean...Math.tan
?
– meowgoesthedog
Jul 21 '17 at 9:58
Nope... Its Math.atan2
– Mwirabua Tim
Jul 21 '17 at 10:09
So you mean the inverse ofMath.atan2
is itself? I'm not trying to be funny here, but your problem statement (and title) is a little confusing.
– meowgoesthedog
Jul 21 '17 at 10:12
I just want an algorithm that gets me to [lat2, lon2] given [lat1, lat2] and horizontal distance moved. This is slightly similar stackoverflow.com/questions/2187657/…
– Mwirabua Tim
Jul 21 '17 at 10:15
movable-type.co.uk/scripts/latlong-vincenty.html
– Mohammed Sohail
Jul 22 '17 at 19:13
add a comment |
I am using the Haversine formula to calculate the distance from two latitude-longitude pairs.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2)
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1);
var dLon = deg2rad(lon2-lon1);
var lat1 = deg2rad(lat1);
var lat2 = deg2rad(lat2);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) *
Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
Given a starting point (lat1, lat2), the distance required to move on a straight line and the angle, I need to determine the endpoint (as in lat2 and lon2).
See my attempt below:
function getFinalLatLon(lat1, lon1, distance, angle)
var R = 6371; // Radius of the earth in km
var c = distance/R;
// Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) = c/2
var a = // stuck here
// looking for this part of the code
return [lat2, lon2];
javascript math geolocation haversine earthdistance
I am using the Haversine formula to calculate the distance from two latitude-longitude pairs.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2)
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1);
var dLon = deg2rad(lon2-lon1);
var lat1 = deg2rad(lat1);
var lat2 = deg2rad(lat2);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) *
Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
Given a starting point (lat1, lat2), the distance required to move on a straight line and the angle, I need to determine the endpoint (as in lat2 and lon2).
See my attempt below:
function getFinalLatLon(lat1, lon1, distance, angle)
var R = 6371; // Radius of the earth in km
var c = distance/R;
// Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) = c/2
var a = // stuck here
// looking for this part of the code
return [lat2, lon2];
javascript math geolocation haversine earthdistance
javascript math geolocation haversine earthdistance
edited Jul 24 '17 at 8:16
Mwirabua Tim
asked Jul 21 '17 at 9:55
Mwirabua TimMwirabua Tim
2,8325 gold badges38 silver badges50 bronze badges
2,8325 gold badges38 silver badges50 bronze badges
Inverse ofMath.atan2
? You mean...Math.tan
?
– meowgoesthedog
Jul 21 '17 at 9:58
Nope... Its Math.atan2
– Mwirabua Tim
Jul 21 '17 at 10:09
So you mean the inverse ofMath.atan2
is itself? I'm not trying to be funny here, but your problem statement (and title) is a little confusing.
– meowgoesthedog
Jul 21 '17 at 10:12
I just want an algorithm that gets me to [lat2, lon2] given [lat1, lat2] and horizontal distance moved. This is slightly similar stackoverflow.com/questions/2187657/…
– Mwirabua Tim
Jul 21 '17 at 10:15
movable-type.co.uk/scripts/latlong-vincenty.html
– Mohammed Sohail
Jul 22 '17 at 19:13
add a comment |
Inverse ofMath.atan2
? You mean...Math.tan
?
– meowgoesthedog
Jul 21 '17 at 9:58
Nope... Its Math.atan2
– Mwirabua Tim
Jul 21 '17 at 10:09
So you mean the inverse ofMath.atan2
is itself? I'm not trying to be funny here, but your problem statement (and title) is a little confusing.
– meowgoesthedog
Jul 21 '17 at 10:12
I just want an algorithm that gets me to [lat2, lon2] given [lat1, lat2] and horizontal distance moved. This is slightly similar stackoverflow.com/questions/2187657/…
– Mwirabua Tim
Jul 21 '17 at 10:15
movable-type.co.uk/scripts/latlong-vincenty.html
– Mohammed Sohail
Jul 22 '17 at 19:13
Inverse of
Math.atan2
? You mean... Math.tan
?– meowgoesthedog
Jul 21 '17 at 9:58
Inverse of
Math.atan2
? You mean... Math.tan
?– meowgoesthedog
Jul 21 '17 at 9:58
Nope... Its Math.atan2
– Mwirabua Tim
Jul 21 '17 at 10:09
Nope... Its Math.atan2
– Mwirabua Tim
Jul 21 '17 at 10:09
So you mean the inverse of
Math.atan2
is itself? I'm not trying to be funny here, but your problem statement (and title) is a little confusing.– meowgoesthedog
Jul 21 '17 at 10:12
So you mean the inverse of
Math.atan2
is itself? I'm not trying to be funny here, but your problem statement (and title) is a little confusing.– meowgoesthedog
Jul 21 '17 at 10:12
I just want an algorithm that gets me to [lat2, lon2] given [lat1, lat2] and horizontal distance moved. This is slightly similar stackoverflow.com/questions/2187657/…
– Mwirabua Tim
Jul 21 '17 at 10:15
I just want an algorithm that gets me to [lat2, lon2] given [lat1, lat2] and horizontal distance moved. This is slightly similar stackoverflow.com/questions/2187657/…
– Mwirabua Tim
Jul 21 '17 at 10:15
movable-type.co.uk/scripts/latlong-vincenty.html
– Mohammed Sohail
Jul 22 '17 at 19:13
movable-type.co.uk/scripts/latlong-vincenty.html
– Mohammed Sohail
Jul 22 '17 at 19:13
add a comment |
2 Answers
2
active
oldest
votes
If you are moving horizontally, you can increment the longitude by distance / (R * cos(lat))
. No atan
needed.
EDIT: Since you wanted a formula for the general case, consider the following geometric derivation:
Front view:
Side view:
Entire setup:
Notes:
r
is the unit vector of your starting position, ands
is the endpoint.a, b, c
are intermediate vectors to aid calculation.(θ, φ)
are the (lat, long) coordinates.γ
is the bearing of the direction you are going to travel in.δ
is the angle travelled through (distance / radiusR = 6400000m
).
We need a, b
to be perpendicular to r
and also a
aligned with North. This gives:
c
is given by (simple trigonometry):
And thus we get s
(through some very tedious algebra):
Now we can calculate the final (lat, long) coordinates of s
using:
Code:
function deg2rad(deg) return deg * (Math.PI / 180.0)
function rad2deg(rad) return rad * (180.0 / Math.PI)
function getFinalLatLong(lat1, long1, distance, angle, radius)
// calculate angles
var delta = distance / radius,
theta = deg2rad(lat1),
phi = deg2rad(long1),
gamma = deg2rad(angle);
// calculate sines and cosines
var c_theta = Math.cos(theta), s_theta = Math.sin(theta);
var c_phi = Math.cos(phi) , s_phi = Math.sin(phi) ;
var c_delta = Math.cos(delta), s_delta = Math.sin(delta);
var c_gamma = Math.cos(gamma), s_gamma = Math.sin(gamma);
// calculate end vector
var x = c_delta * c_theta * c_phi - s_delta * (s_theta * c_phi * c_gamma + s_phi * s_gamma);
var y = c_delta * c_theta * s_phi - s_delta * (s_theta * s_phi * c_gamma - c_phi * s_gamma);
var z = s_delta * c_theta * c_gamma + c_delta * s_theta;
// calculate end lat long
var theta2 = Math.asin(z), phi2 = Math.atan2(y, x);
return [rad2deg(theta2), rad2deg(phi2)];
Test cases:
Input
(lat, long) = (45, 0)
,angle = 0
,distance = radius * deg2rad(90)
=>(45, 180)
(as I said before)Input
(lat, long) = (0, 0)
,angle = 90
,distance = radius * deg2rad(90)
=>(0, 90)
(as expected - start at equator, travel east by 90 longitude)Input
(lat, long) = (54, 29)
,angle = 36
,distance = radius * deg2rad(360)
=>(54, 29)
(as expected - start at any random position and go full-circle in any direction)Interesting case: input
(lat, long) = (30, 0)
, everything else same. =>(0, 90)
(we expected(30, 90)
? - not starting at equator, travel by 90 degrees to North)The reason for this is that 90 degrees to North is not East (if you're not at the equator)! This diagram should show why:
As you can see, the path of movement at 90 degrees to the North is not in the direction of East.
Let me prove this one before I accept... Sounds so simple it blows my mind.
– Mwirabua Tim
Jul 21 '17 at 10:24
@TechyTimo oops hang on, sorry, there was a bit missing
– meowgoesthedog
Jul 21 '17 at 10:26
1
@meowgoesthedog Multiply by 180/Pi to get longitude increment in degrees
– MBo
Jul 21 '17 at 10:44
Great explanation. Seems to fail on the pass the first test case though - Taking earth radius = 6371000 metres, distance = radius * deg2rad(90) and getFinalLatLong(45, 0, distance, 90, radius) returns [4.96.., 90]
– Mwirabua Tim
Jul 22 '17 at 18:02
@TechyTimo you didnt show the rest of thatlat
value though - 4.961562726608714e-15 - i.e. a very small number close to the expected value of zero. This is a floating point error typical to these types of calculations, and is approximately the machine epsilon of double precision numbers.
– meowgoesthedog
Jul 22 '17 at 18:22
|
show 4 more comments
I just found a similar question here and I followed the solution to come up with a function that works for my case.
Hope it helps someone else:
function getFinalLatLon(lat1, lon1, distance, angle)
function deg2rad(deg)
return deg * (Math.PI/180)
// dy = R*sin(theta)
var dy = distance * Math.sin(deg2rad(angle))
var delta_latitude = dy/110574
// One degree of latitude on the Earth's surface equals (110574 meters
delta_latitude = parseFloat(delta_latitude.toFixed(6));
// final latitude = start_latitude + delta_latitude
var lat2 = lat1 + delta_latitude
// dx = R*cos(theta)
var dx = distance * Math.cos(deg2rad(angle))
// One degree of longitude equals 111321 meters (at the equator)
var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1)))
delta_longitude = parseFloat(delta_longitude.toFixed(6));
// final longitude = start_longitude + delta_longitude
var lon2 = lon1 + delta_longitude
return [lat2, lon2];
The angle is 0 degrees for a horizontal move. You can switch that as you wish. If someone is moving north that would be 90 deg. 135 degrees for north west and so on...
Not sure if this works. Say if you move due North by2 * (90 - lat)
. You should end up atlat
again, but you get180 - lat
, which is incorrect.
– meowgoesthedog
Jul 21 '17 at 11:07
I think its fixed - I was missing a degrees to radians conversion that was very much required.
– Mwirabua Tim
Jul 22 '17 at 4:09
although that is necessary, it doesn't solve the issue I pointed out above.
– meowgoesthedog
Jul 22 '17 at 10:38
I dont understand your question.. You move North by what? Can you use actual figures...
– Mwirabua Tim
Jul 22 '17 at 10:40
say if you are at latitude = 45. If you move North by distance (earth radius) * 90, you should still arrive at latitude 45 (just on the other side of the earth, i.e. your longitude changes by 180). However if you run your code, the latitude becomes 135, and the longitude doesn't change at all; I think this is an incorrect result.
– meowgoesthedog
Jul 22 '17 at 10:43
|
show 5 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f45234631%2ffind-the-final-latitude-longitude-after-a-movement-on-the-globe%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you are moving horizontally, you can increment the longitude by distance / (R * cos(lat))
. No atan
needed.
EDIT: Since you wanted a formula for the general case, consider the following geometric derivation:
Front view:
Side view:
Entire setup:
Notes:
r
is the unit vector of your starting position, ands
is the endpoint.a, b, c
are intermediate vectors to aid calculation.(θ, φ)
are the (lat, long) coordinates.γ
is the bearing of the direction you are going to travel in.δ
is the angle travelled through (distance / radiusR = 6400000m
).
We need a, b
to be perpendicular to r
and also a
aligned with North. This gives:
c
is given by (simple trigonometry):
And thus we get s
(through some very tedious algebra):
Now we can calculate the final (lat, long) coordinates of s
using:
Code:
function deg2rad(deg) return deg * (Math.PI / 180.0)
function rad2deg(rad) return rad * (180.0 / Math.PI)
function getFinalLatLong(lat1, long1, distance, angle, radius)
// calculate angles
var delta = distance / radius,
theta = deg2rad(lat1),
phi = deg2rad(long1),
gamma = deg2rad(angle);
// calculate sines and cosines
var c_theta = Math.cos(theta), s_theta = Math.sin(theta);
var c_phi = Math.cos(phi) , s_phi = Math.sin(phi) ;
var c_delta = Math.cos(delta), s_delta = Math.sin(delta);
var c_gamma = Math.cos(gamma), s_gamma = Math.sin(gamma);
// calculate end vector
var x = c_delta * c_theta * c_phi - s_delta * (s_theta * c_phi * c_gamma + s_phi * s_gamma);
var y = c_delta * c_theta * s_phi - s_delta * (s_theta * s_phi * c_gamma - c_phi * s_gamma);
var z = s_delta * c_theta * c_gamma + c_delta * s_theta;
// calculate end lat long
var theta2 = Math.asin(z), phi2 = Math.atan2(y, x);
return [rad2deg(theta2), rad2deg(phi2)];
Test cases:
Input
(lat, long) = (45, 0)
,angle = 0
,distance = radius * deg2rad(90)
=>(45, 180)
(as I said before)Input
(lat, long) = (0, 0)
,angle = 90
,distance = radius * deg2rad(90)
=>(0, 90)
(as expected - start at equator, travel east by 90 longitude)Input
(lat, long) = (54, 29)
,angle = 36
,distance = radius * deg2rad(360)
=>(54, 29)
(as expected - start at any random position and go full-circle in any direction)Interesting case: input
(lat, long) = (30, 0)
, everything else same. =>(0, 90)
(we expected(30, 90)
? - not starting at equator, travel by 90 degrees to North)The reason for this is that 90 degrees to North is not East (if you're not at the equator)! This diagram should show why:
As you can see, the path of movement at 90 degrees to the North is not in the direction of East.
Let me prove this one before I accept... Sounds so simple it blows my mind.
– Mwirabua Tim
Jul 21 '17 at 10:24
@TechyTimo oops hang on, sorry, there was a bit missing
– meowgoesthedog
Jul 21 '17 at 10:26
1
@meowgoesthedog Multiply by 180/Pi to get longitude increment in degrees
– MBo
Jul 21 '17 at 10:44
Great explanation. Seems to fail on the pass the first test case though - Taking earth radius = 6371000 metres, distance = radius * deg2rad(90) and getFinalLatLong(45, 0, distance, 90, radius) returns [4.96.., 90]
– Mwirabua Tim
Jul 22 '17 at 18:02
@TechyTimo you didnt show the rest of thatlat
value though - 4.961562726608714e-15 - i.e. a very small number close to the expected value of zero. This is a floating point error typical to these types of calculations, and is approximately the machine epsilon of double precision numbers.
– meowgoesthedog
Jul 22 '17 at 18:22
|
show 4 more comments
If you are moving horizontally, you can increment the longitude by distance / (R * cos(lat))
. No atan
needed.
EDIT: Since you wanted a formula for the general case, consider the following geometric derivation:
Front view:
Side view:
Entire setup:
Notes:
r
is the unit vector of your starting position, ands
is the endpoint.a, b, c
are intermediate vectors to aid calculation.(θ, φ)
are the (lat, long) coordinates.γ
is the bearing of the direction you are going to travel in.δ
is the angle travelled through (distance / radiusR = 6400000m
).
We need a, b
to be perpendicular to r
and also a
aligned with North. This gives:
c
is given by (simple trigonometry):
And thus we get s
(through some very tedious algebra):
Now we can calculate the final (lat, long) coordinates of s
using:
Code:
function deg2rad(deg) return deg * (Math.PI / 180.0)
function rad2deg(rad) return rad * (180.0 / Math.PI)
function getFinalLatLong(lat1, long1, distance, angle, radius)
// calculate angles
var delta = distance / radius,
theta = deg2rad(lat1),
phi = deg2rad(long1),
gamma = deg2rad(angle);
// calculate sines and cosines
var c_theta = Math.cos(theta), s_theta = Math.sin(theta);
var c_phi = Math.cos(phi) , s_phi = Math.sin(phi) ;
var c_delta = Math.cos(delta), s_delta = Math.sin(delta);
var c_gamma = Math.cos(gamma), s_gamma = Math.sin(gamma);
// calculate end vector
var x = c_delta * c_theta * c_phi - s_delta * (s_theta * c_phi * c_gamma + s_phi * s_gamma);
var y = c_delta * c_theta * s_phi - s_delta * (s_theta * s_phi * c_gamma - c_phi * s_gamma);
var z = s_delta * c_theta * c_gamma + c_delta * s_theta;
// calculate end lat long
var theta2 = Math.asin(z), phi2 = Math.atan2(y, x);
return [rad2deg(theta2), rad2deg(phi2)];
Test cases:
Input
(lat, long) = (45, 0)
,angle = 0
,distance = radius * deg2rad(90)
=>(45, 180)
(as I said before)Input
(lat, long) = (0, 0)
,angle = 90
,distance = radius * deg2rad(90)
=>(0, 90)
(as expected - start at equator, travel east by 90 longitude)Input
(lat, long) = (54, 29)
,angle = 36
,distance = radius * deg2rad(360)
=>(54, 29)
(as expected - start at any random position and go full-circle in any direction)Interesting case: input
(lat, long) = (30, 0)
, everything else same. =>(0, 90)
(we expected(30, 90)
? - not starting at equator, travel by 90 degrees to North)The reason for this is that 90 degrees to North is not East (if you're not at the equator)! This diagram should show why:
As you can see, the path of movement at 90 degrees to the North is not in the direction of East.
Let me prove this one before I accept... Sounds so simple it blows my mind.
– Mwirabua Tim
Jul 21 '17 at 10:24
@TechyTimo oops hang on, sorry, there was a bit missing
– meowgoesthedog
Jul 21 '17 at 10:26
1
@meowgoesthedog Multiply by 180/Pi to get longitude increment in degrees
– MBo
Jul 21 '17 at 10:44
Great explanation. Seems to fail on the pass the first test case though - Taking earth radius = 6371000 metres, distance = radius * deg2rad(90) and getFinalLatLong(45, 0, distance, 90, radius) returns [4.96.., 90]
– Mwirabua Tim
Jul 22 '17 at 18:02
@TechyTimo you didnt show the rest of thatlat
value though - 4.961562726608714e-15 - i.e. a very small number close to the expected value of zero. This is a floating point error typical to these types of calculations, and is approximately the machine epsilon of double precision numbers.
– meowgoesthedog
Jul 22 '17 at 18:22
|
show 4 more comments
If you are moving horizontally, you can increment the longitude by distance / (R * cos(lat))
. No atan
needed.
EDIT: Since you wanted a formula for the general case, consider the following geometric derivation:
Front view:
Side view:
Entire setup:
Notes:
r
is the unit vector of your starting position, ands
is the endpoint.a, b, c
are intermediate vectors to aid calculation.(θ, φ)
are the (lat, long) coordinates.γ
is the bearing of the direction you are going to travel in.δ
is the angle travelled through (distance / radiusR = 6400000m
).
We need a, b
to be perpendicular to r
and also a
aligned with North. This gives:
c
is given by (simple trigonometry):
And thus we get s
(through some very tedious algebra):
Now we can calculate the final (lat, long) coordinates of s
using:
Code:
function deg2rad(deg) return deg * (Math.PI / 180.0)
function rad2deg(rad) return rad * (180.0 / Math.PI)
function getFinalLatLong(lat1, long1, distance, angle, radius)
// calculate angles
var delta = distance / radius,
theta = deg2rad(lat1),
phi = deg2rad(long1),
gamma = deg2rad(angle);
// calculate sines and cosines
var c_theta = Math.cos(theta), s_theta = Math.sin(theta);
var c_phi = Math.cos(phi) , s_phi = Math.sin(phi) ;
var c_delta = Math.cos(delta), s_delta = Math.sin(delta);
var c_gamma = Math.cos(gamma), s_gamma = Math.sin(gamma);
// calculate end vector
var x = c_delta * c_theta * c_phi - s_delta * (s_theta * c_phi * c_gamma + s_phi * s_gamma);
var y = c_delta * c_theta * s_phi - s_delta * (s_theta * s_phi * c_gamma - c_phi * s_gamma);
var z = s_delta * c_theta * c_gamma + c_delta * s_theta;
// calculate end lat long
var theta2 = Math.asin(z), phi2 = Math.atan2(y, x);
return [rad2deg(theta2), rad2deg(phi2)];
Test cases:
Input
(lat, long) = (45, 0)
,angle = 0
,distance = radius * deg2rad(90)
=>(45, 180)
(as I said before)Input
(lat, long) = (0, 0)
,angle = 90
,distance = radius * deg2rad(90)
=>(0, 90)
(as expected - start at equator, travel east by 90 longitude)Input
(lat, long) = (54, 29)
,angle = 36
,distance = radius * deg2rad(360)
=>(54, 29)
(as expected - start at any random position and go full-circle in any direction)Interesting case: input
(lat, long) = (30, 0)
, everything else same. =>(0, 90)
(we expected(30, 90)
? - not starting at equator, travel by 90 degrees to North)The reason for this is that 90 degrees to North is not East (if you're not at the equator)! This diagram should show why:
As you can see, the path of movement at 90 degrees to the North is not in the direction of East.
If you are moving horizontally, you can increment the longitude by distance / (R * cos(lat))
. No atan
needed.
EDIT: Since you wanted a formula for the general case, consider the following geometric derivation:
Front view:
Side view:
Entire setup:
Notes:
r
is the unit vector of your starting position, ands
is the endpoint.a, b, c
are intermediate vectors to aid calculation.(θ, φ)
are the (lat, long) coordinates.γ
is the bearing of the direction you are going to travel in.δ
is the angle travelled through (distance / radiusR = 6400000m
).
We need a, b
to be perpendicular to r
and also a
aligned with North. This gives:
c
is given by (simple trigonometry):
And thus we get s
(through some very tedious algebra):
Now we can calculate the final (lat, long) coordinates of s
using:
Code:
function deg2rad(deg) return deg * (Math.PI / 180.0)
function rad2deg(rad) return rad * (180.0 / Math.PI)
function getFinalLatLong(lat1, long1, distance, angle, radius)
// calculate angles
var delta = distance / radius,
theta = deg2rad(lat1),
phi = deg2rad(long1),
gamma = deg2rad(angle);
// calculate sines and cosines
var c_theta = Math.cos(theta), s_theta = Math.sin(theta);
var c_phi = Math.cos(phi) , s_phi = Math.sin(phi) ;
var c_delta = Math.cos(delta), s_delta = Math.sin(delta);
var c_gamma = Math.cos(gamma), s_gamma = Math.sin(gamma);
// calculate end vector
var x = c_delta * c_theta * c_phi - s_delta * (s_theta * c_phi * c_gamma + s_phi * s_gamma);
var y = c_delta * c_theta * s_phi - s_delta * (s_theta * s_phi * c_gamma - c_phi * s_gamma);
var z = s_delta * c_theta * c_gamma + c_delta * s_theta;
// calculate end lat long
var theta2 = Math.asin(z), phi2 = Math.atan2(y, x);
return [rad2deg(theta2), rad2deg(phi2)];
Test cases:
Input
(lat, long) = (45, 0)
,angle = 0
,distance = radius * deg2rad(90)
=>(45, 180)
(as I said before)Input
(lat, long) = (0, 0)
,angle = 90
,distance = radius * deg2rad(90)
=>(0, 90)
(as expected - start at equator, travel east by 90 longitude)Input
(lat, long) = (54, 29)
,angle = 36
,distance = radius * deg2rad(360)
=>(54, 29)
(as expected - start at any random position and go full-circle in any direction)Interesting case: input
(lat, long) = (30, 0)
, everything else same. =>(0, 90)
(we expected(30, 90)
? - not starting at equator, travel by 90 degrees to North)The reason for this is that 90 degrees to North is not East (if you're not at the equator)! This diagram should show why:
As you can see, the path of movement at 90 degrees to the North is not in the direction of East.
edited Jul 23 '17 at 19:46
answered Jul 21 '17 at 10:20
meowgoesthedogmeowgoesthedog
12.1k4 gold badges16 silver badges28 bronze badges
12.1k4 gold badges16 silver badges28 bronze badges
Let me prove this one before I accept... Sounds so simple it blows my mind.
– Mwirabua Tim
Jul 21 '17 at 10:24
@TechyTimo oops hang on, sorry, there was a bit missing
– meowgoesthedog
Jul 21 '17 at 10:26
1
@meowgoesthedog Multiply by 180/Pi to get longitude increment in degrees
– MBo
Jul 21 '17 at 10:44
Great explanation. Seems to fail on the pass the first test case though - Taking earth radius = 6371000 metres, distance = radius * deg2rad(90) and getFinalLatLong(45, 0, distance, 90, radius) returns [4.96.., 90]
– Mwirabua Tim
Jul 22 '17 at 18:02
@TechyTimo you didnt show the rest of thatlat
value though - 4.961562726608714e-15 - i.e. a very small number close to the expected value of zero. This is a floating point error typical to these types of calculations, and is approximately the machine epsilon of double precision numbers.
– meowgoesthedog
Jul 22 '17 at 18:22
|
show 4 more comments
Let me prove this one before I accept... Sounds so simple it blows my mind.
– Mwirabua Tim
Jul 21 '17 at 10:24
@TechyTimo oops hang on, sorry, there was a bit missing
– meowgoesthedog
Jul 21 '17 at 10:26
1
@meowgoesthedog Multiply by 180/Pi to get longitude increment in degrees
– MBo
Jul 21 '17 at 10:44
Great explanation. Seems to fail on the pass the first test case though - Taking earth radius = 6371000 metres, distance = radius * deg2rad(90) and getFinalLatLong(45, 0, distance, 90, radius) returns [4.96.., 90]
– Mwirabua Tim
Jul 22 '17 at 18:02
@TechyTimo you didnt show the rest of thatlat
value though - 4.961562726608714e-15 - i.e. a very small number close to the expected value of zero. This is a floating point error typical to these types of calculations, and is approximately the machine epsilon of double precision numbers.
– meowgoesthedog
Jul 22 '17 at 18:22
Let me prove this one before I accept... Sounds so simple it blows my mind.
– Mwirabua Tim
Jul 21 '17 at 10:24
Let me prove this one before I accept... Sounds so simple it blows my mind.
– Mwirabua Tim
Jul 21 '17 at 10:24
@TechyTimo oops hang on, sorry, there was a bit missing
– meowgoesthedog
Jul 21 '17 at 10:26
@TechyTimo oops hang on, sorry, there was a bit missing
– meowgoesthedog
Jul 21 '17 at 10:26
1
1
@meowgoesthedog Multiply by 180/Pi to get longitude increment in degrees
– MBo
Jul 21 '17 at 10:44
@meowgoesthedog Multiply by 180/Pi to get longitude increment in degrees
– MBo
Jul 21 '17 at 10:44
Great explanation. Seems to fail on the pass the first test case though - Taking earth radius = 6371000 metres, distance = radius * deg2rad(90) and getFinalLatLong(45, 0, distance, 90, radius) returns [4.96.., 90]
– Mwirabua Tim
Jul 22 '17 at 18:02
Great explanation. Seems to fail on the pass the first test case though - Taking earth radius = 6371000 metres, distance = radius * deg2rad(90) and getFinalLatLong(45, 0, distance, 90, radius) returns [4.96.., 90]
– Mwirabua Tim
Jul 22 '17 at 18:02
@TechyTimo you didnt show the rest of that
lat
value though - 4.961562726608714e-15 - i.e. a very small number close to the expected value of zero. This is a floating point error typical to these types of calculations, and is approximately the machine epsilon of double precision numbers.– meowgoesthedog
Jul 22 '17 at 18:22
@TechyTimo you didnt show the rest of that
lat
value though - 4.961562726608714e-15 - i.e. a very small number close to the expected value of zero. This is a floating point error typical to these types of calculations, and is approximately the machine epsilon of double precision numbers.– meowgoesthedog
Jul 22 '17 at 18:22
|
show 4 more comments
I just found a similar question here and I followed the solution to come up with a function that works for my case.
Hope it helps someone else:
function getFinalLatLon(lat1, lon1, distance, angle)
function deg2rad(deg)
return deg * (Math.PI/180)
// dy = R*sin(theta)
var dy = distance * Math.sin(deg2rad(angle))
var delta_latitude = dy/110574
// One degree of latitude on the Earth's surface equals (110574 meters
delta_latitude = parseFloat(delta_latitude.toFixed(6));
// final latitude = start_latitude + delta_latitude
var lat2 = lat1 + delta_latitude
// dx = R*cos(theta)
var dx = distance * Math.cos(deg2rad(angle))
// One degree of longitude equals 111321 meters (at the equator)
var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1)))
delta_longitude = parseFloat(delta_longitude.toFixed(6));
// final longitude = start_longitude + delta_longitude
var lon2 = lon1 + delta_longitude
return [lat2, lon2];
The angle is 0 degrees for a horizontal move. You can switch that as you wish. If someone is moving north that would be 90 deg. 135 degrees for north west and so on...
Not sure if this works. Say if you move due North by2 * (90 - lat)
. You should end up atlat
again, but you get180 - lat
, which is incorrect.
– meowgoesthedog
Jul 21 '17 at 11:07
I think its fixed - I was missing a degrees to radians conversion that was very much required.
– Mwirabua Tim
Jul 22 '17 at 4:09
although that is necessary, it doesn't solve the issue I pointed out above.
– meowgoesthedog
Jul 22 '17 at 10:38
I dont understand your question.. You move North by what? Can you use actual figures...
– Mwirabua Tim
Jul 22 '17 at 10:40
say if you are at latitude = 45. If you move North by distance (earth radius) * 90, you should still arrive at latitude 45 (just on the other side of the earth, i.e. your longitude changes by 180). However if you run your code, the latitude becomes 135, and the longitude doesn't change at all; I think this is an incorrect result.
– meowgoesthedog
Jul 22 '17 at 10:43
|
show 5 more comments
I just found a similar question here and I followed the solution to come up with a function that works for my case.
Hope it helps someone else:
function getFinalLatLon(lat1, lon1, distance, angle)
function deg2rad(deg)
return deg * (Math.PI/180)
// dy = R*sin(theta)
var dy = distance * Math.sin(deg2rad(angle))
var delta_latitude = dy/110574
// One degree of latitude on the Earth's surface equals (110574 meters
delta_latitude = parseFloat(delta_latitude.toFixed(6));
// final latitude = start_latitude + delta_latitude
var lat2 = lat1 + delta_latitude
// dx = R*cos(theta)
var dx = distance * Math.cos(deg2rad(angle))
// One degree of longitude equals 111321 meters (at the equator)
var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1)))
delta_longitude = parseFloat(delta_longitude.toFixed(6));
// final longitude = start_longitude + delta_longitude
var lon2 = lon1 + delta_longitude
return [lat2, lon2];
The angle is 0 degrees for a horizontal move. You can switch that as you wish. If someone is moving north that would be 90 deg. 135 degrees for north west and so on...
Not sure if this works. Say if you move due North by2 * (90 - lat)
. You should end up atlat
again, but you get180 - lat
, which is incorrect.
– meowgoesthedog
Jul 21 '17 at 11:07
I think its fixed - I was missing a degrees to radians conversion that was very much required.
– Mwirabua Tim
Jul 22 '17 at 4:09
although that is necessary, it doesn't solve the issue I pointed out above.
– meowgoesthedog
Jul 22 '17 at 10:38
I dont understand your question.. You move North by what? Can you use actual figures...
– Mwirabua Tim
Jul 22 '17 at 10:40
say if you are at latitude = 45. If you move North by distance (earth radius) * 90, you should still arrive at latitude 45 (just on the other side of the earth, i.e. your longitude changes by 180). However if you run your code, the latitude becomes 135, and the longitude doesn't change at all; I think this is an incorrect result.
– meowgoesthedog
Jul 22 '17 at 10:43
|
show 5 more comments
I just found a similar question here and I followed the solution to come up with a function that works for my case.
Hope it helps someone else:
function getFinalLatLon(lat1, lon1, distance, angle)
function deg2rad(deg)
return deg * (Math.PI/180)
// dy = R*sin(theta)
var dy = distance * Math.sin(deg2rad(angle))
var delta_latitude = dy/110574
// One degree of latitude on the Earth's surface equals (110574 meters
delta_latitude = parseFloat(delta_latitude.toFixed(6));
// final latitude = start_latitude + delta_latitude
var lat2 = lat1 + delta_latitude
// dx = R*cos(theta)
var dx = distance * Math.cos(deg2rad(angle))
// One degree of longitude equals 111321 meters (at the equator)
var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1)))
delta_longitude = parseFloat(delta_longitude.toFixed(6));
// final longitude = start_longitude + delta_longitude
var lon2 = lon1 + delta_longitude
return [lat2, lon2];
The angle is 0 degrees for a horizontal move. You can switch that as you wish. If someone is moving north that would be 90 deg. 135 degrees for north west and so on...
I just found a similar question here and I followed the solution to come up with a function that works for my case.
Hope it helps someone else:
function getFinalLatLon(lat1, lon1, distance, angle)
function deg2rad(deg)
return deg * (Math.PI/180)
// dy = R*sin(theta)
var dy = distance * Math.sin(deg2rad(angle))
var delta_latitude = dy/110574
// One degree of latitude on the Earth's surface equals (110574 meters
delta_latitude = parseFloat(delta_latitude.toFixed(6));
// final latitude = start_latitude + delta_latitude
var lat2 = lat1 + delta_latitude
// dx = R*cos(theta)
var dx = distance * Math.cos(deg2rad(angle))
// One degree of longitude equals 111321 meters (at the equator)
var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1)))
delta_longitude = parseFloat(delta_longitude.toFixed(6));
// final longitude = start_longitude + delta_longitude
var lon2 = lon1 + delta_longitude
return [lat2, lon2];
The angle is 0 degrees for a horizontal move. You can switch that as you wish. If someone is moving north that would be 90 deg. 135 degrees for north west and so on...
edited Jul 22 '17 at 4:07
answered Jul 21 '17 at 10:40
Mwirabua TimMwirabua Tim
2,8325 gold badges38 silver badges50 bronze badges
2,8325 gold badges38 silver badges50 bronze badges
Not sure if this works. Say if you move due North by2 * (90 - lat)
. You should end up atlat
again, but you get180 - lat
, which is incorrect.
– meowgoesthedog
Jul 21 '17 at 11:07
I think its fixed - I was missing a degrees to radians conversion that was very much required.
– Mwirabua Tim
Jul 22 '17 at 4:09
although that is necessary, it doesn't solve the issue I pointed out above.
– meowgoesthedog
Jul 22 '17 at 10:38
I dont understand your question.. You move North by what? Can you use actual figures...
– Mwirabua Tim
Jul 22 '17 at 10:40
say if you are at latitude = 45. If you move North by distance (earth radius) * 90, you should still arrive at latitude 45 (just on the other side of the earth, i.e. your longitude changes by 180). However if you run your code, the latitude becomes 135, and the longitude doesn't change at all; I think this is an incorrect result.
– meowgoesthedog
Jul 22 '17 at 10:43
|
show 5 more comments
Not sure if this works. Say if you move due North by2 * (90 - lat)
. You should end up atlat
again, but you get180 - lat
, which is incorrect.
– meowgoesthedog
Jul 21 '17 at 11:07
I think its fixed - I was missing a degrees to radians conversion that was very much required.
– Mwirabua Tim
Jul 22 '17 at 4:09
although that is necessary, it doesn't solve the issue I pointed out above.
– meowgoesthedog
Jul 22 '17 at 10:38
I dont understand your question.. You move North by what? Can you use actual figures...
– Mwirabua Tim
Jul 22 '17 at 10:40
say if you are at latitude = 45. If you move North by distance (earth radius) * 90, you should still arrive at latitude 45 (just on the other side of the earth, i.e. your longitude changes by 180). However if you run your code, the latitude becomes 135, and the longitude doesn't change at all; I think this is an incorrect result.
– meowgoesthedog
Jul 22 '17 at 10:43
Not sure if this works. Say if you move due North by
2 * (90 - lat)
. You should end up at lat
again, but you get 180 - lat
, which is incorrect.– meowgoesthedog
Jul 21 '17 at 11:07
Not sure if this works. Say if you move due North by
2 * (90 - lat)
. You should end up at lat
again, but you get 180 - lat
, which is incorrect.– meowgoesthedog
Jul 21 '17 at 11:07
I think its fixed - I was missing a degrees to radians conversion that was very much required.
– Mwirabua Tim
Jul 22 '17 at 4:09
I think its fixed - I was missing a degrees to radians conversion that was very much required.
– Mwirabua Tim
Jul 22 '17 at 4:09
although that is necessary, it doesn't solve the issue I pointed out above.
– meowgoesthedog
Jul 22 '17 at 10:38
although that is necessary, it doesn't solve the issue I pointed out above.
– meowgoesthedog
Jul 22 '17 at 10:38
I dont understand your question.. You move North by what? Can you use actual figures...
– Mwirabua Tim
Jul 22 '17 at 10:40
I dont understand your question.. You move North by what? Can you use actual figures...
– Mwirabua Tim
Jul 22 '17 at 10:40
say if you are at latitude = 45. If you move North by distance (earth radius) * 90, you should still arrive at latitude 45 (just on the other side of the earth, i.e. your longitude changes by 180). However if you run your code, the latitude becomes 135, and the longitude doesn't change at all; I think this is an incorrect result.
– meowgoesthedog
Jul 22 '17 at 10:43
say if you are at latitude = 45. If you move North by distance (earth radius) * 90, you should still arrive at latitude 45 (just on the other side of the earth, i.e. your longitude changes by 180). However if you run your code, the latitude becomes 135, and the longitude doesn't change at all; I think this is an incorrect result.
– meowgoesthedog
Jul 22 '17 at 10:43
|
show 5 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f45234631%2ffind-the-final-latitude-longitude-after-a-movement-on-the-globe%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Inverse of
Math.atan2
? You mean...Math.tan
?– meowgoesthedog
Jul 21 '17 at 9:58
Nope... Its Math.atan2
– Mwirabua Tim
Jul 21 '17 at 10:09
So you mean the inverse of
Math.atan2
is itself? I'm not trying to be funny here, but your problem statement (and title) is a little confusing.– meowgoesthedog
Jul 21 '17 at 10:12
I just want an algorithm that gets me to [lat2, lon2] given [lat1, lat2] and horizontal distance moved. This is slightly similar stackoverflow.com/questions/2187657/…
– Mwirabua Tim
Jul 21 '17 at 10:15
movable-type.co.uk/scripts/latlong-vincenty.html
– Mohammed Sohail
Jul 22 '17 at 19:13