gpx_ruby 0.1.0
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.
- checksums.yaml +7 -0
- data/Rakefile +7 -0
- data/lib/gpx_ruby.rb +24 -0
- data/lib/gpx_ruby/gpx/document.rb +19 -0
- data/lib/gpx_ruby/gpx/parser.rb +54 -0
- data/lib/gpx_ruby/gpx/parsers/track_parser.rb +121 -0
- data/lib/gpx_ruby/gpx/point.rb +78 -0
- data/lib/gpx_ruby/gpx/track.rb +100 -0
- data/lib/version.rb +3 -0
- data/test/test_gpx_parser.rb +167 -0
- data/test/test_helper.rb +3 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8d28ab6aad3c8f49b2a1623c39a58a54a550e2fc
|
4
|
+
data.tar.gz: 9e87c82457414596fdad17d515489e7cf4a01375
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f1e26c42d0a11f5e6598f0f486b189ebdb37bf0af645dea7320ff7a736150a877123bf02d2996d7ffa885978b2e203406e870efcc197f8b397c05135b303b328
|
7
|
+
data.tar.gz: 241a076a866fefeb6e476ef24aa26e40f44941a82cdc6ad6041e1a7fe613d37cae92648743194288fdcb017c9da6c0ce8f91a118bb45ab07b0276d84facc9281
|
data/Rakefile
ADDED
data/lib/gpx_ruby.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module GpxRuby
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'time'
|
5
|
+
require 'tempfile'
|
6
|
+
require 'gpx_ruby/gpx/point'
|
7
|
+
require 'gpx_ruby/gpx/track'
|
8
|
+
require 'gpx_ruby/gpx/parsers/track_parser'
|
9
|
+
require 'gpx_ruby/gpx/document'
|
10
|
+
require 'gpx_ruby/gpx/parser'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def File(input)
|
15
|
+
Gpx::Parser.new(input).parse
|
16
|
+
end
|
17
|
+
|
18
|
+
def XML(xml_string)
|
19
|
+
Gpx::Parser.new(xml: xml_string).parse
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GpxRuby
|
2
|
+
|
3
|
+
module Gpx
|
4
|
+
|
5
|
+
class Document
|
6
|
+
|
7
|
+
attr_accessor :version, :creator, :tracks
|
8
|
+
|
9
|
+
def initialize(a_hash)
|
10
|
+
@creator = a_hash[:creator]
|
11
|
+
@version = a_hash[:version]
|
12
|
+
@tracks = a_hash[:tracks]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module GpxRuby
|
2
|
+
|
3
|
+
module Gpx
|
4
|
+
|
5
|
+
class Parser
|
6
|
+
|
7
|
+
def initialize(input)
|
8
|
+
@xml = case input
|
9
|
+
when File
|
10
|
+
input.read
|
11
|
+
when Tempfile
|
12
|
+
input.read
|
13
|
+
when String
|
14
|
+
::File.open(input, 'r') { |f| f.read }
|
15
|
+
when Hash
|
16
|
+
if input[:file_path] && input[:file_path].is_a?(String)
|
17
|
+
::File.open(input[:file_path], 'r') { |f| f.read }
|
18
|
+
end
|
19
|
+
if input[:xml] && input[:xml].is_a?(String)
|
20
|
+
input[:xml]
|
21
|
+
elsif input[:file] && (input[:file].is_a?(File) || input[:file].is_a?(Tempfile))
|
22
|
+
input[:file].read
|
23
|
+
else
|
24
|
+
raise 'Error: invalid input!'
|
25
|
+
end
|
26
|
+
else
|
27
|
+
raise 'Error: invalid input!'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def parse
|
33
|
+
doc = Nokogiri::XML(@xml)
|
34
|
+
@gpx_node = doc.at_xpath('//xmlns:gpx')
|
35
|
+
|
36
|
+
properties = {
|
37
|
+
creator: @gpx_node.at_xpath('@creator').value,
|
38
|
+
version: @gpx_node.at_xpath('@version').value.to_f,
|
39
|
+
tracks: []
|
40
|
+
}
|
41
|
+
|
42
|
+
# parse track elements
|
43
|
+
tracks = Parsers::TrackParser.new(@gpx_node).parse
|
44
|
+
properties = properties.merge(tracks: tracks)
|
45
|
+
|
46
|
+
Document.new properties
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module GpxRuby
|
2
|
+
|
3
|
+
module Gpx
|
4
|
+
|
5
|
+
module Parsers
|
6
|
+
|
7
|
+
class TrackParser
|
8
|
+
|
9
|
+
def initialize(gpx_node)
|
10
|
+
@gpx_node = gpx_node
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse
|
14
|
+
tracks = []
|
15
|
+
if track_nodes = @gpx_node.xpath('./xmlns:trk')
|
16
|
+
# iterate over all tracks
|
17
|
+
track_nodes.each do |trk|
|
18
|
+
trk_segments = trk.xpath('./xmlns:trkseg')
|
19
|
+
|
20
|
+
# map track segments for this track
|
21
|
+
track_segments = trk_segments.map do |trkseg|
|
22
|
+
|
23
|
+
# map all track points for this track segment
|
24
|
+
track_points = trkseg.xpath('./xmlns:trkpt').map do |trkpt|
|
25
|
+
|
26
|
+
lat = trkpt.at_xpath('./@lat').value.to_f
|
27
|
+
lon = trkpt.at_xpath('./@lon').value.to_f
|
28
|
+
|
29
|
+
time = begin
|
30
|
+
DateTime.xmlschema(trkpt.at_xpath('./xmlns:time').text).to_time
|
31
|
+
rescue
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
elevation = begin
|
36
|
+
trkpt.at_xpath('./xmlns:ele').text.to_f
|
37
|
+
rescue
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
Track::Point.new lat: lat, lon: lon, time: time, elevation: elevation
|
42
|
+
end
|
43
|
+
|
44
|
+
Track::Segment.new track_points
|
45
|
+
end
|
46
|
+
|
47
|
+
trk_name = begin
|
48
|
+
trk.at_xpath('./xmlns:name').text
|
49
|
+
rescue
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
trk_cmt = begin
|
54
|
+
trk.at_xpath('./xmlns:cmt').text
|
55
|
+
rescue
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
trk_src = begin
|
60
|
+
trk.at_xpath('./xmlns:src').text
|
61
|
+
rescue
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
trk_desc = begin
|
66
|
+
trk.at_xpath('./xmlns:desc').text
|
67
|
+
rescue
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
trk_number = begin
|
72
|
+
trk.at_xpath('./xmlns:number').text
|
73
|
+
rescue
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
|
77
|
+
trk_url = begin
|
78
|
+
trk.at_xpath('./xmlns:url').text
|
79
|
+
rescue
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
trk_url_name = begin
|
84
|
+
trk.at_xpath('./xmlns:urlname').text
|
85
|
+
rescue
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
trk_time = begin
|
90
|
+
DateTime.xmlschema(trk.at_xpath('./xmlns:time').text).to_time
|
91
|
+
rescue
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
track_hash = {
|
96
|
+
segments: track_segments,
|
97
|
+
name: trk_name,
|
98
|
+
time: trk_time,
|
99
|
+
source: trk_src,
|
100
|
+
description: trk_desc,
|
101
|
+
number: trk_number,
|
102
|
+
comment: trk_cmt,
|
103
|
+
url: trk_url,
|
104
|
+
url_name: trk_url_name
|
105
|
+
}
|
106
|
+
|
107
|
+
tracks << Track.new(track_hash)
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
tracks
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module GpxRuby
|
2
|
+
|
3
|
+
module Gpx
|
4
|
+
|
5
|
+
class Point
|
6
|
+
|
7
|
+
attr_accessor :lat, :lon
|
8
|
+
|
9
|
+
RADIUS_KM = 6371
|
10
|
+
|
11
|
+
def initialize(a_hash)
|
12
|
+
@lat = a_hash[:lat]
|
13
|
+
@lon = a_hash[:lon]
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def [](index)
|
18
|
+
case index
|
19
|
+
when 0
|
20
|
+
lat
|
21
|
+
when 1
|
22
|
+
lon
|
23
|
+
else
|
24
|
+
raise 'Invalid index!'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def +(a_point)
|
29
|
+
nlat = lat + a_point.lat
|
30
|
+
nlon = lon + a_point.lon
|
31
|
+
Point.new lat: nlat, lon: nlon
|
32
|
+
end
|
33
|
+
|
34
|
+
def /(a_scalar)
|
35
|
+
nlat = lat / a_scalar.to_f
|
36
|
+
nlon = lon / a_scalar.to_f
|
37
|
+
Point.new lat: nlat, lon: nlon
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"lat: #{lat}, lon: #{lon}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_a
|
45
|
+
[lat, lon]
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_hash
|
49
|
+
{ lat: lat, lon: lon }
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :to_h, :to_hash
|
53
|
+
|
54
|
+
|
55
|
+
def distance(a_point)
|
56
|
+
p_point = self
|
57
|
+
rad_per_deg, radius_meter = Math::PI/180, RADIUS_KM * 1000
|
58
|
+
|
59
|
+
dlon_rad = (a_point.lon-p_point.lon) * rad_per_deg
|
60
|
+
dlat_rad = (a_point.lat-p_point.lat) * rad_per_deg
|
61
|
+
|
62
|
+
lat1_rad = p_point.lat * rad_per_deg
|
63
|
+
lat2_rad = a_point.lat * rad_per_deg
|
64
|
+
|
65
|
+
p_point = Math.sin(dlat_rad/2)**2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(dlon_rad/2)**2
|
66
|
+
c = 2 * Math::atan2(Math::sqrt(p_point), Math::sqrt(1-p_point))
|
67
|
+
|
68
|
+
radius_meter * c
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module GpxRuby
|
2
|
+
|
3
|
+
module Gpx
|
4
|
+
|
5
|
+
class Track
|
6
|
+
|
7
|
+
attr_accessor :segments, :name, :time,
|
8
|
+
:description, :source, :comment,
|
9
|
+
:number, :url, :url_name
|
10
|
+
|
11
|
+
def initialize(a_hash)
|
12
|
+
@name = a_hash[:name]
|
13
|
+
@time = a_hash[:time]
|
14
|
+
@segments = a_hash[:segments] || []
|
15
|
+
@number = a_hash[:number]
|
16
|
+
@source = a_hash[:source]
|
17
|
+
@url = a_hash[:url]
|
18
|
+
@url_name = a_hash[:url_name]
|
19
|
+
@comment = a_hash[:comment]
|
20
|
+
@description = a_hash[:description]
|
21
|
+
end
|
22
|
+
|
23
|
+
def points
|
24
|
+
@points ||= @segments.map {|segment| segment.points }.reduce(:+)
|
25
|
+
end
|
26
|
+
|
27
|
+
def distance
|
28
|
+
@distance ||= @segments.map {|segment| segment.distance }.reduce(:+)
|
29
|
+
end
|
30
|
+
|
31
|
+
def total_time
|
32
|
+
start_time = @segments.first.points.first.time
|
33
|
+
end_time = @segments.last.points.last.time
|
34
|
+
end_time - start_time rescue 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def center_of_gravity
|
38
|
+
track_points = points
|
39
|
+
len = track_points.size
|
40
|
+
center = track_points.reduce(:+)
|
41
|
+
center / len
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
class Point < Gpx::Point
|
46
|
+
|
47
|
+
attr_accessor :lat, :lon, :time, :elevation
|
48
|
+
|
49
|
+
def initialize(params)
|
50
|
+
@lat = params[:lat]
|
51
|
+
@lon = params[:lon]
|
52
|
+
@time = params[:time]
|
53
|
+
@elevation = params[:elevation]
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_a
|
57
|
+
[@lat,@lon]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
class Segment
|
64
|
+
|
65
|
+
attr_accessor :points
|
66
|
+
|
67
|
+
def initialize(points)
|
68
|
+
@points = points || []
|
69
|
+
end
|
70
|
+
|
71
|
+
def distance
|
72
|
+
if @distance
|
73
|
+
@distance
|
74
|
+
else
|
75
|
+
zipped_points = @points[0...-1].zip(@points[1..-1])
|
76
|
+
distances = zipped_points.map {|(p,q)| p.distance(q) }
|
77
|
+
@distance = distances.reduce(:+)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def total_time
|
82
|
+
start_time, end_time = @points.first.time, @points.last.time
|
83
|
+
end_time - start_time rescue 0
|
84
|
+
end
|
85
|
+
|
86
|
+
def center_of_gravity
|
87
|
+
track_points = points
|
88
|
+
len = track_points.size
|
89
|
+
center = track_points.reduce(:+)
|
90
|
+
center / len
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestGpxParser < MiniTest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@gpx_parser = GpxRuby::Gpx::Parser.new './test/run_keeper.gpx'
|
7
|
+
@gpx_file = @gpx_parser.parse
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_should_read_gpx_file
|
11
|
+
gpx_parser = GpxRuby::Gpx::Parser.new File.open('./test/run_keeper.gpx','r')
|
12
|
+
gpx_file = gpx_parser.parse
|
13
|
+
assert gpx_file.creator
|
14
|
+
assert gpx_file.version
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def test_should_read_gpx_temp_file
|
19
|
+
xml = File.open('./test/run_keeper.gpx','r') { |f| f.read }
|
20
|
+
tmp_file = Tempfile.open('blah.gpx')
|
21
|
+
tmp_file.write xml
|
22
|
+
tmp_file.rewind
|
23
|
+
gpx_parser = GpxRuby::Gpx::Parser.new tmp_file
|
24
|
+
gpx_file = gpx_parser.parse
|
25
|
+
assert gpx_file.creator
|
26
|
+
assert gpx_file.version
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def test_should_read_file_path
|
31
|
+
gpx_parser = GpxRuby::Gpx::Parser.new './test/run_keeper.gpx'
|
32
|
+
gpx_file = gpx_parser.parse
|
33
|
+
assert gpx_file.creator
|
34
|
+
assert gpx_file.version
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def test_should_read_gpx_xml
|
39
|
+
xml = File.open('./test/run_keeper.gpx') do |f|
|
40
|
+
f.read
|
41
|
+
end
|
42
|
+
gpx_parser = GpxRuby::Gpx::Parser.new xml: xml
|
43
|
+
gpx_file = gpx_parser.parse
|
44
|
+
assert gpx_file.creator
|
45
|
+
assert gpx_file.version
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def test_should_read_gpx_xml_using_a_shortcut
|
50
|
+
xml = File.open('./test/run_keeper.gpx') do |f|
|
51
|
+
f.read
|
52
|
+
end
|
53
|
+
gpx_file = GpxRuby::XML(xml)
|
54
|
+
assert gpx_file.creator
|
55
|
+
assert gpx_file.version
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def test_should_read_gpx_file_using_a_shortcut
|
60
|
+
gpx_file = GpxRuby::File './test/run_keeper.gpx'
|
61
|
+
assert gpx_file.creator
|
62
|
+
assert gpx_file.version
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def test_should_compute_center_of_gravity
|
67
|
+
gpx_parser = GpxRuby::Gpx::Parser.new './test/run_keeper.gpx'
|
68
|
+
gpx_file = gpx_parser.parse
|
69
|
+
track = gpx_file.tracks.first
|
70
|
+
pp 'center of gravity: %s' % track.center_of_gravity
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def test_should_read_fell_loops
|
75
|
+
gpx_file = GpxRuby::File './test/gpx_samples/fells_loop.gpx'
|
76
|
+
assert gpx_file.creator
|
77
|
+
assert gpx_file.version
|
78
|
+
track = gpx_file.tracks.first
|
79
|
+
assert track.nil?
|
80
|
+
gpx_file.tracks.each do |track|
|
81
|
+
assert track.name || track.name.nil?
|
82
|
+
assert track.time || track.time.nil?
|
83
|
+
assert track.distance
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def test_should_read_boise_front
|
89
|
+
gpx_file = GpxRuby.File './test/gpx_samples/BoiseFront.gpx'
|
90
|
+
assert gpx_file.creator
|
91
|
+
assert gpx_file.version
|
92
|
+
track = gpx_file.tracks.first
|
93
|
+
assert track.nil? == false
|
94
|
+
assert track.total_time == 0
|
95
|
+
gpx_file.tracks.each do |track|
|
96
|
+
assert track.name || track.name.nil?
|
97
|
+
assert track.time || track.time.nil?
|
98
|
+
assert track.distance
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def test_should_read_track
|
104
|
+
track = @gpx_file.tracks.first
|
105
|
+
assert track
|
106
|
+
assert track.is_a? GpxRuby::Gpx::Track
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def test_should_read_track_segments
|
111
|
+
track = @gpx_file.tracks.first
|
112
|
+
track_segments = track.segments
|
113
|
+
assert track_segments.size == 4
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def test_should_read_track_segment_points
|
118
|
+
track = @gpx_file.tracks.first
|
119
|
+
track_segment = track.segments.last
|
120
|
+
assert track_segment.points.size > 0
|
121
|
+
track_points = track_segment.points
|
122
|
+
track_points.each do |track_point|
|
123
|
+
assert track_point.lat
|
124
|
+
assert track_point.lon
|
125
|
+
assert track_point.elevation
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
def test_should_read_track_points
|
132
|
+
track = @gpx_file.tracks.first
|
133
|
+
assert track
|
134
|
+
assert track.points.size > 0
|
135
|
+
track_points = track.points
|
136
|
+
track_points.each do |track_point|
|
137
|
+
assert track_point.lat
|
138
|
+
assert track_point.lon
|
139
|
+
assert track_point.elevation
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def test_should_compute_total_track_segment_distance
|
145
|
+
track = @gpx_file.tracks.first
|
146
|
+
puts track.segments.map {|segment| segment.distance }
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
def test_should_compute_total_track_distance
|
151
|
+
track = @gpx_file.tracks.first
|
152
|
+
puts track.distance
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
def test_should_compute_total_track_time
|
157
|
+
track = @gpx_file.tracks.first
|
158
|
+
puts track.total_time
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def test_should_compute_total_segment_time
|
163
|
+
track = @gpx_file.tracks.first
|
164
|
+
puts track.segments.map {|segment| segment.total_time }
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gpx_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Rüeedlinger
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.6.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.6.1
|
33
|
+
description: A simple gpx file parser for reading gpx files.
|
34
|
+
email: a.rueedlinger@gmail.com
|
35
|
+
executables: []
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- Rakefile
|
40
|
+
- lib/gpx_ruby.rb
|
41
|
+
- lib/gpx_ruby/gpx/document.rb
|
42
|
+
- lib/gpx_ruby/gpx/parser.rb
|
43
|
+
- lib/gpx_ruby/gpx/parsers/track_parser.rb
|
44
|
+
- lib/gpx_ruby/gpx/point.rb
|
45
|
+
- lib/gpx_ruby/gpx/track.rb
|
46
|
+
- lib/version.rb
|
47
|
+
- test/test_gpx_parser.rb
|
48
|
+
- test/test_helper.rb
|
49
|
+
homepage: http://github.com/lexruee/gpx_ruby
|
50
|
+
licenses:
|
51
|
+
- MIT
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.9.3
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 2.2.2
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: A gpx file parser for reading gpx files.
|
73
|
+
test_files: []
|