gpx 1.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f206f4729605d96cdaf65fe3fe52237c14f61eb1ae69558eb826c6f831e4076b
4
- data.tar.gz: b05a8fd9d66446f57640474b3dad428b5eab24617b2e0cb3b19e655d079ea0d6
3
+ metadata.gz: 94b41dda1f7722e6a90e261b66420e08074a953c866f7c4b32947ff41046bbcb
4
+ data.tar.gz: 8aec6ca78168bab0c9ec5dd1d8e689387cfe700aa4b3984639ba9d8f9bcf4095
5
5
  SHA512:
6
- metadata.gz: 28c8c86253452eb56383790c43189de24929482781b5d94ac9416ab93be596fbbe5259e0226a18bbb7e44070503d6b721671bff2b239a5512a935fcb21dbc19f
7
- data.tar.gz: be64658d5bf4cf3d7653b2457f286401971d3a7a272766002d78296341eedd2c4ad237dc5ac38d38debe7dd7288275185b6ac27bef99460d250c2e62bd3d9c5b
6
+ metadata.gz: 96c15693a26a49344ffb7e552d352fc342ee033af8cf62219295e4b3a3334ee9a3ceb201c168a4fbd079647714e0e10dd8a5653842c5ac1c2ce5442946622063
7
+ data.tar.gz: 9e30c74ad0165287406fa0c322651fd8ab326bdf712f8563097c11451bb7601cc245acc4b74cc5d9d40e059126583ce421df0c4950183bc36833add6f5862db2
@@ -19,16 +19,17 @@ jobs:
19
19
 
20
20
  runs-on: ubuntu-latest
21
21
  strategy:
22
+ fail-fast: true
22
23
  matrix:
23
- ruby-version: ['2.7', '3.0', '3.1']
24
+ ruby-version: ['2.7', '3.0', '3.1', '3.2']
24
25
 
25
26
  steps:
26
- - uses: actions/checkout@v2
27
+ - uses: actions/checkout@v4
27
28
  - name: Set up Ruby
28
29
  # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
29
30
  # change this to (see https://github.com/ruby/setup-ruby#versioning):
30
31
  # uses: ruby/setup-ruby@v1
31
- uses: ruby/setup-ruby@f0971f0dd45a5cbb3f119f7db77cc58057c53530
32
+ uses: ruby/setup-ruby@v1.159.0
32
33
  with:
33
34
  ruby-version: ${{ matrix.ruby-version }}
34
35
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
data/.rubocop ADDED
@@ -0,0 +1 @@
1
+ --server
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.5
2
+ TargetRubyVersion: 2.7
3
3
 
4
4
  Style/Alias:
5
5
  Enabled: false
@@ -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/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.2
1
+ 3.2.2
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.2.2
data/.travis.yml CHANGED
@@ -1,8 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.5
4
- - 2.6
5
3
  - 2.7
6
4
  - 3.0
7
- # - 3.1 # Not supported by Travis yet as of 2021-12-29
5
+ - 3.1
8
6
  script: "bundle exec rake"
