columbus3 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +41 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +7 -0
  10. data/bower_components/leaflet/.bower.json +34 -0
  11. data/bower_components/leaflet/CHANGELOG.md +929 -0
  12. data/bower_components/leaflet/CONTRIBUTING.md +155 -0
  13. data/bower_components/leaflet/Jakefile.js +48 -0
  14. data/bower_components/leaflet/LICENSE +23 -0
  15. data/bower_components/leaflet/PLUGIN-GUIDE.md +127 -0
  16. data/bower_components/leaflet/README.md +34 -0
  17. data/bower_components/leaflet/bower.json +24 -0
  18. data/bower_components/leaflet/component.json +20 -0
  19. data/bower_components/leaflet/dist/images/layers-2x.png +0 -0
  20. data/bower_components/leaflet/dist/images/layers.png +0 -0
  21. data/bower_components/leaflet/dist/images/marker-icon-2x.png +0 -0
  22. data/bower_components/leaflet/dist/images/marker-icon.png +0 -0
  23. data/bower_components/leaflet/dist/images/marker-shadow.png +0 -0
  24. data/bower_components/leaflet/dist/leaflet-src.js +9180 -0
  25. data/bower_components/leaflet/dist/leaflet.css +478 -0
  26. data/bower_components/leaflet/dist/leaflet.js +9 -0
  27. data/bower_components/leaflet/package.json +33 -0
  28. data/bower_components/leaflet-providers/.bower.json +35 -0
  29. data/bower_components/leaflet-providers/CONTRIBUTING.md +10 -0
  30. data/bower_components/leaflet-providers/README.md +54 -0
  31. data/bower_components/leaflet-providers/bower.json +25 -0
  32. data/bower_components/leaflet-providers/css/gh-fork-ribbon.css +127 -0
  33. data/bower_components/leaflet-providers/css/gh-fork-ribbon.ie.css +68 -0
  34. data/bower_components/leaflet-providers/leaflet-providers.js +630 -0
  35. data/bower_components/leaflet-providers/license.md +9 -0
  36. data/bower_components/leaflet-providers/package.json +38 -0
  37. data/columbus3.gemspec +28 -0
  38. data/exe/columbus3 +144 -0
  39. data/lib/columbus3/metadata/query_parser.racc +160 -0
  40. data/lib/columbus3/metadata/query_parser.tab.rb +349 -0
  41. data/lib/columbus3/metadata/sidecar.rb +48 -0
  42. data/lib/columbus3/renderer/renderer.rb +73 -0
  43. data/lib/columbus3/v900track/v900track.rb +157 -0
  44. data/lib/columbus3/v900track/v900waypoint.rb +51 -0
  45. data/lib/columbus3/version.rb +3 -0
  46. data/lib/columbus3.rb +6 -0
  47. data/lib/html/show.html.erb +84 -0
  48. data/lib/html/track.js.erb +15 -0
  49. metadata +164 -0
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "leaflet-providers",
3
+ "version": "1.1.1",
4
+ "description": "An extension to Leaflet that contains configurations for various free tile providers.",
5
+ "main": "leaflet-providers.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git://github.com/leaflet-extras/leaflet-providers.git"
9
+ },
10
+ "scripts": {
11
+ "test": "npm run lint && npm run testsuite",
12
+ "testsuite": "mocha-phantomjs tests/index.html",
13
+ "lint": "eslint --config .eslintrc leaflet-providers.js preview/preview.js preview/shared.js preview/https-support.js tests/test.js",
14
+ "min": "uglifyjs leaflet-providers.js -mc -o leaflet-providers.min.js",
15
+ "release": "mversion patch -m"
16
+ },
17
+ "license": "BSD-2-Clause",
18
+ "bugs": {
19
+ "url": "https://github.com/leaflet-extras/leaflet-providers/issues"
20
+ },
21
+ "devDependencies": {
22
+ "chai": "^2.3.0",
23
+ "eslint": "^0.15.0",
24
+ "mocha": "^2.2.4",
25
+ "mocha-phantomjs": "^3.5.3",
26
+ "mversion": "^1.3.0",
27
+ "uglify-js": "^2.4.15",
28
+ "phantomjs": "^1.9.16"
29
+ },
30
+ "autoupdate": {
31
+ "source": "git",
32
+ "target": "git://github.com/leaflet-extras/leaflet-providers.git",
33
+ "basePath": "/",
34
+ "files": [
35
+ "leaflet-providers.js"
36
+ ]
37
+ }
38
+ }
data/columbus3.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'columbus3/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "columbus3"
8
+ spec.version = Columbus3::VERSION
9
+ spec.authors = ["Adolfo Villafiorita"]
10
+ spec.email = ["adolfo.villafiorita@me.com"]
11
+
12
+ spec.summary = %q{Manage V900 and V990 GPS tracks from the command line.}
13
+ spec.description = %q{Some simple command line commands to manage tracks generated by the V900 family of GPS loggers (CSV format).}
14
+ spec.homepage = "http://ict4g.net/adolfo/columbus3"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.10"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest"
25
+
26
+ spec.add_dependency "slop", "~> 3.6.0"
27
+ spec.add_dependency "geocoder"
28
+ end
data/exe/columbus3 ADDED
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "slop"
4
+ require "columbus3"
5
+
6
+ appname = "columbus3"
7
+ version = Columbus3::VERSION
8
+ usage = "#{appname} [-h|-v]\n#{appname} command [options] [args]"
9
+ man = <<EOS
10
+ NAME
11
+ #{appname} -- manage Columbus V900 and V990 tracks from the command line
12
+
13
+ SYNOPSYS
14
+ #{appname} [-h|-v]
15
+ #{appname} command [options] [args]
16
+
17
+ DESCRIPTION
18
+
19
+ columbus3 manages Columbus V900 and V990 tracks from the command line,
20
+ allowing a user to associate a sidecar file with the main information
21
+ about a track, searching tracks (through sidecar files), displaying
22
+ tracks on a map.
23
+
24
+ EXAMPLES
25
+ #{appname} -h # get syntax of each command
26
+ columbus3 process 11010101.CSV # generate a sidecar file
27
+ columbus3 search ...
28
+ columbus3 show 11010101.CSV 11010201.CSV # show tracks
29
+
30
+ VERSION
31
+ This is version #{version}
32
+
33
+ LICENSE
34
+ MIT
35
+
36
+ Columbus3 uses leaflet and leafleft-providers to diplay tracks. They
37
+ are distributed under a different license: see their websites for more
38
+ details (or have a look at the license file shipped with the Gem)
39
+
40
+ SEE ALSO
41
+ If you are looking for a graphical client, you might want to
42
+ download Columbus from http://www.minimalbit.com
43
+
44
+ https://github.com/avillafiorita/columbus3
45
+ EOS
46
+
47
+ #
48
+ # Main App Starts Here!
49
+ #
50
+ opts = Slop.parse :help => true do
51
+ banner usage
52
+
53
+ ##############################################################################
54
+ on "-v", "--version", 'Print version information' do
55
+ puts "#{appname} version #{version}"
56
+ end
57
+
58
+ ##############################################################################
59
+ command :help do
60
+ banner "#{appname} help"
61
+ description "Print man page for #{appname}"
62
+
63
+ run do |_, _|
64
+ puts man
65
+ end
66
+ end
67
+
68
+ ##############################################################################
69
+ command :process do
70
+ banner "#{appname} process track [... track]"
71
+ description "Generate a sidecar file for the track"
72
+
73
+ run do |opts, args|
74
+ args.each do |arg|
75
+ track = V900Track.new arg
76
+ sidecar = Columbus3::Sidecar.new arg
77
+ sidecar.metadata = track.metadata
78
+ sidecar.save
79
+ end
80
+ end
81
+ end
82
+
83
+ ##############################################################################
84
+ command :search do
85
+ banner "#{appname} search --dir directory term"
86
+ description "Search dir for tracks matching criteria in dir"
87
+
88
+ on "--debug", "Show how the query is processed"
89
+ on "-d", "--dir=", "Directory with sidecar files"
90
+
91
+ run do |opts, args|
92
+ debug = opts.to_hash[:debug]
93
+ directory = opts.to_hash[:dir] || "."
94
+
95
+ files = Dir.glob(directory + "/" + "*.yaml")
96
+ puts args
97
+ puts args.join(" ")
98
+ query = QueryParser.new.parse(args.join(" "))
99
+
100
+ if debug then
101
+ puts "Searched files: #{files.join(",")}"
102
+ puts "Searched files count: #{files.size}"
103
+ puts "Processed query: #{query}"
104
+ else
105
+ sidecar_search = Columbus3::SidecarSearch.new
106
+ sidecar_search.load files
107
+ match = sidecar_search.search query
108
+ match.each do |m|
109
+ string = [:filename, :start_location, :end_location, :start_date, :end_date, :duration, :min_speed, :max_speed, :min_height, :max_height].map { |x| "#{m[x]}"}.join("\t")
110
+ puts string
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ ##############################################################################
117
+ command :show do
118
+ banner "#{appname} show [--force] track [... track]"
119
+ description "View tracks"
120
+
121
+ on "--force", "Force rewriting of the js file, even if it already exists"
122
+
123
+ run do |opts, args|
124
+ force = opts.to_hash[:force]
125
+
126
+ args.each do |arg|
127
+ Columbus3::LeafletRenderer::to_leaflet arg, force
128
+ end
129
+ Columbus3::LeafletRenderer::show args
130
+ end
131
+ end
132
+
133
+ ##############################################################################
134
+ command :export do
135
+ banner "#{appname} export track [... track]"
136
+ description "Export track to GPX"
137
+
138
+ run do |opts, args|
139
+
140
+ end
141
+ end
142
+
143
+ end
144
+
@@ -0,0 +1,160 @@
1
+ # parses a query and makes it into an expression which can be evaluated
2
+ #
3
+ # the search engine evals an expression against an array of hashes and select
4
+ # those matching. It does so using a select which iterates over x.
5
+ #
6
+ # this parser reads a string containing a query and returns a string containing
7
+ # the Ruby code which can be passed as argument to the search function
8
+ #
9
+ # the following queries are supported:
10
+ #
11
+ # location ~ ""
12
+ # location == ""
13
+ # start_location ~ ""
14
+ # end_location ""
15
+ #
16
+ # date ==|>=|<= YYYY-MM-DD
17
+ # year == 2015
18
+ # start_date ...
19
+ # end_date ...
20
+ #
21
+ # duration ==|>=|<= HH:MM:SS
22
+ #
23
+ # max_speed ==|>=|<= NUMBER
24
+ # min_height ==|>=|<= NUMBER
25
+ # max_height ==|>=|<= NUMBER
26
+ #
27
+ # AND and OR can be used to form complex expressions
28
+ #
29
+ #["location ~ \"USA\"", "start_location ~ \"Africa\"", "end_location ~ \"Africa\"", "date >= 2015-01-01", "start_date <= 2015-01-01", "date == 2015-01-01", "duration > 10:00:00", "duration <= 01:49:50", "\"USA\"", "duration == 10:00:00" ].each.map { |x| QueryParser.new.parse(x) }
30
+
31
+
32
+ class QueryParser
33
+ token
34
+ LOCATION_GEN # generic location (start or end)
35
+ LOCATION # start or end location
36
+ DATE_GEN # generic date (start or end)
37
+ DATE_FIELD # the "date" field
38
+ YEAR_FIELD # year (start or end)
39
+ FIELD
40
+ MATCH EQUAL OP
41
+ DATE NUMBER DURATION STRING
42
+ AND OR
43
+ '(' ')'
44
+ prechigh
45
+ left AND
46
+ left OR
47
+ preclow
48
+ rule
49
+ start exp
50
+
51
+ exp : simple_exp { result = "#{val[0]}" }
52
+ | exp AND exp { result = "(#{val[0]} and #{val[2]})" }
53
+ | exp OR exp { result = "(#{val[0]} or #{val[2]})" }
54
+ | '(' exp ')' { result = "(#{val[1]})" }
55
+
56
+ simple_exp: STRING { result = "x[:start_location].include?(#{val[0]}) or x[:end_location].include?(#{val[0]})" }
57
+ | LOCATION_GEN MATCH STRING
58
+ { result = "x[:start_location].include?(#{val[2]}) or x[:end_location].include?(#{val[2]})" }
59
+ | LOCATION_GEN EQUAL STRING
60
+ { result = "x[:start_location] == #{val[2]} or x[:end_location] == #{val[2]}" }
61
+ | LOCATION MATCH STRING
62
+ { result = "x[:#{val[0]}].include?(#{val[2]})" }
63
+ | LOCATION EQUAL STRING
64
+ { result = "x[:#{val[0]}] == #{val[2]}" }
65
+ | DATE_GEN op_or_equal date
66
+ { result = "x[:start_date] #{val[1]} #{val[2]} or x[:end_date] #{val[1]} #{val[2]}"}
67
+ | DATE_FIELD op_or_equal date
68
+ { result = "#{val[0]} #{val[1]} #{val[2]}" }
69
+ | YEAR_FIELD op_or_equal NUMBER
70
+ { result = "x[:start_date].year #{val[1]} #{val[2]} or x[:end_date].year #{val[1]} #{val[2]}" }
71
+ | FIELD op_or_equal value
72
+ { result = "x[:#{val[0]}] #{val[1]} #{val[2]}" }
73
+
74
+ date : DATE { result = "Date.parse(\"#{val[0]}\")" }
75
+
76
+ op_or_equal : OP
77
+ | EQUAL
78
+
79
+ value: NUMBER
80
+ | DURATION
81
+
82
+ end
83
+ ---- header
84
+ require 'date'
85
+ ---- inner
86
+ attr_accessor :result
87
+
88
+ def parse(str)
89
+ @tokens = make_tokens str
90
+ do_parse
91
+ end
92
+
93
+ def next_token
94
+ @tokens.shift
95
+ end
96
+
97
+ LOCATION_GEN = /location/
98
+ LOCATION = /(start|end)_location/
99
+ DATE_GEN = /date/
100
+ DATE_FIELD = /(start|end)_date/
101
+ YEAR = /year/
102
+ FIELD = /(duration|distance(_aerial)?|(min|max)_height|(min|max)_speed|points|bearing)/
103
+
104
+ def make_tokens str
105
+ require 'strscan'
106
+ result = []
107
+ scanner = StringScanner.new str
108
+ until scanner.empty?
109
+ case
110
+ when match = scanner.scan(/(or|OR)/)
111
+ result << [:OR, nil]
112
+ when match = scanner.scan(/(and|AND)/)
113
+ result << [:AND, nil]
114
+ when match = scanner.scan(/\(/)
115
+ result << ['(', nil]
116
+ when match = scanner.scan(/\)/)
117
+ result << [')', nil]
118
+ when match = scanner.scan(/[0-9]+-[0-9]+-[0-9]+/)
119
+ result << [:DATE, match]
120
+ when match = scanner.scan(/([0-9]+):([0-9]+):([0-9]+)/)
121
+ seconds = match[6..7].to_i + match[3..4].to_i * 60 + match[0..1].to_i * 3600
122
+ result << [:DURATION, seconds]
123
+ when match = scanner.scan(/[0-9]+(\.[0-9]+)?/)
124
+ result << [:NUMBER, match]
125
+ when match = scanner.scan(LOCATION_GEN)
126
+ result << [:LOCATION_GEN, nil]
127
+ when match = scanner.scan(LOCATION)
128
+ result << [:LOCATION, match]
129
+ when match = scanner.scan(DATE_GEN)
130
+ result << [:DATE_GEN, nil]
131
+ when match = scanner.scan(DATE_FIELD)
132
+ result << [:DATE_FIELD, match]
133
+ when match = scanner.scan(YEAR)
134
+ result << [:YEAR, nil]
135
+ when match = scanner.scan(FIELD)
136
+ result << [:FIELD, match]
137
+ when match = scanner.scan(/"[^"]+"/)
138
+ result << [:STRING, match ]
139
+ when match = scanner.scan(/~/)
140
+ result << [:MATCH, '~']
141
+ when match = scanner.scan(/==/)
142
+ result << [:EQUAL, '==']
143
+ when match = scanner.scan(/>=/)
144
+ result << [:OP, '>=']
145
+ when match = scanner.scan(/>/)
146
+ result << [:OP, '>']
147
+ when match = scanner.scan(/<=/)
148
+ result << [:OP, '<=']
149
+ when match = scanner.scan(/</)
150
+ result << [:OP, '<']
151
+ when scanner.scan(/\s+/)
152
+ # ignore whitespace
153
+ else
154
+ raise "The lexer can't recognize <#{scanner.peek(5)}>"
155
+ end
156
+ end
157
+ result << [false, false]
158
+ return result
159
+ end
160
+