-
-
Save 7kry/be49088ec63424787861 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# -*- coding: utf-8 -*- | |
require 'nokogiri' | |
require 'pp' | |
module GpxDistance | |
def calc_gpx_distance(gpx_file) | |
distance = calc_distance(get_latlons(gpx_file)) | |
distance / 1000 # kilometers | |
end | |
private | |
def get_latlons(gpx_file) | |
gpx = Nokogiri::XML(open(gpx_file)) | |
gpx.css("gpx trk trkpt").map{|pt| | |
[pt.attribute("lat").value.to_f, pt.attribute("lon").value.to_f] | |
} | |
end | |
def calc_distance(latlons) | |
distance = | |
latlons.map{|latlon| | |
deg_to_rad(latlon) | |
}.each_cons(2).inject(0){|dist, pt| | |
dist + hubeny(*pt) | |
} | |
distance # meters | |
end | |
def deg_to_rad(latlng) | |
latlng.map { |deg| deg * Math::PI / 180 } | |
end | |
# http://yamadarake.jp/trdi/report000001.html | |
# WGS84 (GPS) | |
A = 6378137.000 | |
B = 6356752.314245 | |
def hubeny(latlng_1, latlng_2) | |
pow_e = 1 - B ** 2 / A ** 2 | |
ave = (latlng_1[0] + latlng_2[0]) / 2 | |
dp = latlng_1[0] - latlng_2[0] | |
dr = latlng_1[1] - latlng_2[1] | |
sin_ave = Math.sin(ave) | |
cos_ave = Math.cos(ave) | |
w = Math.sqrt(1 - pow_e * sin_ave ** 2) | |
m = A * (1 - pow_e) / w ** 3 | |
n = A / w | |
distance = Math.sqrt((m * dp) ** 2 + (n * cos_ave * dr) ** 2) | |
distance #meters | |
end | |
extend self | |
end | |
if __FILE__ == $0 | |
exit 1 if ARGV.length < 1 | |
gpx_file = ARGV[0] | |
distance = GpxDistance::calc_gpx_distance(gpx_file) | |
puts sprintf("%.3f km", distance) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment