gpx 1.1.1 → 1.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +2 -2
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +6 -0
- data/README.md +32 -6
- data/lib/gpx/bounds.rb +1 -1
- data/lib/gpx/geo_json.rb +30 -16
- data/lib/gpx/gpx_file.rb +1 -4
- data/lib/gpx/route.rb +1 -1
- data/lib/gpx/segment.rb +2 -2
- data/lib/gpx/track.rb +1 -1
- data/lib/gpx/version.rb +1 -1
- data/tests/geojson_files/line_string_data.json +11 -2
- data/tests/geojson_files/multi_line_string_data.json +3 -0
- data/tests/geojson_files/multi_point_data.json +3 -0
- data/tests/geojson_files/point_data.json +9 -0
- data/tests/geojson_test.rb +63 -0
- data/tests/gpx_file_test.rb +34 -29
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94b41dda1f7722e6a90e261b66420e08074a953c866f7c4b32947ff41046bbcb
|
4
|
+
data.tar.gz: 8aec6ca78168bab0c9ec5dd1d8e689387cfe700aa4b3984639ba9d8f9bcf4095
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96c15693a26a49344ffb7e552d352fc342ee033af8cf62219295e4b3a3334ee9a3ceb201c168a4fbd079647714e0e10dd8a5653842c5ac1c2ce5442946622063
|
7
|
+
data.tar.gz: 9e30c74ad0165287406fa0c322651fd8ab326bdf712f8563097c11451bb7601cc245acc4b74cc5d9d40e059126583ce421df0c4950183bc36833add6f5862db2
|
data/.github/workflows/ruby.yml
CHANGED
@@ -24,12 +24,12 @@ jobs:
|
|
24
24
|
ruby-version: ['2.7', '3.0', '3.1', '3.2']
|
25
25
|
|
26
26
|
steps:
|
27
|
-
- uses: actions/checkout@
|
27
|
+
- uses: actions/checkout@v4
|
28
28
|
- name: Set up Ruby
|
29
29
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
30
30
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
31
31
|
# uses: ruby/setup-ruby@v1
|
32
|
-
uses: ruby/setup-ruby@v1.
|
32
|
+
uses: ruby/setup-ruby@v1.159.0
|
33
33
|
with:
|
34
34
|
ruby-version: ${{ matrix.ruby-version }}
|
35
35
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
data/.rubocop.yml
CHANGED
@@ -65,6 +65,9 @@ Style/NegatedWhile:
|
|
65
65
|
Enabled: false
|
66
66
|
StyleGuide: http://relaxed.ruby.style/#stylenegatedwhile
|
67
67
|
|
68
|
+
Style/OptionalBooleanParameter:
|
69
|
+
Enabled: false
|
70
|
+
|
68
71
|
Style/ParallelAssignment:
|
69
72
|
Enabled: false
|
70
73
|
StyleGuide: http://relaxed.ruby.style/#styleparallelassignment
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## [1.1.2] - 2024-07-26
|
2
|
+
|
3
|
+
* Adds ability to address various GeoJSON properties when performing GeoJSON to GPX conversion. (#53 via @niborg)
|
4
|
+
* Allow anything that responds to `read` for GPXFile input. (#55 via @hiroaki)
|
5
|
+
|
1
6
|
## [1.1.1] - 2023-05-19
|
2
7
|
|
3
8
|
* updates CI, minimal Ruby version now 2.7, updates tooling like rubocop and GitHub actions
|
@@ -5,6 +10,7 @@
|
|
5
10
|
* adds UPGRADING.md to document changes between versions
|
6
11
|
|
7
12
|
## [1.1.0] - 2023-05-18
|
13
|
+
|
8
14
|
* Specify UTF-8 encoding for XML encoding (#35 via @sh1nduu)
|
9
15
|
* Added GeoJSON conversion (#38 via @tyrauber and @niborg)
|
10
16
|
* Support Ruby 3 (#43 via @LocoDelAssembly)
|
data/README.md
CHANGED
@@ -6,12 +6,12 @@
|
|
6
6
|
## What It Does
|
7
7
|
|
8
8
|
This library reads GPX files and provides an API for reading and manipulating
|
9
|
-
the data as objects.
|
9
|
+
the data as objects. For more info on the GPX format, see
|
10
10
|
http://www.topografix.com/gpx.asp.
|
11
11
|
|
12
12
|
In addition to parsing GPX files, this library is capable of converting
|
13
13
|
Magellan NMEA files to GPX, converting GeoJSON data to GPX, and writing
|
14
|
-
new GPX files.
|
14
|
+
new GPX files. It can crop and delete rectangular areas within a file,
|
15
15
|
and it also calculates some meta-data about the tracks and points in a file (such as distance, duration, average speed, etc).
|
16
16
|
|
17
17
|
## Requirements
|
@@ -20,12 +20,23 @@ and it also calculates some meta-data about the tracks and points in a file (suc
|
|
20
20
|
- As of `1.0.0`, `gpx` requires at least Ruby 2.2 to run.
|
21
21
|
|
22
22
|
## Installation
|
23
|
+
|
23
24
|
Add to your gemfile:
|
25
|
+
|
24
26
|
```
|
25
27
|
gem 'gpx'
|
26
28
|
```
|
29
|
+
|
27
30
|
## Examples
|
28
31
|
|
32
|
+
Initialize a `GPXFile` object with either a file-like object or a string representation:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
gpx = GPX::GPXFile.new(:gpx_file => string_io) # Anything that responds to `read`
|
36
|
+
gpx = GPX::GPXFile.new(:gpx_file => path_to_a_file)
|
37
|
+
gpx = GPX::GPXFile.new(:gpx_data => some_string)
|
38
|
+
```
|
39
|
+
|
29
40
|
Reading a GPX file, and cropping its contents to a given area:
|
30
41
|
|
31
42
|
```ruby
|
@@ -36,6 +47,7 @@ gpx.write(filename) # Save it
|
|
36
47
|
```
|
37
48
|
|
38
49
|
Converting a Magellan track log to GPX:
|
50
|
+
|
39
51
|
```ruby
|
40
52
|
if GPX::MagellanTrackLog::is_magellan_file?(filename)
|
41
53
|
GPX::MagellanTrackLog::convert_to_gpx(filename, "#{filename}.gpx")
|
@@ -44,6 +56,7 @@ end
|
|
44
56
|
|
45
57
|
Converting GeoJSON data to GPX can be achieved by providing a
|
46
58
|
file path, file, or the data in string format:
|
59
|
+
|
47
60
|
```ruby
|
48
61
|
# Converting from a file name
|
49
62
|
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: 'mygeojsonfile.json')
|
@@ -51,9 +64,23 @@ gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: 'mygeojsonfile.json')
|
|
51
64
|
# Converting from a string
|
52
65
|
data = JSON.generate(my_geojson_hash)
|
53
66
|
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_data: data)
|
67
|
+
|
68
|
+
# The above won't transfer anything but coordinate values. If you want to
|
69
|
+
# transfer ad hoc "properties" information, you can specify an object that
|
70
|
+
# responds to `call` to manipulate GPX data structures as follows:
|
71
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(
|
72
|
+
geojson_data: data,
|
73
|
+
line_string_feature_to_segment: ->(ls, seg) { seg.distance = ls["properties"]["distance"] },
|
74
|
+
multi_line_string_feature_to_track: lambda { |mls, track|
|
75
|
+
track.name = mls["properties"]["name"]
|
76
|
+
},
|
77
|
+
point_feature_to_waypoint: ->(pt, wpt) { wpt.name = pt["properties"]["name"] }
|
78
|
+
multi_point_feature_to_waypoint: ->(mpt, wpt) { wpt.sym = mpt["properties"]["icon"] }
|
79
|
+
)
|
54
80
|
```
|
55
81
|
|
56
82
|
Exporting an ActiveRecord to GPXFile (as Waypoints)
|
83
|
+
|
57
84
|
```ruby
|
58
85
|
#
|
59
86
|
# Our active record in this example is called stop
|
@@ -98,12 +125,11 @@ Mime::Type.register "application/gpx+xml", :gpx
|
|
98
125
|
|
99
126
|
You have a complete example on how to create a gpx file from scratch on `tests/output_text.rb`.
|
100
127
|
|
101
|
-
|
102
128
|
## Notes
|
103
129
|
|
104
130
|
This library was written to bridge the gap between my Garmin Geko
|
105
|
-
and my website, WalkingBoss.org (RIP).
|
106
|
-
work-in-progress than an attempt at full GPX compliance.
|
131
|
+
and my website, WalkingBoss.org (RIP). For that reason, it has always been more of a
|
132
|
+
work-in-progress than an attempt at full GPX compliance. The track side of the
|
107
133
|
library has seen much more use than the route/waypoint side, so if you're doing
|
108
134
|
something with routes or waypoints, you may need to tweak some things.
|
109
135
|
|
@@ -113,7 +139,7 @@ working with tracks from several days or weeks.
|
|
113
139
|
|
114
140
|
Finally, it should be noted that none of the distance/speed calculation or
|
115
141
|
crop/delete code has been tested under International Date Line-crossing
|
116
|
-
conditions.
|
142
|
+
conditions. That particular part of the code will likely be unreliable if
|
117
143
|
you're zig-zagging across 180 degrees longitude routinely.
|
118
144
|
|
119
145
|
## License
|
data/lib/gpx/bounds.rb
CHANGED
@@ -28,7 +28,7 @@ module GPX
|
|
28
28
|
|
29
29
|
# Returns true if the pt is within these bounds.
|
30
30
|
def contains?(pt)
|
31
|
-
(
|
31
|
+
(pt.lat >= min_lat) && (pt.lat <= max_lat) && (pt.lon >= min_lon) && (pt.lon <= max_lon)
|
32
32
|
end
|
33
33
|
|
34
34
|
# Adds an item to itself, expanding its min/max lat/lon as needed to
|
data/lib/gpx/geo_json.rb
CHANGED
@@ -34,8 +34,8 @@ module GPX
|
|
34
34
|
def convert_to_gpx(opts = {})
|
35
35
|
geojson = geojson_data_from(opts)
|
36
36
|
gpx_file = GPX::GPXFile.new
|
37
|
-
add_tracks_to(gpx_file, geojson)
|
38
|
-
add_waypoints_to(gpx_file, geojson)
|
37
|
+
add_tracks_to(gpx_file, geojson, opts)
|
38
|
+
add_waypoints_to(gpx_file, geojson, opts)
|
39
39
|
gpx_file
|
40
40
|
end
|
41
41
|
|
@@ -61,32 +61,35 @@ module GPX
|
|
61
61
|
JSON.parse(data)
|
62
62
|
end
|
63
63
|
|
64
|
-
def add_tracks_to(gpx_file, geojson)
|
65
|
-
tracks = [line_strings_to_track(geojson)] +
|
66
|
-
multi_line_strings_to_tracks(geojson)
|
64
|
+
def add_tracks_to(gpx_file, geojson, opts)
|
65
|
+
tracks = [line_strings_to_track(geojson, opts)] +
|
66
|
+
multi_line_strings_to_tracks(geojson, opts)
|
67
67
|
tracks.compact!
|
68
68
|
gpx_file.tracks += tracks
|
69
69
|
gpx_file.tracks.each { |t| gpx_file.update_meta_data(t) }
|
70
70
|
end
|
71
71
|
|
72
|
-
def add_waypoints_to(gpx_file, geojson)
|
72
|
+
def add_waypoints_to(gpx_file, geojson, opts)
|
73
73
|
gpx_file.waypoints +=
|
74
|
-
points_to_waypoints(geojson, gpx_file) +
|
75
|
-
multi_points_to_waypoints(geojson, gpx_file)
|
74
|
+
points_to_waypoints(geojson, gpx_file, opts) +
|
75
|
+
multi_points_to_waypoints(geojson, gpx_file, opts)
|
76
76
|
end
|
77
77
|
|
78
78
|
# Converts GeoJSON 'LineString' features.
|
79
79
|
# Current strategy is to convert each LineString into a
|
80
80
|
# Track Segment, returning a Track for all LineStrings.
|
81
81
|
#
|
82
|
-
def line_strings_to_track(geojson)
|
82
|
+
def line_strings_to_track(geojson, opts)
|
83
83
|
line_strings = line_strings_in(geojson)
|
84
84
|
return nil unless line_strings.any?
|
85
85
|
|
86
86
|
track = GPX::Track.new
|
87
87
|
line_strings.each do |ls|
|
88
88
|
coords = ls['geometry']['coordinates']
|
89
|
-
|
89
|
+
segment = coords_to_segment(coords)
|
90
|
+
|
91
|
+
opts[:line_string_feature_to_segment]&.call(ls, segment)
|
92
|
+
track.append_segment(segment)
|
90
93
|
end
|
91
94
|
track
|
92
95
|
end
|
@@ -96,15 +99,18 @@ module GPX
|
|
96
99
|
# into a Track, with each set of LineString coordinates
|
97
100
|
# within a MultiLineString a Track Segment.
|
98
101
|
#
|
99
|
-
def multi_line_strings_to_tracks(geojson)
|
102
|
+
def multi_line_strings_to_tracks(geojson, opts)
|
100
103
|
tracks = []
|
101
104
|
multi_line_strings_in(geojson).each do |mls|
|
102
105
|
track = GPX::Track.new
|
103
106
|
mls['geometry']['coordinates'].each do |coords|
|
104
107
|
seg = coords_to_segment(coords)
|
105
108
|
seg.track = track
|
109
|
+
|
106
110
|
track.append_segment(seg)
|
107
111
|
end
|
112
|
+
|
113
|
+
opts[:multi_line_string_feature_to_track]&.call(mls, track)
|
108
114
|
tracks << track
|
109
115
|
end
|
110
116
|
tracks
|
@@ -114,10 +120,14 @@ module GPX
|
|
114
120
|
# Current strategy is to convert each Point
|
115
121
|
# feature into a GPX waypoint.
|
116
122
|
#
|
117
|
-
def points_to_waypoints(geojson, gpx_file)
|
123
|
+
def points_to_waypoints(geojson, gpx_file, opts)
|
118
124
|
points_in(geojson).reduce([]) do |acc, pt|
|
119
125
|
coords = pt['geometry']['coordinates']
|
120
|
-
|
126
|
+
waypoint = point_to_waypoint(coords, gpx_file)
|
127
|
+
|
128
|
+
opts[:point_feature_to_waypoint]&.call(pt, waypoint)
|
129
|
+
|
130
|
+
acc << waypoint
|
121
131
|
end
|
122
132
|
end
|
123
133
|
|
@@ -132,10 +142,14 @@ module GPX
|
|
132
142
|
# series of turn points leading to a destination."
|
133
143
|
# See http://www.topografix.com/gpx/1/1/#type_rteType
|
134
144
|
#
|
135
|
-
def multi_points_to_waypoints(geojson, gpx_file)
|
136
|
-
multi_points_in(geojson).
|
145
|
+
def multi_points_to_waypoints(geojson, gpx_file, opts)
|
146
|
+
multi_points_in(geojson).each_with_object([]) do |mpt, acc|
|
137
147
|
mpt['geometry']['coordinates'].each do |coords|
|
138
|
-
|
148
|
+
waypoint = point_to_waypoint(coords, gpx_file)
|
149
|
+
|
150
|
+
opts[:multi_point_feature_to_waypoint]&.call(mpt, waypoint)
|
151
|
+
|
152
|
+
acc << waypoint
|
139
153
|
end
|
140
154
|
end
|
141
155
|
end
|
data/lib/gpx/gpx_file.rb
CHANGED
@@ -35,7 +35,7 @@ module GPX
|
|
35
35
|
if opts[:gpx_file] || opts[:gpx_data]
|
36
36
|
if opts[:gpx_file]
|
37
37
|
gpx_file = opts[:gpx_file]
|
38
|
-
gpx_file = File.open(gpx_file) unless gpx_file.
|
38
|
+
gpx_file = File.open(gpx_file) unless gpx_file.respond_to?(:read)
|
39
39
|
@xml = Nokogiri::XML(gpx_file)
|
40
40
|
else
|
41
41
|
@xml = Nokogiri::XML(opts[:gpx_data])
|
@@ -194,8 +194,6 @@ module GPX
|
|
194
194
|
@moving_duration = 0.0
|
195
195
|
end
|
196
196
|
|
197
|
-
# rubocop:disable Style/OptionalBooleanParameter
|
198
|
-
|
199
197
|
# Updates the meta data for this GPX file. Meta data includes the
|
200
198
|
# bounds, the high and low points, and the distance. This is useful when
|
201
199
|
# you modify the GPX data (i.e. by adding or deleting points) and you
|
@@ -222,7 +220,6 @@ module GPX
|
|
222
220
|
doc = generate_xml_doc
|
223
221
|
doc.to_xml
|
224
222
|
end
|
225
|
-
# rubocop:enable Style/OptionalBooleanParameter
|
226
223
|
|
227
224
|
def inspect
|
228
225
|
"<#{self.class.name}:...>"
|
data/lib/gpx/route.rb
CHANGED
data/lib/gpx/segment.rb
CHANGED
@@ -62,7 +62,7 @@ module GPX
|
|
62
62
|
|
63
63
|
# Returns true if the given time is within this Segment.
|
64
64
|
def contains_time?(time)
|
65
|
-
(
|
65
|
+
(time >= @earliest_point.time) && (time <= @latest_point.time)
|
66
66
|
rescue StandardError
|
67
67
|
false
|
68
68
|
end
|
@@ -105,7 +105,7 @@ module GPX
|
|
105
105
|
|
106
106
|
# Returns true if this Segment has no points.
|
107
107
|
def empty?
|
108
|
-
|
108
|
+
points.nil? || points.empty?
|
109
109
|
end
|
110
110
|
|
111
111
|
# Prints out a nice summary of this Segment.
|
data/lib/gpx/track.rb
CHANGED
@@ -95,7 +95,7 @@ module GPX
|
|
95
95
|
# Returns true if this track has no points in it. This should return
|
96
96
|
# true even when the track has empty segments.
|
97
97
|
def empty?
|
98
|
-
|
98
|
+
points.nil? || points.empty?
|
99
99
|
end
|
100
100
|
|
101
101
|
# Prints out a friendly summary of this track (sans points). Useful for
|
data/lib/gpx/version.rb
CHANGED
@@ -24,8 +24,11 @@
|
|
24
24
|
[-118.41506, 34.06301, 80],
|
25
25
|
[-118.415, 34.06305, 80],
|
26
26
|
[-118.41494, 34.06309, 80]
|
27
|
-
|
28
|
-
|
27
|
+
]
|
28
|
+
},
|
29
|
+
"properties": {
|
30
|
+
"distance": 10
|
31
|
+
}
|
29
32
|
}, {
|
30
33
|
"type": "Feature",
|
31
34
|
"geometry": {
|
@@ -49,6 +52,9 @@
|
|
49
52
|
[-118.36894, 34.05818, 40],
|
50
53
|
[-118.369, 34.05806, 40]
|
51
54
|
]
|
55
|
+
},
|
56
|
+
"properties": {
|
57
|
+
"distance": 100
|
52
58
|
}
|
53
59
|
}, {
|
54
60
|
"type": "Feature",
|
@@ -78,6 +84,9 @@
|
|
78
84
|
[-118.35046, 34.03779, 30],
|
79
85
|
[-118.3505, 34.03768, 30]
|
80
86
|
]
|
87
|
+
},
|
88
|
+
"properties": {
|
89
|
+
"distance": 1000
|
81
90
|
}
|
82
91
|
}]
|
83
92
|
}
|
@@ -5,18 +5,27 @@
|
|
5
5
|
"geometry": {
|
6
6
|
"type": "Point",
|
7
7
|
"coordinates": [-118.41585, 34.06253, 80]
|
8
|
+
},
|
9
|
+
"properties": {
|
10
|
+
"name": "Foo"
|
8
11
|
}
|
9
12
|
}, {
|
10
13
|
"type": "Feature",
|
11
14
|
"geometry": {
|
12
15
|
"type": "Point",
|
13
16
|
"coordinates": [-118.36855, 34.05844, 40]
|
17
|
+
},
|
18
|
+
"properties": {
|
19
|
+
"name": "Bar"
|
14
20
|
}
|
15
21
|
}, {
|
16
22
|
"type": "Feature",
|
17
23
|
"geometry": {
|
18
24
|
"type": "Point",
|
19
25
|
"coordinates": [-118.35043, 34.0392, 30]
|
26
|
+
},
|
27
|
+
"properties": {
|
28
|
+
"name": "Baz"
|
20
29
|
}
|
21
30
|
}]
|
22
31
|
}
|
data/tests/geojson_test.rb
CHANGED
@@ -54,6 +54,28 @@ class GeojsonTest < Minitest::Test
|
|
54
54
|
assert_equal(58, pts_size)
|
55
55
|
end
|
56
56
|
|
57
|
+
def test_line_string_functionality_with_lambda
|
58
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/line_string_data.json')
|
59
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(
|
60
|
+
geojson_file: file,
|
61
|
+
line_string_feature_to_segment: lambda { |line_string, segment|
|
62
|
+
segment.points << GPX::Point.new(
|
63
|
+
{
|
64
|
+
lat: line_string['geometry']['coordinates'][0][1],
|
65
|
+
lon: line_string['geometry']['coordinates'][0][0]
|
66
|
+
}
|
67
|
+
)
|
68
|
+
}
|
69
|
+
)
|
70
|
+
|
71
|
+
assert_equal(1, gpx_file.tracks.size)
|
72
|
+
assert_equal(3, gpx_file.tracks.first.segments.size)
|
73
|
+
pts_size = gpx_file.tracks.first.segments[0].points.size +
|
74
|
+
gpx_file.tracks.first.segments[1].points.size +
|
75
|
+
gpx_file.tracks.first.segments[2].points.size
|
76
|
+
assert_equal(61, pts_size)
|
77
|
+
end
|
78
|
+
|
57
79
|
def test_multi_line_string_functionality
|
58
80
|
file = File.join(File.dirname(__FILE__), 'geojson_files/multi_line_string_data.json')
|
59
81
|
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
@@ -65,18 +87,59 @@ class GeojsonTest < Minitest::Test
|
|
65
87
|
assert_equal(58, pts_size)
|
66
88
|
end
|
67
89
|
|
90
|
+
def test_multi_line_string_functionality_with_lambda
|
91
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/multi_line_string_data.json')
|
92
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(
|
93
|
+
geojson_file: file,
|
94
|
+
multi_line_string_feature_to_track: lambda { |multi_line_string, segment|
|
95
|
+
segment.name = multi_line_string['properties']['name']
|
96
|
+
}
|
97
|
+
)
|
98
|
+
assert_equal(1, gpx_file.tracks.size)
|
99
|
+
assert_equal(3, gpx_file.tracks.first.segments.size)
|
100
|
+
pts_size = gpx_file.tracks.first.segments[0].points.size +
|
101
|
+
gpx_file.tracks.first.segments[1].points.size +
|
102
|
+
gpx_file.tracks.first.segments[2].points.size
|
103
|
+
assert_equal(58, pts_size)
|
104
|
+
assert_equal("Foo", gpx_file.tracks[0].name)
|
105
|
+
end
|
106
|
+
|
68
107
|
def test_point_functionality
|
69
108
|
file = File.join(File.dirname(__FILE__), 'geojson_files/point_data.json')
|
70
109
|
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
71
110
|
assert_equal(3, gpx_file.waypoints.size)
|
72
111
|
end
|
73
112
|
|
113
|
+
def test_point_functionality_with_proc
|
114
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/point_data.json')
|
115
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(
|
116
|
+
geojson_file: file,
|
117
|
+
point_feature_to_waypoint: ->(point, waypoint) { waypoint.name = point['properties']['name'] }
|
118
|
+
)
|
119
|
+
assert_equal(3, gpx_file.waypoints.size)
|
120
|
+
assert_equal('Foo', gpx_file.waypoints[0].name)
|
121
|
+
assert_equal('Bar', gpx_file.waypoints[1].name)
|
122
|
+
assert_equal('Baz', gpx_file.waypoints[2].name)
|
123
|
+
end
|
124
|
+
|
74
125
|
def test_multi_point_functionality
|
75
126
|
file = File.join(File.dirname(__FILE__), 'geojson_files/multi_point_data.json')
|
76
127
|
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
77
128
|
assert_equal(3, gpx_file.waypoints.size)
|
78
129
|
end
|
79
130
|
|
131
|
+
def test_multi_point_functionality_with_proc
|
132
|
+
file = File.join(File.dirname(__FILE__), 'geojson_files/multi_point_data.json')
|
133
|
+
gpx_file = GPX::GeoJSON.convert_to_gpx(
|
134
|
+
geojson_file: file,
|
135
|
+
multi_point_feature_to_waypoint: ->(multi_point, waypoint) { waypoint.name = multi_point['properties']['name'] }
|
136
|
+
)
|
137
|
+
assert_equal(3, gpx_file.waypoints.size)
|
138
|
+
assert_equal('Foo', gpx_file.waypoints[0].name)
|
139
|
+
assert_equal('Foo', gpx_file.waypoints[1].name)
|
140
|
+
assert_equal('Foo', gpx_file.waypoints[2].name)
|
141
|
+
end
|
142
|
+
|
80
143
|
def test_combined_functionality
|
81
144
|
file = File.join(File.dirname(__FILE__), 'geojson_files/combined_data.json')
|
82
145
|
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file)
|
data/tests/gpx_file_test.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'minitest/autorun'
|
4
4
|
require 'gpx'
|
5
|
+
require 'stringio'
|
5
6
|
|
6
7
|
class GPXFileTest < Minitest::Test
|
7
8
|
ONE_TRACK_FILE = File.join(File.dirname(__FILE__), 'gpx_files/one_track.gpx')
|
@@ -11,39 +12,12 @@ class GPXFileTest < Minitest::Test
|
|
11
12
|
|
12
13
|
def test_load_data_from_string
|
13
14
|
gpx_file = GPX::GPXFile.new(gpx_data: File.open(ONE_TRACK_FILE).read)
|
14
|
-
|
15
|
-
assert_equal(8, gpx_file.tracks.first.segments.size)
|
16
|
-
assert_equal('ACTIVE LOG', gpx_file.tracks.first.name)
|
17
|
-
assert_equal('active_log.gpx', gpx_file.name)
|
18
|
-
assert_equal('2006-04-08T16:44:28Z', gpx_file.time.xmlschema)
|
19
|
-
assert_equal(38.681488, gpx_file.bounds.min_lat)
|
20
|
-
assert_equal(-109.606948, gpx_file.bounds.min_lon)
|
21
|
-
assert_equal(38.791759, gpx_file.bounds.max_lat)
|
22
|
-
assert_equal(-109.447045, gpx_file.bounds.max_lon)
|
23
|
-
assert_equal('description of my GPX file with special char like &, <, >', gpx_file.description)
|
24
|
-
assert_equal('description of my GPX file with special char like &, <, >', gpx_file.description)
|
25
|
-
assert_equal(3.0724966849262554, gpx_file.distance)
|
26
|
-
assert_equal(15_237.0, gpx_file.duration)
|
27
|
-
assert_equal(3036.0, gpx_file.moving_duration)
|
28
|
-
assert_equal(3.6432767014935834, gpx_file.average_speed)
|
15
|
+
shared_assertions_for_one_track_file(gpx_file)
|
29
16
|
end
|
30
17
|
|
31
18
|
def test_load_data_from_file
|
32
19
|
gpx_file = GPX::GPXFile.new(gpx_file: ONE_TRACK_FILE)
|
33
|
-
|
34
|
-
assert_equal(8, gpx_file.tracks.first.segments.size)
|
35
|
-
assert_equal('ACTIVE LOG', gpx_file.tracks.first.name)
|
36
|
-
assert_equal('active_log.gpx', gpx_file.name)
|
37
|
-
assert_equal('2006-04-08T16:44:28Z', gpx_file.time.xmlschema)
|
38
|
-
assert_equal(38.681488, gpx_file.bounds.min_lat)
|
39
|
-
assert_equal(-109.606948, gpx_file.bounds.min_lon)
|
40
|
-
assert_equal(38.791759, gpx_file.bounds.max_lat)
|
41
|
-
assert_equal(-109.447045, gpx_file.bounds.max_lon)
|
42
|
-
assert_equal('description of my GPX file with special char like &, <, >', gpx_file.description)
|
43
|
-
assert_equal(3.0724966849262554, gpx_file.distance)
|
44
|
-
assert_equal(15_237.0, gpx_file.duration)
|
45
|
-
assert_equal(3036.0, gpx_file.moving_duration)
|
46
|
-
assert_equal(3.6432767014935834, gpx_file.average_speed)
|
20
|
+
shared_assertions_for_one_track_file(gpx_file)
|
47
21
|
end
|
48
22
|
|
49
23
|
def test_big_file
|
@@ -74,4 +48,35 @@ class GPXFileTest < Minitest::Test
|
|
74
48
|
assert_equal(21.0, gpx_file.moving_duration)
|
75
49
|
assert_equal(6.674040636626879, gpx_file.average_speed)
|
76
50
|
end
|
51
|
+
|
52
|
+
def test_load_data_from_stringio_assigned_gpx_file
|
53
|
+
str = File.open(ONE_TRACK_FILE).read
|
54
|
+
io = StringIO.new(str, 'r+')
|
55
|
+
gpx_file = GPX::GPXFile.new(gpx_file: io)
|
56
|
+
shared_assertions_for_one_track_file(gpx_file)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_load_data_from_stringio_assigned_gpx_data
|
60
|
+
str = File.open(ONE_TRACK_FILE).read
|
61
|
+
io = StringIO.new(str, 'r+')
|
62
|
+
gpx_file = GPX::GPXFile.new(gpx_data: io)
|
63
|
+
shared_assertions_for_one_track_file(gpx_file)
|
64
|
+
end
|
65
|
+
|
66
|
+
def shared_assertions_for_one_track_file(gpx_file)
|
67
|
+
assert_equal(1, gpx_file.tracks.size)
|
68
|
+
assert_equal(8, gpx_file.tracks.first.segments.size)
|
69
|
+
assert_equal('ACTIVE LOG', gpx_file.tracks.first.name)
|
70
|
+
assert_equal('active_log.gpx', gpx_file.name)
|
71
|
+
assert_equal('2006-04-08T16:44:28Z', gpx_file.time.xmlschema)
|
72
|
+
assert_equal(38.681488, gpx_file.bounds.min_lat)
|
73
|
+
assert_equal(-109.606948, gpx_file.bounds.min_lon)
|
74
|
+
assert_equal(38.791759, gpx_file.bounds.max_lat)
|
75
|
+
assert_equal(-109.447045, gpx_file.bounds.max_lon)
|
76
|
+
assert_equal('description of my GPX file with special char like &, <, >', gpx_file.description)
|
77
|
+
assert_equal(3.0724966849262554, gpx_file.distance)
|
78
|
+
assert_equal(15_237.0, gpx_file.duration)
|
79
|
+
assert_equal(3036.0, gpx_file.moving_duration)
|
80
|
+
assert_equal(3.6432767014935834, gpx_file.average_speed)
|
81
|
+
end
|
77
82
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gpx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Dott
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2024-07-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|