Generate more points between two longitude-lattitude points












0














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
















0














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














0












0








0







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


















1














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


    }
    });














    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









    1














    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




























      1














      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


























        1












        1








        1






        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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()