Search code examples
rubyruby-on-rails-3google-mapscoordinatesgtfs

How to generate coordinates in between two known points


Background:

I'm working with transport routes and Google provides Route points far apart enough to create 'shapes'. These are the bus/train routes you see in Google Maps.

My Requirement:

Google's points are far enough to create straight lines. However I want a point every, say, 5 metres.

Problem:

So, say I have two points [lat,long]:

[-33.8824219918503,151.206686052582] and [-33.8815434600467,151.206556440037]

Given those two points I can calculate the distance between them. Say it's 1km for the sake of argument.

So we can imagine an imaginary straight line in between those two points.

How do I generate coordinates for that imaginary line for every, say, 5 metres?


Solution

  • Destination point given distance and bearing from start point applied to your problem:

    class Numeric
      def to_rad
        self * Math::PI / 180
      end
      def to_deg
        self * 180 / Math::PI
      end
    end
    
    include Math
    
    R = 6371.0
    
    def waypoint(φ1, λ1, θ, d)
      φ2 = asin( sin(φ1) * cos(d/R) + cos(φ1) * sin(d/R) * cos(θ) )
      λ2 = λ1 + atan2( sin(θ) * sin(d/R) * cos(φ1), cos(d/R) - sin(φ1) * sin(φ2) )
      λ2 = (λ2 + 3 * Math::PI) % (2 * Math::PI) - Math::PI # normalise to -180..+180°
      [φ2, λ2]
    end
    
    φ1, λ1 = -33.to_rad, -71.6.to_rad   # Valparaíso
    φ2, λ2 = 31.4.to_rad, 121.8.to_rad  # Shanghai
    
    d = R * acos( sin(φ1) * sin(φ2) + cos(φ1) * cos(φ2) * cos(λ2 - λ1) )
    θ = atan2( sin(λ2 - λ1) * cos(φ2), cos(φ1) * sin(φ2) - sin(φ1) * cos(φ2) * cos(λ2 - λ1) )
    
    waypoints = (0..d).step(2000).map { |d| waypoint(φ1, λ1, θ, d) }
    
    markers = waypoints.map { |φ, λ| "#{φ.to_deg},#{λ.to_deg}" }.join("|")
    
    puts "http://maps.googleapis.com/maps/api/staticmap?size=640x320&sensor=false&markers=#{markers}"
    

    Generates a Google Static Maps link with the waypoints from Valparaíso to Shanghai every 2,000 km:

    http://maps.googleapis.com/maps/api/staticmap?size=640x320&sensor=false&markers=-33.0,-71.60000000000002|-32.54414813683714,-93.02142653011552|-28.59922979115139,-113.43958859125276|-21.877555679819015,-131.91586675556778|-13.305784544363858,-148.5297601858932|-3.7370081151180683,-163.94988578467394|6.094273692291354,-179.03345538133888|15.493534924596633,165.33401731030006|23.70233917422386,148.3186618914762|29.83806632244171,129.34766276764626