gpx 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +1,8 @@
1
- #--
2
- # Copyright (c) 2006 Doug Fales
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
1
  module GPX
24
2
  # This class will parse the lat/lon and time data from a Magellan track log,
25
3
  # which is a NMEA formatted CSV list of points.
26
4
  class MagellanTrackLog
27
- #PMGNTRK
5
+ # PMGNTRK
28
6
  # This message is to be used to transmit Track information (basically a list of previous position fixes)
29
7
  # which is often displayed on the plotter or map screen of the unit. The first field in this message
30
8
  # is the Latitude, followed by N or S. The next field is the Longitude followed by E or W. The next
@@ -35,98 +13,86 @@ module GPX
35
13
  # of the fix. Note that this field is (and its preceding comma) is only produced by the unit when the
36
14
  # command PMGNCMD,TRACK,2 is given. It is not present when a simple command of PMGNCMD,TRACK is issued.
37
15
 
38
- #NOTE: The Latitude and Longitude Fields are shown as having two decimal
16
+ # NOTE: The Latitude and Longitude Fields are shown as having two decimal
39
17
  # places. As many additional decimal places may be added as long as the total
40
18
  # length of the message does not exceed 82 bytes.
41
19
 
42
20
  # $PMGNTRK,llll.ll,a,yyyyy.yy,a,xxxxx,a,hhmmss.ss,A,c----c,ddmmyy*hh<CR><LF>
43
21
  require 'csv'
44
22
 
45
- LAT = 1
46
- LAT_HEMI = 2
47
- LON = 3
48
- LON_HEMI = 4
49
- ELE = 5
23
+ LAT = 1
24
+ LAT_HEMI = 2
25
+ LON = 3
26
+ LON_HEMI = 4
27
+ ELE = 5
50
28
  ELE_UNITS = 6
51
- TIME = 7
29
+ TIME = 7
52
30
  INVALID_FLAG = 8
53
- DATE = 10
31
+ DATE = 10
54
32
 
55
33
  FEET_TO_METERS = 0.3048
56
34
 
57
35
  class << self
58
-
59
36
  # Takes the name of a magellan file, converts the contents to GPX, and
60
37
  # writes the result to gpx_filename.
61
38
  def convert_to_gpx(magellan_filename, gpx_filename)
62
-
63
39
  segment = Segment.new
64
40
 
65
- CSV.open(magellan_filename, "r").each do |row|
66
- next if(row.size < 10 or row[INVALID_FLAG] == 'V')
41
+ CSV.open(magellan_filename, 'r').each do |row|
42
+ next if (row.size < 10) || (row[INVALID_FLAG] == 'V')
67
43
 
68
- lat_deg = row[LAT][0..1]
69
- lat_min = row[LAT][2...-1]
44
+ lat_deg = row[LAT][0..1]
45
+ lat_min = row[LAT][2...-1]
70
46
  lat_hemi = row[LAT_HEMI]
71
47
 
72
48
  lat = lat_deg.to_f + (lat_min.to_f / 60.0)
73
- lat = (-lat) if(lat_hemi == 'S')
49
+ lat = -lat if lat_hemi == 'S'
74
50
 
75
- lon_deg = row[LON][0..2]
76
- lon_min = row[LON][3..-1]
51
+ lon_deg = row[LON][0..2]
52
+ lon_min = row[LON][3..-1]
77
53
  lon_hemi = row[LON_HEMI]
78
54
 
79
55
  lon = lon_deg.to_f + (lon_min.to_f / 60.0)
80
- lon = (-lon) if(lon_hemi == 'W')
81
-
56
+ lon = -lon if lon_hemi == 'W'
82
57
 
83
58
  ele = row[ELE]
84
59
  ele_units = row[ELE_UNITS]
85
60
  ele = ele.to_f
86
- if(ele_units == 'F')
87
- ele *= FEET_TO_METERS
88
- end
61
+ ele *= FEET_TO_METERS if ele_units == 'F'
89
62
 
