columbus3 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/bower_components/leaflet/.bower.json +34 -0
- data/bower_components/leaflet/CHANGELOG.md +929 -0
- data/bower_components/leaflet/CONTRIBUTING.md +155 -0
- data/bower_components/leaflet/Jakefile.js +48 -0
- data/bower_components/leaflet/LICENSE +23 -0
- data/bower_components/leaflet/PLUGIN-GUIDE.md +127 -0
- data/bower_components/leaflet/README.md +34 -0
- data/bower_components/leaflet/bower.json +24 -0
- data/bower_components/leaflet/component.json +20 -0
- data/bower_components/leaflet/dist/images/layers-2x.png +0 -0
- data/bower_components/leaflet/dist/images/layers.png +0 -0
- data/bower_components/leaflet/dist/images/marker-icon-2x.png +0 -0
- data/bower_components/leaflet/dist/images/marker-icon.png +0 -0
- data/bower_components/leaflet/dist/images/marker-shadow.png +0 -0
- data/bower_components/leaflet/dist/leaflet-src.js +9180 -0
- data/bower_components/leaflet/dist/leaflet.css +478 -0
- data/bower_components/leaflet/dist/leaflet.js +9 -0
- data/bower_components/leaflet/package.json +33 -0
- data/bower_components/leaflet-providers/.bower.json +35 -0
- data/bower_components/leaflet-providers/CONTRIBUTING.md +10 -0
- data/bower_components/leaflet-providers/README.md +54 -0
- data/bower_components/leaflet-providers/bower.json +25 -0
- data/bower_components/leaflet-providers/css/gh-fork-ribbon.css +127 -0
- data/bower_components/leaflet-providers/css/gh-fork-ribbon.ie.css +68 -0
- data/bower_components/leaflet-providers/leaflet-providers.js +630 -0
- data/bower_components/leaflet-providers/license.md +9 -0
- data/bower_components/leaflet-providers/package.json +38 -0
- data/columbus3.gemspec +28 -0
- data/exe/columbus3 +144 -0
- data/lib/columbus3/metadata/query_parser.racc +160 -0
- data/lib/columbus3/metadata/query_parser.tab.rb +349 -0
- data/lib/columbus3/metadata/sidecar.rb +48 -0
- data/lib/columbus3/renderer/renderer.rb +73 -0
- data/lib/columbus3/v900track/v900track.rb +157 -0
- data/lib/columbus3/v900track/v900waypoint.rb +51 -0
- data/lib/columbus3/version.rb +3 -0
- data/lib/columbus3.rb +6 -0
- data/lib/html/show.html.erb +84 -0
- data/lib/html/track.js.erb +15 -0
- 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
|
+
|