Generate more points between two longitude-lattitude points









up vote
0
down vote

favorite












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?










share|improve this question





















  • Related: gis.stackexchange.com/questions/221843/…
    – Michael Butscher
    Nov 10 at 23:06














up vote
0
down vote

favorite












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?










share|improve this question





















  • Related: gis.stackexchange.com/questions/221843/…
    – Michael Butscher
    Nov 10 at 23:06












up vote
0
down vote

favorite









up vote
0
down vote

favorite











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?










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 23:01









Quang Thinh Ha

1174




1174











  • 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




Related: gis.stackexchange.com/questions/221843/…
– Michael Butscher
Nov 10 at 23:06












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










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



Geometry



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. ]))





share|improve this answer






















    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',
    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
    );



    );













    draft saved

    draft discarded


















    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








    up vote
    1
    down vote



    accepted










    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



    Geometry



    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. ]))





    share|improve this answer


























      up vote
      1
      down vote



      accepted










      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



      Geometry



      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. ]))





      share|improve this answer
























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        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



        Geometry



        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. ]))





        share|improve this answer














        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



        Geometry



        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. ]))






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 11 at 1:01

























        answered Nov 11 at 0:55









        Matthias Ossadnik

        57427




        57427



























            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Use pre created SQLite database for Android project in kotlin

            Darth Vader #20

            Ondo