data/CHANGELOG.md CHANGED
@@ -1,10 +1,23 @@
1
- ## [1.1.0] - 202
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
+
6
+ ## [1.1.1] - 2023-05-19
7
+
8
+ * updates CI, minimal Ruby version now 2.7, updates tooling like rubocop and GitHub actions
9
+ * adds support for Ruby 3.2
10
+ * adds UPGRADING.md to document changes between versions
11
+
12
+ ## [1.1.0] - 2023-05-18
13
+
2
14
  * Specify UTF-8 encoding for XML encoding (#35 via @sh1nduu)
3
15
  * Added GeoJSON conversion (#38 via @tyrauber and @niborg)
4
16
  * Support Ruby 3 (#43 via @LocoDelAssembly)
5
17
  * Fix nil-to-Time comparison (#46 via @frodrigo)
6
18
  * Fix bug when <rte> GPX file does not specify <name> tag (#41 via @niborg)
7
19
  * Drop Ruby 2.5 and 2.6 from CI (#50 via @niborg)
20
+
8
21
  ## [1.0.0] - 2018-03-06
9
22
 
10
23
  * Fix duplication of points on appending segment to track (#20 via @niborg)
data/README.md CHANGED
@@ -6,25 +6,37 @@
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. For more info on the GPX format, see
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. It can crop and delete rectangular areas within a file,
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
18
18
 
19
- As of `1.0.0`, `gpx` requires at least Ruby 2.2 to run.
19
+ - As of `1.1.1`, `gpx` requires at least Ruby 2.7 to run.
20
+ - As of `1.0.0`, `gpx` requires at least Ruby 2.2 to run.
20
21
 
21
22
  ## Installation
23
+
22
24
  Add to your gemfile:
25
+
23
26
  ```
24
27
  gem 'gpx'
25
28
  ```
29
+
26
30
  ## Examples
27
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
+
28
40
  Reading a GPX file, and cropping its contents to a given area:
29
41
 
30
42
  ```ruby
@@ -35,6 +47,7 @@ gpx.write(filename) # Save it
35
47
  ```
36
48
 
37
49
  Converting a Magellan track log to GPX:
50
+
38
51
  ```ruby
39
52
  if GPX::MagellanTrackLog::is_magellan_file?(filename)
40
53
  GPX::MagellanTrackLog::convert_to_gpx(filename, "#{filename}.gpx")
@@ -43,6 +56,7 @@ end
43
56
 
44
57
  Converting GeoJSON data to GPX can be achieved by providing a
45
58
  file path, file, or the data in string format:
59
+
46
60
  ```ruby
47
61
  # Converting from a file name
48
62
  gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: 'mygeojsonfile.json')
@@ -50,9 +64,23 @@ gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: 'mygeojsonfile.json')
50
64
  # Converting from a string
51
65
  data = JSON.generate(my_geojson_hash)
52
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
+ )
53
80
  ```
54
81
 
55
82
  Exporting an ActiveRecord to GPXFile (as Waypoints)
83
+
56
84
  ```ruby
57
85
  #
58
86
  # Our active record in this example is called stop
@@ -97,12 +125,11 @@ Mime::Type.register "application/gpx+xml", :gpx
97
125
 
98
126
  You have a complete example on how to create a gpx file from scratch on `tests/output_text.rb`.
99
127
 
100
-
101
128
  ## Notes
102
129
 
103
130
  This library was written to bridge the gap between my Garmin Geko
104
- and my website, WalkingBoss.org (RIP). For that reason, it has always been more of a
105
- work-in-progress than an attempt at full GPX compliance. The track side of the
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
106
133
  library has seen much more use than the route/waypoint side, so if you're doing
107
134
  something with routes or waypoints, you may need to tweak some things.
108
135
 
@@ -112,7 +139,7 @@ working with tracks from several days or weeks.
112
139
 
113
140
  Finally, it should be noted that none of the distance/speed calculation or
114
141
  crop/delete code has been tested under International Date Line-crossing
115
- conditions. That particular part of the code will likely be unreliable if
142
+ conditions. That particular part of the code will likely be unreliable if
116
143
  you're zig-zagging across 180 degrees longitude routinely.
117
144
 
118
145
  ## License
data/UPGRADING.md ADDED
@@ -0,0 +1,7 @@
1
+ # Upgrading
2
+
3
+ You will find all the information you need to upgrade from one version to another here.
4
+
5
+ ## Version 1.0.0 to 1.1.1
6
+
7
+ Please make sure, that you need at least Ruby 2.7.0 to use this gem now. As support for Ruby versions below 2.7.0 has been dropped.
data/gpx.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.summary = 'A basic API for reading and writing GPX files.'
13
13
  s.description = 'A basic API for reading and writing GPX files.'
14
14
 
15
- s.required_ruby_version = '>= 2.5', '< 4'
15
+ s.required_ruby_version = '>= 2.7', '< 4'
16
16
 
17
17
  s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
18
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
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
- ((pt.lat >= min_lat) && (pt.lat <= max_lat) && (pt.lon >= min_lon) && (pt.lon <= max_lon))
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
- track.append_segment(coords_to_segment(coords))
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
- acc << point_to_waypoint(coords, gpx_file)
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).reduce([]) do |acc, mpt|
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
- acc << point_to_waypoint(coords, gpx_file)
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.is_a?(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}:...>"
@@ -51,7 +51,7 @@ module GPX
51
51
  lat = -lat if lat_hemi == 'S'
52
52
 
53
53
  lon_deg = row[LON][0..2]
54
- lon_min = row[LON][3..-1]
54
+ lon_min = row[LON][3..]
55
55
  lon_hemi = row[LON_HEMI]
56
56
 
57
57
  lon = lon_deg.to_f + (lon_min.to_f / 60.0)
data/lib/gpx/route.rb CHANGED
@@ -19,7 +19,7 @@ module GPX
19
19
  @points << Point.new(element: point, gpx_file: @gpx_file)
20
20
  end
21
21
  else
22
- @points = (opts[:points] || [])
22
+ @points = opts[:points] || []
23
23
  @name = (opts[:name])
24
24
  end
25
25
  end
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
- ((time >= @earliest_point.time) && (time <= @latest_point.time))
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
- (points.nil? || points.empty?)
108
+ points.nil? || points.empty?
109
109
  end
110
110
 
111
111
  # Prints out a nice summary of this Segment.
@@ -193,7 +193,7 @@ module GPX
193
193
  elsif time <= pts[midpoint].time
194
194
  find_closest(pts[0..midpoint], time)
195
195
  else
196
- find_closest(pts[(midpoint + 1)..-1], time)
196
+ find_closest(pts[(midpoint + 1)..], time)
197
197
  end
198
198
  end
199
199
 
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
- (points.nil? || points.empty?)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GPX
4
- VERSION = "1.1.0"
4
+ VERSION = "1.1.2"
5
5
  end
@@ -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
  }
@@ -69,6 +69,9 @@
69
69
  [-118.35046, 34.03779, 30],
70
70
  [-118.3505, 34.03768, 30]
71
71
  ]]
