geoptima 0.1.15 → 0.1.17
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/geoptima_file_time +2 -2
- data/bin/geoptima_file_time_stats +133 -0
- data/bin/show_geoptima +46 -7
- data/examples/geoptima_file_time.rb +2 -2
- data/examples/geoptima_file_time_stats.rb +133 -0
- data/examples/show_geoptima.rb +46 -7
- data/geoptima.gemspec +1 -1
- data/lib/geoptima/data.rb +265 -36
- data/lib/geoptima/file_time.rb +3 -2
- data/lib/geoptima/locationrange.rb +45 -6
- data/lib/geoptima/timer.rb +39 -0
- data/lib/geoptima/version.rb +1 -1
- metadata +75 -66
data/bin/geoptima_file_time
CHANGED
@@ -7,8 +7,8 @@ $: << '../lib'
|
|
7
7
|
require 'geoptima/version'
|
8
8
|
require 'geoptima/file_time'
|
9
9
|
|
10
|
-
Geoptima::assert_version(">=0.1.
|
10
|
+
Geoptima::assert_version(">=0.1.17")
|
11
11
|
|
12
12
|
ARGV.each do |filename|
|
13
|
-
puts "#{(filename.to_s+" "*40)[0..40]} --> #{Geoptima::FileTime.from_file
|
13
|
+
puts "#{(filename.to_s+" "*40)[0..40]} --> #{Geoptima::FileTime.from_file(filename).join(', ')}"
|
14
14
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# useful if being run inside a source code checkout
|
4
|
+
$: << 'lib'
|
5
|
+
$: << '../lib'
|
6
|
+
|
7
|
+
require 'geoptima/version'
|
8
|
+
require 'geoptima/file_time'
|
9
|
+
|
10
|
+
Geoptima::assert_version(">=0.1.17")
|
11
|
+
|
12
|
+
class Stats
|
13
|
+
attr_accessor :no_server, :has_server, :count
|
14
|
+
def initialize
|
15
|
+
@no_server = []
|
16
|
+
@has_server = []
|
17
|
+
@count = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_file(path)
|
21
|
+
return unless(path =~ /\.json$/i)
|
22
|
+
filetime = JSONFileTime.new(File.basename path)
|
23
|
+
@count += 1
|
24
|
+
if filetime.has_server?
|
25
|
+
@has_server << filetime
|
26
|
+
else
|
27
|
+
@no_server << filetime
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def process_path(path)
|
32
|
+
puts "Processing path: #{path}" if($debug)
|
33
|
+
if File.directory? path
|
34
|
+
process_dir(path)
|
35
|
+
elsif File.exist? path
|
36
|
+
process_file path
|
37
|
+
else
|
38
|
+
puts "No such file or directory: #{path}" if($debug)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_dir(dir)
|
43
|
+
Dir.open(dir).each do |file|
|
44
|
+
next if(file =~ /^\./)
|
45
|
+
process_path "#{dir}/#{file}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def report(out)
|
50
|
+
puts "Loaded #{count} files:"
|
51
|
+
puts "\t#{no_server.length} without server timestamp"
|
52
|
+
puts "\t#{has_server.length} with server timestamp"
|
53
|
+
stats = {}
|
54
|
+
has_server.each do |file|
|
55
|
+
key = file.correction.to_i
|
56
|
+
stats[key] ||= 0
|
57
|
+
stats[key] += 1
|
58
|
+
end
|
59
|
+
stats.keys.sort.each do |key|
|
60
|
+
puts "\t\t#{key}:\t#{stats[key]}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
class JSONFileTime
|
67
|
+
attr_accessor :name, :times, :client_time, :server_time, :correction
|
68
|
+
def initialize(name)
|
69
|
+
@name = name
|
70
|
+
@times = Geoptima::FileTime.from_file name
|
71
|
+
@client_time = @times[0]
|
72
|
+
if @times.length > 1
|
73
|
+
puts "\tCalculating times for #{name}: #{@times.join(', ')}" if($debug)
|
74
|
+
@server_time = @times[1]
|
75
|
+
puts "\t\tClient: #{t2s client_time}" if($debug)
|
76
|
+
puts "\t\tServer: #{t2s server_time}" if($debug)
|
77
|
+
@correction = (@server_time - @client_time) * Geoptima::FileTime::DAY_SECONDS
|
78
|
+
puts "\t\tTime offset: #{@correction}" if($debug)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
def t2s(time)
|
82
|
+
time.new_offset(0).strftime("%Y-%m-%d %H:%M:%S.%3N").gsub(/\.(\d{3})\d+/,'.\1')
|
83
|
+
end
|
84
|
+
def has_server?
|
85
|
+
@server_time
|
86
|
+
end
|
87
|
+
def to_s
|
88
|
+
"#{name}:#{client_time}"
|
89
|
+
end
|
90
|
+
def row
|
91
|
+
"#{(name.to_s+" "*40)[0..40]} --> #{times.join(', ')}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
stats = Stats.new
|
96
|
+
$paths = []
|
97
|
+
|
98
|
+
while arg = ARGV.shift
|
99
|
+
if arg =~ /^[\-\+]+(\w+)/
|
100
|
+
$1.split(//).each do |aa|
|
101
|
+
case aa
|
102
|
+
when 'd'
|
103
|
+
$debug = true
|
104
|
+
when 'h'
|
105
|
+
$help = true
|
106
|
+
else
|
107
|
+
puts "Unknown option: -#{aa}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
else
|
111
|
+
$paths << arg
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
$help = true if($paths.length < 1)
|
116
|
+
|
117
|
+
if $help
|
118
|
+
puts <<EOHELP
|
119
|
+
usage: geoptima_file_time_stats <-dh> path <paths..>
|
120
|
+
-d Debug mode
|
121
|
+
-h Print help and exit
|
122
|
+
Each path can be a file or directory. When a directory is selected, a recursive
|
123
|
+
search for files is done. Only files with .json extension are processed.
|
124
|
+
EOHELP
|
125
|
+
exit 0
|
126
|
+
end
|
127
|
+
|
128
|
+
$paths.each do |path|
|
129
|
+
stats.process_path(path)
|
130
|
+
end
|
131
|
+
|
132
|
+
stats.report(STDOUT)
|
133
|
+
|
data/bin/show_geoptima
CHANGED
@@ -8,7 +8,7 @@ require 'date'
|
|
8
8
|
require 'geoptima'
|
9
9
|
require 'geoptima/options'
|
10
10
|
|
11
|
-
Geoptima::assert_version(">=0.1.
|
11
|
+
Geoptima::assert_version(">=0.1.16")
|
12
12
|
|
13
13
|
$debug=false
|
14
14
|
|
@@ -39,6 +39,7 @@ $files = Geoptima::Options.process_args do |option|
|
|
39
39
|
option.L {$print_limit = [1,ARGV.shift.to_i].max}
|
40
40
|
option.M {$mapfile = ARGV.shift}
|
41
41
|
option.G {$gpx_options.merge! ARGV.shift.split(/[\,\;]+/).inject({}){|a,v| k=v.split(/[\:\=]+/);a[k[0]]=k[1]||true;a}}
|
42
|
+
option.A {$app_categories = Geoptima::AppCategories.new(ARGV.shift)}
|
42
43
|
end.map do |file|
|
43
44
|
File.exist?(file) ? file : puts("No such file: #{file}")
|
44
45
|
end.compact
|
@@ -136,9 +137,14 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types>
|
|
136
137
|
-h show this help
|
137
138
|
-P prefix for exported files (default: ''; current: #{$export_prefix})
|
138
139
|
-E comma-seperated list of event types to show and export (default: all; current: #{$event_names.join(',')})
|
140
|
+
-A application category map file (default: app names)
|
139
141
|
-T time range to limit results to (default: all; current: #{$time_range})
|
140
|
-
-B location limited to specified bounds in formats
|
141
|
-
|
142
|
+
-B location limited to specified bounds in one of these formats:
|
143
|
+
minlat,minlon,maxlat,maxlon
|
144
|
+
minlat..maxlat,minlon..maxlon
|
145
|
+
DIST(distance_in_km,lat,lon)
|
146
|
+
RANGE[minlat,minlon,maxlat,maxlon]
|
147
|
+
RANGE[minlat..maxlat,minlon..maxlon]
|
142
148
|
(default: all; current: #{$location_range})
|
143
149
|
-L limit verbose output to specific number of lines #{cw $print_limit}
|
144
150
|
-M mapfile of normal->altered header names: #{$mapfile}
|
@@ -148,12 +154,14 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types>
|
|
148
154
|
limit:#{$gpx_options['limit']}\t\tLimit GPX output to traces with at least this number of events
|
149
155
|
png_limit:#{$gpx_options['png_limit']}\t\tLimit PNG output to traces with at least this number of events
|
150
156
|
merge:#{$gpx_options['merge']}\t\tMerge all traces into a single trace
|
157
|
+
only_merge:#{$gpx_options['merge']}\t\tDo not export unmerged traces
|
151
158
|
scale:#{$gpx_options['scale']}\t\tSize of print area in PNG output
|
152
159
|
padding:#{$gpx_options['padding']}\t\tSpace around print area
|
153
160
|
points:#{$gpx_options['points']}\t\tTurn on/off points
|
154
161
|
point_size:#{$gpx_options['point_size']}\t\tSet point size
|
155
162
|
point_color:#{$gpx_options['point_color']}\tSet point color: RRGGBBAA in hex (else 'auto')
|
156
163
|
format:#{$gpx_options['format']}\t\tExport format: 'gpx', 'csv', 'png', default 'all'
|
164
|
+
waypoints:#{$gpx_options['waypoints']}\t\tExport waypoints for events: <event_type>, default 'all'
|
157
165
|
PNG images will be 'scale + 2 * padding' big (#{$gpx_options['scale'].to_i+2*$gpx_options['padding'].to_i} for current settings). The scale will be used for the widest dimension, and the other will be reduced to fit the actual size of the trace. The projection used is non, with the points simply mapped to their GPS locations. This will cause visual distortions far from the equator where dlat!=dlon.
|
158
166
|
EOHELP
|
159
167
|
show_header_maps
|
@@ -281,7 +289,9 @@ class Export
|
|
281
289
|
end || hnames
|
282
290
|
end
|
283
291
|
def export_stats(stats)
|
284
|
-
|
292
|
+
filename="#{$export_prefix}#{imei}_stats.csv"
|
293
|
+
puts "Exporting stats to #{filename}"
|
294
|
+
File.open(filename,'w') do |out|
|
285
295
|
stats.keys.sort.each do |header|
|
286
296
|
out.puts header
|
287
297
|
values = stats[header].keys.sort{|a,b| b.to_s<=>a.to_s}
|
@@ -373,51 +383,80 @@ $datasets.keys.sort.each do |imei|
|
|
373
383
|
dataset.report_errors "\t"
|
374
384
|
end
|
375
385
|
if $export_gpx
|
386
|
+
dataset.timer('export.gpx').start
|
387
|
+
$gpx_options['merge'] = true if($gpx_options['only_merge'])
|
376
388
|
merged_traces = Geoptima::MergedTrace.new(dataset)
|
377
389
|
dataset.each_trace do |trace|
|
378
|
-
|
379
|
-
|
380
|
-
|
390
|
+
dataset.timer('export.gpx.trace').start
|
391
|
+
unless $gpx_options['only_merge']
|
392
|
+
Export.export_gpx(trace) if(trace.length>=($gpx_options['limit'] || 1).to_i)
|
393
|
+
Export.export_gps(trace) if(trace.length>=($gpx_options['limit'] || 1).to_i)
|
394
|
+
Export.export_png(trace) if(trace.length>=($gpx_options['png_limit'] || 10).to_i)
|
395
|
+
end
|
381
396
|
merged_traces << trace if($gpx_options['merge'])
|
397
|
+
dataset.timer('export.gpx.trace').stop
|
382
398
|
end
|
383
399
|
if($gpx_options['merge'])
|
400
|
+
dataset.timer('export.gpx.merged').start
|
384
401
|
Export.export_gpx(merged_traces)
|
385
402
|
Export.export_gps(merged_traces)
|
386
403
|
Export.export_png(merged_traces)
|
404
|
+
dataset.timer('export.gpx.merged').stop
|
405
|
+
end
|
406
|
+
if($gpx_options['waypoints'])
|
407
|
+
dataset.timer('export.gpx.waypoints').start
|
408
|
+
waypoints = dataset.waypoints($gpx_options['waypoints'])
|
409
|
+
waypoints.check_trace_bounds(merged_traces) # expand the waypoints to the traces, to make image superposition easier
|
410
|
+
Export.export_gpx(waypoints)
|
411
|
+
Export.export_gps(waypoints)
|
412
|
+
Export.export_png(waypoints)
|
413
|
+
dataset.timer('export.gpx.waypoints').stop
|
387
414
|
end
|
415
|
+
dataset.timer('export.gpx').stop
|
388
416
|
end
|
389
417
|
if events && ($print || $export)
|
418
|
+
dataset.timer('export').start
|
390
419
|
names = $event_names
|
391
420
|
names = dataset.events_names if(names.length<1)
|
392
421
|
export = Export.new(imei,names,dataset)
|
393
422
|
export.export_stats(dataset.stats) if($export_stats)
|
394
423
|
if $header_maps && $header_maps.length > 0
|
424
|
+
puts "Exporting #{dataset} with specified header maps: #{$header_maps.inspect}"
|
395
425
|
$header_maps.each do |hm|
|
396
426
|
puts "Searching for events for header_maps '#{hm.event}'"
|
397
427
|
events.each do |event|
|
398
428
|
if event.name == hm.event
|
429
|
+
dataset.timer('export.event').start
|
399
430
|
header = export.header(event.name)
|
400
431
|
fields = header.map{|h| event[h]}
|
401
432
|
b_header = export.base_headers + export.more_headers
|
402
433
|
b_fields = export.base_fields(event) + export.more_fields(event,dataset)
|
403
434
|
all_fields = hm.map_fields(b_header + header, b_fields + fields)
|
404
435
|
export.puts_to all_fields.join("\t"), event.name
|
436
|
+
dataset.timer('export.event').stop
|
405
437
|
end
|
406
438
|
end
|
407
439
|
end
|
408
440
|
else
|
441
|
+
puts "Exporting #{dataset}"
|
409
442
|
events.each do |event|
|
410
443
|
names.each do |name|
|
411
444
|
if event.name === name
|
445
|
+
dataset.timer('export.event').start
|
412
446
|
fields = export.header($seperate ? name : nil).map{|h| event[h]}
|
413
447
|
b_fields = export.time_fields(event) + export.base_fields(event) + export.more_fields(event,dataset)
|
448
|
+
dataset.timer('export.event.write').start
|
414
449
|
export.puts_to "#{b_fields.join("\t")}\t#{fields.join("\t")}", name
|
450
|
+
dataset.timer('export.event.write').stop
|
415
451
|
if_le{puts "#{b_fields.join("\t")}\t#{event.fields.inspect}"}
|
452
|
+
dataset.timer('export.event').stop
|
416
453
|
end
|
417
454
|
end
|
418
455
|
end
|
419
456
|
end
|
420
457
|
export.close
|
458
|
+
dataset.timer('export').stop
|
421
459
|
end
|
460
|
+
dataset.dump_timers
|
422
461
|
end
|
423
462
|
|
@@ -7,8 +7,8 @@ $: << '../lib'
|
|
7
7
|
require 'geoptima/version'
|
8
8
|
require 'geoptima/file_time'
|
9
9
|
|
10
|
-
Geoptima::assert_version(">=0.1.
|
10
|
+
Geoptima::assert_version(">=0.1.17")
|
11
11
|
|
12
12
|
ARGV.each do |filename|
|
13
|
-
puts "#{(filename.to_s+" "*40)[0..40]} --> #{Geoptima::FileTime.from_file
|
13
|
+
puts "#{(filename.to_s+" "*40)[0..40]} --> #{Geoptima::FileTime.from_file(filename).join(', ')}"
|
14
14
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# useful if being run inside a source code checkout
|
4
|
+
$: << 'lib'
|
5
|
+
$: << '../lib'
|
6
|
+
|
7
|
+
require 'geoptima/version'
|
8
|
+
require 'geoptima/file_time'
|
9
|
+
|
10
|
+
Geoptima::assert_version(">=0.1.17")
|
11
|
+
|
12
|
+
class Stats
|
13
|
+
attr_accessor :no_server, :has_server, :count
|
14
|
+
def initialize
|
15
|
+
@no_server = []
|
16
|
+
@has_server = []
|
17
|
+
@count = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_file(path)
|
21
|
+
return unless(path =~ /\.json$/i)
|
22
|
+
filetime = JSONFileTime.new(File.basename path)
|
23
|
+
@count += 1
|
24
|
+
if filetime.has_server?
|
25
|
+
@has_server << filetime
|
26
|
+
else
|
27
|
+
@no_server << filetime
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def process_path(path)
|
32
|
+
puts "Processing path: #{path}" if($debug)
|
33
|
+
if File.directory? path
|
34
|
+
process_dir(path)
|
35
|
+
elsif File.exist? path
|
36
|
+
process_file path
|
37
|
+
else
|
38
|
+
puts "No such file or directory: #{path}" if($debug)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_dir(dir)
|
43
|
+
Dir.open(dir).each do |file|
|
44
|
+
next if(file =~ /^\./)
|
45
|
+
process_path "#{dir}/#{file}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def report(out)
|
50
|
+
puts "Loaded #{count} files:"
|
51
|
+
puts "\t#{no_server.length} without server timestamp"
|
52
|
+
puts "\t#{has_server.length} with server timestamp"
|
53
|
+
stats = {}
|
54
|
+
has_server.each do |file|
|
55
|
+
key = file.correction.to_i
|
56
|
+
stats[key] ||= 0
|
57
|
+
stats[key] += 1
|
58
|
+
end
|
59
|
+
stats.keys.sort.each do |key|
|
60
|
+
puts "\t\t#{key}:\t#{stats[key]}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
class JSONFileTime
|
67
|
+
attr_accessor :name, :times, :client_time, :server_time, :correction
|
68
|
+
def initialize(name)
|
69
|
+
@name = name
|
70
|
+
@times = Geoptima::FileTime.from_file name
|
71
|
+
@client_time = @times[0]
|
72
|
+
if @times.length > 1
|
73
|
+
puts "\tCalculating times for #{name}: #{@times.join(', ')}" if($debug)
|
74
|
+
@server_time = @times[1]
|
75
|
+
puts "\t\tClient: #{t2s client_time}" if($debug)
|
76
|
+
puts "\t\tServer: #{t2s server_time}" if($debug)
|
77
|
+
@correction = (@server_time - @client_time) * Geoptima::FileTime::DAY_SECONDS
|
78
|
+
puts "\t\tTime offset: #{@correction}" if($debug)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
def t2s(time)
|
82
|
+
time.new_offset(0).strftime("%Y-%m-%d %H:%M:%S.%3N").gsub(/\.(\d{3})\d+/,'.\1')
|
83
|
+
end
|
84
|
+
def has_server?
|
85
|
+
@server_time
|
86
|
+
end
|
87
|
+
def to_s
|
88
|
+
"#{name}:#{client_time}"
|
89
|
+
end
|
90
|
+
def row
|
91
|
+
"#{(name.to_s+" "*40)[0..40]} --> #{times.join(', ')}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
stats = Stats.new
|
96
|
+
$paths = []
|
97
|
+
|
98
|
+
while arg = ARGV.shift
|
99
|
+
if arg =~ /^[\-\+]+(\w+)/
|
100
|
+
$1.split(//).each do |aa|
|
101
|
+
case aa
|
102
|
+
when 'd'
|
103
|
+
$debug = true
|
104
|
+
when 'h'
|
105
|
+
$help = true
|
106
|
+
else
|
107
|
+
puts "Unknown option: -#{aa}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
else
|
111
|
+
$paths << arg
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
$help = true if($paths.length < 1)
|
116
|
+
|
117
|
+
if $help
|
118
|
+
puts <<EOHELP
|
119
|
+
usage: geoptima_file_time_stats <-dh> path <paths..>
|
120
|
+
-d Debug mode
|
121
|
+
-h Print help and exit
|
122
|
+
Each path can be a file or directory. When a directory is selected, a recursive
|
123
|
+
search for files is done. Only files with .json extension are processed.
|
124
|
+
EOHELP
|
125
|
+
exit 0
|
126
|
+
end
|
127
|
+
|
128
|
+
$paths.each do |path|
|
129
|
+
stats.process_path(path)
|
130
|
+
end
|
131
|
+
|
132
|
+
stats.report(STDOUT)
|
133
|
+
|
data/examples/show_geoptima.rb
CHANGED
@@ -8,7 +8,7 @@ require 'date'
|
|
8
8
|
require 'geoptima'
|
9
9
|
require 'geoptima/options'
|
10
10
|
|
11
|
-
Geoptima::assert_version(">=0.1.
|
11
|
+
Geoptima::assert_version(">=0.1.16")
|
12
12
|
|
13
13
|
$debug=false
|
14
14
|
|
@@ -39,6 +39,7 @@ $files = Geoptima::Options.process_args do |option|
|
|
39
39
|
option.L {$print_limit = [1,ARGV.shift.to_i].max}
|
40
40
|
option.M {$mapfile = ARGV.shift}
|
41
41
|
option.G {$gpx_options.merge! ARGV.shift.split(/[\,\;]+/).inject({}){|a,v| k=v.split(/[\:\=]+/);a[k[0]]=k[1]||true;a}}
|
42
|
+
option.A {$app_categories = Geoptima::AppCategories.new(ARGV.shift)}
|
42
43
|
end.map do |file|
|
43
44
|
File.exist?(file) ? file : puts("No such file: #{file}")
|
44
45
|
end.compact
|
@@ -136,9 +137,14 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types>
|
|
136
137
|
-h show this help
|
137
138
|
-P prefix for exported files (default: ''; current: #{$export_prefix})
|
138
139
|
-E comma-seperated list of event types to show and export (default: all; current: #{$event_names.join(',')})
|
140
|
+
-A application category map file (default: app names)
|
139
141
|
-T time range to limit results to (default: all; current: #{$time_range})
|
140
|
-
-B location limited to specified bounds in formats
|
141
|
-
|
142
|
+
-B location limited to specified bounds in one of these formats:
|
143
|
+
minlat,minlon,maxlat,maxlon
|
144
|
+
minlat..maxlat,minlon..maxlon
|
145
|
+
DIST(distance_in_km,lat,lon)
|
146
|
+
RANGE[minlat,minlon,maxlat,maxlon]
|
147
|
+
RANGE[minlat..maxlat,minlon..maxlon]
|
142
148
|
(default: all; current: #{$location_range})
|
143
149
|
-L limit verbose output to specific number of lines #{cw $print_limit}
|
144
150
|
-M mapfile of normal->altered header names: #{$mapfile}
|
@@ -148,12 +154,14 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types>
|
|
148
154
|
limit:#{$gpx_options['limit']}\t\tLimit GPX output to traces with at least this number of events
|
149
155
|
png_limit:#{$gpx_options['png_limit']}\t\tLimit PNG output to traces with at least this number of events
|
150
156
|
merge:#{$gpx_options['merge']}\t\tMerge all traces into a single trace
|
157
|
+
only_merge:#{$gpx_options['merge']}\t\tDo not export unmerged traces
|
151
158
|
scale:#{$gpx_options['scale']}\t\tSize of print area in PNG output
|
152
159
|
padding:#{$gpx_options['padding']}\t\tSpace around print area
|
153
160
|
points:#{$gpx_options['points']}\t\tTurn on/off points
|
154
161
|
point_size:#{$gpx_options['point_size']}\t\tSet point size
|
155
162
|
point_color:#{$gpx_options['point_color']}\tSet point color: RRGGBBAA in hex (else 'auto')
|
156
163
|
format:#{$gpx_options['format']}\t\tExport format: 'gpx', 'csv', 'png', default 'all'
|
164
|
+
waypoints:#{$gpx_options['waypoints']}\t\tExport waypoints for events: <event_type>, default 'all'
|
157
165
|
PNG images will be 'scale + 2 * padding' big (#{$gpx_options['scale'].to_i+2*$gpx_options['padding'].to_i} for current settings). The scale will be used for the widest dimension, and the other will be reduced to fit the actual size of the trace. The projection used is non, with the points simply mapped to their GPS locations. This will cause visual distortions far from the equator where dlat!=dlon.
|
158
166
|
EOHELP
|
159
167
|
show_header_maps
|
@@ -281,7 +289,9 @@ class Export
|
|
281
289
|
end || hnames
|
282
290
|
end
|
283
291
|
def export_stats(stats)
|
284
|
-
|
292
|
+
filename="#{$export_prefix}#{imei}_stats.csv"
|
293
|
+
puts "Exporting stats to #{filename}"
|
294
|
+
File.open(filename,'w') do |out|
|
285
295
|
stats.keys.sort.each do |header|
|
286
296
|
out.puts header
|
287
297
|
values = stats[header].keys.sort{|a,b| b.to_s<=>a.to_s}
|
@@ -373,51 +383,80 @@ $datasets.keys.sort.each do |imei|
|
|
373
383
|
dataset.report_errors "\t"
|
374
384
|
end
|
375
385
|
if $export_gpx
|
386
|
+
dataset.timer('export.gpx').start
|
387
|
+
$gpx_options['merge'] = true if($gpx_options['only_merge'])
|
376
388
|
merged_traces = Geoptima::MergedTrace.new(dataset)
|
377
389
|
dataset.each_trace do |trace|
|
378
|
-
|
379
|
-
|
380
|
-
|
390
|
+
dataset.timer('export.gpx.trace').start
|
391
|
+
unless $gpx_options['only_merge']
|
392
|
+
Export.export_gpx(trace) if(trace.length>=($gpx_options['limit'] || 1).to_i)
|
393
|
+
Export.export_gps(trace) if(trace.length>=($gpx_options['limit'] || 1).to_i)
|
394
|
+
Export.export_png(trace) if(trace.length>=($gpx_options['png_limit'] || 10).to_i)
|
395
|
+
end
|
381
396
|
merged_traces << trace if($gpx_options['merge'])
|
397
|
+
dataset.timer('export.gpx.trace').stop
|
382
398
|
end
|
383
399
|
if($gpx_options['merge'])
|
400
|
+
dataset.timer('export.gpx.merged').start
|
384
401
|
Export.export_gpx(merged_traces)
|
385
402
|
Export.export_gps(merged_traces)
|
386
403
|
Export.export_png(merged_traces)
|
404
|
+
dataset.timer('export.gpx.merged').stop
|
405
|
+
end
|
406
|
+
if($gpx_options['waypoints'])
|
407
|
+
dataset.timer('export.gpx.waypoints').start
|
408
|
+
waypoints = dataset.waypoints($gpx_options['waypoints'])
|
409
|
+
waypoints.check_trace_bounds(merged_traces) # expand the waypoints to the traces, to make image superposition easier
|
410
|
+
Export.export_gpx(waypoints)
|
411
|
+
Export.export_gps(waypoints)
|
412
|
+
Export.export_png(waypoints)
|
413
|
+
dataset.timer('export.gpx.waypoints').stop
|
387
414
|
end
|
415
|
+
dataset.timer('export.gpx').stop
|
388
416
|
end
|
389
417
|
if events && ($print || $export)
|
418
|
+
dataset.timer('export').start
|
390
419
|
names = $event_names
|
391
420
|
names = dataset.events_names if(names.length<1)
|
392
421
|
export = Export.new(imei,names,dataset)
|
393
422
|
export.export_stats(dataset.stats) if($export_stats)
|
394
423
|
if $header_maps && $header_maps.length > 0
|
424
|
+
puts "Exporting #{dataset} with specified header maps: #{$header_maps.inspect}"
|
395
425
|
$header_maps.each do |hm|
|
396
426
|
puts "Searching for events for header_maps '#{hm.event}'"
|
397
427
|
events.each do |event|
|
398
428
|
if event.name == hm.event
|
429
|
+
dataset.timer('export.event').start
|
399
430
|
header = export.header(event.name)
|
400
431
|
fields = header.map{|h| event[h]}
|
401
432
|
b_header = export.base_headers + export.more_headers
|
402
433
|
b_fields = export.base_fields(event) + export.more_fields(event,dataset)
|
403
434
|
all_fields = hm.map_fields(b_header + header, b_fields + fields)
|
404
435
|
export.puts_to all_fields.join("\t"), event.name
|
436
|
+
dataset.timer('export.event').stop
|
405
437
|
end
|
406
438
|
end
|
407
439
|
end
|
408
440
|
else
|
441
|
+
puts "Exporting #{dataset}"
|
409
442
|
events.each do |event|
|
410
443
|
names.each do |name|
|
411
444
|
if event.name === name
|
445
|
+
dataset.timer('export.event').start
|
412
446
|
fields = export.header($seperate ? name : nil).map{|h| event[h]}
|
413
447
|
b_fields = export.time_fields(event) + export.base_fields(event) + export.more_fields(event,dataset)
|
448
|
+
dataset.timer('export.event.write').start
|
414
449
|
export.puts_to "#{b_fields.join("\t")}\t#{fields.join("\t")}", name
|
450
|
+
dataset.timer('export.event.write').stop
|
415
451
|
if_le{puts "#{b_fields.join("\t")}\t#{event.fields.inspect}"}
|
452
|
+
dataset.timer('export.event').stop
|
416
453
|
end
|
417
454
|
end
|
418
455
|
end
|
419
456
|
end
|
420
457
|
export.close
|
458
|
+
dataset.timer('export').stop
|
421
459
|
end
|
460
|
+
dataset.dump_timers
|
422
461
|
end
|
423
462
|
|
data/geoptima.gemspec
CHANGED
@@ -25,7 +25,7 @@ EOF
|
|
25
25
|
s.files = Dir.glob("{bin,lib,rdoc}/**/*").reject{|x| x=~/(tmp|target|test-data)/ || x=~/~$/} +
|
26
26
|
Dir.glob("examples/*rb") + Dir.glob("examples/sample*json") +
|
27
27
|
%w(README.rdoc CHANGELOG CONTRIBUTORS Gemfile geoptima.gemspec)
|
28
|
-
s.executables = ['show_geoptima','geoptima_file_time','csv_chart','csv_stats','csv_merge']
|
28
|
+
s.executables = ['show_geoptima','geoptima_file_time','geoptima_file_time_stats','csv_chart','csv_stats','csv_merge']
|
29
29
|
|
30
30
|
s.extra_rdoc_files = %w( README.rdoc )
|
31
31
|
s.rdoc_options = ["--quiet", "--title", "Geoptima.rb", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
|