90
- hrs = row[TIME][0..1].to_i
63
+ hrs = row[TIME][0..1].to_i
91
64
  mins = row[TIME][2..3].to_i
92
65
  secs = row[TIME][4..5].to_i
93
- day = row[DATE][0..1].to_i
94
- mon = row[DATE][2..3].to_i
95
- yr = 2000 + row[DATE][4..5].to_i
66
+ day = row[DATE][0..1].to_i
67
+ mon = row[DATE][2..3].to_i
68
+ yr = 2000 + row[DATE][4..5].to_i
96
69
 
97
70
  time = Time.gm(yr, mon, day, hrs, mins, secs)
98
71
 
99
- #must create point
100
- pt = TrackPoint.new(:lat => lat, :lon => lon, :time => time, :elevation => ele)
72
+ # must create point
73
+ pt = TrackPoint.new(lat: lat, lon: lon, time: time, elevation: ele)
101
74
  segment.append_point(pt)
102
-
103
75
  end
104
76
 
105
77
  trk = Track.new
106
78
  trk.append_segment(segment)
107
- gpx_file = GPXFile.new(:tracks => [trk])
79
+ gpx_file = GPXFile.new(tracks: [trk])
108
80
  gpx_file.write(gpx_filename)
109
-
110
81
  end
111
82
 
112
83
  # Tests to see if the given file is a magellan NMEA track log.
113
- def is_magellan_file?(filename)
84
+ def magellan_file?(filename)
114
85
  i = 0
115
- File.open(filename, "r") do |f|
86
+ File.open(filename, 'r') do |f|
116
87
  f.each do |line|
117
- i += 1
118
- if line =~ /^\$PMGNTRK/
119
- return true
120
- elsif line =~ /<\?xml/
121
- return false
122
- elsif(i > 10)
123
- return false
124
- end
88
+ i += 1
89
+ return true if line =~ /^\$PMGNTRK/
90
+ return false if line =~ /<\?xml/
91
+ return false if i > 10
125
92
  end
126
93
  end
127
- return false
94
+ false
128
95
  end
129
96
  end
130
-
131
97
  end
132
98
  end
@@ -1,46 +1,31 @@
1
- #--
2
- # Copyright (c) 2006 Doug Fales
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
1
  module GPX
24
2
  # The base class for all points. Trackpoint and Waypoint both descend from this base class.
25
3
  class Point < Base
26
- D_TO_R = Math::PI/180.0;
27
- attr_accessor :lat, :lon, :time, :elevation, :gpx_file, :speed, :extensions
4
+ D_TO_R = Math::PI / 180.0
5
+ attr_accessor :time, :elevation, :gpx_file, :speed, :extensions
6
+ attr_reader :lat, :lon
28
7
 
29
8
  # When you need to manipulate individual points, you can create a Point
30
9
  # object with a latitude, a longitude, an elevation, and a time. In
31
10
  # addition, you can pass an XML element to this initializer, and the
32
11
  # relevant info will be parsed out.
33
- def initialize(opts = {:lat => 0.0, :lon => 0.0, :elevation => 0.0, :time => Time.now } )
12
+ def initialize(opts = { lat: 0.0, lon: 0.0, elevation: 0.0, time: Time.now })
34
13
  @gpx_file = opts[:gpx_file]
35
- if (opts[:element])
14
+ if opts[:element]
36
15
  elem = opts[:element]
