ruby-mapsource 0.0.1 → 0.2
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/Gemfile +0 -5
- data/README.md +21 -6
- data/Rakefile +1 -1
- data/lib/mapsource/reader.rb +79 -20
- data/lib/mapsource/structure.rb +11 -1
- data/lib/mapsource/version.rb +1 -1
- data/lib/mapsource.rb +11 -0
- data/ruby-mapsource.gemspec +4 -3
- data/spec/integration/reader_spec.rb +12 -1
- data/spec/unit/reader_spec.rb +1 -0
- metadata +45 -19
- data/.rvmrc +0 -71
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,15 +2,30 @@ ruby-mapsource is a library that allows ruby programs to read files created by G
|
|
2
2
|
|
3
3
|
# Usage
|
4
4
|
|
5
|
-
|
5
|
+
gdb = MapSource.read('/path/to/gdb_file.gdb')
|
6
|
+
# => #<MapSource::Reader:0x007fedfcb1b768>
|
6
7
|
|
7
|
-
#
|
8
|
+
# Read waypoints
|
9
|
+
gdb.waypoints.each { |wp|
|
10
|
+
puts "#{wp.shortname} - (#{wp.latitude}, #{wp.longitude})"
|
11
|
+
}
|
8
12
|
|
9
|
-
|
13
|
+
# Read tracks
|
14
|
+
gdb.tracks.each do |track|
|
15
|
+
puts "#{track.name} has #{track.size} points"
|
10
16
|
|
11
|
-
|
12
|
-
|
17
|
+
track.waypoints.each { |wp|
|
18
|
+
puts "\t#{wp.shortname} - (#{wp.latitude}, #{wp.longitude})"
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# TODO
|
23
|
+
|
24
|
+
- read routes
|
25
|
+
- comprehensive testing of different versions
|
13
26
|
|
14
27
|
# Thanks
|
15
28
|
|
16
|
-
GPSBabel
|
29
|
+
[GPSBabel][1] - gdb.c was vital in understanding the format
|
30
|
+
|
31
|
+
[1]: http://www.gpsbabel.org/
|
data/Rakefile
CHANGED
data/lib/mapsource/reader.rb
CHANGED
@@ -27,27 +27,29 @@ module MapSource
|
|
27
27
|
|
28
28
|
# Public: Read waypoints from file.
|
29
29
|
#
|
30
|
-
# Returns
|
30
|
+
# Returns an Array of waypoints.
|
31
31
|
def waypoints
|
32
32
|
read_data
|
33
33
|
@waypoints
|
34
34
|
end
|
35
35
|
|
36
|
+
# Public: Reads tracks from file.
|
37
|
+
#
|
38
|
+
# Returns an Array of tracks.
|
36
39
|
def tracks
|
37
40
|
read_data
|
38
41
|
@tracks
|
39
42
|
end
|
40
43
|
|
41
44
|
private
|
42
|
-
#
|
45
|
+
# Reads data from the GDB file and sets Reader's internal state.
|
43
46
|
#
|
44
|
-
# Returns
|
47
|
+
# Returns nothing.
|
45
48
|
def read_data
|
46
49
|
return if @parsed
|
47
50
|
|
48
51
|
@waypoints = []
|
49
52
|
@tracks = []
|
50
|
-
@routes = []
|
51
53
|
|
52
54
|
while true
|
53
55
|
len = @gdb.read(4).unpack('l').shift
|
@@ -67,7 +69,7 @@ module MapSource
|
|
67
69
|
@parsed = true
|
68
70
|
end
|
69
71
|
|
70
|
-
#
|
72
|
+
# Converts coordinates in semicircles to degrees.
|
71
73
|
#
|
72
74
|
# v - coordinate as semicircle
|
73
75
|
#
|
@@ -76,7 +78,7 @@ module MapSource
|
|
76
78
|
(v.to_f / (1 << 31)) * 180.0
|
77
79
|
end
|
78
80
|
|
79
|
-
#
|
81
|
+
# Reads a waypoint record from the GDB.
|
80
82
|
#
|
81
83
|
# record - a binary string containing waypoint data.
|
82
84
|
#
|
@@ -97,14 +99,14 @@ module MapSource
|
|
97
99
|
wpt = Waypoint.new(lat, lon)
|
98
100
|
wpt.shortname = shortname
|
99
101
|
|
100
|
-
if
|
102
|
+
if read_boolean(io)
|
101
103
|
alt = read_double(io)
|
102
104
|
|
103
105
|
wpt.altitude = alt if alt < 1.0e24
|
104
106
|
end
|
105
107
|
|
106
108
|
wpt.notes = read_string(io)
|
107
|
-
wpt.proximity = read_double(io) if
|
109
|
+
wpt.proximity = read_double(io) if read_boolean(io)
|
108
110
|
|
109
111
|
read_int io # display
|
110
112
|
read_int io # color, not implemented
|
@@ -114,7 +116,47 @@ module MapSource
|
|
114
116
|
wpt.state = read_string(io)
|
115
117
|
wpt.facility = read_string(io)
|
116
118
|
|
117
|
-
|
119
|
+
read_meaningless_chars io, 1
|
120
|
+
|
121
|
+
wpt.depth = read_double(io) if read_boolean(io)
|
122
|
+
|
123
|
+
if header.version <= 2
|
124
|
+
read_meaningless_chars 2
|
125
|
+
wptflag = read_boolean(io)
|
126
|
+
|
127
|
+
read_meaningless_chars (waypt_flag ? 2 : 3)
|
128
|
+
read_string io # undocumented and unused string
|
129
|
+
|
130
|
+
wpt.add_url read_string(io)
|
131
|
+
if wptclass != 0
|
132
|
+
# It's a description, not an URL. Remove from URL list and set it.
|
133
|
+
wpt.description = wpt.urls.shift
|
134
|
+
end
|
135
|
+
else
|
136
|
+
wptflag = 0
|
137
|
+
|
138
|
+
wpt.address = read_string(io)
|
139
|
+
|
140
|
+
read_meaningless_chars io, 5 # not sure if they are in fact meaningless
|
141
|
+
wpt.description = read_string(io)
|
142
|
+
|
143
|
+
url_count = read_int(io)
|
144
|
+
url_count.times do
|
145
|
+
url = read_string(io)
|
146
|
+
wpt.add_url(url) if url
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
wpt.category = ((i = read_int16(io)) && i != 0)
|
151
|
+
wpt.temperature = read_double(io) if read_boolean(io)
|
152
|
+
|
153
|
+
if header.version <= 2
|
154
|
+
if wptflag != 0
|
155
|
+
read_meaningless_chars io, 1
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
wpt.set_creation_time read_int(io) if read_boolean(io)
|
118
160
|
|
119
161
|
wpt
|
120
162
|
end
|
@@ -133,14 +175,14 @@ module MapSource
|
|
133
175
|
|
134
176
|
wpt = Waypoint.new(lat, lon)
|
135
177
|
|
136
|
-
if
|
178
|
+
if read_boolean(io)
|
137
179
|
alt = read_double(io)
|
138
180
|
wpt.altitude = alt if alt < 1.0e24
|
139
181
|
end
|
140
182
|
|
141
|
-
wpt.creation_time = read_int(io) if
|
142
|
-
wpt.depth = read_double(io) if
|
143
|
-
wpt.temperature = read_double(io) if
|
183
|
+
wpt.creation_time = read_int(io) if read_boolean(io)
|
184
|
+
wpt.depth = read_double(io) if read_boolean(io)
|
185
|
+
wpt.temperature = read_double(io) if read_boolean(io)
|
144
186
|
|
145
187
|
track.add_waypoint wpt
|
146
188
|
end
|
@@ -148,7 +190,7 @@ module MapSource
|
|
148
190
|
track
|
149
191
|
end
|
150
192
|
|
151
|
-
#
|
193
|
+
# Reads a string from an IO object.
|
152
194
|
#
|
153
195
|
# io - an IO object
|
154
196
|
# chars - number of chars to read. If not specified, read_string stops at
|
@@ -169,7 +211,7 @@ module MapSource
|
|
169
211
|
end
|
170
212
|
end
|
171
213
|
|
172
|
-
#
|
214
|
+
# Reads an Integer from an IO object, unpacking it appropriately.
|
173
215
|
#
|
174
216
|
# io - an IO object.
|
175
217
|
#
|
@@ -178,7 +220,15 @@ module MapSource
|
|
178
220
|
io.read(4).unpack('l').shift
|
179
221
|
end
|
180
222
|
|
181
|
-
|
223
|
+
def read_int16(io)
|
224
|
+
io.read(2).unpack('s').shift
|
225
|
+
end
|
226
|
+
|
227
|
+
def read_meaningless_chars(io, number_of_chars)
|
228
|
+
io.read number_of_chars
|
229
|
+
end
|
230
|
+
|
231
|
+
# Reads a Double from an IO object, unpacking it appropriately.
|
182
232
|
#
|
183
233
|
# io - an IO object.
|
184
234
|
#
|
@@ -187,8 +237,8 @@ module MapSource
|
|
187
237
|
io.read(8).unpack('E').shift
|
188
238
|
end
|
189
239
|
|
190
|
-
#
|
191
|
-
#
|
240
|
+
# Reads a single character from an IO object, unpacking it
|
241
|
+
# appropriately.
|
192
242
|
#
|
193
243
|
# io - an IO object.
|
194
244
|
#
|
@@ -197,8 +247,17 @@ module MapSource
|
|
197
247
|
io.read(1).unpack('c').shift
|
198
248
|
end
|
199
249
|
|
200
|
-
#
|
201
|
-
#
|
250
|
+
# Reads a boolean from an IO object.
|
251
|
+
#
|
252
|
+
# io - an IO object.
|
253
|
+
#
|
254
|
+
# Returns a single character.
|
255
|
+
def read_boolean(io)
|
256
|
+
read_char(io) == 1
|
257
|
+
end
|
258
|
+
|
259
|
+
# Reads a GDB's header to determine the version being parsed, its creator
|
260
|
+
# and signer.
|
202
261
|
#
|
203
262
|
# Returns a properly filled header.
|
204
263
|
# Raises MapSource::InvalidFormatError if it's not a GDB file.
|
data/lib/mapsource/structure.rb
CHANGED
@@ -8,11 +8,21 @@ module MapSource
|
|
8
8
|
|
9
9
|
# Public: A Waypoint.
|
10
10
|
class Waypoint
|
11
|
-
attr_accessor :shortname, :latitude, :longitude, :altitude, :temperature, :depth, :notes, :creation_time, :proximity, :icon, :city, :state, :facility
|
11
|
+
attr_accessor :shortname, :latitude, :longitude, :altitude, :temperature, :depth, :notes, :creation_time, :proximity, :icon, :city, :state, :facility, :address, :description, :category
|
12
|
+
attr_reader :urls
|
12
13
|
|
13
14
|
def initialize(latitude, longitude)
|
14
15
|
@latitude = latitude
|
15
16
|
@longitude = longitude
|
17
|
+
@urls = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_url(url)
|
21
|
+
@urls << url
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_creation_time(value)
|
25
|
+
puts value
|
16
26
|
end
|
17
27
|
end
|
18
28
|
|
data/lib/mapsource/version.rb
CHANGED
data/lib/mapsource.rb
CHANGED
@@ -28,3 +28,14 @@ require 'stringio'
|
|
28
28
|
require 'mapsource/structure'
|
29
29
|
require 'mapsource/defs'
|
30
30
|
require 'mapsource/reader'
|
31
|
+
|
32
|
+
module MapSource
|
33
|
+
# Public: Reads a GDB file and returns a Ruby-friendly representation.
|
34
|
+
#
|
35
|
+
# path - A String pointing to a GDB in the filesystem.
|
36
|
+
#
|
37
|
+
# Returns a MapSource::Reader.
|
38
|
+
def self.read(path)
|
39
|
+
MapSource::Reader.new open(path)
|
40
|
+
end
|
41
|
+
end
|
data/ruby-mapsource.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = MapSource::VERSION
|
8
8
|
s.authors = ["Vitor Capela"]
|
9
9
|
s.email = ["dodecaphonic@gmail.com"]
|
10
|
-
s.homepage = ""
|
10
|
+
s.homepage = "http://github.com/dodecaphonic/ruby-mapsource"
|
11
11
|
s.summary = %q{A Ruby library for reading MapSource/BaseCamp-created GDB files}
|
12
12
|
s.description = %q{A Ruby library for reading MapSource/BaseCamp-created GDB files}
|
13
13
|
|
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_development_dependency "minitest"
|
22
|
-
s.add_development_dependency "mocha"
|
21
|
+
s.add_development_dependency "minitest"
|
22
|
+
s.add_development_dependency "mocha"
|
23
|
+
s.add_development_dependency "rake"
|
23
24
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe MapSource::Reader do
|
4
|
+
let(:filename) { File.dirname(__FILE__) + '/../assets/sample.gdb' }
|
5
|
+
|
4
6
|
before :each do
|
5
|
-
@gdb_file = open(
|
7
|
+
@gdb_file = open(filename)
|
6
8
|
@reader = MapSource::Reader.new(@gdb_file)
|
7
9
|
end
|
8
10
|
|
@@ -30,4 +32,13 @@ describe MapSource::Reader do
|
|
30
32
|
wpt.longitude.must_be_close_to -44.83632
|
31
33
|
wpt.altitude.must_be_close_to 1471, 0.05
|
32
34
|
end
|
35
|
+
|
36
|
+
describe 'can be started with a convenience method' do
|
37
|
+
it 'reads the file' do
|
38
|
+
gdb = MapSource.read(filename)
|
39
|
+
|
40
|
+
gdb.waypoints.size.must_equal 312
|
41
|
+
gdb.tracks.find { |t| t.name == 'ACTIVE LOG 009' }.size.must_equal 296
|
42
|
+
end
|
43
|
+
end
|
33
44
|
end
|
data/spec/unit/reader_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-mapsource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,30 +9,56 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
21
|
+
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: mocha
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
|
-
- -
|
51
|
+
- - ! '>='
|
31
52
|
- !ruby/object:Gem::Version
|
32
|
-
version: '0
|
53
|
+
version: '0'
|
33
54
|
type: :development
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
36
62
|
description: A Ruby library for reading MapSource/BaseCamp-created GDB files
|
37
63
|
email:
|
38
64
|
- dodecaphonic@gmail.com
|
@@ -41,7 +67,6 @@ extensions: []
|
|
41
67
|
extra_rdoc_files: []
|
42
68
|
files:
|
43
69
|
- .gitignore
|
44
|
-
- .rvmrc
|
45
70
|
- Gemfile
|
46
71
|
- Guardfile
|
47
72
|
- LICENSE
|
@@ -58,7 +83,7 @@ files:
|
|
58
83
|
- spec/integration/reader_spec.rb
|
59
84
|
- spec/spec_helper.rb
|
60
85
|
- spec/unit/reader_spec.rb
|
61
|
-
homepage:
|
86
|
+
homepage: http://github.com/dodecaphonic/ruby-mapsource
|
62
87
|
licenses: []
|
63
88
|
post_install_message:
|
64
89
|
rdoc_options: []
|
@@ -70,21 +95,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
95
|
- - ! '>='
|
71
96
|
- !ruby/object:Gem::Version
|
72
97
|
version: '0'
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
hash: -3373937689098540236
|
73
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
102
|
none: false
|
75
103
|
requirements:
|
76
104
|
- - ! '>='
|
77
105
|
- !ruby/object:Gem::Version
|
78
106
|
version: '0'
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
hash: -3373937689098540236
|
79
110
|
requirements: []
|
80
111
|
rubyforge_project: ruby-mapsource
|
81
|
-
rubygems_version: 1.8.
|
112
|
+
rubygems_version: 1.8.24
|
82
113
|
signing_key:
|
83
114
|
specification_version: 3
|
84
115
|
summary: A Ruby library for reading MapSource/BaseCamp-created GDB files
|
85
|
-
test_files:
|
86
|
-
- spec/assets/sample.gdb
|
87
|
-
- spec/assets/track.bin
|
88
|
-
- spec/integration/reader_spec.rb
|
89
|
-
- spec/spec_helper.rb
|
90
|
-
- spec/unit/reader_spec.rb
|
116
|
+
test_files: []
|
data/.rvmrc
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
-
# development environment upon cd'ing into the directory
|
5
|
-
|
6
|
-
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
|
7
|
-
environment_id="ruby-1.9.3-p0@mapsource_gdb"
|
8
|
-
|
9
|
-
#
|
10
|
-
# Uncomment following line if you want options to be set only for given project.
|
11
|
-
#
|
12
|
-
# PROJECT_JRUBY_OPTS=( --1.9 )
|
13
|
-
#
|
14
|
-
# The variable PROJECT_JRUBY_OPTS requires the following to be run in shell:
|
15
|
-
#
|
16
|
-
# chmod +x ${rvm_path}/hooks/after_use_jruby_opts
|
17
|
-
#
|
18
|
-
|
19
|
-
#
|
20
|
-
# First we attempt to load the desired environment directly from the environment
|
21
|
-
# file. This is very fast and efficient compared to running through the entire
|
22
|
-
# CLI and selector. If you want feedback on which environment was used then
|
23
|
-
# insert the word 'use' after --create as this triggers verbose mode.
|
24
|
-
#
|
25
|
-
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
26
|
-
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
27
|
-
then
|
28
|
-
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
29
|
-
|
30
|
-
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
31
|
-
then
|
32
|
-
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
33
|
-
fi
|
34
|
-
else
|
35
|
-
# If the environment file has not yet been created, use the RVM CLI to select.
|
36
|
-
if ! rvm --create use "$environment_id"
|
37
|
-
then
|
38
|
-
echo "Failed to create RVM environment '${environment_id}'."
|
39
|
-
return 1
|
40
|
-
fi
|
41
|
-
fi
|
42
|
-
|
43
|
-
#
|
44
|
-
# If you use an RVM gemset file to install a list of gems (*.gems), you can have
|
45
|
-
# it be automatically loaded. Uncomment the following and adjust the filename if
|
46
|
-
# necessary.
|
47
|
-
#
|
48
|
-
# filename=".gems"
|
49
|
-
# if [[ -s "$filename" ]]
|
50
|
-
# then
|
51
|
-
# rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
|
52
|
-
# fi
|
53
|
-
|
54
|
-
# If you use bundler, this might be useful to you:
|
55
|
-
# if [[ -s Gemfile ]] && ! command -v bundle >/dev/null
|
56
|
-
# then
|
57
|
-
# printf "The rubygem 'bundler' is not installed. Installing it now.\n"
|
58
|
-
# gem install bundler
|
59
|
-
# fi
|
60
|
-
# if [[ -s Gemfile ]] && command -v bundle
|
61
|
-
# then
|
62
|
-
# bundle install
|
63
|
-
# fi
|
64
|
-
|
65
|
-
if [[ $- == *i* ]] # check for interactive shells
|
66
|
-
then
|
67
|
-
echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
68
|
-
else
|
69
|
-
echo "Using: $GEM_HOME" # don't use colors in interactive shells
|
70
|
-
fi
|
71
|
-
|