module PathCompare

Constants

EARTH_DIAMETER_KM
RAD_PER_DEG
VERSION

Public Class Methods

calc(dlat, lat1, lat2, dlon) click to toggle source
# File lib/path_compare/path_compare.rb, line 50
def self.calc(dlat, lat1, lat2, dlon)
    (Math.sin(deg_to_rad(dlat)/2))**2 + Math.cos(deg_to_rad(lat1)) * Math.cos((deg_to_rad(lat2))) * (Math.sin(deg_to_rad(dlon)/2))**2
end
compare(p1, p2) click to toggle source

p1 and p2 given as geojson strings

# File lib/path_compare/path_compare.rb, line 4
def self.compare(p1, p2)
    p1 = JSON.parse(p1)['coordinates'].first
    p2 = JSON.parse(p2)['coordinates'].first
    p1 = even_split(p1, 10)
    p2 = even_split(p2, 10)

    point_distances = []
    p1.each_with_index do |coord, index|
        unless p2.size < index + 1  #TODO: Handle different length paths
            point_distances << Math.sqrt((coord[0] - p2[index][0]) ** 2) + Math.sqrt((coord[1] - p2[index][1]) ** 2)
        end
    end
    return point_distances.sum / point_distances.size
end
deg_to_rad(num) click to toggle source
# File lib/path_compare/path_compare.rb, line 47
def self.deg_to_rad(num)
    num * RAD_PER_DEG
end
distance(lat1, lon1, lat2, lon2) click to toggle source
# File lib/path_compare/path_compare.rb, line 39
def self.distance(lat1, lon1, lat2, lon2)
    dlon = lon2 - lon1
    dlat = lat2 - lat1

    a = calc(dlat, lat1, lat2, dlon)

    2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a)) * EARTH_DIAMETER_KM * 1000
end
even_split(coords, split_size) click to toggle source

Splits a linestring in to points split_size apart. (Not quite but it should be close)

# File lib/path_compare/path_compare.rb, line 20
def self.even_split(coords, split_size)
    new_coords = []
    current_distance = 0
    target_distance = split_size
    last_coord = coords.first
    coords.each do |coord|
        if current_distance < target_distance
            current_distance += distance(coord[0], coord[1], last_coord[0], last_coord[1])
        else
            new_coords << last_coord #TODO: Add a new point at exactly the right spot instead of using last point
            target_distance += split_size
        end
        last_coord = coord
    end
    new_coords
end