37
- @lat, @lon = elem["lat"].to_f, elem["lon"].to_f
38
- @latr, @lonr = (D_TO_R * @lat), (D_TO_R * @lon)
39
- #'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
40
- @time = (Time.xmlschema(elem.at("time").inner_text) rescue nil)
41
- @elevation = elem.at("ele").inner_text.to_f unless elem.at("ele").nil?
42
- @speed = elem.at("speed").inner_text.to_f unless elem.at("speed").nil?
43
- @extensions = elem.at("extensions") unless elem.at("extensions").nil?
16
+ @lat = elem['lat'].to_f
17
+ @lon = elem['lon'].to_f
18
+ @latr = (D_TO_R * @lat)
19
+ @lonr = (D_TO_R * @lon)
20
+ # '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
21
+ @time = (begin
22
+ Time.xmlschema(elem.at('time').inner_text)
23
+ rescue StandardError
24
+ nil
25
+ end)
26
+ @elevation = elem.at('ele').inner_text.to_f unless elem.at('ele').nil?
27
+ @speed = elem.at('speed').inner_text.to_f unless elem.at('speed').nil?
28
+ @extensions = elem.at('extensions') unless elem.at('extensions').nil?
44
29
  else
45
30
  @lat = opts[:lat]
46
31
  @lon = opts[:lon]
@@ -49,10 +34,8 @@ module GPX
49
34
  @speed = opts[:speed]
50
35
  @extensions = opts[:extensions]
51
36
  end
52
-
53
37
  end
54
38
 
55
-
56
39
  # Returns the latitude and longitude (in that order), separated by the
57
40
  # given delimeter. This is useful for passing a point into another API
58
41
  # (i.e. the Google Maps javascript API).
@@ -1,58 +1,34 @@
1
- #--
2
- # Copyright (c) 2006 Doug Fales
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
1
  module GPX
24
2
  # A Route in GPX is very similar to a Track, but it is created by a user
25
3
  # from a series of Waypoints, whereas a Track is created by the GPS device
26
4
  # automatically logging your progress at regular intervals.
27
5
  class Route < Base
28
-
29
6
  attr_accessor :points, :name, :gpx_file
30
7
 
31
8
  # Initialize a Route from a XML::Node.
32
9
  def initialize(opts = {})
33
- if(opts[:gpx_file] and opts[:element])
10
+ if opts[:gpx_file] && opts[:element]
34
11
  rte_element = opts[:element]
35
12
  @gpx_file = opts[:gpx_file]
36
- @name = rte_element.at("name").inner_text
13
+ @name = rte_element.at('name').inner_text
37
14
  @points = []
38
- rte_element.search("rtept").each do |point|
39
- @points << Point.new(:element => point, :gpx_file => @gpx_file)
15
+ rte_element.search('rtept').each do |point|
16
+ @points << Point.new(element: point, gpx_file: @gpx_file)
40
17
  end
41
18
  else
42
- @points = (opts[:points] or [])
19
+ @points = (opts[:points] || [])
43
20
  @name = (opts[:name])
44
21
  end
45
-
46
22
  end
47
23
 
48
24
  # Delete points outside of a given area.
49
25
  def crop(area)
50
- points.delete_if{ |pt| not area.contains? pt }
26
+ points.delete_if { |pt| !area.contains? pt }
51
27
  end
52
28
 
53
29
  # Delete points within the given area.
54
30
  def delete_area(area)
55
- points.delete_if{ |pt| area.contains? pt }
31
+ points.delete_if { |pt| area.contains? pt }
56
32
  end
57
33
  end
58
34
  end
@@ -1,32 +1,9 @@
1
- #--
2
- # Copyright (c) 2006 Doug Fales
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
1
  module GPX
24
2
  # A segment is the basic container in a GPX file. A Segment contains points
25
3
  # (in this lib, they're called TrackPoints). A Track contains Segments. An
26
4
  # instance of Segment knows its highest point, lowest point, earliest and
27
5
  # latest points, distance, and bounds.
28
6
  class Segment < Base
29
-
30
7
  attr_reader :earliest_point, :latest_point, :bounds, :highest_point, :lowest_point, :distance, :duration
31
8
  attr_accessor :points, :track
32
9
 
@@ -43,15 +20,12 @@ module GPX
43
20
  @distance = 0.0
44
21
  @duration = 0.0
45
22
  @bounds = Bounds.new
