columbus3 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +126 -33
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/columbus3.gemspec +7 -7
- data/doc/ChangeLog.org +47 -0
- data/doc/todo.org +24 -11
- data/lib/columbus3/cli/command_semantics.rb +71 -192
- data/lib/columbus3/cli/command_syntax.rb +214 -15
- data/lib/columbus3/metadata/sidecar.rb +6 -1
- data/lib/columbus3/renderer/flot_renderer.rb +12 -8
- data/lib/columbus3/renderer/leaflet_renderer.rb +12 -8
- data/lib/columbus3/version.rb +1 -1
- data/lib/html/flot.html.erb +1 -1
- data/lib/html/show.html.erb +1 -1
- data/lib/html/track.js.erb +3 -3
- metadata +18 -18
- data/doc/manual.txt +0 -122
@@ -18,34 +18,107 @@ module Columbus3
|
|
18
18
|
def self.version_opts
|
19
19
|
opts = Slop::Options.new
|
20
20
|
opts.banner = "version -- print version information"
|
21
|
-
|
21
|
+
help = <<EOS
|
22
|
+
NAME
|
23
|
+
#{opts.banner}
|
24
|
+
|
25
|
+
SYNOPSYS
|
26
|
+
#{opts.to_s}
|
27
|
+
|
28
|
+
DESCRIPTION
|
29
|
+
return version information
|
30
|
+
|
31
|
+
EXAMPLES
|
32
|
+
columbus3 version
|
33
|
+
columbus3 version #{VERSION}
|
34
|
+
EOS
|
35
|
+
return { :version => [opts, :version, help] }
|
22
36
|
end
|
23
37
|
|
24
38
|
def self.console_opts
|
25
39
|
opts = Slop::Options.new
|
26
40
|
opts.banner = "console [options] -- Enter the console"
|
27
|
-
|
28
|
-
|
41
|
+
help = <<EOS
|
42
|
+
NAME
|
43
|
+
#{opts.banner}
|
44
|
+
|
45
|
+
SYNOPSYS
|
46
|
+
#{opts.to_s}
|
47
|
+
|
48
|
+
DESCRIPTION
|
49
|
+
Invoke a console, from which you can more easily run
|
50
|
+
columbus3 commands.
|
51
|
+
|
52
|
+
EXAMPLES
|
53
|
+
columbus3 console
|
54
|
+
columbus3:000> process 11010101.CSV
|
55
|
+
columbus3:001> show 11010101.CSV
|
56
|
+
columbus3:002>
|
57
|
+
EOS
|
58
|
+
return { :console => [opts, :console, help] }
|
29
59
|
end
|
30
60
|
|
31
61
|
def self.man_opts
|
32
62
|
opts = Slop::Options.new
|
33
63
|
opts.banner = "man -- print a manual page"
|
34
|
-
|
64
|
+
help = <<EOS
|
65
|
+
NAME
|
66
|
+
#{opts.banner}
|
67
|
+
|
68
|
+
SYNOPSYS
|
69
|
+
#{opts.to_s}
|
70
|
+
|
71
|
+
DESCRIPTION
|
72
|
+
Print the README file of this gem
|
73
|
+
|
74
|
+
EXAMPLES
|
75
|
+
columbus3 man
|
76
|
+
EOS
|
77
|
+
return { :man => [opts, :man, help] }
|
35
78
|
end
|
36
79
|
|
37
80
|
def self.help_opts
|
38
81
|
opts = Slop::Options.new
|
39
82
|
opts.banner = "help [command] -- print usage string"
|
40
|
-
|
83
|
+
help = <<EOS
|
84
|
+
NAME
|
85
|
+
#{opts.banner}
|
86
|
+
|
87
|
+
SYNOPSYS
|
88
|
+
#{opts.to_s}
|
89
|
+
|
90
|
+
DESCRIPTION
|
91
|
+
Print help about a command
|
92
|
+
|
93
|
+
EXAMPLES
|
94
|
+
columbus3 help
|
95
|
+
columbus3 help process
|
96
|
+
EOS
|
97
|
+
return { :help => [opts, :help, help] }
|
41
98
|
end
|
42
99
|
|
43
100
|
def self.process_opts
|
44
101
|
opts = Slop::Options.new
|
45
102
|
opts.banner = "process [track ...] -- generate sidecar files for given tracks"
|
46
103
|
opts.boolean "-f", "--force", "Overwrite existing sidecar file"
|
47
|
-
|
48
|
-
|
104
|
+
help = <<EOS
|
105
|
+
NAME
|
106
|
+
#{opts.banner}
|
107
|
+
|
108
|
+
SYNOPSYS
|
109
|
+
#{opts.to_s}
|
110
|
+
|
111
|
+
DESCRIPTION
|
112
|
+
Generate a sidecar file for the track(s) passed as input.
|
113
|
+
|
114
|
+
Once created a sidecar file usually does not need to be regenerated. You can
|
115
|
+
use the `--force` option to cause the sidecar file to be rewritten.
|
116
|
+
|
117
|
+
EXAMPLES
|
118
|
+
columbus3 process 11010101.CSV 11010201.CSV
|
119
|
+
columbus3 process *
|
120
|
+
EOS
|
121
|
+
return { process: [opts, :process, help] }
|
49
122
|
end
|
50
123
|
|
51
124
|
def self.search_opts
|
@@ -54,10 +127,81 @@ module Columbus3
|
|
54
127
|
|
55
128
|
opts.boolean "--debug", "Show how the query is processed"
|
56
129
|
opts.boolean "-r", "--recurse", "Recurse in subdirectories"
|
57
|
-
opts.string "-d", "--dir", "Directory to search"
|
130
|
+
opts.string "-d", "--dir", "Directory to search (default to current directory)"
|
58
131
|
opts.array "--fields", "Comma separated list of fields to print"
|
132
|
+
help = <<EOS
|
133
|
+
NAME
|
134
|
+
#{opts.banner}
|
135
|
+
|
136
|
+
SYNOPSYS
|
137
|
+
#{opts.to_s}
|
138
|
+
|
139
|
+
DESCRIPTION
|
140
|
+
Search a directory for tracks matching your search criteria.
|
141
|
+
|
142
|
+
By default columbus3 searches in the current dir; use the `--dir`
|
143
|
+
option to choose a different directory.
|
144
|
+
|
145
|
+
Use `--recurse` to recurce in subdirectories as well.
|
146
|
+
|
147
|
+
Use `--fields` to choose what information is displayed in the output.
|
148
|
+
|
149
|
+
Terms you can search for:
|
150
|
+
|
151
|
+
location, start_location, end_location
|
152
|
+
date, start_date, end_date
|
153
|
+
year
|
154
|
+
duration
|
155
|
+
max_speed
|
156
|
+
min_height
|
157
|
+
max_height
|
158
|
+
|
159
|
+
Numerical operators:
|
59
160
|
|
60
|
-
|
161
|
+
<, <=, ==, >=, >
|
162
|
+
|
163
|
+
String operators (locations):
|
164
|
+
|
165
|
+
~ (contains), == (is exactly)
|
166
|
+
|
167
|
+
Complex Terms:
|
168
|
+
|
169
|
+
Use "and" and "or" to build complex queries
|
170
|
+
|
171
|
+
Examples of simple searches
|
172
|
+
|
173
|
+
'location ~ "USA"' any track whose start or end location contains USA
|
174
|
+
'date > 2015-02-14' any track whose start or end date is after Feb 14, 2015
|
175
|
+
'year == 2015' any track whose start or end date is in 2015
|
176
|
+
'duration <= 01:02:03' any track with a duration of less than 1h, 2min, and 3secs
|
177
|
+
'max_speed > 120' any track with a max speed greater than 120 km/h
|
178
|
+
'min_height == 10' any track with a min height lower than 10 meters
|
179
|
+
|
180
|
+
Examples of complex searches
|
181
|
+
'location ~ "USA" and start_date >= 2015-01-01' tracks in the USA after or on Jan 1, 2015
|
182
|
+
'start_location ~ "Trenton" and end_location ~ "New York"' trips from Trenton to New York
|
183
|
+
|
184
|
+
List of supported fields in the output list:
|
185
|
+
|
186
|
+
yaml -> full pathname of the YAML metadata file
|
187
|
+
path -> full pathname of the CSV file
|
188
|
+
filename -> basename of the CSV file
|
189
|
+
start_location -> start location
|
190
|
+
end_location -> end location
|
191
|
+
start_date -> start date (and time)
|
192
|
+
end_date -> end date (and time)
|
193
|
+
duration -> duration in seconds
|
194
|
+
min_speed -> minimum speed in km/h
|
195
|
+
max_speed -> maximum speed in km/h
|
196
|
+
min_height -> minimum height in meters
|
197
|
+
max_height -> maximum height in meters
|
198
|
+
|
199
|
+
EXAMPLES
|
200
|
+
|
201
|
+
columbus3 search 'location ~ "USA"'
|
202
|
+
columbus3 search 'location ~ "USA" and speed < 10' --fields path | columbus3 show
|
203
|
+
EOS
|
204
|
+
return { search: [opts, :search, help] }
|
61
205
|
end
|
62
206
|
|
63
207
|
def self.show_opts
|
@@ -66,9 +210,21 @@ module Columbus3
|
|
66
210
|
|
67
211
|
opts.string "-f", "--filename=", "Output filename (default is _show.html)"
|
68
212
|
opts.boolean "--force", "Force rewriting of the js file, even if it already exists"
|
69
|
-
|
213
|
+
help = <<EOS
|
214
|
+
NAME
|
215
|
+
#{opts.banner}
|
216
|
+
|
217
|
+
SYNOPSYS
|
218
|
+
#{opts.to_s}
|
219
|
+
|
220
|
+
DESCRIPTION
|
221
|
+
Generate an html file which shows the track on a map.
|
70
222
|
|
71
|
-
|
223
|
+
EXAMPLES
|
224
|
+
columbus3 show 11010101.CSV 11010201.CSV
|
225
|
+
columbus3 search 'location ~ "USA" and speed < 10' --fields path | columbus3 show --filename "us_tracks.html"
|
226
|
+
EOS
|
227
|
+
return { show: [opts, :show, help] }
|
72
228
|
end
|
73
229
|
|
74
230
|
def self.graph_opts
|
@@ -76,18 +232,61 @@ module Columbus3
|
|
76
232
|
opts.banner = "graph [--filename filename] [--force] track -- plot speed and height profile of track"
|
77
233
|
|
78
234
|
opts.boolean "--force", "Force rewriting of the js file, even if it already exists"
|
235
|
+
help = <<EOS
|
236
|
+
NAME
|
237
|
+
#{opts.banner}
|
79
238
|
|
80
|
-
|
239
|
+
SYNOPSYS
|
240
|
+
#{opts.to_s}
|
241
|
+
|
242
|
+
DESCRIPTION
|
243
|
+
Plot speed and height profile of a single track.
|
244
|
+
|
245
|
+
EXAMPLES
|
246
|
+
columbus3 graph 11010101.CSV
|
247
|
+
EOS
|
248
|
+
return { graph: [opts, :graph, help] }
|
81
249
|
end
|
82
250
|
|
83
251
|
def self.convert_opts
|
84
252
|
opts = Slop::Options.new
|
85
253
|
opts.banner = "convert track -- convert a GPX into a set of CSV files"
|
86
|
-
opts.boolean "--force", "Force rewriting of the csv files, even if
|
254
|
+
opts.boolean "--force", "Force rewriting of the csv files, even if they already exist"
|
255
|
+
help = <<EOS
|
256
|
+
NAME
|
257
|
+
#{opts.banner}
|
87
258
|
|
88
|
-
|
89
|
-
|
259
|
+
SYNOPSYS
|
260
|
+
#{opts.to_s}
|
261
|
+
|
262
|
+
DESCRIPTION
|
263
|
+
Convert a GPX track to a CSV track
|
264
|
+
|
265
|
+
The command is useful if you are using different loggers for generating your
|
266
|
+
tracks:
|
267
|
+
|
268
|
+
columbus3 convert file.gpx
|
90
269
|
|
270
|
+
will generate
|
271
|
+
|
272
|
+
file-1.csv
|
273
|
+
file-2.csv
|
274
|
+
...
|
275
|
+
|
276
|
+
one per track in the GPX file.
|
277
|
+
|
278
|
+
EXAMPLES
|
279
|
+
columbus3 convert track.gpx
|
280
|
+
|
281
|
+
BUGS AND LIMITATIONS
|
282
|
+
|
283
|
+
The Columbus V900 format has fields with fixed width, and uses ^@ as a filler.
|
284
|
+
The CSV file generated by the convert command generates fields of variable width
|
285
|
+
(standard CSV files, I dare say). The heading field is not computed
|
286
|
+
and the field is filled with -1.
|
287
|
+
EOS
|
288
|
+
return { convert: [opts, :convert, help] }
|
289
|
+
end
|
91
290
|
|
92
291
|
# def self.split_opts
|
93
292
|
# opts = Slop::Options.new
|
@@ -21,6 +21,11 @@ module Columbus3
|
|
21
21
|
@metadata.keys
|
22
22
|
end
|
23
23
|
|
24
|
+
# it always works because initialization requires a filename
|
25
|
+
def filename
|
26
|
+
@metadata[:filename] + ".yaml"
|
27
|
+
end
|
28
|
+
|
24
29
|
def load
|
25
30
|
@metadata = YAML.load(File.read(@metadata[:filename] + ".yaml"))
|
26
31
|
end
|
@@ -47,7 +52,7 @@ module Columbus3
|
|
47
52
|
end
|
48
53
|
|
49
54
|
def load array
|
50
|
-
@metadata = array.each.map { |x| YAML.load(File.read(x)).merge({ :
|
55
|
+
@metadata = array.each.map { |x| YAML.load(File.read(x)).merge({ path: x.gsub(/\.yaml$/, ''), yaml: x }) }
|
51
56
|
end
|
52
57
|
|
53
58
|
def search term
|
@@ -5,9 +5,14 @@ require 'columbus3/renderer/sanitizer'
|
|
5
5
|
module Columbus3
|
6
6
|
# make a track into a flot graph (speed and height)
|
7
7
|
module FlotRenderer
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
OUTPUT_FILENAME = "_graph.html"
|
9
|
+
|
10
|
+
# apply the ERB in html/flot.html.erb and save it in the current directory
|
11
|
+
# use filename if provided or the default OUTPUT_FILENAME
|
12
|
+
def self.show hash
|
13
|
+
filename = hash[:filename] || OUTPUT_FILENAME
|
14
|
+
files = hash[:files] || []
|
15
|
+
|
11
16
|
template = File.join(File.dirname(__FILE__), "/../../html/flot.html.erb")
|
12
17
|
renderer = ERB.new(File.read(template))
|
13
18
|
|
@@ -19,7 +24,7 @@ module Columbus3
|
|
19
24
|
File.join(bower_dir, 'flot/jquery.flot.time.js'),
|
20
25
|
File.join(bower_dir, 'flot/jquery.flot.selection.js')
|
21
26
|
]
|
22
|
-
@file =
|
27
|
+
@file = files[0]
|
23
28
|
# TODO: manage the case of sidecar not existing
|
24
29
|
@track_info = Sidecar.new @file
|
25
30
|
@track_info.load
|
@@ -34,8 +39,8 @@ module Columbus3
|
|
34
39
|
end
|
35
40
|
|
36
41
|
# make a v900 track into a graph layer cached to disk
|
37
|
-
def self.
|
38
|
-
target =
|
42
|
+
def self.to_javascript_file filename, force = false
|
43
|
+
target = to_javascript_filename filename
|
39
44
|
|
40
45
|
if force or not File.exists? target
|
41
46
|
track = V900Track.new filename: filename
|
@@ -50,10 +55,9 @@ height_#{id} = #{track.range.each.map { |i|[track[i].time.to_i * 1000, track[i].
|
|
50
55
|
EOS
|
51
56
|
end
|
52
57
|
end
|
53
|
-
|
54
58
|
end
|
55
59
|
|
56
|
-
def self.
|
60
|
+
def self.to_javascript_filename filename
|
57
61
|
filename + "_graph.js"
|
58
62
|
end
|
59
63
|
|
@@ -6,9 +6,14 @@ module Columbus3
|
|
6
6
|
# renderer controls the transformation of a V900 tracks into a displayable format,
|
7
7
|
# whatever this means
|
8
8
|
module LeafletRenderer
|
9
|
+
OUTPUT_FILENAME = "_show.html"
|
10
|
+
|
9
11
|
# apply the ERB in html/show.html.erb (which includes all the tracks to display)
|
10
12
|
# and save it in the current directory, under _show.html
|
11
|
-
def self.show
|
13
|
+
def self.show hash
|
14
|
+
filename = hash[:filename] || OUTPUT_FILENAME
|
15
|
+
files = hash[:files] || []
|
16
|
+
|
12
17
|
template = File.join(File.dirname(__FILE__), "/../../html/show.html.erb")
|
13
18
|
renderer = ERB.new(File.read(template))
|
14
19
|
|
@@ -25,10 +30,9 @@ module Columbus3
|
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
|
-
# make a v900 track into a
|
29
|
-
def self.
|
30
|
-
|
31
|
-
target = to_geojson_filename filename
|
33
|
+
# make a v900 track into a geojson file
|
34
|
+
def self.to_javascript_file filename, force = false
|
35
|
+
target = to_javascript_filename filename
|
32
36
|
|
33
37
|
if force or not File.exists? target
|
34
38
|
# load the template
|
@@ -47,15 +51,15 @@ module Columbus3
|
|
47
51
|
|
48
52
|
end
|
49
53
|
|
50
|
-
def self.
|
54
|
+
def self.to_javascript_filename filename
|
51
55
|
filename + ".js"
|
52
56
|
end
|
53
57
|
|
54
58
|
def self.to_leaflet_layername filename
|
55
|
-
|
59
|
+
to_javascript_varname "layer_", Sanitizer::sanitize(filename)
|
56
60
|
end
|
57
61
|
|
58
|
-
def self.
|
62
|
+
def self.to_javascript_varname prefix, filename
|
59
63
|
prefix + Sanitizer::sanitize(filename)
|
60
64
|
end
|
61
65
|
end
|
data/lib/columbus3/version.rb
CHANGED
data/lib/html/flot.html.erb
CHANGED
@@ -35,7 +35,7 @@
|
|
35
35
|
<% end %>
|
36
36
|
</div>
|
37
37
|
|
38
|
-
<script src="<%=
|
38
|
+
<script src="<%= to_javascript_filename @file %>"></script>
|
39
39
|
<script>
|
40
40
|
// required by plot for tooltips (it moves the tooltip, appending it directly to body
|
41
41
|
$("<div id='tooltip'></div>").appendTo("body");
|
data/lib/html/show.html.erb
CHANGED
@@ -38,7 +38,7 @@
|
|
38
38
|
|
39
39
|
<%# insert the requested GPX Tracks (in json format) %>
|
40
40
|
<% @files.each do |file| %>
|
41
|
-
<script src="<%=
|
41
|
+
<script src="<%= to_javascript_filename file %>"></script>
|
42
42
|
<% end %>
|
43
43
|
|
44
44
|
<%# make each track into a layer%>
|
data/lib/html/track.js.erb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
var <%=
|
1
|
+
var <%= to_javascript_varname "track_", @filename %> =
|
2
2
|
{ "type": "FeatureCollection",
|
3
3
|
"features": [
|
4
4
|
{ "type": "Feature",
|
@@ -39,7 +39,7 @@ var <%= to_varname "track_", @filename %> =
|
|
39
39
|
]
|
40
40
|
};
|
41
41
|
|
42
|
-
<%= to_leaflet_layername @filename %> = L.geoJson(<%=
|
42
|
+
<%= to_leaflet_layername @filename %> = L.geoJson(<%= to_javascript_varname "track_", @filename %>, {
|
43
43
|
onEachFeature: function onEachFeature(feature, layer) {
|
44
44
|
if (feature.properties && feature.properties.name) {
|
45
45
|
layer.bindPopup(feature.properties.name);
|
@@ -58,4 +58,4 @@ var <%= to_varname "track_", @filename %> =
|
|
58
58
|
}
|
59
59
|
*/
|
60
60
|
});
|
61
|
-
|
61
|
+
<%= to_leaflet_layername @filename %>.addTo(map);
|