geoptima 0.1.18 → 0.1.19
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.
- data/CONTRIBUTORS +1 -1
 - data/Gemfile +4 -2
 - data/README.rdoc +59 -3
 - data/bin/show_geoptima +87 -18
 - data/examples/show_geoptima.rb +87 -18
 - data/geoptima.gemspec +33 -7
 - data/lib/geoptima/after.ports +17 -0
 - data/lib/geoptima/before.ports +16 -0
 - data/lib/geoptima/data.rb +12 -19
 - data/lib/geoptima/locator.rb +172 -0
 - data/lib/geoptima/version.rb +1 -1
 - metadata +50 -32
 
    
        data/CONTRIBUTORS
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -1,5 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            source :gemcutter
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            gemspec
         
     | 
| 
       4 
2 
     | 
    
         | 
| 
       5 
3 
     | 
    
         
             
            group 'test' do
         
     | 
| 
         @@ -10,6 +8,10 @@ group 'test' do 
     | 
|
| 
       10 
8 
     | 
    
         
             
              gem "test-unit"
         
     | 
| 
       11 
9 
     | 
    
         
             
            end
         
     | 
| 
       12 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
            gem "multi_json", ">= 1.1.0"
         
     | 
| 
      
 12 
     | 
    
         
            +
            gem "json_pure", ">= 1.6.5"
         
     | 
| 
      
 13 
     | 
    
         
            +
            gem "json", ">= 1.6.5"
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       13 
15 
     | 
    
         
             
            #gem 'ruby-debug-base19' if RUBY_VERSION.include? "1.9"
         
     | 
| 
       14 
16 
     | 
    
         
             
            #gem 'ruby-debug-base' if RUBY_VERSION.include? "1.8"
         
     | 
| 
       15 
17 
     | 
    
         
             
            #gem "ruby-debug-ide"
         
     | 
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -24,10 +24,11 @@ This script imports the JSON files on the command-line and then: 
     | 
|
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
            Which event types to include and various other options are available using the command-line. Run it with the -h option to get a full list of options. The current version should support:
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
              Usage: show_geoptima <- 
     | 
| 
      
 27 
     | 
    
         
            +
              Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit>
         
     | 
| 
      
 28 
     | 
    
         
            +
                                 <-E types> <-T min,max> <-M mapfile> file <files>
         
     | 
| 
       28 
29 
     | 
    
         
             
              -d  debug mode (output more context during processing) (false)
         
     | 
| 
       29 
30 
     | 
    
         
             
              -w  verbose mode (output extra information to console) 
         
     | 
| 
       30 
     | 
    
         
            -
              -v  print geoptima library version 0.1. 
     | 
| 
      
 31 
     | 
    
         
            +
              -v  print geoptima library version 0.1.19
         
     | 
| 
       31 
32 
     | 
    
         
             
              -p  print mode (print out final results to console) 
         
     | 
| 
       32 
33 
     | 
    
         
             
              -x  export IMEI specific CSV files for further processing 
         
     | 
| 
       33 
34 
     | 
    
         
             
              -o  export field statistis 
         
     | 
| 
         @@ -36,12 +37,67 @@ Which event types to include and various other options are available using the c 
     | 
|
| 
       36 
37 
     | 
    
         
             
              -s  seperate the export files by event type 
         
     | 
| 
       37 
38 
     | 
    
         
             
              -a  combine all IMEI's into a single dataset 
         
     | 
| 
       38 
39 
     | 
    
         
             
              -f  flush stdout 
         
     | 
| 
      
 40 
     | 
    
         
            +
              -e  show error statistics 
         
     | 
| 
      
 41 
     | 
    
         
            +
              -g  export GPX traces 
         
     | 
| 
      
 42 
     | 
    
         
            +
              -t  split time colum to multiple columns 
         
     | 
| 
       39 
43 
     | 
    
         
             
              -h  show this help
         
     | 
| 
       40 
44 
     | 
    
         
             
              -P  prefix for exported files (default: ''; current: )
         
     | 
| 
       41 
45 
     | 
    
         
             
              -E  comma-seperated list of event types to show and export (default: all; current: )
         
     | 
| 
      
 46 
     | 
    
         
            +
              -A  application category map file (default: app names)
         
     | 
| 
       42 
47 
     | 
    
         
             
              -T  time range to limit results to (default: all; current: )
         
     | 
| 
      
 48 
     | 
    
         
            +
              -B  location limited to specified bounds in one of these formats:
         
     | 
| 
      
 49 
     | 
    
         
            +
                    minlat,minlon,maxlat,maxlon
         
     | 
| 
      
 50 
     | 
    
         
            +
                    minlat..maxlat,minlon..maxlon
         
     | 
| 
      
 51 
     | 
    
         
            +
                    DIST(distance_in_km,lat,lon)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    RANGE[minlat,minlon,maxlat,maxlon]
         
     | 
| 
      
 53 
     | 
    
         
            +
                    RANGE[minlat..maxlat,minlon..maxlon]
         
     | 
| 
      
 54 
     | 
    
         
            +
                  (default: all; current: )
         
     | 
| 
       43 
55 
     | 
    
         
             
              -L  limit verbose output to specific number of lines (10000)
         
     | 
| 
       44 
56 
     | 
    
         
             
              -M  mapfile of normal->altered header names: 
         
     | 
| 
      
 57 
     | 
    
         
            +
              -G  GPX export options as ';' separated list of key:value pairs
         
     | 
| 
      
 58 
     | 
    
         
            +
                  Current GPX options: {"scale"=>190, "padding"=>5, "limit"=>2,
         
     | 
| 
      
 59 
     | 
    
         
            +
                  "png_limit"=>10, "points"=>true, "point_size"=>2, "point_color"=>"auto"}
         
     | 
| 
      
 60 
     | 
    
         
            +
              -X  Geolocation options as ';' separated list of key:value pairs
         
     | 
| 
      
 61 
     | 
    
         
            +
                  Current geolocation options: {"algorithm"=>"window", "window"=>60}
         
     | 
| 
      
 62 
     | 
    
         
            +
              
         
     | 
| 
      
 63 
     | 
    
         
            +
              The GPX and Geolocation options require futher explanation:
         
     | 
| 
      
 64 
     | 
    
         
            +
              
         
     | 
| 
      
 65 
     | 
    
         
            +
              Known supported GPX options (might be more, see data.rb code):
         
     | 
| 
      
 66 
     | 
    
         
            +
              limit:2     	    Limit GPX output to traces with at least this number of events
         
     | 
| 
      
 67 
     | 
    
         
            +
              png_limit:10	    Limit PNG output to traces with at least this number of events
         
     | 
| 
      
 68 
     | 
    
         
            +
              merge:     	    Merge all traces into a single trace
         
     | 
| 
      
 69 
     | 
    
         
            +
              only_merge:	    Do not export unmerged traces
         
     | 
| 
      
 70 
     | 
    
         
            +
              scale:190	    Size of print area in PNG output
         
     | 
| 
      
 71 
     | 
    
         
            +
              padding:5	    Space around print area
         
     | 
| 
      
 72 
     | 
    
         
            +
              points:true	    Turn on/off points
         
     | 
| 
      
 73 
     | 
    
         
            +
              point_size:2	    Set point size
         
     | 
| 
      
 74 
     | 
    
         
            +
              point_color:auto  Set point color: RRGGBBAA in hex (else 'auto')
         
     | 
| 
      
 75 
     | 
    
         
            +
              format:     	    Export format: 'gpx', 'csv', 'png', default 'all'
         
     | 
| 
      
 76 
     | 
    
         
            +
              waypoints:	    Export waypoints for events: <event_type>, default 'all'
         
     | 
| 
      
 77 
     | 
    
         
            +
              
         
     | 
| 
      
 78 
     | 
    
         
            +
              PNG images will be 'scale + 2 * padding' big (200 for current settings).
         
     | 
| 
      
 79 
     | 
    
         
            +
              The scale will be used for the widest dimension, and the other will be reduced
         
     | 
| 
      
 80 
     | 
    
         
            +
              to fit the actual size of the trace. No projection is used, with the points
         
     | 
| 
      
 81 
     | 
    
         
            +
              simply mapped to their GPS locations. This will cause visual distortions far
         
     | 
| 
      
 82 
     | 
    
         
            +
              from the equator where dlat!=dlon.
         
     | 
| 
      
 83 
     | 
    
         
            +
              
         
     | 
| 
      
 84 
     | 
    
         
            +
              Known supported geolocation options (might be more, see data.rb code):
         
     | 
| 
      
 85 
     | 
    
         
            +
              algorithm:window  Which geolocation algorithm to use
         
     | 
| 
      
 86 
     | 
    
         
            +
              window:60	    Time window in seconds, has slightly different
         
     | 
| 
      
 87 
     | 
    
         
            +
                                meanings for different algorithms
         
     | 
| 
      
 88 
     | 
    
         
            +
              
         
     | 
| 
      
 89 
     | 
    
         
            +
              Currently supported algorithms:
         
     | 
| 
      
 90 
     | 
    
         
            +
              window:      select GPS point within window seconds of event,
         
     | 
