-
Notifications
You must be signed in to change notification settings - Fork 0
/
hilo.rb
100 lines (89 loc) · 2.2 KB
/
hilo.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require 'hashie/mash'
require 'csv'
class Hilo
require_relative File.join(File.dirname(__FILE__), "hilofields.lua")
INPUT_FIELDS = HILOFIELDS.split(",").map {|x| x.downcase.to_sym}
class Point < Hashie::Mash
def km; super.to_f; end
def lat; super.to_f; end
def lon; super.to_f; end
def mile; km * 0.621371192237334; end
end
attr_reader :points
class Range
attr_reader :start, :stop, :field
def initialize(start, stop, field)
@start, @stop, @field = start, stop, field
raise "Range start doesn't have value!" if value.nil?
end
def value
start[field]
end
def start_km
start.km
end
def stop_km
stop.km
end
def length
stop_km - start_km
end
end
def ranges(field)
[].tap do |ranges|
last_point = nil
points.each do |point|
if point[field]
if last_point
ranges << Range.new(last_point, point, field)
end
last_point = point
end
end
# case where last point does not have that field (as it normally wouldn't), count that last segment too
if last_point && last_point != points.last
ranges << Range.new(last_point, points.last, field)
end
end
end
def initialize(f=nil)
if f.is_a? String
@filename = f
f = open(f, "r")
end
@points = f.nil? ? [] : [].tap do |array|
CSV(f, :headers => true, :header_converters => :symbol).each do |row|
array << Point.new(row.to_hash)
end
end
end
def save(file=nil)
file ||= @filename || STDOUT
file = file.is_a?(String) ? open(file, "wb") : file
CSV(file) do |csv|
csv << INPUT_FIELDS.map{ |field| field.to_s.upcase }
points.each do |point|
csv << INPUT_FIELDS.map{ |field| point[field] }
end
end
file.close unless file.is_a?(String)
end
def self.reader
hilo = Hilo.new(ARGV[0] || STDIN)
hilo.points.each do |p|
yield p
end
end
def self.filter(insitu = false)
insitu = ARGV.delete("-i")
hilo = Hilo.new(ARGV[0] || STDIN)
hilo.points.each do |p|
yield p
end
if insitu
hilo.save
else
hilo.save(ARGV[1] || STDOUT)
end
end
end