gpx 1.0.0 → 1.1.1
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 +4 -4
- data/.github/workflows/ruby.yml +37 -0
- data/.rubocop +1 -0
- data/.rubocop.yml +2 -5
- data/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/.travis.yml +4 -5
- data/CHANGELOG.md +14 -0
- data/Gemfile +2 -0
- data/README.md +21 -5
- data/Rakefile +7 -0
- data/UPGRADING.md +7 -0
- data/bin/gpx_distance +2 -0
- data/bin/gpx_smooth +5 -2
- data/gpx.gemspec +2 -2
- data/lib/gpx/bounds.rb +3 -0
- data/lib/gpx/geo_json.rb +199 -0
- data/lib/gpx/gpx.rb +2 -0
- data/lib/gpx/gpx_file.rb +53 -51
- data/lib/gpx/magellan_track_log.rb +3 -1
- data/lib/gpx/point.rb +5 -1
- data/lib/gpx/route.rb +4 -1
- data/lib/gpx/segment.rb +14 -9
- data/lib/gpx/track.rb +11 -4
- data/lib/gpx/track_point.rb +2 -0
- data/lib/gpx/version.rb +3 -1
- data/lib/gpx/waypoint.rb +3 -0
- data/lib/gpx.rb +3 -1
- data/tests/geojson_files/combined_data.json +68 -0
- data/tests/geojson_files/line_string_data.json +83 -0
- data/tests/geojson_files/multi_line_string_data.json +74 -0
- data/tests/geojson_files/multi_point_data.json +14 -0
- data/tests/geojson_files/point_data.json +22 -0
- data/tests/geojson_test.rb +92 -0
- data/tests/gpx10_test.rb +2 -0
- data/tests/gpx_file_test.rb +2 -0
- data/tests/gpx_files/one_segment_mixed_times.gpx +884 -0
- data/tests/gpx_files/routes_without_names.gpx +29 -0
- data/tests/magellan_test.rb +2 -0
- data/tests/output_test.rb +3 -1
- data/tests/route_test.rb +52 -0
- data/tests/segment_test.rb +13 -1
- data/tests/track_file_test.rb +3 -0
- data/tests/track_point_test.rb +2 -0
- data/tests/track_test.rb +2 -0
- data/tests/waypoint_test.rb +2 -0
- metadata +25 -9
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GPX
|
2
4
|
# This class will parse the lat/lon and time data from a Magellan track log,
|
3
5
|
# which is a NMEA formatted CSV list of points.
|
@@ -49,7 +51,7 @@ module GPX
|
|
49
51
|
lat = -lat if lat_hemi == 'S'
|
50
52
|
|
51
53
|
lon_deg = row[LON][0..2]
|
52
|
-
lon_min = row[LON][3
|
54
|
+
lon_min = row[LON][3..]
|
53
55
|
lon_hemi = row[LON_HEMI]
|
54
56
|
|
55
57
|
lon = lon_deg.to_f + (lon_min.to_f / 60.0)
|
data/lib/gpx/point.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GPX
|
2
4
|
# The base class for all points. Trackpoint and Waypoint both descend from this base class.
|
3
5
|
class Point < Base
|
@@ -10,6 +12,7 @@ module GPX
|
|
10
12
|
# addition, you can pass an XML element to this initializer, and the
|
11
13
|
# relevant info will be parsed out.
|
12
14
|
def initialize(opts = { lat: 0.0, lon: 0.0, elevation: 0.0, time: Time.now })
|
15
|
+
super()
|
13
16
|
@gpx_file = opts[:gpx_file]
|
14
17
|
if opts[:element]
|
15
18
|
elem = opts[:element]
|
@@ -18,7 +21,8 @@ module GPX
|
|
18
21
|
@latr = (D_TO_R * @lat)
|
19
22
|
@lonr = (D_TO_R * @lon)
|
20
23
|
# '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
|
21
|
-
@time = (
|
24
|
+
@time = (
|
25
|
+
begin
|
22
26
|
Time.xmlschema(elem.at('time').inner_text)
|
23
27
|
rescue StandardError
|
24
28
|
nil
|
data/lib/gpx/route.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GPX
|
2
4
|
# A Route in GPX is very similar to a Track, but it is created by a user
|
3
5
|
# from a series of Waypoints, whereas a Track is created by the GPS device
|
@@ -7,10 +9,11 @@ module GPX
|
|
7
9
|
|
8
10
|
# Initialize a Route from a XML::Node.
|
9
11
|
def initialize(opts = {})
|
12
|
+
super()
|
10
13
|
if opts[:gpx_file] && opts[:element]
|
11
14
|
rte_element = opts[:element]
|
12
15
|
@gpx_file = opts[:gpx_file]
|
13
|
-
@name = rte_element.at('name')
|
16
|
+
@name = rte_element.at('name')&.inner_text
|
14
17
|
@points = []
|
15
18
|
rte_element.search('rtept').each do |point|
|
16
19
|
@points << Point.new(element: point, gpx_file: @gpx_file)
|
data/lib/gpx/segment.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GPX
|
2
4
|
# A segment is the basic container in a GPX file. A Segment contains points
|
3
5
|
# (in this lib, they're called TrackPoints). A Track contains Segments. An
|
@@ -10,6 +12,7 @@ module GPX
|
|
10
12
|
# If a XML::Node object is passed-in, this will initialize a new
|
11
13
|
# Segment based on its contents. Otherwise, a blank Segment is created.
|
12
14
|
def initialize(opts = {})
|
15
|
+
super()
|
13
16
|
@gpx_file = opts[:gpx_file]
|
14
17
|
@track = opts[:track]
|
15
18
|
@points = []
|
@@ -22,7 +25,8 @@ module GPX
|
|
22
25
|
@bounds = Bounds.new
|
23
26
|
|
24
27
|
segment_element = opts[:element]
|
25
|
-
return unless segment_element
|
28
|
+
return unless segment_element.is_a?(Nokogiri::XML::Node)
|
29
|
+
|
26
30
|
segment_element.search('trkpt').each do |trkpt|
|
27
31
|
pt = TrackPoint.new(element: trkpt, segment: self, gpx_file: @gpx_file)
|
28
32
|
append_point(pt)
|
@@ -33,8 +37,8 @@ module GPX
|
|
33
37
|
def append_point(pt)
|
34
38
|
last_pt = @points[-1]
|
35
39
|
if pt.time
|
36
|
-
@earliest_point = pt if @earliest_point.nil? || (pt.time < @earliest_point.time)
|
37
|
-
@latest_point = pt if @latest_point.nil? || (pt.time > @latest_point.time)
|
40
|
+
@earliest_point = pt if @earliest_point.nil? || (@earliest_point.time && pt.time < @earliest_point.time)
|
41
|
+
@latest_point = pt if @latest_point.nil? || (@latest_point.time && pt.time > @latest_point.time)
|
38
42
|
else
|
39
43
|
# when no time information in data, we consider the points are ordered
|
40
44
|
@earliest_point = @points[0]
|
@@ -91,6 +95,7 @@ module GPX
|
|
91
95
|
last_pt = nil
|
92
96
|
points.each do |pt|
|
93
97
|
next if yield(pt)
|
98
|
+
|
94
99
|
keep_points << pt
|
95
100
|
update_meta_data(pt, last_pt)
|
96
101
|
last_pt = pt
|
@@ -124,7 +129,7 @@ module GPX
|
|
124
129
|
elsif indicator.is_a?(Time)
|
125
130
|
closest_point(indicator)
|
126
131
|
else
|
127
|
-
raise
|
132
|
+
raise ArgumentError, 'find_end_point_by_time_or_offset requires an argument of type Time or Integer'
|
128
133
|
end
|
129
134
|
end
|
130
135
|
|
@@ -174,9 +179,9 @@ module GPX
|
|
174
179
|
|
175
180
|
protected
|
176
181
|
|
177
|
-
# rubocop:disable Style/GuardClause
|
178
182
|
def find_closest(pts, time)
|
179
183
|
return pts.first if pts.size == 1
|
184
|
+
|
180
185
|
midpoint = pts.size / 2
|
181
186
|
if pts.size == 2
|
182
187
|
diff_1 = pts[0].time - time
|
@@ -184,14 +189,13 @@ module GPX
|
|
184
189
|
return (diff_1 < diff_2 ? pts[0] : pts[1])
|
185
190
|
end
|
186
191
|
if (time >= pts[midpoint].time) && (time <= pts[midpoint + 1].time)
|
187
|
-
|
192
|
+
pts[midpoint]
|
188
193
|
elsif time <= pts[midpoint].time
|
189
|
-
|
194
|
+
find_closest(pts[0..midpoint], time)
|
190
195
|
else
|
191
|
-
|
196
|
+
find_closest(pts[(midpoint + 1)..], time)
|
192
197
|
end
|
193
198
|
end
|
194
|
-
# rubocop:enable Style/GuardClause
|
195
199
|
|
196
200
|
# Calculate the Haversine distance between two points. This is the method
|
197
201
|
# the library uses to calculate the cumulative distance of GPX files.
|
@@ -231,6 +235,7 @@ module GPX
|
|
231
235
|
@bounds.add(pt)
|
232
236
|
|
233
237
|
return unless last_pt
|
238
|
+
|
234
239
|
@distance += haversine_distance(last_pt, pt)
|
235
240
|
@duration += pt.time - last_pt.time if pt.time && last_pt.time
|
236
241
|
end
|
data/lib/gpx/track.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GPX
|
2
4
|
# In GPX, a single Track can hold multiple Segments, each of which hold
|
3
5
|
# multiple points (in this library, those points are instances of
|
@@ -12,6 +14,7 @@ module GPX
|
|
12
14
|
# Initialize a track from a XML::Node, or, if no :element option is
|
13
15
|
# passed, initialize a blank Track object.
|
14
16
|
def initialize(opts = {})
|
17
|
+
super()
|
15
18
|
@gpx_file = opts[:gpx_file]
|
16
19
|
@segments = []
|
17
20
|
@points = []
|
@@ -20,17 +23,20 @@ module GPX
|
|
20
23
|
return unless opts[:element]
|
21
24
|
|
22
25
|
trk_element = opts[:element]
|
23
|
-
@name = (
|
26
|
+
@name = (
|
27
|
+
begin
|
24
28
|
trk_element.at('name').inner_text
|
25
29
|
rescue StandardError
|
26
30
|
''
|
27
31
|
end)
|
28
|
-
@comment = (
|
32
|
+
@comment = (
|
33
|
+
begin
|
29
34
|
trk_element.at('cmt').inner_text
|
30
35
|
rescue StandardError
|
31
36
|
''
|
32
37
|
end)
|
33
|
-
@description = (
|
38
|
+
@description = (
|
39
|
+
begin
|
34
40
|
trk_element.at('desc').inner_text
|
35
41
|
rescue StandardError
|
36
42
|
''
|
@@ -44,6 +50,7 @@ module GPX
|
|
44
50
|
# Append a segment to this track, updating its meta data along the way.
|
45
51
|
def append_segment(seg)
|
46
52
|
return if seg.points.empty?
|
53
|
+
|
47
54
|
update_meta_data(seg)
|
48
55
|
@segments << seg
|
49
56
|
end
|
@@ -88,7 +95,7 @@ module GPX
|
|
88
95
|
# Returns true if this track has no points in it. This should return
|
89
96
|
# true even when the track has empty segments.
|
90
97
|
def empty?
|
91
|
-
(points.nil? || points.
|
98
|
+
(points.nil? || points.empty?)
|
92
99
|
end
|
93
100
|
|
94
101
|
# Prints out a friendly summary of this track (sans points). Useful for
|
data/lib/gpx/track_point.rb
CHANGED
data/lib/gpx/version.rb
CHANGED
data/lib/gpx/waypoint.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GPX
|
2
4
|
# This class supports the concept of a waypoint. Beware that this class has
|
3
5
|
# not seen much use yet, since WalkingBoss does not use waypoints right now.
|
@@ -5,6 +7,7 @@ module GPX
|
|
5
7
|
SUB_ELEMENTS = %w[ele magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid extensions].freeze
|
6
8
|
|
7
9
|
attr_reader :gpx_file
|
10
|
+
|
8
11
|
SUB_ELEMENTS.each { |sub_el| attr_accessor sub_el.to_sym }
|
9
12
|
|
10
13
|
# Not implemented
|
data/lib/gpx.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'time'
|
2
4
|
require 'nokogiri'
|
3
5
|
|
4
6
|
require File.expand_path('gpx/version', __dir__)
|
5
|
-
|
6
7
|
require File.expand_path('gpx/gpx', __dir__)
|
7
8
|
require File.expand_path('gpx/gpx_file', __dir__)
|
8
9
|
require File.expand_path('gpx/bounds', __dir__)
|
@@ -13,3 +14,4 @@ require File.expand_path('gpx/point', __dir__)
|
|
13
14
|
require File.expand_path('gpx/track_point', __dir__)
|
14
15
|
require File.expand_path('gpx/waypoint', __dir__)
|
15
16
|
require File.expand_path('gpx/magellan_track_log', __dir__)
|
17
|
+
require File.expand_path('gpx/geo_json', __dir__)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
{
|
2
|
+
"type": "FeatureCollection",
|
3
|
+
"features": [{
|
4
|
+
"type": "Feature",
|
5
|
+
"geometry": {
|
6
|
+
"type": "LineString",
|
7
|
+
"coordinates": [
|
8
|
+
[-118.41511, 34.06298, 80],
|
9
|
+
[-118.41506, 34.06301, 80],
|
10
|
+
[-118.415, 34.06305, 80],
|
11
|
+
[-118.41494, 34.06309, 80]
|
12
|
+
]
|
13
|
+
}
|
14
|
+
}, {
|
15
|
+
"type": "Feature",
|
16
|
+
"geometry": {
|
17
|
+
"type": "LineString",
|
18
|
+
"coordinates": [
|
19
|
+
[-118.3689, 34.05826, 40],
|
20
|
+
[-118.36894, 34.05818, 40],
|
21
|
+
[-118.369, 34.05806, 40]
|
22
|
+
]
|
23
|
+
}
|
24
|
+
}, {
|
25
|
+
"type": "Feature",
|
26
|
+
"geometry": {
|
27
|
+
"type": "LineString",
|
28
|
+
"coordinates": [
|
29
|
+
[-118.35042, 34.03788, 30],
|
30
|
+
[-118.35046, 34.03779, 30]
|
31
|
+
]
|
32
|
+
}
|
33
|
+
}, {
|
34
|
+
"type": "Feature",
|
35
|
+
"geometry": {
|
36
|
+
"type": "MultiLineString",
|
37
|
+
"coordinates": [
|
38
|
+
[
|
39
|
+
[-118.41511, 34.06298, 80],
|
40
|
+
[-118.41506, 34.06301, 80],
|
41
|
+
[-118.415, 34.06305, 80],
|
42
|
+
[-118.41494, 34.06309, 80]
|
43
|
+
],
|
44
|
+
[
|
45
|
+
[-118.3689, 34.05826, 40],
|
46
|
+
[-118.36894, 34.05818, 40],
|
47
|
+
[-118.369, 34.05806, 40]
|
48
|
+
]
|
49
|
+
]
|
50
|
+
}
|
51
|
+
}, {
|
52
|
+
"type": "Feature",
|
53
|
+
"geometry": {
|
54
|
+
"type": "Point",
|
55
|
+
"coordinates": [-118.41585, 34.06253, 80]
|
56
|
+
}
|
57
|
+
}, {
|
58
|
+
"type": "Feature",
|
59
|
+
"geometry": {
|
60
|
+
"type": "MultiPoint",
|
61
|
+
"coordinates": [
|
62
|
+
[-118.41585, 34.06253, 80],
|
63
|
+
[-118.4158, 34.06256, 80],
|
64
|
+
[-118.41575, 34.06259, 80]
|
65
|
+
]
|
66
|
+
}
|
67
|
+
}]
|
68
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
{
|
2
|
+
"type": "FeatureCollection",
|
3
|
+
"features": [{
|
4
|
+
"type": "Feature",
|
5
|
+
"geometry": {
|
6
|
+
"type": "LineString",
|
7
|
+
"coordinates": [
|
8
|
+
[-118.41585, 34.06253, 80],
|
9
|
+
[-118.4158, 34.06256, 80],
|
10
|
+
[-118.41575, 34.06259, 80],
|
11
|
+
[-118.4157, 34.06262, 80],
|
12
|
+
[-118.41566, 34.06265, 80],
|
13
|
+
[-118.41561, 34.06268, 80],
|
14
|
+
[-118.41556, 34.06271, 80],
|
15
|
+
[-118.41551, 34.06274, 80],
|
16
|
+
[-118.41546, 34.06277, 80],
|
17
|
+
[-118.41541, 34.0628, 80],
|
18
|
+
[-118.41536, 34.06283, 80],
|
19
|
+
[-118.41531, 34.06286, 80],
|
20
|
+
[-118.41526, 34.06289, 80],
|
21
|
+
[-118.41521, 34.06292, 80],
|
22
|
+
[-118.41516, 34.06295, 80],
|
23
|
+
[-118.41511, 34.06298, 80],
|
24
|
+
[-118.41506, 34.06301, 80],
|
25
|
+
[-118.415, 34.06305, 80],
|
26
|
+
[-118.41494, 34.06309, 80]
|
27
|
+
]
|
28
|
+
}
|
29
|
+
}, {
|
30
|
+
"type": "Feature",
|
31
|
+
"geometry": {
|
32
|
+
"type": "LineString",
|
33
|
+
"coordinates": [
|
34
|
+
[-118.36855, 34.05844, 40],
|
35
|
+
[-118.36849, 34.05843, 40],
|
36
|
+
[-118.36843, 34.05842, 40],
|
37
|
+
[-118.36837, 34.05841, 40],
|
38
|
+
[-118.36906, 34.05878, 40],
|
39
|
+
[-118.36895, 34.05877, 40],
|
40
|
+
[-118.36884, 34.05876, 40],
|
41
|
+
[-118.36873, 34.05875, 40],
|
42
|
+
[-118.36866, 34.05874, 40],
|
43
|
+
[-118.3687, 34.05866, 40],
|
44
|
+
[-118.36874, 34.05858, 40],
|
45
|
+
[-118.36878, 34.0585, 40],
|
46
|
+
[-118.36882, 34.05842, 40],
|
47
|
+
[-118.36886, 34.05834, 40],
|
48
|
+
[-118.3689, 34.05826, 40],
|
49
|
+
[-118.36894, 34.05818, 40],
|
50
|
+
[-118.369, 34.05806, 40]
|
51
|
+
]
|
52
|
+
}
|
53
|
+
}, {
|
54
|
+
"type": "Feature",
|
55
|
+
"geometry": {
|
56
|
+
"type": "LineString",
|
57
|
+
"coordinates": [
|
58
|
+
[-118.35043, 34.0392, 30],
|
59
|
+
[-118.35047, 34.03911, 30],
|
60
|
+
[-118.35051, 34.03902, 30],
|
61
|
+
[-118.35055, 34.03893, 30],
|
62
|
+
[-118.35057, 34.03887, 30],
|
63
|
+
[-118.35045, 34.03885, 30],
|
64
|
+
[-118.35033, 34.03883, 30],
|
65
|
+
[-118.35021, 34.03881, 30],
|
66
|
+
[-118.35009, 34.03879, 30],
|
67
|
+
[-118.35002, 34.03878, 30],
|
68
|
+
[-118.35006, 34.03869, 30],
|
69
|
+
[-118.3501, 34.0386, 30],
|
70
|
+
[-118.35014, 34.03851, 30],
|
71
|
+
[-118.35018, 34.03842, 30],
|
72
|
+
[-118.35022, 34.03833, 30],
|
73
|
+
[-118.35026, 34.03824, 30],
|
74
|
+
[-118.3503, 34.03815, 30],
|
75
|
+
[-118.35034, 34.03806, 30],
|
76
|
+
[-118.35038, 34.03797, 30],
|
77
|
+
[-118.35042, 34.03788, 30],
|
78
|
+
[-118.35046, 34.03779, 30],
|
79
|
+
[-118.3505, 34.03768, 30]
|
80
|
+
]
|
81
|
+
}
|
82
|
+
}]
|
83
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
{
|
2
|
+
"type": "FeatureCollection",
|
3
|
+
"features": [{
|
4
|
+
"type": "Feature",
|
5
|
+
"geometry": {
|
6
|
+
"type": "MultiLineString",
|
7
|
+
"coordinates": [
|
8
|
+
[
|
9
|
+
[-118.41585, 34.06253, 80],
|
10
|
+
[-118.4158, 34.06256, 80],
|
11
|
+
[-118.41575, 34.06259, 80],
|
12
|
+
[-118.4157, 34.06262, 80],
|
13
|
+
[-118.41566, 34.06265, 80],
|
14
|
+
[-118.41561, 34.06268, 80],
|
15
|
+
[-118.41556, 34.06271, 80],
|
16
|
+
[-118.41551, 34.06274, 80],
|
17
|
+
[-118.41546, 34.06277, 80],
|
18
|
+
[-118.41541, 34.0628, 80],
|
19
|
+
[-118.41536, 34.06283, 80],
|
20
|
+
[-118.41531, 34.06286, 80],
|
21
|
+
[-118.41526, 34.06289, 80],
|
22
|
+
[-118.41521, 34.06292, 80],
|
23
|
+
[-118.41516, 34.06295, 80],
|
24
|
+
[-118.41511, 34.06298, 80],
|
25
|
+
[-118.41506, 34.06301, 80],
|
26
|
+
[-118.415, 34.06305, 80],
|
27
|
+
[-118.41494, 34.06309, 80]
|
28
|
+
],
|
29
|
+
[
|
30
|
+
[-118.36855, 34.05844, 40],
|
31
|
+
[-118.36849, 34.05843, 40],
|
32
|
+
[-118.36843, 34.05842, 40],
|
33
|
+
[-118.36837, 34.05841, 40],
|
34
|
+
[-118.36906, 34.05878, 40],
|
35
|
+
[-118.36895, 34.05877, 40],
|
36
|
+
[-118.36884, 34.05876, 40],
|
37
|
+
[-118.36873, 34.05875, 40],
|
38
|
+
[-118.36866, 34.05874, 40],
|
39
|
+
[-118.3687, 34.05866, 40],
|
40
|
+
[-118.36874, 34.05858, 40],
|
41
|
+
[-118.36878, 34.0585, 40],
|
42
|
+
[-118.36882, 34.05842, 40],
|
43
|
+
[-118.36886, 34.05834, 40],
|
44
|
+
[-118.3689, 34.05826, 40],
|
45
|
+
[-118.36894, 34.05818, 40],
|
46
|
+
[-118.369, 34.05806, 40]
|
47
|
+
],
|
48
|
+
[
|
49
|
+
[-118.35043, 34.0392, 30],
|
50
|
+
[-118.35047, 34.03911, 30],
|
51
|
+
[-118.35051, 34.03902, 30],
|
52
|
+
[-118.35055, 34.03893, 30],
|
53
|
+
[-118.35057, 34.03887, 30],
|
54
|
+
[-118.35045, 34.03885, 30],
|
55
|
+
[-118.35033, 34.03883, 30],
|
56
|
+
[-118.35021, 34.03881, 30],
|
57
|
+
[-118.35009, 34.03879, 30],
|
58
|
+
[-118.35002, 34.03878, 30],
|
59
|
+
[-118.35006, 34.03869, 30],
|
60
|
+
[-118.3501, 34.0386, 30],
|
61
|
+
[-118.35014, 34.03851, 30],
|
62
|
+
[-118.35018, 34.03842, 30],
|
63
|
+
[-118.35022, 34.03833, 30],
|
64
|
+
[-118.35026, 34.03824, 30],
|
65
|
+
[-118.3503, 34.03815, 30],
|
66
|
+
[-118.35034, 34.03806, 30],
|
67
|
+
[-118.35038, 34.03797, 30],
|
68
|
+
[-118.35042, 34.03788, 30],
|
69
|
+
[-118.35046, 34.03779, 30],
|
70
|
+
[-118.3505, 34.03768, 30]
|
71
|
+
]]
|
72
|
+
}
|
73
|
+
}]
|
74
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"type": "FeatureCollection",
|
3
|
+
"features": [{
|
4
|
+
"type": "Feature",
|
5
|
+
"geometry": {
|
6
|
+
"type": "Point",
|
7
|
+
"coordinates": [-118.41585, 34.06253, 80]
|
8
|
+
}
|
9
|
+
}, {
|
10
|
+
"type": "Feature",
|
11
|
+
"geometry": {
|
12
|
+
"type": "Point",
|
13
|
+
"coordinates": [-118.36855, 34.05844, 40]
|
14
|
+
}
|
15
|
+
}, {
|
16
|
+
"type": "Feature",
|
17
|
+
"geometry": {
|
18
|
+
"type": "Point",
|
19
|
+
"coordinates": [-118.35043, 34.0392, 30]
|
20
|
+
}
|
21
|
+
}]
|
22
|
+
}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'gpx'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
class GeojsonTest < Minitest::Test
|
8
|
+
# Test passing a file name
|
9
|
+
def test_geojson_file_name_as_param
|
10
|
+
file_name = "#{File.dirname(__FILE__)}/geojson_files/line_string_data.json"
|
11
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file_name)
|
12
|
+
assert_equal(1, gpx_file.tracks.size)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Test passing a file
|
16
|
+
def test_geojson_file_as_param
|
17
|
+
file_name = "#{File.dirname(__FILE__)}/geojson_files/line_string_data.json"
|
18
|
+
file = File.new(file_name, 'r')
|
19
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
20
|
+
assert_equal(1, gpx_file.tracks.size)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_raises_arg_error_when_no_params
|
24
|
+
assert_raises(ArgumentError) do
|
25
|
+
GPX::GeoJSON.convert_to_gpx
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Test that lat/lon allocated correctly
|
30
|
+
def test_point_to_waypoint
|
31
|
+
pt = [-118, 34]
|
32
|
+
waypoint = GPX::GeoJSON.send(:point_to_waypoint, pt, nil)
|
33
|
+
assert_equal(34, waypoint.lat)
|
34
|
+
assert_equal(-118, waypoint.lon)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Test that lat/lon allocated correctly
|
38
|
+
def test_point_to_trackpoint
|
39
|
+
pt = [-118, 34]
|
40
|
+
waypoint = GPX::GeoJSON.send(:point_to_track_point, pt, nil)
|
41
|
+
assert_equal(34, waypoint.lat)
|
42
|
+
assert_equal(-118, waypoint.lon)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_line_string_functionality
|
46
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/line_string_data.json')
|
47
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
48
|
+
|
49
|
+
assert_equal(1, gpx_file.tracks.size)
|
50
|
+
assert_equal(3, gpx_file.tracks.first.segments.size)
|
51
|
+
pts_size = gpx_file.tracks.first.segments[0].points.size +
|
52
|
+
gpx_file.tracks.first.segments[1].points.size +
|
53
|
+
gpx_file.tracks.first.segments[2].points.size
|
54
|
+
assert_equal(58, pts_size)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_multi_line_string_functionality
|
58
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/multi_line_string_data.json')
|
59
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
60
|
+
assert_equal(1, gpx_file.tracks.size)
|
61
|
+
assert_equal(3, gpx_file.tracks.first.segments.size)
|
62
|
+
pts_size = gpx_file.tracks.first.segments[0].points.size +
|
63
|
+
gpx_file.tracks.first.segments[1].points.size +
|
64
|
+
gpx_file.tracks.first.segments[2].points.size
|
65
|
+
assert_equal(58, pts_size)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_point_functionality
|
69
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/point_data.json')
|
70
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
71
|
+
assert_equal(3, gpx_file.waypoints.size)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_multi_point_functionality
|
75
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/multi_point_data.json')
|
76
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
77
|
+
assert_equal(3, gpx_file.waypoints.size)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_combined_functionality
|
81
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/combined_data.json')
|
82
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
83
|
+
|
84
|
+
# 1 for all LineStrings, 1 for MultiLineString
|
85
|
+
assert_equal(2, gpx_file.tracks.size)
|
86
|
+
assert_equal(3, gpx_file.tracks.first.segments.size)
|
87
|
+
assert_equal(2, gpx_file.tracks.last.segments.size)
|
88
|
+
pt_sum = gpx_file.tracks.inject(0) { |sum, trk| sum + trk.points.size }
|
89
|
+
assert_equal(16, pt_sum)
|
90
|
+
assert_equal(4, gpx_file.waypoints.size)
|
91
|
+
end
|
92
|
+
end
|
data/tests/gpx10_test.rb
CHANGED