columbus3 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- return { :version => [opts, :version] }
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
- opts.string "-f", "--filename", "Password file to encrypt. Write to <file>.enc"
28
- return { :console => [opts, :console] }
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
- return { :man => [opts, :man] }
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
- return { :help => [opts, :help] }
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
- return { process: [opts, :process] }
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
- return { search: [opts, :search] }
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
- opts.boolean "--sidecar", "Pass sidecar files rather than CSV files (use it when piping searches)"
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
- return { show: [opts, :show] }
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
- return { graph: [opts, :graph] }
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 it already exists"
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
- return { convert: [opts, :convert] }
89
- end
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({ :path => x }) }
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
- # apply the ERB in html/flot.html.erb
9
- # and save it in the current directory, under _flot.html
10
- def self.show filename, file
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 = 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.to_graph_data filename, force = false
38
- target = to_graph_filename filename
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.to_graph_filename filename
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 filename, files
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 leaflet layer cached to disk
29
- def self.to_leaflet filename, force = false
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.to_geojson_filename filename
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
- to_varname "layer_", Sanitizer::sanitize(filename)
59
+ to_javascript_varname "layer_", Sanitizer::sanitize(filename)
56
60
  end
57
61
 
58
- def self.to_varname prefix, filename
62
+ def self.to_javascript_varname prefix, filename
59
63
  prefix + Sanitizer::sanitize(filename)
60
64
  end
61
65
  end
@@ -1,3 +1,3 @@
1
1
  module Columbus3
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -35,7 +35,7 @@
35
35
  <% end %>
36
36
  </div>
37
37
 
38
- <script src="<%= to_graph_filename @file %>"></script>
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");
@@ -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="<%= to_geojson_filename file %>"></script>
41
+ <script src="<%= to_javascript_filename file %>"></script>
42
42
  <% end %>
43
43
 
44
44
  <%# make each track into a layer%>
@@ -1,4 +1,4 @@
1
- var <%= to_varname "track_", @filename %> =
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(<%= to_varname "track_", @filename %>, {
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
- <%= to_leaflet_layername @filename %>.addTo(map);
61
+ <%= to_leaflet_layername @filename %>.addTo(map);