Generate more points between two longitude-lattitude points
In a 2D plane, given two points (x1, y1)
and (x2, y2)
, it is straight forward to generate N
equally spaced points along the straight line between the two points. This also applies for 3D plane.
However, I'm trying to work out how would you do so for geo-coordinated points. To illustrate my point further, say you have point A with (latA, lonA)
that represents the lattitude and longitude of its, and another point B with (latB, lonB)
. How would you generate N
points between A and B? Is there a straightforward library in python
that could achieve this?
python python-3.x latitude-longitude
add a comment |
In a 2D plane, given two points (x1, y1)
and (x2, y2)
, it is straight forward to generate N
equally spaced points along the straight line between the two points. This also applies for 3D plane.
However, I'm trying to work out how would you do so for geo-coordinated points. To illustrate my point further, say you have point A with (latA, lonA)
that represents the lattitude and longitude of its, and another point B with (latB, lonB)
. How would you generate N
points between A and B? Is there a straightforward library in python
that could achieve this?
python python-3.x latitude-longitude
Related: gis.stackexchange.com/questions/221843/…
– Michael Butscher
Nov 10 at 23:06
add a comment |
In a 2D plane, given two points (x1, y1)
and (x2, y2)
, it is straight forward to generate N
equally spaced points along the straight line between the two points. This also applies for 3D plane.
However, I'm trying to work out how would you do so for geo-coordinated points. To illustrate my point further, say you have point A with (latA, lonA)
that represents the lattitude and longitude of its, and another point B with (latB, lonB)
. How would you generate N
points between A and B? Is there a straightforward library in python
that could achieve this?
python python-3.x latitude-longitude
In a 2D plane, given two points (x1, y1)
and (x2, y2)
, it is straight forward to generate N
equally spaced points along the straight line between the two points. This also applies for 3D plane.
However, I'm trying to work out how would you do so for geo-coordinated points. To illustrate my point further, say you have point A with (latA, lonA)
that represents the lattitude and longitude of its, and another point B with (latB, lonB)
. How would you generate N
points between A and B? Is there a straightforward library in python
that could achieve this?
python python-3.x latitude-longitude
python python-3.x latitude-longitude
asked Nov 10 at 23:01
Quang Thinh Ha
1174
1174
Related: gis.stackexchange.com/questions/221843/…
– Michael Butscher
Nov 10 at 23:06
add a comment |
Related: gis.stackexchange.com/questions/221843/…
– Michael Butscher
Nov 10 at 23:06
Related: gis.stackexchange.com/questions/221843/…
– Michael Butscher
Nov 10 at 23:06
Related: gis.stackexchange.com/questions/221843/…
– Michael Butscher
Nov 10 at 23:06
add a comment |
1 Answer
1
active
oldest
votes
You can do this directly with numpy. The idea is to use the standard interpolation formula for 3D space, like A + d * (B - A)
. Points computed like this lie on the chord between A and B but can be projected back to the sphere.
In order to have a uniform distribution over angles, we need the mapping from angles to distances on the chord, like in the figure here
This shows chord locations for uniformly spaced angles and was generated with the code below to check correctness, since all the angles and trigonometric functions are easy to mess up.
def embed_latlon(lat, lon):
"""lat, lon -> 3d point"""
lat_, lon_ = np.deg2rad(lat), np.deg2rad(lon)
r = np.cos(lat_)
return np.array([
r * np.cos(lon_),
r * np.sin(lon_),
np.sin(lat_)
]).T
def project_latlon(x):
"""3d point -> (lat, lon)"""
return (
np.rad2deg(np.arcsin(x[:, 2])),
np.rad2deg(np.arctan2(x[:, 1], x[:, 0]))
)
def _great_circle_linspace_3d(x, y, n):
"""interpolate two points on the unit sphere"""
# angle from scalar product
alpha = np.arccos(x.dot(y))
# angle relative to mid point
beta = alpha * np.linspace(-.5, .5, n)
# distance of interpolated point to center of sphere
r = np.cos(.5 * alpha) / np.cos(beta)
# distance to mid line
m = r * np.sin(beta)
# interpolation on chord
chord = 2. * np.sin(.5 * alpha)
d = (m + np.sin(.5 * alpha)) / chord
points = x[None, :] + (y - x)[None, :] * d[:, None]
return points / np.sqrt(np.sum(points**2, axis=1, keepdims=True))
def great_circle_linspace(lat1, lon1, lat2, lon2, n):
"""interpolate two points on the unit sphere"""
x = embed_latlon(lat1, lon1)
y = embed_latlon(lat2, lon2)
return project_latlon(_great_circle_linspace_3d(x, y, n))
# example on equator
A = 0, 0.
B = 0., 30.
great_circle_linspace(*A, *B, n=5)
(array([0., 0., 0., 0., 0.]), array([ 0. , 7.5, 15. , 22.5, 30. ]))
add a comment |
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%2f53244262%2fgenerate-more-points-between-two-longitude-lattitude-points%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can do this directly with numpy. The idea is to use the standard interpolation formula for 3D space, like A + d * (B - A)
. Points computed like this lie on the chord between A and B but can be projected back to the sphere.
In order to have a uniform distribution over angles, we need the mapping from angles to distances on the chord, like in the figure here
This shows chord locations for uniformly spaced angles and was generated with the code below to check correctness, since all the angles and trigonometric functions are easy to mess up.
def embed_latlon(lat, lon):
"""lat, lon -> 3d point"""
lat_, lon_ = np.deg2rad(lat), np.deg2rad(lon)
r = np.cos(lat_)
return np.array([
r * np.cos(lon_),
r * np.sin(lon_),
np.sin(lat_)
]).T
def project_latlon(x):
"""3d point -> (lat, lon)"""
return (
np.rad2deg(np.arcsin(x[:, 2])),
np.rad2deg(np.arctan2(x[:, 1], x[:, 0]))
)
def _great_circle_linspace_3d(x, y, n):
"""interpolate two points on the unit sphere"""
# angle from scalar product
alpha = np.arccos(x.dot(y))
# angle relative to mid point
beta = alpha * np.linspace(-.5, .5, n)
# distance of interpolated point to center of sphere
r = np.cos(.5 * alpha) / np.cos(beta)
# distance to mid line
m = r * np.sin(beta)
# interpolation on chord
chord = 2. * np.sin(.5 * alpha)
d = (m + np.sin(.5 * alpha)) / chord
points = x[None, :] + (y - x)[None, :] * d[:, None]
return points / np.sqrt(np.sum(points**2, axis=1, keepdims=True))
def great_circle_linspace(lat1, lon1, lat2, lon2, n):
"""interpolate two points on the unit sphere"""
x = embed_latlon(lat1, lon1)
y = embed_latlon(lat2, lon2)
return project_latlon(_great_circle_linspace_3d(x, y, n))
# example on equator
A = 0, 0.
B = 0., 30.
great_circle_linspace(*A, *B, n=5)
(array([0., 0., 0., 0., 0.]), array([ 0. , 7.5, 15. , 22.5, 30. ]))
add a comment |
You can do this directly with numpy. The idea is to use the standard interpolation formula for 3D space, like A + d * (B - A)
. Points computed like this lie on the chord between A and B but can be projected back to the sphere.
In order to have a uniform distribution over angles, we need the mapping from angles to distances on the chord, like in the figure here
This shows chord locations for uniformly spaced angles and was generated with the code below to check correctness, since all the angles and trigonometric functions are easy to mess up.
def embed_latlon(lat, lon):
"""lat, lon -> 3d point"""
lat_, lon_ = np.deg2rad(lat), np.deg2rad(lon)
r = np.cos(lat_)
return np.array([
r * np.cos(lon_),
r * np.sin(lon_),
np.sin(lat_)
]).T
def project_latlon(x):
"""3d point -> (lat, lon)"""
return (
np.rad2deg(np.arcsin(x[:, 2])),
np.rad2deg(np.arctan2(x[:, 1], x[:, 0]))
)
def _great_circle_linspace_3d(x, y, n):
"""interpolate two points on the unit sphere"""
# angle from scalar product
alpha = np.arccos(x.dot(y))
# angle relative to mid point
beta = alpha * np.linspace(-.5, .5, n)
# distance of interpolated point to center of sphere
r = np.cos(.5 * alpha) / np.cos(beta)
# distance to mid line
m = r * np.sin(beta)
# interpolation on chord
chord = 2. * np.sin(.5 * alpha)
d = (m + np.sin(.5 * alpha)) / chord
points = x[None, :] + (y - x)[None, :] * d[:, None]
return points / np.sqrt(np.sum(points**2, axis=1, keepdims=True))
def great_circle_linspace(lat1, lon1, lat2, lon2, n):
"""interpolate two points on the unit sphere"""
x = embed_latlon(lat1, lon1)
y = embed_latlon(lat2, lon2)
return project_latlon(_great_circle_linspace_3d(x, y, n))
# example on equator
A = 0, 0.
B = 0., 30.
great_circle_linspace(*A, *B, n=5)
(array([0., 0., 0., 0., 0.]), array([ 0. , 7.5, 15. , 22.5, 30. ]))
add a comment |
You can do this directly with numpy. The idea is to use the standard interpolation formula for 3D space, like A + d * (B - A)
. Points computed like this lie on the chord between A and B but can be projected back to the sphere.
In order to have a uniform distribution over angles, we need the mapping from angles to distances on the chord, like in the figure here
This shows chord locations for uniformly spaced angles and was generated with the code below to check correctness, since all the angles and trigonometric functions are easy to mess up.
def embed_latlon(lat, lon):
"""lat, lon -> 3d point"""
lat_, lon_ = np.deg2rad(lat), np.deg2rad(lon)
r = np.cos(lat_)
return np.array([
r * np.cos(lon_),
r * np.sin(lon_),
np.sin(lat_)
]).T
def project_latlon(x):
"""3d point -> (lat, lon)"""
return (
np.rad2deg(np.arcsin(x[:, 2])),
np.rad2deg(np.arctan2(x[:, 1], x[:, 0]))
)
def _great_circle_linspace_3d(x, y, n):
"""interpolate two points on the unit sphere"""
# angle from scalar product
alpha = np.arccos(x.dot(y))
# angle relative to mid point
beta = alpha * np.linspace(-.5, .5, n)
# distance of interpolated point to center of sphere
r = np.cos(.5 * alpha) / np.cos(beta)
# distance to mid line
m = r * np.sin(beta)
# interpolation on chord
chord = 2. * np.sin(.5 * alpha)
d = (m + np.sin(.5 * alpha)) / chord
points = x[None, :] + (y - x)[None, :] * d[:, None]
return points / np.sqrt(np.sum(points**2, axis=1, keepdims=True))
def great_circle_linspace(lat1, lon1, lat2, lon2, n):
"""interpolate two points on the unit sphere"""
x = embed_latlon(lat1, lon1)
y = embed_latlon(lat2, lon2)
return project_latlon(_great_circle_linspace_3d(x, y, n))
# example on equator
A = 0, 0.
B = 0., 30.
great_circle_linspace(*A, *B, n=5)
(array([0., 0., 0., 0., 0.]), array([ 0. , 7.5, 15. , 22.5, 30. ]))
You can do this directly with numpy. The idea is to use the standard interpolation formula for 3D space, like A + d * (B - A)
. Points computed like this lie on the chord between A and B but can be projected back to the sphere.
In order to have a uniform distribution over angles, we need the mapping from angles to distances on the chord, like in the figure here
This shows chord locations for uniformly spaced angles and was generated with the code below to check correctness, since all the angles and trigonometric functions are easy to mess up.
def embed_latlon(lat, lon):
"""lat, lon -> 3d point"""
lat_, lon_ = np.deg2rad(lat), np.deg2rad(lon)
r = np.cos(lat_)
return np.array([
r * np.cos(lon_),
r * np.sin(lon_),
np.sin(lat_)
]).T
def project_latlon(x):
"""3d point -> (lat, lon)"""
return (
np.rad2deg(np.arcsin(x[:, 2])),
np.rad2deg(np.arctan2(x[:, 1], x[:, 0]))
)
def _great_circle_linspace_3d(x, y, n):
"""interpolate two points on the unit sphere"""
# angle from scalar product
alpha = np.arccos(x.dot(y))
# angle relative to mid point
beta = alpha * np.linspace(-.5, .5, n)
# distance of interpolated point to center of sphere
r = np.cos(.5 * alpha) / np.cos(beta)
# distance to mid line
m = r * np.sin(beta)
# interpolation on chord
chord = 2. * np.sin(.5 * alpha)
d = (m + np.sin(.5 * alpha)) / chord
points = x[None, :] + (y - x)[None, :] * d[:, None]
return points / np.sqrt(np.sum(points**2, axis=1, keepdims=True))
def great_circle_linspace(lat1, lon1, lat2, lon2, n):
"""interpolate two points on the unit sphere"""
x = embed_latlon(lat1, lon1)
y = embed_latlon(lat2, lon2)
return project_latlon(_great_circle_linspace_3d(x, y, n))
# example on equator
A = 0, 0.
B = 0., 30.
great_circle_linspace(*A, *B, n=5)
(array([0., 0., 0., 0., 0.]), array([ 0. , 7.5, 15. , 22.5, 30. ]))
edited Nov 11 at 1:01
answered Nov 11 at 0:55
Matthias Ossadnik
57427
57427
add a comment |
add a comment |
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53244262%2fgenerate-more-points-between-two-longitude-lattitude-points%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
Related: gis.stackexchange.com/questions/221843/…
– Michael Butscher
Nov 10 at 23:06