| 
      
 91 
     | 
    
         
            +
                           GPS points after the event take priority.
         
     | 
| 
      
 92 
     | 
    
         
            +
                           (this is the default for geoptima GEM version >= 0.1.19)
         
     | 
| 
      
 93 
     | 
    
         
            +
              +win:        select only GPS points after event (within time window)
         
     | 
| 
      
 94 
     | 
    
         
            +
              -win:        select only GPS points before event (within time window)
         
     | 
| 
      
 95 
     | 
    
         
            +
                           (this is the default for geoptima GEM version < 0.1.19)
         
     | 
| 
      
 96 
     | 
    
         
            +
              closest:     select closest GPS point within window seconds of event
         
     | 
| 
      
 97 
     | 
    
         
            +
                           (similar to window option, but chooses closest)
         
     | 
| 
      
 98 
     | 
    
         
            +
              interpolate: Linear interpolation between two closest points
         
     | 
| 
      
 99 
     | 
    
         
            +
                           (experimental, do not use yet)
         
     | 
| 
      
 100 
     | 
    
         
            +
                           (read redmine wiki page for explanation of algorithm)
         
     | 
| 
       45 
101 
     | 
    
         | 
| 
       46 
102 
     | 
    
         
             
            Currently the script also locates events that are close enough in time to GPS events. We hope to improve this with interpolation in the near future to be more compatible with the results from the commercial solutions. This time-window is also used for some of the extended header information, like LAC and CI, and effectively duplicates those fields from their own events to others. Take this into account when doing statistics on the results. It is better to use the original values, not the duplicates, if you want reliable statistics.
         
     | 
| 
       47 
103 
     | 
    
         | 
| 
         @@ -150,7 +206,7 @@ To get the optimized json gem installed, or to get chart support working you wil 
     | 
|
| 
       150 
206 
     | 
    
         | 
| 
       151 
207 
     | 
    
         
             
            ==== Running on Windows
         
     | 
| 
       152 