46
- if(opts[:element])
47
- segment_element = opts[:element]
48
- last_pt = nil
49
- if segment_element.is_a?(Nokogiri::XML::Node)
50
- segment_element.search("trkpt").each do |trkpt|
51
- pt = TrackPoint.new(:element => trkpt, :segment => self, :gpx_file => @gpx_file)
52
- append_point(pt)
53
- end
54
- end
23
+
24
+ segment_element = opts[:element]
25
+ return unless segment_element && segment_element.is_a?(Nokogiri::XML::Node)
26
+ segment_element.search('trkpt').each do |trkpt|
27
+ pt = TrackPoint.new(element: trkpt, segment: self, gpx_file: @gpx_file)
28
+ append_point(pt)
55
29
  end
56
30
  end
57
31
 
@@ -59,8 +33,8 @@ module GPX
59
33
  def append_point(pt)
60
34
  last_pt = @points[-1]
61
35
  if pt.time
62
- @earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
63
- @latest_point = pt if(@latest_point.nil? or pt.time > @latest_point.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)
64
38
  else
65
39
  # when no time information in data, we consider the points are ordered
66
40
  @earliest_point = @points[0]
@@ -68,8 +42,8 @@ module GPX
68
42
  end
69
43
 
70
44
  if pt.elevation
71
- @lowest_point = pt if(@lowest_point.nil? or pt.elevation < @lowest_point.elevation)
72
- @highest_point = pt if(@highest_point.nil? or pt.elevation > @highest_point.elevation)
45
+ @lowest_point = pt if @lowest_point.nil? || (pt.elevation < @lowest_point.elevation)
46
+ @highest_point = pt if @highest_point.nil? || (pt.elevation > @highest_point.elevation)
73
47
  end
74
48
  @bounds.min_lat = pt.lat if pt.lat < @bounds.min_lat
75
49
  @bounds.min_lon = pt.lon if pt.lon < @bounds.min_lon
@@ -77,14 +51,16 @@ module GPX
77
51
  @bounds.max_lon = pt.lon if pt.lon > @bounds.max_lon
78
52
  if last_pt
79
53
  @distance += haversine_distance(last_pt, pt)
80
- @duration += pt.time - last_pt.time if pt.time and last_pt.time
54
+ @duration += pt.time - last_pt.time if pt.time && last_pt.time
81
55
  end
82
56
  @points << pt
83
57
  end
84
58
 
85
59
  # Returns true if the given time is within this Segment.
86
60
  def contains_time?(time)
87
- (time >= @earliest_point.time and time <= @latest_point.time) rescue false
61
+ ((time >= @earliest_point.time) && (time <= @latest_point.time))
62
+ rescue StandardError
63
+ false
88
64
  end
89
65
 
90
66
  # Finds the closest point in time to the passed-in time argument. Useful
@@ -97,12 +73,12 @@ module GPX
97
73
  # Deletes all points within this Segment that lie outside of the given
98
74
  # area (which should be a Bounds object).
99
75
  def crop(area)
100
- delete_if { |pt| not area.contains?(pt) }
76
+ delete_if { |pt| !area.contains?(pt) }
101
77
  end
102
78
 
103
79
  # Deletes all points in this Segment that lie within the given area.
104
80
  def delete_area(area)
105
- delete_if{ |pt| area.contains?(pt) }
81
+ delete_if { |pt| area.contains?(pt) }
106
82
  end
107
83
 
108
84
  # A handy method that deletes points based on a block that is passed in.
@@ -114,18 +90,17 @@ module GPX
114
90
  keep_points = []
115
91
  last_pt = nil
116
92
  points.each do |pt|
117
- unless yield(pt)
118
- keep_points << pt
119
- update_meta_data(pt, last_pt)
120
- last_pt = pt
121
- end
93
+ next if yield(pt)
94
+ keep_points << pt
95
+ update_meta_data(pt, last_pt)
96
+ last_pt = pt
122
97
  end
123
98
  @points = keep_points
124
99
  end
125
100
 
126
101
  # Returns true if this Segment has no points.
127
102
  def empty?
