geoptima 0.1.13 → 0.1.14
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/show_geoptima +29 -21
- data/examples/show_geoptima.rb +29 -21
- data/lib/geoptima/data.rb +104 -14
- data/lib/geoptima/locationrange.rb +95 -0
- data/lib/geoptima/version.rb +1 -1
- metadata +3 -2
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.14")
|
12
12
|
|
13
13
|
$debug=false
|
14
14
|
|
@@ -16,7 +16,7 @@ $event_names=[]
|
|
16
16
|
$files = []
|
17
17
|
$print_limit = 10000
|
18
18
|
$gpx_options = {
|
19
|
-
'scale' =>
|
19
|
+
'scale' => 190, 'padding' => 5,
|
20
20
|
'limit' => 2, 'png_limit' => 10,
|
21
21
|
'points' => true, 'point_size' => 2, 'point_color' => '0000aa'
|
22
22
|
}
|
@@ -35,6 +35,7 @@ $files = Geoptima::Options.process_args do |option|
|
|
35
35
|
option.P {$export_prefix = ARGV.shift}
|
36
36
|
option.E {$event_names += ARGV.shift.split(/[\,\;\:\.]+/)}
|
37
37
|
option.T {$time_range = Geoptima::DateRange.from ARGV.shift}
|
38
|
+
option.B {$location_range = Geoptima::LocationRange.from ARGV.shift}
|
38
39
|
option.L {$print_limit = [1,ARGV.shift.to_i].max}
|
39
40
|
option.M {$mapfile = ARGV.shift}
|
40
41
|
option.G {$gpx_options.merge! ARGV.shift.split(/[\,\;]+/).inject({}){|a,v| k=v.split(/[\:\=]+/);a[k[0]]=k[1]||true;a}}
|
@@ -136,20 +137,23 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types>
|
|
136
137
|
-P prefix for exported files (default: ''; current: #{$export_prefix})
|
137
138
|
-E comma-seperated list of event types to show and export (default: all; current: #{$event_names.join(',')})
|
138
139
|
-T time range to limit results to (default: all; current: #{$time_range})
|
140
|
+
-B location limited to specified bounds in formats
|
141
|
+
either minlat,minlon,maxlat,maxlon or minlat..maxlat,minlon..maxlon
|
142
|
+
(default: all; current: #{$location_range})
|
139
143
|
-L limit verbose output to specific number of lines #{cw $print_limit}
|
140
144
|
-M mapfile of normal->altered header names: #{$mapfile}
|
141
145
|
-G GPX export options as ';' separated list of key:value pairs
|
142
146
|
Current GPX options: #{$gpx_options.inspect}
|
143
147
|
Known supported GPX options (might be more, see data.rb code):
|
144
|
-
limit:#{$gpx_options['limit']}\tLimit GPX output to traces with at least this number of events
|
145
|
-
png_limit:#{$gpx_options['png_limit']}\tLimit PNG output to traces with at least this number of events
|
146
|
-
scale:#{$gpx_options['scale']}\tSize of print area in PNG output
|
147
|
-
padding:#{$gpx_options['padding']}\tSpace around print area
|
148
|
-
points:#{$gpx_options['points']}\tTurn on/off points
|
149
|
-
point_size:#{$gpx_options['point_size']}\tSet point size
|
150
|
-
point_color:#{$gpx_options['point_color']}\tSet point color: RRGGBBAA in hex
|
151
|
-
|
152
|
-
the widest dimension, and the other will be reduced to fit the trace.
|
148
|
+
limit:#{$gpx_options['limit']}\t\tLimit GPX output to traces with at least this number of events
|
149
|
+
png_limit:#{$gpx_options['png_limit']}\t\tLimit PNG output to traces with at least this number of events
|
150
|
+
scale:#{$gpx_options['scale']}\t\tSize of print area in PNG output
|
151
|
+
padding:#{$gpx_options['padding']}\t\tSpace around print area
|
152
|
+
points:#{$gpx_options['points']}\t\tTurn on/off points
|
153
|
+
point_size:#{$gpx_options['point_size']}\t\tSet point size
|
154
|
+
point_color:#{$gpx_options['point_color']}\tSet point color: RRGGBBAA in hex (else 'auto')
|
155
|
+
format:#{$gpx_options['format']}\t\tExport format: 'gpx', 'png', default 'all'
|
156
|
+
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.
|
153
157
|
EOHELP
|
154
158
|
show_header_maps
|
155
159
|
exit 0
|
@@ -158,7 +162,7 @@ end
|
|
158
162
|
$verbose = $verbose || $debug
|
159
163
|
show_header_maps if($verbose)
|
160
164
|
|
161
|
-
$datasets = Geoptima::Dataset.make_datasets($files, :locate => true, :time_range => $time_range, :combine_all => $combine_all)
|
165
|
+
$datasets = Geoptima::Dataset.make_datasets($files, :locate => true, :time_range => $time_range, :location_range => $location_range, :combine_all => $combine_all)
|
162
166
|
|
163
167
|
class Export
|
164
168
|
attr_reader :files, :imei, :names, :headers
|
@@ -287,19 +291,23 @@ class Export
|
|
287
291
|
end
|
288
292
|
end
|
289
293
|
def export_gpx(trace)
|
290
|
-
|
291
|
-
|
292
|
-
|
294
|
+
if !($gpx_options['format'].to_s =~ /png/)
|
295
|
+
File.open("#{$export_prefix}#{trace}.gpx",'w') do |out|
|
296
|
+
puts "Exporting #{trace.length} GPS events to trace: #{trace}"
|
297
|
+
out.puts trace.as_gpx
|
298
|
+
end
|
293
299
|
end
|
294
300
|
end
|
295
301
|
def export_png(trace)
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
302
|
+
if !($gpx_options['format'].to_s =~ /gpx/)
|
303
|
+
puts "Exporting #{trace.length} GPS events to PNG: #{trace}"
|
304
|
+
if $verbose
|
305
|
+
puts "\tBounds: #{trace.bounds}"
|
306
|
+
puts "\tWidth: #{trace.width}"
|
307
|
+
puts "\tHeight: #{trace.height}"
|
308
|
+
end
|
309
|
+
trace.to_png "#{$export_prefix}#{trace}.png", $gpx_options
|
301
310
|
end
|
302
|
-
trace.to_png "#{$export_prefix}#{trace}.png", $gpx_options
|
303
311
|
end
|
304
312
|
def header(name=nil)
|
305
313
|
@headers[name]
|
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.14")
|
12
12
|
|
13
13
|
$debug=false
|
14
14
|
|
@@ -16,7 +16,7 @@ $event_names=[]
|
|
16
16
|
$files = []
|
17
17
|
$print_limit = 10000
|
18
18
|
$gpx_options = {
|
19
|
-
'scale' =>
|
19
|
+
'scale' => 190, 'padding' => 5,
|
20
20
|
'limit' => 2, 'png_limit' => 10,
|
21
21
|
'points' => true, 'point_size' => 2, 'point_color' => '0000aa'
|
22
22
|
}
|
@@ -35,6 +35,7 @@ $files = Geoptima::Options.process_args do |option|
|
|
35
35
|
option.P {$export_prefix = ARGV.shift}
|
36
36
|
option.E {$event_names += ARGV.shift.split(/[\,\;\:\.]+/)}
|
37
37
|
option.T {$time_range = Geoptima::DateRange.from ARGV.shift}
|
38
|
+
option.B {$location_range = Geoptima::LocationRange.from ARGV.shift}
|
38
39
|
option.L {$print_limit = [1,ARGV.shift.to_i].max}
|
39
40
|
option.M {$mapfile = ARGV.shift}
|
40
41
|
option.G {$gpx_options.merge! ARGV.shift.split(/[\,\;]+/).inject({}){|a,v| k=v.split(/[\:\=]+/);a[k[0]]=k[1]||true;a}}
|
@@ -136,20 +137,23 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types>
|
|
136
137
|
-P prefix for exported files (default: ''; current: #{$export_prefix})
|
137
138
|
-E comma-seperated list of event types to show and export (default: all; current: #{$event_names.join(',')})
|
138
139
|
-T time range to limit results to (default: all; current: #{$time_range})
|
140
|
+
-B location limited to specified bounds in formats
|
141
|
+
either minlat,minlon,maxlat,maxlon or minlat..maxlat,minlon..maxlon
|
142
|
+
(default: all; current: #{$location_range})
|
139
143
|
-L limit verbose output to specific number of lines #{cw $print_limit}
|
140
144
|
-M mapfile of normal->altered header names: #{$mapfile}
|
141
145
|
-G GPX export options as ';' separated list of key:value pairs
|
142
146
|
Current GPX options: #{$gpx_options.inspect}
|
143
147
|
Known supported GPX options (might be more, see data.rb code):
|
144
|
-
limit:#{$gpx_options['limit']}\tLimit GPX output to traces with at least this number of events
|
145
|
-
png_limit:#{$gpx_options['png_limit']}\tLimit PNG output to traces with at least this number of events
|
146
|
-
scale:#{$gpx_options['scale']}\tSize of print area in PNG output
|
147
|
-
padding:#{$gpx_options['padding']}\tSpace around print area
|
148
|
-
points:#{$gpx_options['points']}\tTurn on/off points
|
149
|
-
point_size:#{$gpx_options['point_size']}\tSet point size
|
150
|
-
point_color:#{$gpx_options['point_color']}\tSet point color: RRGGBBAA in hex
|
151
|
-
|
152
|
-
the widest dimension, and the other will be reduced to fit the trace.
|
148
|
+
limit:#{$gpx_options['limit']}\t\tLimit GPX output to traces with at least this number of events
|
149
|
+
png_limit:#{$gpx_options['png_limit']}\t\tLimit PNG output to traces with at least this number of events
|
150
|
+
scale:#{$gpx_options['scale']}\t\tSize of print area in PNG output
|
151
|
+
padding:#{$gpx_options['padding']}\t\tSpace around print area
|
152
|
+
points:#{$gpx_options['points']}\t\tTurn on/off points
|
153
|
+
point_size:#{$gpx_options['point_size']}\t\tSet point size
|
154
|
+
point_color:#{$gpx_options['point_color']}\tSet point color: RRGGBBAA in hex (else 'auto')
|
155
|
+
format:#{$gpx_options['format']}\t\tExport format: 'gpx', 'png', default 'all'
|
156
|
+
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.
|
153
157
|
EOHELP
|
154
158
|
show_header_maps
|
155
159
|
exit 0
|
@@ -158,7 +162,7 @@ end
|
|
158
162
|
$verbose = $verbose || $debug
|
159
163
|
show_header_maps if($verbose)
|
160
164
|
|
161
|
-
$datasets = Geoptima::Dataset.make_datasets($files, :locate => true, :time_range => $time_range, :combine_all => $combine_all)
|
165
|
+
$datasets = Geoptima::Dataset.make_datasets($files, :locate => true, :time_range => $time_range, :location_range => $location_range, :combine_all => $combine_all)
|
162
166
|
|
163
167
|
class Export
|
164
168
|
attr_reader :files, :imei, :names, :headers
|
@@ -287,19 +291,23 @@ class Export
|
|
287
291
|
end
|
288
292
|
end
|
289
293
|
def export_gpx(trace)
|
290
|
-
|
291
|
-
|
292
|
-
|
294
|
+
if !($gpx_options['format'].to_s =~ /png/)
|
295
|
+
File.open("#{$export_prefix}#{trace}.gpx",'w') do |out|
|
296
|
+
puts "Exporting #{trace.length} GPS events to trace: #{trace}"
|
297
|
+
out.puts trace.as_gpx
|
298
|
+
end
|
293
299
|
end
|
294
300
|
end
|
295
301
|
def export_png(trace)
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
302
|
+
if !($gpx_options['format'].to_s =~ /gpx/)
|
303
|
+
puts "Exporting #{trace.length} GPS events to PNG: #{trace}"
|
304
|
+
if $verbose
|
305
|
+
puts "\tBounds: #{trace.bounds}"
|
306
|
+
puts "\tWidth: #{trace.width}"
|
307
|
+
puts "\tHeight: #{trace.height}"
|
308
|
+
end
|
309
|
+
trace.to_png "#{$export_prefix}#{trace}.png", $gpx_options
|
301
310
|
end
|
302
|
-
trace.to_png "#{$export_prefix}#{trace}.png", $gpx_options
|
303
311
|
end
|
304
312
|
def header(name=nil)
|
305
313
|
@headers[name]
|
data/lib/geoptima/data.rb
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'multi_json'
|
5
5
|
require 'geoptima/daterange'
|
6
|
+
require 'geoptima/locationrange'
|
6
7
|
begin
|
7
8
|
require 'png'
|
8
|
-
rescue
|
9
|
+
rescue LoadError
|
9
10
|
puts "No PNG library installed, ignoring PNG output of GPX results"
|
10
11
|
end
|
11
12
|
|
@@ -39,15 +40,23 @@ module Geoptima
|
|
39
40
|
end
|
40
41
|
|
41
42
|
class Trace
|
42
|
-
attr_reader :dataset, :
|
43
|
+
attr_reader :dataset, :data_id, :data_ids, :name, :tracename
|
44
|
+
attr_reader :bounds, :events, :totals, :scale, :padding
|
43
45
|
def initialize(dataset)
|
44
46
|
@dataset = dataset
|
47
|
+
@data_id = nil
|
48
|
+
@data_ids = []
|
45
49
|
@name = dataset.name
|
46
50
|
@events = []
|
47
51
|
end
|
48
52
|
def <<(e)
|
49
53
|
@tracename ||= "#{name}-#{e.time}"
|
54
|
+
unless @data_id
|
55
|
+
@data_id ||= e.file.id
|
56
|
+
@data_ids << e.file.id
|
57
|
+
end
|
50
58
|
check_bounds(e)
|
59
|
+
check_totals(e)
|
51
60
|
@events << e unless(co_located(e,@events[-1]))
|
52
61
|
end
|
53
62
|
def co_located(event,other)
|
@@ -59,6 +68,12 @@ module Geoptima
|
|
59
68
|
def to_s
|
60
69
|
tracename || name
|
61
70
|
end
|
71
|
+
def check_totals(e)
|
72
|
+
@totals ||= [0.0,0.0,0]
|
73
|
+
@totals[0] += e.latitude
|
74
|
+
@totals[1] += e.longitude
|
75
|
+
@totals[2] += 1
|
76
|
+
end
|
62
77
|
def check_bounds(e)
|
63
78
|
@bounds ||= {}
|
64
79
|
check_bounds_min :minlat, e.latitude
|
@@ -69,7 +84,14 @@ module Geoptima
|
|
69
84
|
@height = nil
|
70
85
|
end
|
71
86
|
def check_bounds_min(key,value)
|
72
|
-
|
87
|
+
if value.is_a? String
|
88
|
+
raise "Passed a string value: #{value.inspect}"
|
89
|
+
end
|
90
|
+
begin
|
91
|
+
@bounds[key] = value if(@bounds[key].nil? || @bounds[key] > value)
|
92
|
+
rescue
|
93
|
+
raise "Failed to set bounds using current:#{@bounds.inspect}, value=#{value.inspect}"
|
94
|
+
end
|
73
95
|
end
|
74
96
|
def check_bounds_max(key,value)
|
75
97
|
@bounds[key] = value if(@bounds[key].nil? || @bounds[key] < value)
|
@@ -109,6 +131,34 @@ module Geoptima
|
|
109
131
|
def bottom
|
110
132
|
@bottom ||= @bounds[:minlat].to_f
|
111
133
|
end
|
134
|
+
def average
|
135
|
+
[totals[0] / totals[2], totals[1] / totals[2]]
|
136
|
+
end
|
137
|
+
def remove_outliers
|
138
|
+
if width > 0.1 || height > 0.1
|
139
|
+
distances = []
|
140
|
+
total_distance = 0.0
|
141
|
+
max_distance = 0.0
|
142
|
+
center = Point.new(*average)
|
143
|
+
self.each do |e|
|
144
|
+
distance = e.distance_from(center)
|
145
|
+
distances << [e,distance]
|
146
|
+
total_distance += distance
|
147
|
+
max_distance = distance if(max_distance < distance)
|
148
|
+
end
|
149
|
+
average_distance = total_distance / distances.length
|
150
|
+
threshold = max_distance / 3
|
151
|
+
if threshold > average_distance * 3
|
152
|
+
puts "Average distance #{average_distance} much less than max distance #{max_distance}, trimming all beyond #{threshold}"
|
153
|
+
@bounds = {}
|
154
|
+
distances.each do |d|
|
155
|
+
check_bounds(d[0]) if(d[1] < threshold)
|
156
|
+
end
|
157
|
+
else
|
158
|
+
puts "Average distance #{average_distance} not much less than max distance #{max_distance}, not trimming outliers"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
112
162
|
def scale_event(e)
|
113
163
|
p = [e.longitude.to_f, e.latitude.to_f]
|
114
164
|
if scale
|
@@ -164,7 +214,7 @@ module Geoptima
|
|
164
214
|
[self]
|
165
215
|
end
|
166
216
|
def colors
|
167
|
-
@colors ||= PNG::Color.constants.reject{|c| (c.is_a?(PNG::Color)) || c.to_s =~ /max/i || c.to_s =~ /background/i}.map{|c| PNG::Color.const_get c}.reject{|c| c == PNG::Color::Background}
|
217
|
+
@colors ||= PNG::Color.constants.reject{|c| (c.is_a?(PNG::Color)) || c.to_s =~ /max/i || c.to_s =~ /background/i}.map{|c| PNG::Color.const_get c}.reject{|c| c == PNG::Color::Background || c == PNG::Color::Black || c == PNG::Color::White}
|
168
218
|
end
|
169
219
|
def color(index=1)
|
170
220
|
self.colors[index%(self.colors.length)]
|
@@ -174,14 +224,24 @@ module Geoptima
|
|
174
224
|
puts "Exporting with options: #{options.inspect}"
|
175
225
|
self.scale = options['scale']
|
176
226
|
self.padding = options['padding']
|
227
|
+
remove_outliers
|
177
228
|
['scale','padding','size','bounds','width','height'].each do |a|
|
178
229
|
puts "\t#{a}: #{self.send(a).inspect}"
|
179
230
|
end
|
180
|
-
|
231
|
+
begin
|
232
|
+
canvas = PNG::Canvas.new size[0],size[1]
|
233
|
+
rescue
|
234
|
+
puts "Unable to initialize PNG:Canvas - is 'png' gem installed? #{$!}"
|
235
|
+
return
|
236
|
+
end
|
181
237
|
|
238
|
+
data_idm = data_ids.inject({}){|a,v| a[v]=a.length;a}
|
239
|
+
if data_ids.length > 1
|
240
|
+
data_ids.each do |did|
|
241
|
+
puts "Mapped data ID '#{did}' to color: #{color(data_idm[did])}"
|
242
|
+
end
|
243
|
+
end
|
182
244
|
traces.each_with_index do |trace,index|
|
183
|
-
prev = nil
|
184
|
-
point_color = color(index)
|
185
245
|
line_color = PNG::Color.from "0x00006688"
|
186
246
|
if options['point_color'] && !(options['point_color'] =~ /auto/i)
|
187
247
|
pc = options['point_color'].gsub(/^\#/,'').gsub(/^0x/,'').upcase
|
@@ -191,8 +251,15 @@ module Geoptima
|
|
191
251
|
rescue
|
192
252
|
puts "Failed to interpret color #{pc}, use format 0x00000000: #{$!}"
|
193
253
|
end
|
254
|
+
elsif data_ids.length > 1
|
255
|
+
point_color = color(data_idm[trace.data_id])
|
256
|
+
puts "Got point color #{point_color} from data ID '#{trace.data_id}' index #{data_idm[trace.data_id]}" if($debug)
|
257
|
+
else
|
258
|
+
point_color = color(index)
|
259
|
+
puts "Got point color #{point_color} from trace index #{index}"
|
194
260
|
end
|
195
|
-
|
261
|
+
|
262
|
+
prev = nil
|
196
263
|
trace.events.each do |e|
|
197
264
|
p = scale_event(e)
|
198
265
|
begin
|
@@ -229,19 +296,33 @@ module Geoptima
|
|
229
296
|
def initialize(dataset)
|
230
297
|
@dataset = dataset
|
231
298
|
@name = dataset.name
|
299
|
+
@data_ids = []
|
232
300
|
@traces = []
|
233
301
|
end
|
234
302
|
def tracename
|
235
303
|
@tracename ||= "Merged-#{traces.length}-traces-#{traces[0]}"
|
236
304
|
end
|
237
305
|
def <<(t)
|
238
|
-
|
306
|
+
check_trace_totals(t)
|
307
|
+
check_trace_bounds(t)
|
308
|
+
@data_ids = (@data_ids+t.data_ids).sort.uniq.compact
|
239
309
|
@traces << t
|
240
310
|
end
|
311
|
+
def each
|
312
|
+
traces.each do |t|
|
313
|
+
t.events.each do |e|
|
314
|
+
yield e
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
241
318
|
def length
|
242
319
|
@length ||= traces.inject(0){|a,t| a+=t.length;a}
|
243
320
|
end
|
244
|
-
def
|
321
|
+
def check_trace_totals(t)
|
322
|
+
@totals ||= [0.0,0.0,0]
|
323
|
+
[0,1,2].each{|i| @totals[i] += t.totals[i]}
|
324
|
+
end
|
325
|
+
def check_trace_bounds(t)
|
245
326
|
@bounds ||= {}
|
246
327
|
check_bounds_min :minlat, t.bounds[:minlat]
|
247
328
|
check_bounds_min :minlon, t.bounds[:minlon]
|
@@ -373,9 +454,14 @@ module Geoptima
|
|
373
454
|
def closer_than(other,seconds=60)
|
374
455
|
(self - other).abs < seconds
|
375
456
|
end
|
457
|
+
def location
|
458
|
+
@location ||= self['latitude'] && Point.new(self['latitude'],self['longitude'])
|
459
|
+
end
|
376
460
|
def locate(gps)
|
377
|
-
|
378
|
-
@
|
461
|
+
incr_error "GPS String Data" if(gps['latitude'].is_a? String)
|
462
|
+
@latitude = gps['latitude'].to_f
|
463
|
+
@longitude = gps['longitude'].to_f
|
464
|
+
@location = nil
|
379
465
|
end
|
380
466
|
def locate_if_closer_than(gps,seconds=60)
|
381
467
|
locate(gps) if(closer_than(gps,seconds))
|
@@ -581,6 +667,7 @@ module Geoptima
|
|
581
667
|
@data = []
|
582
668
|
@options = options
|
583
669
|
@time_range = options[:time_range] || DateRange.new(Config[:min_datetime],Config[:max_datetime])
|
670
|
+
@location_range = options[:location_range] || LocationRange.everywhere
|
584
671
|
@fields = {}
|
585
672
|
end
|
586
673
|
|
@@ -729,6 +816,7 @@ module Geoptima
|
|
729
816
|
event_hash = {}
|
730
817
|
puts "Creating sorted maps for #{self}" if($debug)
|
731
818
|
events_names.each do |name|
|
819
|
+
is_gps = name == 'gps'
|
732
820
|
puts "Preparing maps for #{name}" if($debug)
|
733
821
|
@data.each do |data|
|
734
822
|
puts "Processing #{(e=data.events[name]) && e.length} events for #{name}" if($debug)
|
@@ -736,8 +824,10 @@ module Geoptima
|
|
736
824
|
puts "\t\tTesting #{event.time} inside #{@time_range}" if($debug)
|
737
825
|
if @time_range.include?(event.time)
|
738
826
|
puts "\t\t\tEvent at #{event.time} is inside #{@time_range}" if($debug)
|
739
|
-
|
740
|
-
|
827
|
+
if !is_gps || @location_range.nil? || @location_range.include?(event.location)
|
828
|
+
key = "#{event.time_key} #{name}"
|
829
|
+
event_hash[key] = event
|
830
|
+
end
|
741
831
|
end
|
742
832
|
end
|
743
833
|
combine_errors data
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module Geoptima
|
4
|
+
|
5
|
+
class Point
|
6
|
+
attr_reader :latitude, :longitude
|
7
|
+
def initialize(latitude,longitude)
|
8
|
+
@latitude = latitude.to_f
|
9
|
+
@longitude = longitude.to_f
|
10
|
+
end
|
11
|
+
def >(other)
|
12
|
+
self.latitude - other.latitude > 0 && self.longitude - other.longitude > 0
|
13
|
+
end
|
14
|
+
def <(other)
|
15
|
+
self.latitude - other.latitude < 0 && self.longitude - other.longitude < 0
|
16
|
+
end
|
17
|
+
def >=(other)
|
18
|
+
self.latitude - other.latitude >= 0 && self.longitude - other.longitude >= 0
|
19
|
+
end
|
20
|
+
def <=(other)
|
21
|
+
self.latitude - other.latitude <= 0 && self.longitude - other.longitude <= 0
|
22
|
+
end
|
23
|
+
def to_s
|
24
|
+
[@latitude,@longitude].inspect
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class LocationRange
|
29
|
+
attr_reader :min, :max
|
30
|
+
def initialize(spec)
|
31
|
+
f=spec.gsub(/\.\./,':').split(/[\,\;\:]/)
|
32
|
+
if spec =~ /\.\./
|
33
|
+
@min = Point.new(f[0],f[2])
|
34
|
+
@max = Point.new(f[1],f[3])
|
35
|
+
else
|
36
|
+
@min = Point.new(f[0],f[1])
|
37
|
+
@max = Point.new(f[2],f[3])
|
38
|
+
end
|
39
|
+
if @min > @max
|
40
|
+
p = @min
|
41
|
+
@min = @max
|
42
|
+
@max = p
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def include?(point)
|
46
|
+
puts "Testing point #{point} in range #{self}" if($debug)
|
47
|
+
point && point < @max && point >= @min
|
48
|
+
end
|
49
|
+
def to_s
|
50
|
+
[min,max].join(',')
|
51
|
+
end
|
52
|
+
def self.from(spec)
|
53
|
+
if spec == '*' || spec =~ /everywhere/i
|
54
|
+
LocationEverywhere.new
|
55
|
+
else
|
56
|
+
LocationRange.new(spec)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
def self.everywhere
|
60
|
+
@@everywhere ||= LocationEverywhere.new
|
61
|
+
end
|
62
|
+
def self.test
|
63
|
+
[
|
64
|
+
'56.1..57.0,12.0..15.8',
|
65
|
+
'56.1,12.0,57.0,15.8',
|
66
|
+
'everywhere',
|
67
|
+
'*'
|
68
|
+
].each do |test|
|
69
|
+
puts "Testing: #{test}"
|
70
|
+
range = Geoptima::LocationRange.from(test)
|
71
|
+
puts "\t#{range}"
|
72
|
+
puts "\tTesting MIN: #{range}.include?(#{range.min}) => #{range.include?(range.min)}"
|
73
|
+
puts "\tTesting MAX: #{range}.include?(#{range.max}) => #{range.include?(range.max)}"
|
74
|
+
(0..10).each do |i|
|
75
|
+
latitude = 56.0 + 0.1 * i
|
76
|
+
longitude = 11.0 + 0.2 * i
|
77
|
+
p = Point.new(latitude,longitude)
|
78
|
+
puts "\tTesting #{range}.include?(#{p}) => #{range.include?(p)}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
class LocationEverywhere <LocationRange
|
84
|
+
def initialize()
|
85
|
+
super("-90,90,-180,180")
|
86
|
+
end
|
87
|
+
def to_s
|
88
|
+
"everywhere"
|
89
|
+
end
|
90
|
+
def include?(point)
|
91
|
+
true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
data/lib/geoptima/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geoptima
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.14
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- lib/geoptima/daterange.rb
|
89
89
|
- lib/geoptima/options.rb
|
90
90
|
- lib/geoptima/file_time.rb
|
91
|
+
- lib/geoptima/locationrange.rb
|
91
92
|
- lib/geoptima.rb
|
92
93
|
- examples/show_geoptima_sos.rb
|
93
94
|
- examples/show_geoptima.rb
|