72
+ },
73
+ "properties": {
74
+ "name": "Foo"
72
75
  }
73
76
  }]
74
77
  }
@@ -9,6 +9,9 @@
9
9
  [-118.4158, 34.06256, 80],
10
10
  [-118.41575, 34.06259, 80]
11
11
  ]
12
+ },
13
+ "properties": {
14
+ "name": "Foo"
12
15
  }
13
16
  }]
14
17
  }
@@ -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
  }
@@ -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)
@@ -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
- assert_equal(1, gpx_file.tracks.size)
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
- assert_equal(1, gpx_file.tracks.size)
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.0
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: 2023-05-19 00:00:00.000000000 Z
13
+ date: 2024-07-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
@@ -93,14 +93,17 @@ extra_rdoc_files: []
93
93
  files:
94
94
  - ".github/workflows/ruby.yml"
95
95
  - ".gitignore"
96
+ - ".rubocop"
96
97
  - ".rubocop.yml"
97
98
  - ".ruby-version"
99
+ - ".tool-versions"
98
100
  - ".travis.yml"
99
101
  - CHANGELOG.md
100
102
  - Gemfile
101
103
  - LICENSE.txt
102
104
  - README.md
103
105
  - Rakefile
106
+ - UPGRADING.md
104
107
  - bin/gpx_distance
105
108
  - bin/gpx_smooth
106
109
  - gpx.gemspec
@@ -158,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
158
161
  requirements:
159
162
  - - ">="
160
163
  - !ruby/object:Gem::Version
161
- version: '2.5'
164
+ version: '2.7'
162
165
  - - "<"
163
166
  - !ruby/object:Gem::Version
164
167
  version: '4'
@@ -168,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
171
  - !ruby/object:Gem::Version
169
172
  version: '0'
170
173
  requirements: []
171
- rubygems_version: 3.2.22
174
+ rubygems_version: 3.4.10
172
175
  signing_key:
173
176
  specification_version: 4
174
177
  summary: A basic API for reading and writing GPX files.