128
- (points.nil? or (points.size == 0))
103
+ (points.nil? || points.empty?)
129
104
  end
130
105
 
131
106
  # Prints out a nice summary of this Segment.
@@ -133,31 +108,31 @@ module GPX
133
108
  result = "Track Segment\n"
134
109
  result << "\tSize: #{points.size} points\n"
135
110
  result << "\tDistance: #{distance} km\n"
136
- result << "\tEarliest Point: #{earliest_point.time.to_s} \n"
137
- result << "\tLatest Point: #{latest_point.time.to_s} \n"
111
+ result << "\tEarliest Point: #{earliest_point.time} \n"
112
+ result << "\tLatest Point: #{latest_point.time} \n"
138
113
  result << "\tLowest Point: #{lowest_point.elevation} \n"
139
114
  result << "\tHighest Point: #{highest_point.elevation}\n "
140
- result << "\tBounds: #{bounds.to_s}"
115
+ result << "\tBounds: #{bounds}"
141
116
  result
142
117
  end
143
118
 
144
119
  def find_point_by_time_or_offset(indicator)
145
120
  if indicator.nil?
146
- return nil
121
+ nil
147
122
  elsif indicator.is_a?(Integer)
148
- return closest_point(@earliest_point.time + indicator)
149
- elsif(indicator.is_a?(Time))
150
- return closest_point(indicator)
123
+ closest_point(@earliest_point.time + indicator)
124
+ elsif indicator.is_a?(Time)
125
+ closest_point(indicator)
151
126
  else
152
- raise Exception, "find_end_point_by_time_or_offset requires an argument of type Time or Integer"
127
+ raise Exception, 'find_end_point_by_time_or_offset requires an argument of type Time or Integer'
153
128
  end
154
129
  end
155
-
130
+
156
131
  # smooths the location data in the segment (by recalculating the location as an average of 20 neighbouring points. Useful for removing noise from GPS traces.
157
- def smooth_location_by_average(opts={})
132
+ def smooth_location_by_average(opts = {})
158
133
  seconds_either_side = opts[:averaging_window] || 20
159
134
 
160
- #calculate the first and last points to which the smoothing should be applied
135
+ # calculate the first and last points to which the smoothing should be applied
161
136
  earliest = (find_point_by_time_or_offset(opts[:start]) || @earliest_point).time
162
137
  latest = (find_point_by_time_or_offset(opts[:end]) || @latest_point).time
163
138
 
@@ -165,18 +140,18 @@ module GPX
165
140
 
166
141
  @points.each do |point|
167
142
  if point.time > latest || point.time < earliest
168
- tmp_points.push point #add the point unaltered
169
- next
143
+ tmp_points.push point # add the point unaltered
144
+ next
170
145
  end
171
146
  lat_av = 0.to_f
172
147
  lon_av = 0.to_f
173
148
  alt_av = 0.to_f
174
149
  n = 0
175
- # k ranges from the time of the current point +/- 20s
176
- (-1*seconds_either_side..seconds_either_side).each do |k|
150
+ # k ranges from the time of the current point +/- 20s
151
+ (-1 * seconds_either_side..seconds_either_side).each do |k|
177
152
  # find the point nearest to the time offset indicated by k
178
153
  contributing_point = closest_point(point.time + k)
179
- #sum up the contributions to the average
154
+ # sum up the contributions to the average
180
155
  lat_av += contributing_point.lat
181
156
  lon_av += contributing_point.lon
182
157
  alt_av += contributing_point.elevation
@@ -184,39 +159,39 @@ module GPX
184
159
  end
185
160
  # calculate the averages
186
161
  tmp_point = point.clone
187
- tmp_point.lon = ((lon_av) / n).round(7)
188
- tmp_point.elevation = ((alt_av) / n).round(2)
189
- tmp_point.lat = ((lat_av) / n).round(7)
162
+ tmp_point.lon = (lon_av / n).round(7)
163
+ tmp_point.elevation = (alt_av / n).round(2)
164
+ tmp_point.lat = (lat_av / n).round(7)
190
165
  tmp_points.push tmp_point
