gpx2hash 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 91b44c19cbdd746f5289bb07f340fc42fe22d39c
4
+ data.tar.gz: fe448106ceb0b59ffd6f6cb77de70b6b07ed5028
5
+ SHA512:
6
+ metadata.gz: 0145b46834d2b63c06150707c11d1b9fa3a271c9a8ff1838644a3dc714e12dd0797dec47877f19e060a35ffb7b2f3fd634281f048ac257c63aceaae9ba485dd8
7
+ data.tar.gz: 8d08c7f26c6a6ba7bf36b7d2b7687bff3eb8737c45882bcf7c9022b75c8dfdbf7fd278e0840b33a154b63e6b70f1f06073b234222b22aa21ecdeb7ead6616962
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
35
+
36
+ # From bundler
37
+ /.bundle/
38
+ /.yardoc
39
+ /Gemfile.lock
40
+ /_yardoc/
41
+ /coverage/
42
+ /doc/
43
+ /pkg/
44
+ /spec/reports/
45
+ /tmp/
46
+ *.bundle
47
+ *.so
48
+ *.o
49
+ *.a
50
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gpx2hash.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Collin Price
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,34 @@
1
+ # Gpx2hash
2
+
3
+ Simple Ruby library that converts a GPX 1.1 file into a Hash.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'gpx2hash'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install gpx2hash
20
+
21
+ ## Usage
22
+
23
+ require 'gpx2hash'
24
+
25
+ # Read in GPX file.
26
+ Gpx2hash.readFile "file.gpx"
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it ( https://github.com/[my-github-username]/gpx2hash/fork )
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create a new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gpx2hash/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gpx2hash"
8
+ spec.version = Gpx2hash::VERSION
9
+ spec.authors = ["Collin Price"]
10
+ spec.email = ["collin@collinprice.com"]
11
+ spec.summary = "Simple Ruby library that converts a GPX file into a Hash."
12
+ spec.description = "Simple Ruby library that converts a GPX file into a Hash."
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec"
24
+
25
+ spec.add_runtime_dependency "nokogiri"
26
+
27
+ end
@@ -0,0 +1,13 @@
1
+ require "gpx2hash/version"
2
+ require "gpx2hash/gpx2hash_parser.rb"
3
+
4
+ module Gpx2hash
5
+
6
+ def self.readFile file
7
+ Gpx2hashParser.new.readFile file
8
+ end
9
+
10
+ def self.readString file
11
+ Gpx2hashParser.new.readString file
12
+ end
13
+ end
@@ -0,0 +1,151 @@
1
+ require 'nokogiri'
2
+
3
+ module Gpx2hash
4
+
5
+ class Gpx2hashParser
6
+
7
+ def readFile file
8
+ if File.exist? file
9
+ gpxData = File.read file
10
+ parseString gpxData
11
+ else
12
+ false
13
+ end
14
+ end
15
+
16
+ def readString gpxData
17
+ parseString gpxData
18
+ end
19
+
20
+ private
21
+
22
+ def parseString data
23
+
24
+ # Parse DOM
25
+ dom = (Nokogiri::XML data.gsub("\n\t", ""))
26
+ dom.encoding = 'utf-8' # HACK: (Maybe) Might cause a bug in the future. 'xpath' did not like XML documents encoded in UTF-8.
27
+
28
+ # Check if valid xml file.
29
+ if dom.children.length == 0 || dom.root.name != "gpx"
30
+ return false
31
+ end
32
+
33
+ dom = dom.root
34
+
35
+ # Remove whitespace
36
+ dom.xpath('//text()').each do |node|
37
+ if node.content=~/\S/
38
+ node.content = node.content.strip
39
+ else
40
+ node.remove
41
+ end
42
+ end
43
+
44
+ # Remove comments
45
+ dom.xpath('//comment()').each do |node|
46
+ node.remove
47
+ end
48
+
49
+ gpxHash = {}
50
+
51
+ dom.children.each do |child|
52
+
53
+ case child.name
54
+ when "metadata"
55
+ gpxHash[:metadata] = parseNode child
56
+ when "wpt"
57
+ if !gpxHash.has_key? :wpt
58
+ gpxHash[:wpt] = Array.new
59
+ end
60
+ gpxHash[:wpt].push parseNode child
61
+ when "rte"
62
+ if !gpxHash.has_key? :rte
63
+ gpxHash[:rte] = Array.new
64
+ end
65
+ gpxHash[:rte].push parseRoutes child
66
+ when "trk"
67
+ if !gpxHash.has_key? :trk
68
+ gpxHash[:trk] = Array.new
69
+ end
70
+ gpxHash[:trk].push parseTracks child
71
+ end
72
+ end
73
+
74
+ gpxHash
75
+ end
76
+
77
+ def parseTracks trackNode
78
+
79
+ # Extract route points
80
+ trackSegments = Array.new
81
+ trackNode.children.each do |child|
82
+ if child.name == 'trkseg'
83
+ trackSegments.push child
84
+ end
85
+ end
86
+
87
+ # Create route with metadata
88
+ track = parseNode trackNode
89
+
90
+ # Remove meaningless trkseg
91
+ track.delete :trkseg
92
+
93
+ # Add real trkseg
94
+ track[:trkseg] = Array.new
95
+ trackSegments.each do |trackSegment|
96
+ segment = Array.new
97
+ trackSegment.children.each do |point|
98
+ next if point.name == "extensions" # Skip extensions
99
+ segment.push parseNode point
100
+ end
101
+ track[:trkseg].push segment
102
+ end
103
+
104
+ track
105
+ end
106
+
107
+ def parseRoutes routeNode
108
+
109
+ # Extract route points
110
+ routePoints = Array.new
111
+ routeNode.children.each do |child|
112
+ if child.name == 'rtept'
113
+ routePoints.push child
114
+ end
115
+ end
116
+
117
+ # Create route with metadata
118
+ route = parseNode routeNode
119
+
120
+ # Remove meaningless rtept
121
+ route.delete :rtept
122
+
123
+ # Add real rtepts
124
+ route[:rtept] = Array.new
125
+ routePoints.each do |point|
126
+ route[:rtept].push parseNode point
127
+ end
128
+
129
+ route
130
+ end
131
+
132
+ def parseNode node
133
+
134
+ # Return if node only contains text.
135
+ if node.children.length == 1 && (node.children.first.is_a? Nokogiri::XML::Text)
136
+ return node.content
137
+ end
138
+ hash = {}
139
+
140
+ node.attributes.each do |attr|
141
+ hash[attr.last.name.to_sym] = attr.last.value
142
+ end
143
+
144
+ node.children.each do |child|
145
+ hash[child.name.to_sym] = parseNode child
146
+ end
147
+
148
+ hash
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,3 @@
1
+ module Gpx2hash
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gpx2hash do
4
+
5
+ INVALID_FILE = File.join(File.dirname(__FILE__), "gpx_files/invalid_file.gpx")
6
+ ONE_TRACK = File.join(File.dirname(__FILE__), "gpx_files/one_track.gpx")
7
+ ONE_ROUTE = File.join(File.dirname(__FILE__), "gpx_files/one_route.gpx")
8
+ ONE_WAYPOINT = File.join(File.dirname(__FILE__), "gpx_files/one_waypoint.gpx")
9
+ META = File.join(File.dirname(__FILE__), "gpx_files/meta.gpx")
10
+
11
+ it 'missing file' do
12
+ expect(Gpx2hash.readFile("file.gpx")).to be false
13
+ end
14
+
15
+ it 'invalid file' do
16
+ expect(Gpx2hash.readFile(INVALID_FILE)).to be false
17
+ end
18
+
19
+ it 'parse meta' do
20
+ output = Gpx2hash.readFile(META)
21
+
22
+ expect(output).to be_a_kind_of(Hash)
23
+ expect(output.has_key? :metadata).to be true
24
+ end
25
+
26
+ it 'parse waypoint' do
27
+ output = Gpx2hash.readFile(ONE_WAYPOINT)
28
+
29
+ expect(output).to be_a_kind_of(Hash)
30
+ expect(output.has_key? :wpt).to be true
31
+ expect(output[:wpt].length).to equal(1)
32
+ end
33
+
34
+ it 'parse route' do
35
+ output = Gpx2hash.readFile(ONE_ROUTE)
36
+
37
+ expect(output).to be_a_kind_of(Hash)
38
+ expect(output.has_key? :rte).to be true
39
+ expect(output[:rte].length).to equal(1)
40
+ end
41
+
42
+ it 'parse track' do
43
+ output = Gpx2hash.readFile(ONE_TRACK)
44
+
45
+ expect(output).to be_a_kind_of(Hash)
46
+ expect(output.has_key? :trk).to be true
47
+ expect(output[:trk].length).to equal(1)
48
+ end
49
+
50
+ end
@@ -0,0 +1,3 @@
1
+ Rhoncus, integer enim augue! Sit a! Facilisis nisi ac augue vel elit! Nunc diam, a, augue et lorem, quis egestas cras nec, augue etiam vel, diam placerat ac vel est, scelerisque elementum, scelerisque a ac penatibus, dignissim purus porta rhoncus, augue ac platea ultrices aliquet proin et ac ridiculus a dapibus est velit nec, lectus porttitor sociis vel scelerisque a, lectus nunc vel rhoncus! Magna ac amet augue porta elementum, ridiculus etiam amet turpis arcu mattis, porttitor, elementum! Eros adipiscing, penatibus phasellus egestas urna? Phasellus? Penatibus sed aenean a cursus lorem, in sit tincidunt arcu eros. Augue lacus! Ridiculus urna ac nunc, egestas mauris! Duis, rhoncus sociis placerat! Odio porta tincidunt montes, dictumst pid parturient. Mid porta pid tortor integer.
2
+
3
+ Et augue tempor egestas penatibus enim dolor augue nascetur lacus pid? Augue sit montes cum cum montes, odio nunc! Vel, magnis placerat magnis? Diam aliquam egestas in, ridiculus vel, egestas hac et elementum! Ac, porta? Cursus porta habitasse elit penatibus sit turpis porttitor et, eros pulvinar lundium? Sociis porta porttitor proin dolor scelerisque. A porttitor, facilisis, magna odio ultricies? Ut augue, diam porta montes! Integer. Pid urna pid et augue augue. Aenean tincidunt, ultrices turpis adipiscing proin cursus dignissim! Dictumst ultrices, mus tincidunt, habitasse velit integer ridiculus et. Adipiscing, est mauris augue pid augue dignissim, in odio scelerisque parturient. Nisi dignissim, tristique tortor, a adipiscing placerat cum scelerisque in tortor ac! Tempor augue porttitor, in vut auctor lundium enim.
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
2
+ <gpx xmlns="http://www.topografix.com/GPX/1/1" creator="MapSource 6.13.7" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
3
+
4
+ <metadata>
5
+ <name>tsts</name>
6
+ <link href="http://www.garmin.com">
7
+ <text>Garmin International</text>
8
+ </link>
9
+ <time>2012-07-28T19:17:22Z</time>
10
+ <bounds maxlat="49.0398650" maxlon="-76.1574945" minlat="44.4412422" minlon="-88.4402670"/>
11
+ </metadata>
12
+
13
+ </gpx>
@@ -0,0 +1,148 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
2
+ <gpx xmlns="http://www.topografix.com/GPX/1/1" creator="MapSource 6.13.7" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
3
+ <rte>
4
+ <name>LONG LOOP</name>
5
+ <desc>The long loop around the Mystic River, with stops at Draw Seven Park and the MBTA yard at Wellington Station (Orange Line). Crosses Route 28 twice</desc>
6
+ <url>http://www.the-ville.com/mysticview/mw-0900-walkintro.htm</url>
7
+ <urlname>Mystic Riverfront Walking Tour</urlname>
8
+ <number>1</number>
9
+ <rtept lat="42.405495" lon="-71.098364">
10
+ <name>LOOP</name>
11
+ <cmt>STARTING POINT FOR LOOP TRAILS</cmt>
12
+ <desc>Starting point for the Mystic River loop trails.</desc>
13
+ <sym>Trail Head</sym>
14
+ <type>Junction</type>
15
+ </rtept>
16
+ <rtept lat="42.399567" lon="-71.092750">
17
+ <name>THE BEACH</name>
18
+ <cmt>SOMERVILLE BEACH</cmt>
19
+ <desc>The "Somerville Beach"
20
+ People actually used to swim here. Now only shopping carts do.</desc>
21
+ <sym>Swimming Area</sym>
22
+ <type>Beach</type>
23
+ </rtept>
24
+ <rtept lat="42.398467" lon="-71.090467">
25
+ <name>BLESSING</name>
26
+ <cmt>BLESSING OF THE BAY</cmt>
27
+ <desc>The Blessing of the Bay Boathouse, now run by the Somerville Boys and Girls Club.
28
+ A dock with small boats for the children of Somerville. Check out the Mystic River mural at the intersection of Shore Drive and Rt 16!</desc>
29
+ <url>http://www.everydaydesign.com/ourtown/bay.html</url>
30
+ <urlname>Boat-building on the Mystic River</urlname>
31
+ <sym>Boat Ramp</sym>
32
+ <type>Boat Launch</type>
33
+ </rtept>
34
+ <rtept lat="42.397427" lon="-71.084487">
35
+ <name>CROSSWALK1</name>
36
+ <cmt>CROSSWALK</cmt>
37
+ <desc>Crosswalk</desc>
38
+ <sym>Dot</sym>
39
+ <type>Crosswalk</type>
40
+ </rtept>
41
+ <rtept lat="42.395889" lon="-71.077949">
42
+ <name>YACHT CLUB</name>
43
+ <cmt>WINTER HILL YACHT CLUB</cmt>
44
+ <desc>Winter Hill Yacht Club</desc>
45
+ <sym>Boat Ramp</sym>
46
+ <type>Boat Launch</type>
47
+ </rtept>
48
+ <rtept lat="42.393050" lon="-71.076367">
49
+ <name>DRAW7PK</name>
50
+ <cmt>DRAW SEVEN PARK</cmt>
51
+ <desc>Draw Seven Park</desc>
52
+ <sym>Park</sym>
53
+ <type>Park</type>
54
+ </rtept>
55
+ <rtept lat="42.394800" lon="-71.075300">
56
+ <ele>10.942320</ele>
57
+ <time>2002-03-06T00:13:13Z</time>
58
+ <name>EARHARTDAM</name>
59
+ <cmt>AMELIA EARHART DAM</cmt>
60
+ <desc>Amelia Earhart Dam</desc>
61
+ <sym>Dam</sym>
62
+ <type>Dam</type>
63
+ </rtept>
64
+ <rtept lat="42.396994" lon="-71.081137">
65
+ <ele>10.698480</ele>
66
+ <time>2002-03-12T03:34:43Z</time>
67
+ <name>BLOCK 1</name>
68
+ <desc>Concrete platform looking out onto the Mystic</desc>
69
+ <sym>Scenic Area</sym>
70
+ <type>Overlook</type>
71
+ </rtept>
72
+ <rtept lat="42.399733" lon="-71.083567">
73
+ <name>RT 28</name>
74
+ <cmt>WELLINGTON BRIDGE</cmt>
75
+ <desc>Wellington Bridge
76
+ Route 28 crosses the Mystic River on this 6 lane bridge. Pedestrian walkways on both sides. Access to the Assembly Square mall is at the south end of the bridge.</desc>
77
+ <sym>Bridge</sym>
78
+ <type>Bridge</type>
79
+ </rtept>
80
+ <rtept lat="42.400554" lon="-71.079901">
81
+ <name>WELL YACHT</name>
82
+ <cmt>WELLINGTON YACHT CLUB</cmt>
83
+ <desc>Mystic Wellington Yacht Club</desc>
84
+ <sym>Boat Ramp</sym>
85
+ <type>Boat Launch</type>
86
+ </rtept>
87
+ <rtept lat="42.397885" lon="-71.077115">
88
+ <name>WELLING PT</name>
89
+ <desc>Wellington Point
90
+ The bike trail is unpaved beyond this point. A dirt road continues under the railroad bridge. Continue at your own risk...</desc>
91
+ <sym>Danger Area</sym>
92
+ <type>Dead End</type>
93
+ </rtept>
94
+ <rtept lat="42.400554" lon="-71.079901">
95
+ <name>WELL YACHT</name>
96
+ <cmt>WELLINGTON YACHT CLUB</cmt>
97
+ <desc>Mystic Wellington Yacht Club</desc>
98
+ <sym>Boat Ramp</sym>
99
+ <type>Boat Launch</type>
100
+ </rtept>
101
+ <rtept lat="42.402251" lon="-71.082654">
102
+ <name>CROSSWALK2</name>
103
+ <desc>Crosswalk</desc>
104
+ <sym>Dot</sym>
105
+ <type>Crosswalk</type>
106
+ </rtept>
107
+ <rtept lat="42.404429" lon="-71.085691">
108
+ <name>PARKING</name>
109
+ <cmt>PARKING LOT</cmt>
110
+ <desc>Parking Lot</desc>
111
+ <sym>Parking Area</sym>
112
+ <type>Parking</type>
113
+ </rtept>
114
+ <rtept lat="42.401150" lon="-71.088767">
115
+ <ele>6.370320</ele>
116
+ <time>2002-03-08T04:10:57Z</time>
117
+ <name>FISH DOCK</name>
118
+ <cmt>FISHING DOCK</cmt>
119
+ <desc>A wooden fishing dock along the Mystic River in the middle of Torbert McDonald Park.</desc>
120
+ <sym>Anchor</sym>
121
+ <type>Dock</type>
122
+ </rtept>
123
+ <rtept lat="42.403600" lon="-71.091383">
124
+ <ele>8.778240</ele>
125
+ <time>2002-03-08T04:10:57Z</time>
126
+ <name>OBS TOWER</name>
127
+ <cmt>OBSERVATION TOWER</cmt>
128
+ <desc>Observation Tower in Torbert McDonald Park.
129
+ There are good views of the river from atop the wooden observation tower.</desc>
130
+ <sym>Tall Tower</sym>
131
+ <type>Tower</type>
132
+ </rtept>
133
+ <rtept lat="42.405850" lon="-71.096483">
134
+ <name>RT 16</name>
135
+ <cmt>LAWRENCE BRIDGE</cmt>
136
+ <desc>General Lawrence Bridge. Route 16 crosses the Mystic River. The bike path continues under the bridge on the east side of the river, but is currently torn up by construction near Hormel Stadium.</desc>
137
+ <sym>Bridge</sym>
138
+ <type>Bridge</type>
139
+ </rtept>
140
+ <rtept lat="42.405495" lon="-71.098364">
141
+ <name>LOOP</name>
142
+ <cmt>STARTING POINT FOR LOOP TRAILS</cmt>
143
+ <desc>Starting point for the Mystic River loop trails.</desc>
144
+ <sym>Trail Head</sym>
145
+ <type>Junction</type>
146
+ </rtept>
147
+ </rte>
148
+ </gpx>