208 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
            The best way to run on windows is to edit your system path (usually go to 'my computer->properties->advanced->environment), and add the path to your ruby bin directory (usually C 
     | 
| 
      
 209 
     | 
    
         
            +
            The best way to run on windows is to edit your system path (usually go to 'my computer->properties->advanced->environment), and add the path to your ruby bin directory (usually C:\\Ruby\\bin) to the end of the system PATH. After that, open a command-prompt (start->cmd.exe) and type 'ruby -v' to see that it worked. Then you can execute the 'gem install' commands and the 'show_geoptima' commands from this console.
         
     | 
| 
       154 
210 
     | 
    
         | 
| 
       155 
211 
     | 
    
         
             
            ==== Installing Gruff for Charting
         
     | 
| 
       156 
212 
     | 
    
         | 
    
        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.19")
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            $debug=false
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
         @@ -21,6 +21,18 @@ $gpx_options = { 
     | 
|
| 
       21 
21 
     | 
    
         
             
              'points' => true, 'point_size' => 2, 'point_color' => 'auto'
         
     | 
| 
       22 
22 
     | 
    
         
             
            }
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            $geolocation_options = {
         
     | 
| 
      
 25 
     | 
    
         
            +
              'algorithm' => 'window', 'window' => 60
         
     | 
| 
      
 26 
     | 
    
         
            +
            }
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            def make_hash_options(arg)
         
     | 
| 
      
 29 
     | 
    
         
            +
              arg.split(/[\,\;]+/).inject({}) do |a,v|
         
     | 
| 
      
 30 
     | 
    
         
            +
                k=v.split(/[\:\=]+/)
         
     | 
| 
      
 31 
     | 
    
         
            +
                a[k[0]]=k[1]||true
         
     | 
| 
      
 32 
     | 
    
         
            +
                a
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       24 
36 
     | 
    
         
             
            $files = Geoptima::Options.process_args do |option|
         
     | 
| 
       25 
37 
     | 
    
         
             
              option.p {$print = true}
         
     | 
| 
       26 
38 
     | 
    
         
             
              option.x {$export = true}
         
     | 
| 
         @@ -38,8 +50,9 @@ $files = Geoptima::Options.process_args do |option| 
     | 
|
| 
       38 
50 
     | 
    
         
             
              option.B {$location_range = Geoptima::LocationRange.from ARGV.shift}
         
     | 
| 
       39 
51 
     | 
    
         
             
              option.L {$print_limit = [1,ARGV.shift.to_i].max}
         
     | 
| 
       40 
52 
     | 
    
         
             
              option.M {$mapfile = ARGV.shift}
         
     | 
| 
       41 
     | 
    
         
            -
              option.G {$gpx_options.merge! ARGV.shift 
     | 
| 
      
 53 
     | 
    
         
            +
              option.G {$gpx_options.merge! make_hash_options(ARGV.shift)}
         
     | 
| 
       42 
54 
     | 
    
         
             
              option.A {$app_categories = Geoptima::AppCategories.new(ARGV.shift)}
         
     | 
| 
      
 55 
     | 
    
         
            +
              option.X {$geolocation_options.merge! make_hash_options(ARGV.shift)}
         
     | 
| 
       43 
56 
     | 
    
         
             
            end.map do |file|
         
     | 
| 
       44 
57 
     | 
    
         
             
              File.exist?(file) ? file : puts("No such file: #{file}")
         
     | 
| 
       45 
58 
     | 
    
         
             
            end.compact
         
     | 
| 
         @@ -116,10 +129,33 @@ end 
     | 
|
| 
       116 
129 
     | 
    
         | 
| 
       117 
130 
     | 
    
         
             
            exit 0 if($print_version && !$verbose)
         
     | 
| 
       118 
131 
     | 
    
         | 
| 
      
 132 
     | 
    
         
            +
            class String
         
     | 
| 
      
 133 
     | 
    
         
            +
              def wrappad(max=80,pad=8)
         
     | 
| 
      
 134 
     | 
    
         
            +
                max = [max,pad+1].max
         
     | 
| 
      
 135 
     | 
    
         
            +
                wrapped = [self.to_s]
         
     | 
| 
      
 136 
     | 
    
         
            +
                while wrapped[-1].length > max
         
     | 
| 
      
 137 
     | 
    
         
            +
                  a,b = wrapped[-1][0..(max-1)],wrapped[-1][max..-1]
         
     | 
| 
      
 138 
     | 
    
         
            +
                  if (si = a.rindex(/\s+/)) && (a[0..(si-1)] =~ /\S/)
         
     | 
| 
      
 139 
     | 
    
         
            +
                    b = [a[si..-1],b].join.gsub(/^\s+/,'')
         
     | 
| 
      
 140 
     | 
    
         
            +
                    a = a[0..(si-1)]
         
     | 
| 
      
 141 
     | 
    
         
            +
                  else
         
     | 
| 
      
 142 
     | 
    
         
            +
                    a+='-'
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                  a = a.gsub(/\s+$/,'')
         
     | 
| 
      
 145 
     | 
    
         
            +
                  b = b.gsub(/^\s+/,'')
         
     | 
| 
      
 146 
     | 
    
         
            +
                  wrapped[-1] = a
         
     | 
| 
      
 147 
     | 
    
         
            +
                  wrapped << [' '*pad,b].join
         
     | 
| 
      
 148 
     | 
    
         
            +
                  puts "WRAP[#{max}:#{pad}]: #{wrapped.inspect}"
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
                wrapped
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
            end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
       119 
154 
     | 
    
         
             
            $help = true if($files.length < 1)
         
     | 
| 
       120 
155 
     | 
    
         
             
            if $help
         
     | 
| 
       121 
156 
     | 
    
         
             
              puts <<EOHELP
         
     | 
| 
       122 
     | 
    
         
            -
            Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> 
     | 
| 
      
 157 
     | 
    
         
            +
            Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit>
         
     | 
| 
      
 158 
     | 
    
         
            +
                                 <-E types> <-T min,max> <-M mapfile> file <files>
         
     | 
| 
       123 
159 
     | 
    
         
             
              -d  debug mode (output more context during processing) #{cw $debug}
         
     | 
| 
       124 
160 
     | 
    
         
             
              -w  verbose mode (output extra information to console) #{cw $verbose}
         
     | 
| 
       125 
161 
     | 
    
         
             
              -v  print geoptima library version #{Geoptima::VERSION}
         
     | 
| 
         @@ -149,20 +185,47 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types> 
     | 
|
| 
       149 
185 
     | 
    
         
             
              -L  limit verbose output to specific number of lines #{cw $print_limit}
         
     | 
| 
       150 
186 
     | 
    
         
             
              -M  mapfile of normal->altered header names: #{$mapfile}
         
     | 
| 
       151 
187 
     | 
    
         
             
              -G  GPX export options as ';' separated list of key:value pairs
         
     | 
| 
       152 
     | 
    
         
            -
                  Current GPX options:  
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
      
 188 
     | 
    
         
            +
            #{('      Current GPX options: '+$gpx_options.inspect).wrappad(80,6).join("\n")}
         
     | 
| 
      
 189 
     | 
    
         
            +
              -X  Geolocation options as ';' separated list of key:value pairs
         
     | 
| 
      
 190 
     | 
    
         
            +
            #{('      Current geolocation options: '+$geolocation_options.inspect).wrappad(80,6).join("\n")}
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            The GPX and Geolocation options require futher explanation:
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            Known supported GPX options (might be more, see data.rb code):
         
     | 
| 
      
 195 
     | 
    
         
            +
              limit:#{$gpx_options['limit']}     \t    Limit GPX output to traces with at least this number of events
         
     | 
| 
      
 196 
     | 
    
         
            +
              png_limit:#{$gpx_options['png_limit']}\t    Limit PNG output to traces with at least this number of events
         
     | 
| 
      
 197 
     | 
    
         
            +
              merge:#{$gpx_options['merge']}     \t    Merge all traces into a single trace
         
     | 
| 
      
 198 
     | 
    
         
            +
              only_merge:#{$gpx_options['merge']}\t    Do not export unmerged traces
         
     | 
| 
      
 199 
     | 
    
         
            +
              scale:#{$gpx_options['scale']}\t    Size of print area in PNG output
         
     | 
| 
      
 200 
     | 
    
         
            +
              padding:#{$gpx_options['padding']}\t    Space around print area
         
     | 
| 
      
 201 
     | 
    
         
            +
              points:#{$gpx_options['points']}\t    Turn on/off points
         
     | 
| 
      
 202 
     | 
    
         
            +
              point_size:#{$gpx_options['point_size']}\t    Set point size
         
     | 
| 
      
 203 
     | 
    
         
            +
              point_color:#{$gpx_options['point_color']}  Set point color: RRGGBBAA in hex (else 'auto')
         
     | 
| 
      
 204 
     | 
    
         
            +
              format:#{$gpx_options['format']}     \t    Export format: 'gpx', 'csv', 'png', default 'all'
         
     | 
| 
      
 205 
     | 
    
         
            +
              waypoints:#{$gpx_options['waypoints']}\t    Export waypoints for events: <event_type>, default 'all'
         
     | 
| 
      
 206 
     | 
    
         
            +
            PNG images will be 'scale + 2 * padding' big (#{$gpx_options['scale'].to_i+2*$gpx_options['padding'].to_i} for current settings).
         
     | 
| 
      
 207 
     | 
    
         
            +
            The scale will be used for the widest dimension, and the other will be reduced
         
     | 
| 
      
 208 
     | 
    
         
            +
            to fit the actual size of the trace. No projection is used, with the points
         
     | 
| 
      
 209 
     | 
    
         
            +
            simply mapped to their GPS locations. This will cause visual distortions far
         
     | 
| 
      
 210 
     | 
    
         
            +
            from the equator where dlat!=dlon.
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
            Known supported geolocation options (might be more, see data.rb code):
         
     | 
| 
      
 213 
     | 
    
         
            +
            algorithm:#{$geolocation_options['algorithm']}    Which geolocation algorithm to use
         
     | 
| 
      
 214 
     | 
    
         
            +
            window:#{$geolocation_options['window']}\t    Time window in seconds, has slightly different
         
     | 
| 
      
 215 
     | 
    
         
            +
                                meanings for different algorithms
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
            Currently supported algorithms:
         
     | 
| 
      
 218 
     | 
    
         
            +
              window:      select GPS point within window seconds of event,
         
     | 
| 
      
 219 
     | 
    
         
            +
                           GPS points after the event take priority.
         
     | 
| 
      
 220 
     | 
    
         
            +
                           (this is the default for geoptima GEM version >= 0.1.19)
         
     | 
| 
      
 221 
     | 
    
         
            +
              +win:        select only GPS points after event (within time window)
         
     | 
| 
      
 222 
     | 
    
         
            +
              -win:        select only GPS points before event (within time window)
         
     | 
| 
      
 223 
     | 
    
         
            +
                           (this is the default for geoptima GEM version < 0.1.19)
         
     | 
| 
      
 224 
     | 
    
         
            +
              closest:     select closest GPS point within window seconds of event
         
     | 
| 
      
 225 
     | 
    
         
            +
                           (similar to window option, but chooses closest)
         
     | 
| 
      
 226 
     | 
    
         
            +
              interpolate: Linear interpolation between two closest points
         
     | 
| 
      
 227 
     | 
    
         
            +
                           (experimental, do not use yet)
         
     | 
| 
      
 228 
     | 
    
         
            +
                           (read redmine wiki page for explanation of algorithm)
         
     | 
| 
       166 
229 
     | 
    
         
             
            EOHELP
         
     | 
| 
       167 
230 
     | 
    
         
             
              show_header_maps
         
     | 
| 
       168 
231 
     | 
    
         
             
              exit 0
         
     | 
| 
         @@ -171,7 +234,13 @@ end 
     | 
|
| 
       171 
234 
     | 
    
         
             
            $verbose = $verbose || $debug
         
     | 
| 
       172 
235 
     | 
    
         
             
            show_header_maps if($verbose)
         
     | 
| 
       173 
236 
     | 
    
         | 
| 
       174 
     | 
    
         
            -
            $datasets = Geoptima::Dataset.make_datasets($files, 
     | 
| 
      
 237 
     | 
    
         
            +
            $datasets = Geoptima::Dataset.make_datasets($files,
         
     | 
| 
      
 238 
     | 
    
         
            +
              :locate => true,
         
     | 
| 
      
 239 
     | 
    
         
            +
              :time_range => $time_range,
         
     | 
| 
      
 240 
     | 
    
         
            +
              :location_range => $location_range,
         
     | 
| 
      
 241 
     | 
    
         
            +
              :geolocation_options => $geolocation_options,
         
     | 
| 
      
 242 
     | 
    
         
            +
              :combine_all => $combine_all
         
     | 
| 
      
 243 
     | 
    
         
            +
            )
         
     | 
| 
       175 
244 
     | 
    
         | 
| 
       176 
245 
     | 
    
         
             
            class Export
         
     | 
| 
       177 
246 
     | 
    
         
             
              attr_reader :files, :imei, :names, :headers
         
     | 
    
        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.19")
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            $debug=false
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
         @@ -21,6 +21,18 @@ $gpx_options = { 
     | 
|
| 
       21 
21 
     | 
    
         
             
              'points' => true, 'point_size' => 2, 'point_color' => 'auto'
         
     | 
| 
       22 
22 
     | 
    
         
             
            }
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            $geolocation_options = {
         
     | 
| 
      
 25 
     | 
    
         
            +
              'algorithm' => 'window', 'window' => 60
         
     | 
| 
      
 26 
     | 
    
         
            +
            }
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            def make_hash_options(arg)
         
     | 
| 
      
 29 
     | 
    
         
            +
              arg.split(/[\,\;]+/).inject({}) do |a,v|
         
     | 
| 
      
 30 
     | 
    
         
            +
                k=v.split(/[\:\=]+/)
         
     | 
| 
      
 31 
     | 
    
         
            +
                a[k[0]]=k[1]||true
         
     | 
| 
      
 32 
     | 
    
         
            +
                a
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       24 
36 
     | 
    
         
             
            $files = Geoptima::Options.process_args do |option|
         
     | 
| 
       25 
37 
     | 
    
         
             
              option.p {$print = true}
         
     | 
| 
       26 
38 
     | 
    
         
             
              option.x {$export = true}
         
     | 
| 
         @@ -38,8 +50,9 @@ $files = Geoptima::Options.process_args do |option| 
     | 
|
| 
       38 
50 
     | 
    
         
             
              option.B {$location_range = Geoptima::LocationRange.from ARGV.shift}
         
     | 
| 
       39 
51 
     | 
    
         
             
              option.L {$print_limit = [1,ARGV.shift.to_i].max}
         
     | 
| 
       40 
52 
     | 
    
         
             
              option.M {$mapfile = ARGV.shift}
         
     | 
| 
       41 
     | 
    
         
            -
              option.G {$gpx_options.merge! ARGV.shift 
     | 
| 
      
 53 
     | 
    
         
            +
              option.G {$gpx_options.merge! make_hash_options(ARGV.shift)}
         
     | 
| 
       42 
54 
     | 
    
         
             
              option.A {$app_categories = Geoptima::AppCategories.new(ARGV.shift)}
         
     | 
| 
      
 55 
     | 
    
         
            +
              option.X {$geolocation_options.merge! make_hash_options(ARGV.shift)}
         
     | 
| 
       43 
56 
     | 
    
         
             
            end.map do |file|
         
     | 
| 
       44 
57 
     | 
    
         
             
              File.exist?(file) ? file : puts("No such file: #{file}")
         
     | 
| 
       45 
58 
     | 
    
         
             
            end.compact
         
     | 
| 
         @@ -116,10 +129,33 @@ end 
     | 
|
| 
       116 
129 
     | 
    
         | 
| 
       117 
130 
     | 
    
         
             
            exit 0 if($print_version && !$verbose)
         
     | 
| 
       118 
131 
     | 
    
         | 
| 
      
 132 
     | 
    
         
            +
            class String
         
     | 
| 
      
 133 
     | 
    
         
            +
              def wrappad(max=80,pad=8)
         
     | 
| 
      
 134 
     | 
    
         
            +
                max = [max,pad+1].max
         
     | 
| 
      
 135 
     | 
    
         
            +
                wrapped = [self.to_s]
         
     | 
| 
      
 136 
     | 
    
         
            +
                while wrapped[-1].length > max
         
     | 
| 
      
 137 
     | 
    
         
            +
                  a,b = wrapped[-1][0..(max-1)],wrapped[-1][max..-1]
         
     | 
| 
      
 138 
     | 
    
         
            +
                  if (si = a.rindex(/\s+/)) && (a[0..(si-1)] =~ /\S/)
         
     | 
| 
      
 139 
     | 
    
         
            +
                    b = [a[si..-1],b].join.gsub(/^\s+/,'')
         
     | 
| 
      
 140 
     | 
    
         
            +
                    a = a[0..(si-1)]
         
     | 
| 
      
 141 
     | 
    
         
            +
                  else
         
     | 
| 
      
 142 
     | 
    
         
            +
                    a+='-'
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                  a = a.gsub(/\s+$/,'')
         
     | 
| 
      
 145 
     | 
    
         
            +
                  b = b.gsub(/^\s+/,'')
         
     | 
| 
      
 146 
     | 
    
         
            +
                  wrapped[-1] = a
         
     | 
| 
      
 147 
     | 
    
         
            +
                  wrapped << [' '*pad,b].join
         
     | 
| 
      
 148 
     | 
    
         
            +
                  puts "WRAP[#{max}:#{pad}]: #{wrapped.inspect}"
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
                wrapped
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
            end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
       119 
154 
     | 
    
         
             
            $help = true if($files.length < 1)
         
     | 
| 
       120 
155 
     | 
    
         
             
            if $help
         
     | 
| 
       121 
156 
     | 
    
         
             
              puts <<EOHELP
         
     | 
| 
       122 
     | 
    
         
            -
            Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> 
     | 
| 
      
 157 
     | 
    
         
            +
            Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit>
         
     | 
| 
      
 158 
     | 
    
         
            +
                                 <-E types> <-T min,max> <-M mapfile> file <files>
         
     | 
| 
       123 
159 
     | 
    
         
             
              -d  debug mode (output more context during processing) #{cw $debug}
         
     | 
| 
       124 
160 
     | 
    
         
             
              -w  verbose mode (output extra information to console) #{cw $verbose}
         
     | 
| 
       125 
161 
     | 
    
         
             
              -v  print geoptima library version #{Geoptima::VERSION}
         
     | 
| 
         @@ -149,20 +185,47 @@ Usage: show_geoptima <-dwvpxomlsafegh> <-P export_prefix> <-L limit> <-E types> 
     | 
|
| 
       149 
185 
     | 
    
         
             
              -L  limit verbose output to specific number of lines #{cw $print_limit}
         
     | 
| 
       150 
186 
     | 
    
         
             
              -M  mapfile of normal->altered header names: #{$mapfile}
         
     | 
| 
       151 
187 
     | 
    
         
             
              -G  GPX export options as ';' separated list of key:value pairs
         
     | 
| 
       152 
     | 
    
         
            -
                  Current GPX options:  
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
      
 188 
     | 
    
         
            +
            #{('      Current GPX options: '+$gpx_options.inspect).wrappad(80,6).join("\n")}
         
     | 
| 
      
 189 
     | 
    
         
            +
              -X  Geolocation options as ';' separated list of key:value pairs
         
     | 
| 
      
 190 
     | 
    
         
            +
            #{('      Current geolocation options: '+$geolocation_options.inspect).wrappad(80,6).join("\n")}
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            The GPX and Geolocation options require futher explanation:
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            Known supported GPX options (might be more, see data.rb code):
         
     | 
| 
      
 195 
     | 
    
         
            +
              limit:#{$gpx_options['limit']}     \t    Limit GPX output to traces with at least this number of events
         
     | 
| 
      
 196 
     | 
    
         
            +
              png_limit:#{$gpx_options['png_limit']}\t    Limit PNG output to traces with at least this number of events
         
     | 
| 
      
 197 
     | 
    
         
            +
              merge:#{$gpx_options['merge']}     \t    Merge all traces into a single trace
         
     | 
| 
      
 198 
     | 
    
         
            +
              only_merge:#{$gpx_options['merge']}\t    Do not export unmerged traces
         
     | 
| 
      
 199 
     | 
    
         
            +
              scale:#{$gpx_options['scale']}\t    Size of print area in PNG output
         
     | 
| 
      
 200 
     | 
    
         
            +
              padding:#{$gpx_options['padding']}\t    Space around print area
         
     | 
| 
      
 201 
     | 
    
         
            +
              points:#{$gpx_options['points']}\t    Turn on/off points
         
     | 
| 
      
 202 
     | 
    
         
            +
              point_size:#{$gpx_options['point_size']}\t    Set point size
         
     | 
| 
      
 203 
     | 
    
         
            +
              point_color:#{$gpx_options['point_color']}  Set point color: RRGGBBAA in hex (else 'auto')
         
     | 
| 
      
 204 
     | 
    
         
            +
              format:#{$gpx_options['format']}     \t    Export format: 'gpx', 'csv', 'png', default 'all'
         
     | 
| 
      
 205 
     | 
    
         
            +
              waypoints:#{$gpx_options['waypoints']}\t    Export waypoints for events: <event_type>, default 'all'
         
     | 
| 
      
 206 
     | 
    
         
            +
            PNG images will be 'scale + 2 * padding' big (#{$gpx_options['scale'].to_i+2*$gpx_options['padding'].to_i} for current settings).
         
     | 
| 
      
 207 
     | 
    
         
            +
            The scale will be used for the widest dimension, and the other will be reduced
         
     | 
| 
      
 208 
     | 
    
         
            +
            to fit the actual size of the trace. No projection is used, with the points
         
     | 
| 
      
 209 
     | 
    
         
            +
            simply mapped to their GPS locations. This will cause visual distortions far
         
     | 
| 
      
 210 
     | 
    
         
            +
            from the equator where dlat!=dlon.
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
            Known supported geolocation options (might be more, see data.rb code):
         
     | 
| 
      
 213 
     | 
    
         
            +
            algorithm:#{$geolocation_options['algorithm']}    Which geolocation algorithm to use
         
     | 
| 
      
 214 
     | 
    
         
            +
            window:#{$geolocation_options['window']}\t    Time window in seconds, has slightly different
         
     | 
| 
      
 215 
     | 
    
         
            +
                                meanings for different algorithms
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
            Currently supported algorithms:
         
     | 
| 
      
 218 
     | 
    
         
            +
              window:      select GPS point within window seconds of event,
         
     | 
| 
      
 219 
     | 
    
         
            +
                           GPS points after the event take priority.
         
     | 
| 
      
 220 
     | 
    
         
            +
                           (this is the default for geoptima GEM version >= 0.1.19)
         
     | 
| 
      
 221 
     | 
    
         
            +
              +win:        select only GPS points after event (within time window)
         
     | 
| 
      
 222 
     | 
    
         
            +
              -win:        select only GPS points before event (within time window)
         
     | 
| 
      
 223 
     | 
    
         
            +
                           (this is the default for geoptima GEM version < 0.1.19)
         
     | 
| 
      
 224 
     | 
    
         
            +
              closest:     select closest GPS point within window seconds of event
         
     | 
| 
      
 225 
     | 
    
         
            +
                           (similar to window option, but chooses closest)
         
     | 
| 
      
 226 
     | 
    
         
            +
              interpolate: Linear interpolation between two closest points
         
     | 
| 
      
 227 
     | 
    
         
            +
                           (experimental, do not use yet)
         
     | 
| 
      
 228 
     | 
    
         
            +
                           (read redmine wiki page for explanation of algorithm)
         
     | 
| 
       166 
229 
     | 
    
         
             
            EOHELP
         
     | 
| 
       167 
230 
     | 
    
         
             
              show_header_maps
         
     | 
| 
       168 
231 
     | 
    
         
             
              exit 0
         
     | 
| 
         @@ -171,7 +234,13 @@ end 
     | 
|
| 
       171 
234 
     | 
    
         
             
            $verbose = $verbose || $debug
         
     | 
| 
       172 
235 
     | 
    
         
             
            show_header_maps if($verbose)
         
     | 
| 
       173 
236 
     | 
    
         | 
| 
       174 
     | 
    
         
            -
            $datasets = Geoptima::Dataset.make_datasets($files, 
     | 
| 
      
 237 
     | 
    
         
            +
            $datasets = Geoptima::Dataset.make_datasets($files,
         
     | 
| 
      
 238 
     | 
    
         
            +
              :locate => true,
         
     | 
| 
      
 239 
     | 
    
         
            +
              :time_range => $time_range,
         
     | 
| 
      
 240 
     | 
    
         
            +
              :location_range => $location_range,
         
     | 
| 
      
 241 
     | 
    
         
            +
              :geolocation_options => $geolocation_options,
         
     | 
| 
      
 242 
     | 
    
         
            +
              :combine_all => $combine_all
         
     | 
| 
      
 243 
     | 
    
         
            +
            )
         
     | 
| 
       175 
244 
     | 
    
         | 
| 
       176 
245 
     | 
    
         
             
            class Export
         
     | 
| 
       177 
246 
     | 
    
         
             
              attr_reader :files, :imei, :names, :headers
         
     | 
    
        data/geoptima.gemspec
    CHANGED
    
    | 
         @@ -12,13 +12,39 @@ Gem::Specification.new do |s| 
     | 
|
| 
       12 
12 
     | 
    
         
             
              s.rubyforge_project = 'geoptima'
         
     | 
| 
       13 
13 
     | 
    
         
             
              s.summary = "Ruby access to Geoptima JSON files"
         
     | 
| 
       14 
14 
     | 
    
         
             
              s.description = <<-EOF
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            Geoptima is a suite of applications for measuring and locating
         
     | 
| 
      
 17 
     | 
    
         
            +
            mobile/cellular subscriber experience on GPS enabled smartphones.  It is
         
     | 
| 
      
 18 
     | 
    
         
            +
            produced by AmanziTel AB in Helsingborg, Sweden, and supports many phone
         
     | 
| 
      
 19 
     | 
    
         
            +
            manufacturers, with free downloads from the various app stores, markets or
         
     | 
| 
      
 20 
     | 
    
         
            +
            marketplaces.  This Ruby library is capable of reading the JSON format files
         
     | 
| 
      
 21 
     | 
    
         
            +
            produced by these phones and reformating them as CSV, GPX and PNG for
         
     | 
| 
      
 22 
     | 
    
         
            +
            further analysis in Excel.  This is a simple and independent way of
         
     | 
| 
      
 23 
     | 
    
         
            +
            analysing the data, when compared to the full-featured analysis applications
         
     | 
| 
      
 24 
     | 
    
         
            +
            and servers available from AmanziTel.  If you want to analyse a limited
         
     | 
| 
      
 25 
     | 
    
         
            +
            amount of data in excel, or with Ruby, then this GEM might be for you.  If
         
     | 
| 
      
 26 
     | 
    
         
            +
            you want to analyse large amounts of data, from many subscribers, or over
         
     | 
| 
      
 27 
     | 
    
         
            +
            long periods of time then rather consider the NetView and Customer IQ
         
     | 
| 
      
 28 
     | 
    
         
            +
            applications from AmanziTel at www.amanzitel.com.
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            Current features available in the library and the show_geoptima command:
         
     | 
| 
      
 31 
     | 
    
         
            +
            * Import one or many JSON files
         
     | 
| 
      
 32 
     | 
    
         
            +
            * Organize data by device id (IMEI) into datasets
         
     | 
| 
      
 33 
     | 
    
         
            +
            * Split by event type
         
     | 
| 
      
 34 
     | 
    
         
            +
            * Time ordering and time correlation (associate data from one event to another):
         
     | 
| 
      
 35 
     | 
    
         
            +
            ** Add GPS locations to other events (time window and interpolation algorithms)
         
     | 
| 
      
 36 
     | 
    
         
            +
            ** Add signal strenth, battery level, etc. to other events
         
     | 
| 
      
 37 
     | 
    
         
            +
            * Export event tables to CSV format for further processing in excel
         
     | 
| 
      
 38 
     | 
    
         
            +
            * Make and export GPS traces in GPX and PNG format for simple map reports
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            The amount of data possible to process is limited by memory, since all data
         
     | 
| 
      
 41 
     | 
    
         
            +
            is imported in ruby data structures for procssing.  If you need to process
         
     | 
| 
      
 42 
     | 
    
         
            +
            larger amounts of data, you will need a database-driven approach, like that
         
     | 
| 
      
 43 
     | 
    
         
            +
            provided by AmanziTel's NetView and Customer IQ solutions.  This Ruby gem is
         
     | 
| 
      
 44 
     | 
    
         
            +
            actually used by parts of the data pre-processing chain of 'Customer IQ',
         
     | 
| 
      
 45 
     | 
    
         
            +
            but it not used by the main database and statistics engine that generates
         
     | 
| 
      
 46 
     | 
    
         
            +
            the reports.
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
       22 
48 
     | 
    
         
             
            EOF
         
     | 
| 
       23 
49 
     | 
    
         | 
| 
       24 
50 
     | 
    
         
             
              s.require_path = 'lib'
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:53748         0.0.0.0:*               LISTEN     
         
     | 
| 
      
 2 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN     
         
     | 
| 
      
 3 
     | 
    
         
            +
            tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN     
         
     | 
| 
      
 4 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:34678         0.0.0.0:*               LISTEN     
         
     | 
| 
      
 5 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
         
     | 
| 
      
 6 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
         
     | 
| 
      
 7 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:17500           0.0.0.0:*               LISTEN     
         
     | 
| 
      
 8 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN     
         
     | 
| 
      
 9 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:60648           0.0.0.0:*               LISTEN     
         
     | 
| 
      
 10 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN     
         
     | 
| 
      
 11 
     | 
    
         
            +
            tcp6       0      0 127.0.0.1:7473          :::*                    LISTEN     
         
     | 
| 
      
 12 
     | 
    
         
            +
            tcp6       0      0 127.0.0.1:7474          :::*                    LISTEN     
         
     | 
| 
      
 13 
     | 
    
         
            +
            tcp6       0      0 :::22                   :::*                    LISTEN     
         
     | 
| 
      
 14 
     | 
    
         
            +
            tcp6       0      0 ::1:631                 :::*                    LISTEN     
         
     | 
| 
      
 15 
     | 
    
         
            +
            tcp6       0      0 :::3000                 :::*                    LISTEN     
         
     | 
| 
      
 16 
     | 
    
         
            +
            tcp6       0      0 :::1337                 :::*                    LISTEN     
         
     | 
| 
      
 17 
     | 
    
         
            +
            tcp6       0      0 :::34495                :::*                    LISTEN     
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:53748         0.0.0.0:*               LISTEN     
         
     | 
| 
      
 2 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN     
         
     | 
| 
      
 3 
     | 
    
         
            +
            tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN     
         
     | 
| 
      
 4 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:34678         0.0.0.0:*               LISTEN     
         
     | 
| 
      
 5 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
         
     | 
| 
      
 6 
     | 
    
         
            +
            tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
         
     | 
| 
      
 7 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:17500           0.0.0.0:*               LISTEN     
         
     | 
| 
      
 8 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN     
         
     | 
| 
      
 9 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:60648           0.0.0.0:*               LISTEN     
         
     | 
| 
      
 10 
     | 
    
         
            +
            tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN     
         
     | 
| 
      
 11 
     | 
    
         
            +
            tcp6       0      0 127.0.0.1:7473          :::*                    LISTEN     
         
     | 
| 
      
 12 
     | 
    
         
            +
            tcp6       0      0 127.0.0.1:7474          :::*                    LISTEN     
         
     | 
| 
      
 13 
     | 
    
         
            +
            tcp6       0      0 :::22                   :::*                    LISTEN     
         
     | 
| 
      
 14 
     | 
    
         
            +
            tcp6       0      0 ::1:631                 :::*                    LISTEN     
         
     | 
| 
      
 15 
     | 
    
         
            +
            tcp6       0      0 :::1337                 :::*                    LISTEN     
         
     | 
| 
      
 16 
     | 
    
         
            +
            tcp6       0      0 :::34495                :::*                    LISTEN     
         
     | 
    
        data/lib/geoptima/data.rb
    CHANGED
    
    | 
         @@ -4,6 +4,7 @@ require 'rubygems' 
     | 
|
| 
       4 
4 
     | 
    
         
             
            require 'multi_json'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require 'geoptima/daterange'
         
     | 
| 
       6 
6 
     | 
    
         
             
            require 'geoptima/locationrange'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'geoptima/locator'
         
     | 
| 
       7 
8 
     | 
    
         
             
            require 'geoptima/timer'
         
     | 
| 
       8 
9 
     | 
    
         
             
            begin
         
     | 
| 
       9 
10 
     | 
    
         
             
              require 'png'
         
     | 
| 
         @@ -16,8 +17,6 @@ end 
     | 
|
| 
       16 
17 
     | 
    
         
             
            #
         
     | 
| 
       17 
18 
     | 
    
         
             
            module Geoptima
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
              SPERDAY = 60*60*24
         
     | 
| 
       20 
     | 
    
         
            -
              MSPERDAY = 1000*60*60*24
         
     | 
| 
       21 
20 
     | 
    
         
             
              SHORT = 256*256
         
     | 
| 
       22 
21 
     | 
    
         
             
              MIN_VALID_DATETIME = DateTime.parse("1970-01-01")
         
     | 
| 
       23 
22 
     | 
    
         
             
              MAX_VALID_DATETIME = DateTime.parse("2040-01-01")
         
     | 
| 
         @@ -484,7 +483,8 @@ module Geoptima 
     | 
|
| 
       484 
483 
     | 
    
         
             
                }
         
     | 
| 
       485 
484 
     | 
    
         | 
| 
       486 
485 
     | 
    
         
             
                include ErrorCounter
         
     | 
| 
       487 
     | 
    
         
            -
                 
     | 
| 
      
 486 
     | 
    
         
            +
                include Locatable
         
     | 
| 
      
 487 
     | 
    
         
            +
                attr_reader :file, :gps, :header, :name, :data, :fields, :time, :latitude, :longitude, :timeoffset
         
     | 
| 
       488 
488 
     | 
    
         
             
                def initialize(file,start,name,header,data,previous=nil)
         
     | 
| 
       489 
489 
     | 
    
         
             
                  @file = file
         
     | 
| 
       490 
490 
     | 
    
         
             
                  @name = name
         
     | 
| 
         @@ -553,14 +553,12 @@ module Geoptima 
     | 
|
| 
       553 
553 
     | 
    
         
             
                def location
         
     | 
| 
       554 
554 
     | 
    
         
             
                  @location ||= latitude && Point.new(latitude,longitude)
         
     | 
| 
       555 
555 
     | 
    
         
             
                end
         
     | 
| 
       556 
     | 
    
         
            -
                def  
     | 
| 
      
 556 
     | 
    
         
            +
                def set_location(gps)
         
     | 
| 
       557 
557 
     | 
    
         
             
                  incr_error "GPS String Data" if(gps['latitude'].is_a? String)
         
     | 
| 
       558 
558 
     | 
    
         
             
                  @latitude = gps['latitude'].to_f
         
     | 
| 
       559 
559 
     | 
    
         
             
                  @longitude = gps['longitude'].to_f
         
     | 
| 
       560 
560 
     | 
    
         
             
                  @location = nil
         
     | 
| 
       561 
     | 
    
         
            -
             
     | 
| 
       562 
     | 
    
         
            -
                def locate_if_closer_than(gps,seconds=60)
         
     | 
| 
       563 
     | 
    
         
            -
                  locate(gps) if(closer_than(gps,seconds))
         
     | 
| 
      
 561 
     | 
    
         
            +
                  @gps = gps
         
     | 
| 
       564 
562 
     | 
    
         
             
                end
         
     | 
| 
       565 
563 
     | 
    
         
             
                def puts line
         
     | 
| 
       566 
564 
     | 
    
         
             
                  Kernel.puts "#{name}[#{time}]: #{line}"
         
     | 
| 
         @@ -868,6 +866,7 @@ module Geoptima 
     | 
|
| 
       868 
866 
     | 
    
         
             
                  @options = options
         
     | 
| 
       869 
867 
     | 
    
         
             
                  @time_range = options[:time_range] || DateRange.new(Config[:min_datetime],Config[:max_datetime])
         
     | 
| 
       870 
868 
     | 
    
         
             
                  @location_range = options[:location_range] || LocationRange.everywhere
         
     | 
| 
      
 869 
     | 
    
         
            +
                  @geolocation_options = options[:geolocation_options] || {}
         
     | 
| 
       871 
870 
     | 
    
         
             
                  @fields = {}
         
     | 
| 
       872 
871 
     | 
    
         
             
                end
         
     | 
| 
       873 
872 
     | 
    
         | 
| 
         @@ -1098,20 +1097,14 @@ module Geoptima 
     | 
|
| 
       1098 
1097 
     | 
    
         
             
                end
         
     | 
| 
       1099 
1098 
     | 
    
         | 
| 
       1100 
1099 
     | 
    
         
             
                def locate_events
         
     | 
| 
       1101 
     | 
    
         
            -
                  prev_gps = nil
         
     | 
| 
       1102 
     | 
    
         
            -
                  count = 0
         
     | 
| 
       1103 
1100 
     | 
    
         
             
                  puts "Locating #{sorted.length} events" if(true||$debug)
         
     | 
| 
       1104 
     | 
    
         
            -
                   
     | 
| 
       1105 
     | 
    
         
            -
             
     | 
| 
       1106 
     | 
    
         
            -
             
     | 
| 
       1107 
     | 
    
         
            -
             
     | 
| 
       1108 
     | 
    
         
            -
             
     | 
| 
       1109 
     | 
    
         
            -
                     
     | 
| 
       1110 
     | 
    
         
            -
                      count += 1 if(event.locate_if_closer_than(prev_gps,60))
         
     | 
| 
       1111 
     | 
    
         
            -
                    end
         
     | 
| 
       1112 
     | 
    
         
            -
                    timer('locate.each').stop
         
     | 
| 
      
 1101 
     | 
    
         
            +
                  locator = Geoptima::Locator.new self.sorted, @geolocation_options
         
     | 
| 
      
 1102 
     | 
    
         
            +
                  timer("locate.all").start
         
     | 
| 
      
 1103 
     | 
    
         
            +
                  locator.locate
         
     | 
| 
      
 1104 
     | 
    
         
            +
                  timer("locate.all").stop
         
     | 
| 
      
 1105 
     | 
    
         
            +
                  if (true||$debug)
         
     | 
| 
      
 1106 
     | 
    
         
            +
                    puts "Located #{locator.located.length} / #{sorted.length} events (timed: #{timer("locate.all")}"
         
     | 
| 
       1113 
1107 
     | 
    
         
             
                  end
         
     | 
| 
       1114 
     | 
    
         
            -
                  puts "Located #{count} / #{sorted.length} events" if($debug)
         
     | 
| 
       1115 
1108 
     | 
    
         
             
                end
         
     | 
| 
       1116 
1109 
     | 
    
         | 
| 
       1117 
1110 
     | 
    
         
             
                def to_s
         
     | 
| 
         @@ -0,0 +1,172 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'geoptima/locationrange'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Geoptima
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              SPERDAY = 60*60*24
         
     | 
| 
      
 8 
     | 
    
         
            +
              MSPERDAY = 1000*SPERDAY
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              class LocatorAlgorithm
         
     | 
| 
      
 11 
     | 
    
         
            +
                def locate(locatable)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  if locatable.next_point
         
     | 
| 
      
 13 
     | 
    
         
            +
                    locatable.location = locatable.next_point
         
     | 
| 
      
 14 
     | 
    
         
            +
                  elsif locatable.previous_point
         
     | 
| 
      
 15 
     | 
    
         
            +
                    locatable.location = locatable.previous_point
         
     | 
| 
      
 16 
     | 
    
         
            +
                  else
         
     | 
| 
      
 17 
     | 
    
         
            +
                    locatable.location = nil
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
              class BeforeLocatorAlgorithm < LocatorAlgorithm
         
     | 
| 
      
 22 
     | 
    
         
            +
                def locate(locatable)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  if locatable.previous_point
         
     | 
| 
      
 24 
     | 
    
         
            +
                    locatable.location = locatable.previous_point
         
     | 
| 
      
 25 
     | 
    
         
            +
                  else
         
     | 
| 
      
 26 
     | 
    
         
            +
                    locatable.location = nil
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              class AfterLocatorAlgorithm < LocatorAlgorithm
         
     | 
| 
      
 31 
     | 
    
         
            +
                def locate(locatable)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  if locatable.next_point
         
     | 
| 
      
 33 
     | 
    
         
            +
                    locatable.location = locatable.next_point
         
     | 
| 
      
 34 
     | 
    
         
            +
                  else
         
     | 
| 
      
 35 
     | 
    
         
            +
                    locatable.location = nil
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
              class ClosestLocatorAlgorithm < LocatorAlgorithm
         
     | 
| 
      
 40 
     | 
    
         
            +
                def locate(locatable)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  results = [
         
     | 
| 
      
 42 
     | 
    
         
            +
                    [locatable.next_point_gap,locatable.next_point],
         
     | 
| 
      
 43 
     | 
    
         
            +
                    [locatable.previous_point_gap,locatable.previous_point]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  ].reject do |x|
         
     | 
| 
      
 45 
     | 
    
         
            +
                    x[0].nil? && x[1].nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end.sort do |a,b|
         
     | 
| 
      
 47 
     | 
    
         
            +
                    a[0] <=> b[0]
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end[0]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  locatable.location = results && results[1]
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
              class InterpolationLocatorAlgorithm < ClosestLocatorAlgorithm
         
     | 
| 
      
 53 
     | 
    
         
            +
                def locate(locatable)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  if locatable.previous_poing && locatable.next_point && locatable.next_point.prev_point
         
     | 
| 
      
 55 
     | 
    
         
            +
                    correlateEvent2Point(point,wavg(point.prev,point.next,point),'interpolated');
         
     | 
| 
      
 56 
     | 
    
         
            +
                  elsif closest = super.locate(locatable)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    correlateEvent2Point(point,closest,'correlated');
         
     | 
| 
      
 58 
     | 
    
         
            +
                  else
         
     | 
| 
      
 59 
     | 
    
         
            +
                    puts "No correlation possible for point: "+point
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
              module Locatable
         
     | 
| 
      
 64 
     | 
    
         
            +
                attr_accessor :previous_point, :next_point, :previous_point_gap, :next_point_gap, :location
         
     | 
| 
      
 65 
     | 
    
         
            +
                def closer_than(gps,window=0.0)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  if $debug && gps && window > 0
         
     | 
| 
      
 67 
     | 
    
         
            +
                    puts "Comparing times:"
         
     | 
| 
      
 68 
     | 
    
         
            +
                    puts "\tGPS: #{gps.time}"
         
     | 
| 
      
 69 
     | 
    
         
            +
                    puts "\tEvent: #{self.time}"
         
     | 
| 
      
 70 
     | 
    
         
            +
                    puts "\tTDiff: #{(self - gps).abs.to_f}"
         
     | 
| 
      
 71 
     | 
    
         
            +
                    puts "\tWindow: #{window}"
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
                  gps && (window <= 0.0 || (self - gps).abs < window)
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
                def set_next_if(gps,time_window=0.0)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  if closer_than(gps,time_window)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    self.next_point = gps.location
         
     | 
| 
      
 78 
     | 
    
         
            +
                    self.next_point_gap = (self - gps).abs
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
                def set_previous_if(gps,time_window=0.0)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  if closer_than(gps,time_window)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    self.previous_point = gps.location
         
     | 
| 
      
 84 
     | 
    
         
            +
                    self.previous_point_gap = (self - gps).abs
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
              class LocatableImpl
         
     | 
| 
      
 89 
     | 
    
         
            +
                attr_reader :name, :attributes
         
     | 
| 
      
 90 
     | 
    
         
            +
                attr_accessor :time
         
     | 
| 
      
 91 
     | 
    
         
            +
                include Locatable
         
     | 
| 
      
 92 
     | 
    
         
            +
                def initialize(attributes)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  @attributes = Hash[*attributes.map{|k,v| [k.to_s,v]}.flatten]
         
     | 
| 
      
 94 
     | 
    
         
            +
                  @name = @attributes['name']
         
     | 
| 
      
 95 
     | 
    
         
            +
                  @time = @attributes['time']
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
                def [](key)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  @attributes[key.to_s] || @attributes[key.to_s.gsub(/#{name}\./,'')]
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
                def []=(key,value)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  @attributes[key.to_s] = value
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
                def -(other)
         
     | 
| 
      
 104 
     | 
    
         
            +
                  (self.time - other.time) * SPERDAY
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 107 
     | 
    
         
            +
                  @attributes.inspect
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
              class Locator
         
     | 
| 
      
 111 
     | 
    
         
            +
                attr_reader :sorted, :located, :failed, :options
         
     | 
| 
      
 112 
     | 
    
         
            +
                def initialize(sorted, options={})
         
     | 
| 
      
 113 
     | 
    
         
            +
                  @sorted = sorted
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @options = Hash[*options.map{|k,v| [k.to_s.intern,v]}.flatten]
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @options[:algorithm] ||= 'window'
         
     | 
| 
      
 116 
     | 
    
         
            +
                  @options[:window] ||= 60
         
     | 
| 
      
 117 
     | 
    
         
            +
                  puts "Initialized geo-location on #{@sorted.length} events with options: #{@options.inspect}" if($debug)
         
     | 
| 
      
 118 
     | 
    
         
            +
                end
         
     | 
| 
      
 119 
     | 
    
         
            +
                def start
         
     | 
| 
      
 120 
     | 
    
         
            +
                  @start ||= sorted[0] && sorted[0][:time] || DateTime.now
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
                def algorithm
         
     | 
| 
      
 123 
     | 
    
         
            +
                  @algorithm ||= case @options[:algorithm].to_s
         
     | 
| 
      
 124 
     | 
    
         
            +
                  when /^\-win/
         
     | 
| 
      
 125 
     | 
    
         
            +
                    BeforeLocatorAlgorithm.new
         
     | 
| 
      
 126 
     | 
    
         
            +
                  when /^\+win/
         
     | 
| 
      
 127 
     | 
    
         
            +
                    AfterLocatorAlgorithm.new
         
     | 
| 
      
 128 
     | 
    
         
            +
                  when /closest/
         
     | 
| 
      
 129 
     | 
    
         
            +
                    ClosestLocatorAlgorithm.new
         
     | 
| 
      
 130 
     | 
    
         
            +
                  when /inter/
         
     | 
| 
      
 131 
     | 
    
         
            +
                    InterpolationLocatorAlgorithm.new
         
     | 
| 
      
 132 
     | 
    
         
            +
                  else
         
     | 
| 
      
 133 
     | 
    
         
            +
                    LocatorAlgorithm.new
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
                def locate
         
     | 
| 
      
 137 
     | 
    
         
            +
                  gps = nil
         
     | 
| 
      
 138 
     | 
    
         
            +
                  @located = []
         
     | 
| 
      
 139 
     | 
    
         
            +
                  @failed = []
         
     | 
| 
      
 140 
     | 
    
         
            +
                  locatables = []
         
     | 
| 
      
 141 
     | 
    
         
            +
                  time_window = @options[:window].to_i
         
     | 
| 
      
 142 
     | 
    
         
            +
                  time_window = 60 if(time_window<1)
         
     | 
| 
      
 143 
     | 
    
         
            +
                  puts "Locating within window[#{time_window}] using algorithm:#{algorithm.class}" if($debug)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  sorted.each do |event|
         
     | 
| 
      
 145 
     | 
    
         
            +
                    event.time ||= start + event[:timestamp].to_f / Geoptima::MSPERDAY
         
     | 
| 
      
 146 
     | 
    
         
            +
                    if event.name === 'gps'
         
     | 
| 
      
 147 
     | 
    
         
            +
                      gps = event
         
     | 
| 
      
 148 
     | 
    
         
            +
                      puts "Setting GPS location point: #{gps.inspect}" if($debug)
         
     | 
| 
      
 149 
     | 
    
         
            +
                      gps.location = Point.new(gps['latitude'].to_f, gps['longitude'].to_f)
         
     | 
| 
      
 150 
     | 
    
         
            +
                      locatables.each do |event|
         
     | 
| 
      
 151 
     | 
    
         
            +
                        event.set_next_if(gps,time_window)
         
     | 
| 
      
 152 
     | 
    
         
            +
                      end
         
     | 
| 
      
 153 
     | 
    
         
            +
                      locatables = []
         
     | 
| 
      
 154 
     | 
    
         
            +
                    else
         
     | 
| 
      
 155 
     | 
    
         
            +
                      event.set_previous_if(gps,time_window)
         
     | 
| 
      
 156 
     | 
    
         
            +
                      locatables << event
         
     | 
| 
      
 157 
     | 
    
         
            +
                      @located << event
         
     | 
| 
      
 158 
     | 
    
         
            +
                    end
         
     | 
| 
      
 159 
     | 
    
         
            +
                  end
         
     | 
| 
      
 160 
     | 
    
         
            +
                  @located = @located.map do |l|
         
     | 
| 
      
 161 
     | 
    
         
            +
                    if self.algorithm.locate(l)
         
     | 
| 
      
 162 
     | 
    
         
            +
                      l
         
     | 
| 
      
 163 
     | 
    
         
            +
                    else
         
     | 
| 
      
 164 
     | 
    
         
            +
                      @failed << l
         
     | 
| 
      
 165 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 166 
     | 
    
         
            +
                    end
         
     | 
| 
      
 167 
     | 
    
         
            +
                  end.compact
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
              end
         
     | 
| 
      
 170 
     | 
    
         
            +
            end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
    
        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.19
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
7 
     | 
    
         
             
            authors:
         
     | 
| 
         @@ -9,14 +9,14 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2013- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2013-05-03 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: multi_json
         
     | 
| 
       16 
16 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       17 
17 
     | 
    
         
             
                none: false
         
     | 
| 
       18 
18 
     | 
    
         
             
                requirements:
         
     | 
| 
       19 
     | 
    
         
            -
                - -  
     | 
| 
      
 19 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       20 
20 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       21 
21 
     | 
    
         
             
                    version: 1.1.0
         
     | 
| 
       22 
22 
     | 
    
         
             
              type: :runtime
         
     | 
| 
         @@ -24,7 +24,7 @@ dependencies: 
     | 
|
| 
       24 
24 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       25 
25 
     | 
    
         
             
                none: false
         
     | 
| 
       26 
26 
     | 
    
         
             
                requirements:
         
     | 
| 
       27 
     | 
    
         
            -
                - -  
     | 
| 
      
 27 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       28 
28 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       29 
29 
     | 
    
         
             
                    version: 1.1.0
         
     | 
| 
       30 
30 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
         @@ -32,7 +32,7 @@ dependencies: 
     | 
|
| 
       32 
32 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       33 
33 
     | 
    
         
             
                none: false
         
     | 
| 
       34 
34 
     | 
    
         
             
                requirements:
         
     | 
| 
       35 
     | 
    
         
            -
                - -  
     | 
| 
      
 35 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       36 
36 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       37 
37 
     | 
    
         
             
                    version: 1.6.5
         
     | 
| 
       38 
38 
     | 
    
         
             
              type: :runtime
         
     | 
| 
         @@ -40,31 +40,43 @@ dependencies: 
     | 
|
| 
       40 
40 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       41 
41 
     | 
    
         
             
                none: false
         
     | 
| 
       42 
42 
     | 
    
         
             
                requirements:
         
     | 
| 
       43 
     | 
    
         
            -
                - -  
     | 
| 
      
 43 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       44 
44 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       45 
45 
     | 
    
         
             
                    version: 1.6.5
         
     | 
| 
       46 
     | 
    
         
            -
            description:  
     | 
| 
       47 
     | 
    
         
            -
              subscriber experience on GPS enabled smartphones.
         
     | 
| 
      
 46 
     | 
    
         
            +
            description: |2+
         
     | 
| 
       48 
47 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
               
     | 
| 
       50 
     | 
    
         
            -
               
     | 
| 
      
 48 
     | 
    
         
            +
              Geoptima is a suite of applications for measuring and locating
         
     | 
| 
      
 49 
     | 
    
         
            +
              mobile/cellular subscriber experience on GPS enabled smartphones.  It is
         
     | 
| 
      
 50 
     | 
    
         
            +
              produced by AmanziTel AB in Helsingborg, Sweden, and supports many phone
         
     | 
| 
      
 51 
     | 
    
         
            +
              manufacturers, with free downloads from the various app stores, markets or
         
     | 
| 
      
 52 
     | 
    
         
            +
              marketplaces.  This Ruby library is capable of reading the JSON format files
         
     | 
| 
      
 53 
     | 
    
         
            +
              produced by these phones and reformating them as CSV, GPX and PNG for
         
     | 
| 
      
 54 
     | 
    
         
            +
              further analysis in Excel.  This is a simple and independent way of
         
     | 
| 
      
 55 
     | 
    
         
            +
              analysing the data, when compared to the full-featured analysis applications
         
     | 
| 
      
 56 
     | 
    
         
            +
              and servers available from AmanziTel.  If you want to analyse a limited
         
     | 
| 
      
 57 
     | 
    
         
            +
              amount of data in excel, or with Ruby, then this GEM might be for you.  If
         
     | 
| 
      
 58 
     | 
    
         
            +
              you want to analyse large amounts of data, from many subscribers, or over
         
     | 
| 
      
 59 
     | 
    
         
            +
              long periods of time then rather consider the NetView and Customer IQ
         
     | 
| 
      
 60 
     | 
    
         
            +
              applications from AmanziTel at www.amanzitel.com.
         
     | 
| 
       51 
61 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
               
     | 
| 
       53 
     | 
    
         
            -
               
     | 
| 
      
 62 
     | 
    
         
            +
              Current features available in the library and the show_geoptima command:
         
     | 
| 
      
 63 
     | 
    
         
            +
              * Import one or many JSON files
         
     | 
| 
      
 64 
     | 
    
         
            +
              * Organize data by device id (IMEI) into datasets
         
     | 
| 
      
 65 
     | 
    
         
            +
              * Split by event type
         
     | 
| 
      
 66 
     | 
    
         
            +
              * Time ordering and time correlation (associate data from one event to another):
         
     | 
| 
      
 67 
     | 
    
         
            +
              ** Add GPS locations to other events (time window and interpolation algorithms)
         
     | 
| 
      
 68 
     | 
    
         
            +
              ** Add signal strenth, battery level, etc. to other events
         
     | 
| 
      
 69 
     | 
    
         
            +
              * Export event tables to CSV format for further processing in excel
         
     | 
| 
      
 70 
     | 
    
         
            +
              * Make and export GPS traces in GPX and PNG format for simple map reports
         
     | 
| 
       54 
71 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
               
     | 
| 
       56 
     | 
    
         
            -
               
     | 
| 
      
 72 
     | 
    
         
            +
              The amount of data possible to process is limited by memory, since all data
         
     | 
| 
      
 73 
     | 
    
         
            +
              is imported in ruby data structures for procssing.  If you need to process
         
     | 
| 
      
 74 
     | 
    
         
            +
              larger amounts of data, you will need a database-driven approach, like that
         
     | 
| 
      
 75 
     | 
    
         
            +
              provided by AmanziTel's NetView and Customer IQ solutions.  This Ruby gem is
         
     | 
| 
      
 76 
     | 
    
         
            +
              actually used by parts of the data pre-processing chain of 'Customer IQ',
         
     | 
| 
      
 77 
     | 
    
         
            +
              but it not used by the main database and statistics engine that generates
         
     | 
| 
      
 78 
     | 
    
         
            +
              the reports.
         
     | 
| 
       57 
79 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
              compared to the full-featured analysis applications and servers available from AmanziTel.
         
     | 
| 
       59 
     | 
    
         
            -
              If you want to analyse a limited amount
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
              of data in excel, or with Ruby, then this GEM might be for you. If you want to analyse
         
     | 
| 
       62 
     | 
    
         
            -
              large amounts of data, from many subscribers, or over long periods of time
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
              then rather consider the NetView and Customer IQ applications from AmanziTel at
         
     | 
| 
       65 
     | 
    
         
            -
              www.amanzitel.com.
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            '
         
     | 
| 
       68 
80 
     | 
    
         
             
            email: craig@amanzi.com
         
     | 
| 
       69 
81 
     | 
    
         
             
            executables:
         
     | 
| 
       70 
82 
     | 
    
         
             
            - show_geoptima
         
     | 
| 
         @@ -90,8 +102,11 @@ files: 
     | 
|
| 
       90 
102 
     | 
    
         
             
            - lib/geoptima/daterange.rb
         
     | 
| 
       91 
103 
     | 
    
         
             
            - lib/geoptima/options.rb
         
     | 
| 
       92 
104 
     | 
    
         
             
            - lib/geoptima/timer.rb
         
     | 
| 
      
 105 
     | 
    
         
            +
            - lib/geoptima/before.ports
         
     | 
| 
       93 
106 
     | 
    
         
             
            - lib/geoptima/file_time.rb
         
     | 
| 
       94 
107 
     | 
    
         
             
            - lib/geoptima/locationrange.rb
         
     | 
| 
      
 108 
     | 
    
         
            +
            - lib/geoptima/after.ports
         
     | 
| 
      
 109 
     | 
    
         
            +
            - lib/geoptima/locator.rb
         
     | 
| 
       95 
110 
     | 
    
         
             
            - lib/geoptima.rb
         
     | 
| 
       96 
111 
     | 
    
         
             
            - examples/show_geoptima_sos.rb
         
     | 
| 
       97 
112 
     | 
    
         
             
            - examples/show_geoptima.rb
         
     | 
| 
         @@ -111,30 +126,33 @@ homepage: http://github.com/craigtaverner/geoptima.rb 
     | 
|
| 
       111 
126 
     | 
    
         
             
            licenses: []
         
     | 
| 
       112 
127 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       113 
128 
     | 
    
         
             
            rdoc_options:
         
     | 
| 
       114 
     | 
    
         
            -
            - --quiet
         
     | 
| 
       115 
     | 
    
         
            -
            - --title
         
     | 
| 
      
 129 
     | 
    
         
            +
            - "--quiet"
         
     | 
| 
      
 130 
     | 
    
         
            +
            - "--title"
         
     | 
| 
       116 
131 
     | 
    
         
             
            - Geoptima.rb
         
     | 
| 
       117 
     | 
    
         
            -
            - --line-numbers
         
     | 
| 
       118 
     | 
    
         
            -
            - --main
         
     | 
| 
      
 132 
     | 
    
         
            +
            - "--line-numbers"
         
     | 
| 
      
 133 
     | 
    
         
            +
            - "--main"
         
     | 
| 
       119 
134 
     | 
    
         
             
            - README.rdoc
         
     | 
| 
       120 
     | 
    
         
            -
            - --inline-source
         
     | 
| 
      
 135 
     | 
    
         
            +
            - "--inline-source"
         
     | 
| 
       121 
136 
     | 
    
         
             
            require_paths:
         
     | 
| 
       122 
137 
     | 
    
         
             
            - lib
         
     | 
| 
       123 
138 
     | 
    
         
             
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
       124 
139 
     | 
    
         
             
              none: false
         
     | 
| 
       125 
140 
     | 
    
         
             
              requirements:
         
     | 
| 
       126 
     | 
    
         
            -
              - -  
     | 
| 
      
 141 
     | 
    
         
            +
              - - ">="
         
     | 
| 
       127 
142 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       128 
143 
     | 
    
         
             
                  version: 1.8.6
         
     | 
| 
       129 
144 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       130 
145 
     | 
    
         
             
              none: false
         
     | 
| 
       131 
146 
     | 
    
         
             
              requirements:
         
     | 
| 
       132 
     | 
    
         
            -
              - -  
     | 
| 
      
 147 
     | 
    
         
            +
              - - ">="
         
     | 
| 
       133 
148 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       134 
149 
     | 
    
         
             
                  version: '0'
         
     | 
| 
      
 150 
     | 
    
         
            +
                  segments:
         
     | 
| 
      
 151 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 152 
     | 
    
         
            +
                  hash: 909654323
         
     | 
| 
       135 
153 
     | 
    
         
             
            requirements: []
         
     | 
| 
       136 
154 
     | 
    
         
             
            rubyforge_project: geoptima
         
     | 
| 
       137 
     | 
    
         
            -
            rubygems_version: 1.8. 
     | 
| 
      
 155 
     | 
    
         
            +
            rubygems_version: 1.8.25
         
     | 
| 
       138 
156 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       139 
157 
     | 
    
         
             
            specification_version: 3
         
     | 
| 
       140 
158 
     | 
    
         
             
            summary: Ruby access to Geoptima JSON files
         
     |