191
166
  end
192
- last_pt = nil
193
167
  @points.clear
194
168
  reset_meta_data
195
- #now commit the averages back and recalculate the distances
169
+ # now commit the averages back and recalculate the distances
196
170
  tmp_points.each do |point|
197
171
  append_point(point)
198
172
  end
199
173
  end
200
174
 
201
175
  protected
176
+
177
+ # rubocop:disable Style/GuardClause
202
178
  def find_closest(pts, time)
203
179
  return pts.first if pts.size == 1
204
- midpoint = pts.size/2
180
+ midpoint = pts.size / 2
205
181
  if pts.size == 2
206
182
  diff_1 = pts[0].time - time
207
183
  diff_2 = pts[1].time - time
208
184
  return (diff_1 < diff_2 ? pts[0] : pts[1])
209
185
  end
210
- if time >= pts[midpoint].time and time <= pts[midpoint+1].time
211
-
186
+ if (time >= pts[midpoint].time) && (time <= pts[midpoint + 1].time)
212
187
  return pts[midpoint]
213
-
214
- elsif(time <= pts[midpoint].time)
188
+ elsif time <= pts[midpoint].time
215
189
  return find_closest(pts[0..midpoint], time)
216
190
  else
217
- return find_closest(pts[(midpoint+1)..-1], time)
191
+ return find_closest(pts[(midpoint + 1)..-1], time)
218
192
  end
219
193
  end
194
+ # rubocop:enable Style/GuardClause
220
195
 
221
196
  # Calculate the Haversine distance between two points. This is the method
222
197
  # the library uses to calculate the cumulative distance of GPX files.
@@ -224,11 +199,6 @@ module GPX
224
199
  p1.haversine_distance_from(p2)
225
200
  end
226
201
 
227
- # Calculate the plain Pythagorean difference between two points. Not currently used.
228
- def pythagorean_distance(p1, p2)
229
- p1.pythagorean_distance_from(p2)
230
- end
231
-
232
202
  # Calculates the distance between two points using the Law of Cosines formula. Not currently used.
233
203
  def law_of_cosines_distance(p1, p2)
234
204
  p1.law_of_cosines_distance_from(p2)
@@ -246,8 +216,8 @@ module GPX
246
216
 
247
217
  def update_meta_data(pt, last_pt)
248
218
  if pt.time
249
- @earliest_point = pt if(@earliest_point.nil? or pt.time < @earliest_point.time)
250
- @latest_point = pt if(@latest_point.nil? or pt.time > @latest_point.time)
219
+ @earliest_point = pt if @earliest_point.nil? || (pt.time < @earliest_point.time)
220
+ @latest_point = pt if @latest_point.nil? || (pt.time > @latest_point.time)
251
221
  else
252
222
  # when no time information in data, we consider the points are ordered
253
223
  @earliest_point = @points[0]
@@ -255,16 +225,14 @@ module GPX
255
225
  end
256
226
 
257
227
  if pt.elevation
258
- @lowest_point = pt if(@lowest_point.nil? or pt.elevation < @lowest_point.elevation)
259
- @highest_point = pt if(@highest_point.nil? or pt.elevation > @highest_point.elevation)
228
+ @lowest_point = pt if @lowest_point.nil? || (pt.elevation < @lowest_point.elevation)
229
+ @highest_point = pt if @highest_point.nil? || (pt.elevation > @highest_point.elevation)
260
230
  end
261
231
  @bounds.add(pt)
262
- if last_pt
263
- @distance += haversine_distance(last_pt, pt)
264
- @duration += pt.time - last_pt.time if pt.time and last_pt.time
265
- end
266
- end
267
232
 
233
+ return unless last_pt
234
+ @distance += haversine_distance(last_pt, pt)
235
+ @duration += pt.time - last_pt.time if pt.time && last_pt.time
236
+ end
268
237
  end
269
-
270
238
  end