git-fit 0.18.2 → 0.18.3

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: 41afe213d0cfd11467217bc1fca559a90d791d08131f4ad2a8b1be69655cdfbe
4
- data.tar.gz: bd97306411a2b55af3a0253646cbd43aff7907d4253175ea88372cea457f7e0c
3
+ metadata.gz: 4885ddbb01fd4680fac6ae16c6fd3c1b90092910abcef29b317cacd351ee3c1a
4
+ data.tar.gz: e5257d8d6ddcbd46e8e8e07fda87316fcea76ebc1f47ed0da784ba744e6f4e35
5
5
  SHA512:
6
- metadata.gz: eee9145cb899365d6cc669dcc065e6df9d9785ce97522c3e0f561f40225193400f664158b7335395d655b4c5a4d927e835098a39a1a4cb686ff38f4deac455e0
7
- data.tar.gz: 748ed231a6b7ac6fe293e6c5481da6207cf87472645214019c468ed9f95628f2943bd955980df2e4d56456af6f7dae7891c53b0d67159d9ebb799c20b6e2dbeb
6
+ metadata.gz: c398fbe3e1740edf11ee63e02dd7f22816d6c0304144844f66e6a41e42415f79e263a6a8d6b8d26b4959a64c6d38a4e7e971d2bc97465daacc3475a611ebd380
7
+ data.tar.gz: 3cf2651b1d8754e28f23f682970757b4e4ba3f1cecda3126c127ccb71ebe09f0c9ce2244ea6f48a1119b46d97a110ed15fcc59c0a8f403c8960fc67e6c745b50
@@ -4,6 +4,8 @@ require 'msgpack'
4
4
  require 'net/http'
5
5
  require 'uri'
6
6
 
7
+ require_relative 'terrain_lookup'
8
+
7
9
  module GitFit
8
10
  module Elevation
9
11
  module TerrainCoeff
@@ -49,33 +51,39 @@ module GitFit
49
51
  end
50
52
 
51
53
  def hysteresis_threshold(m_val)
52
- return 2.0 if m_val <= 0
53
- pav = model['pav_h']
54
- return 2.0 if m_val <= pav[0][0]
55
- return pav[-1][1] if m_val >= pav[-1][0]
56
- pav.each_with_index do |(_xk, yk), i|
57
- next unless i + 1 < pav.size
58
- return yk if m_val <= pav[i + 1][0]
59
- end
60
- pav[-1][1]
54
+ Lookup.hysteresis_threshold(model['pav_h'], m_val)
61
55
  end
62
56
 
63
57
  def dem_spacing(gain_per_km:, range_per_km:, seg_density:)
64
- nearest_neighbor_spacing(gain_per_km, range_per_km, seg_density)
58
+ Lookup.nearest_neighbor_spacing(lookup, gain_per_km, range_per_km, seg_density)
65
59
  rescue StandardError => e
66
60
  warn "TerrainCoeff: dem_spacing fallback to 181m (#{e.message})"
67
61
  181
68
62
  end
69
63
 
70
64
  def elevations_for(locations)
65
+ uniq_vals = uniquify_locations(locations)
66
+ elevs = {}
67
+ uniq_vals.each_slice(100).with_index do |slice, bi|
68
+ elevs.merge!(fetch_dem_batch(slice, bi))
69
+ sleep 0.15
70
+ end
71
+ locations.map { |lat, lng| elevs[grid_key(lat, lng)] }
72
+ end
73
+
74
+ def uniquify_locations(locations)
71
75
  uniq = {}
72
76
  locations.each { |lat, lng| uniq[grid_key(lat, lng)] ||= [lat, lng] }
73
- uniq_vals = uniq.values
77
+ uniq.values
78
+ end
74
79
 
80
+ def fetch_dem_batch(slice, batch_idx)
75
81
  elevs = {}
76
- uniq_vals.each_slice(100).with_index do |slice, bi|
77
- qs = slice.map { |la, ln| "#{la},#{ln}" }.join('|')
78
- uri = URI("#{DEM_URL}?locations=#{qs.gsub(',', '%2C').gsub('|', '%7C')}")
82
+ qs = slice.map { |la, ln| "#{la},#{ln}" }.join('|')
83
+ uri = URI("#{DEM_URL}?locations=#{qs.gsub(',', '%2C').gsub('|', '%7C')}")
84
+ attempt = 0
85
+ loop do
86
+ # rubocop:disable Style/RedundantBegin
79
87
  begin
80
88
  res = Net::HTTP.get_response(uri)
81
89
  if res.code == '200'
@@ -83,16 +91,28 @@ module GitFit
83
91
  slice.each_with_index do |(lat, lng), i|
84
92
  elevs[grid_key(lat, lng)] = results[i]['elevation'] if results[i]
85
93
  end
94
+ break
95
+ elsif res.code == '429'
96
+ attempt += 1
97
+ if attempt < 5
98
+ delay = 2**attempt
99
+ warn "DEM batch #{batch_idx}: rate limited, retrying in #{delay}s (attempt #{attempt})"
100
+ sleep(delay)
101
+ else
102
+ warn "DEM batch #{batch_idx}: rate limited, giving up after #{attempt} attempts"
103
+ break
104
+ end
86
105
  else
87
- warn "DEM batch #{bi} HTTP #{res.code}"
106
+ warn "DEM batch #{batch_idx} HTTP #{res.code}"
107
+ break
88
108
  end
89
109
  rescue StandardError => e
90
- warn "DEM batch #{bi}: #{e.message}"
110
+ warn "DEM batch #{batch_idx}: #{e.message}"
111
+ break
91
112
  end
92
- sleep 0.15
113
+ # rubocop:enable Style/RedundantBegin
93
114
  end
94
-
95
- locations.map { |lat, lng| elevs[grid_key(lat, lng)] }
115
+ elevs
96
116
  end
97
117
 
98
118
  def grid_key(lat, lng)
@@ -102,24 +122,6 @@ module GitFit
102
122
  def lookup
103
123
  model['lookup']
104
124
  end
105
-
106
- private
107
-
108
- def nearest_neighbor_spacing(gain_per_km, range_per_km, seg_density)
109
- best = nil
110
- best_dist = Float::INFINITY
111
- lookup.each do |ref|
112
- d = Math.sqrt(
113
- (gain_per_km.to_f - ref['gk'])**2 +
114
- (range_per_km.to_f - ref['rk'])**2 +
115
- (seg_density.to_f - ref['sd'])**2,
116
- )
117
- next unless d < best_dist
118
- best_dist = d
119
- best = ref
120
- end
121
- best ? best['sp'] : 181
122
- end
123
125
  end
124
126
  end
125
127
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GitFit
4
+ module Elevation
5
+ module TerrainCoeff
6
+ module Lookup
7
+ class << self
8
+ def nearest_neighbor_spacing(model_lookup, gain_per_km, range_per_km, seg_density)
9
+ best = nil
10
+ best_dist = Float::INFINITY
11
+ model_lookup.each do |ref|
12
+ d = Math.sqrt(
13
+ (gain_per_km.to_f - ref['gk'])**2 +
14
+ (range_per_km.to_f - ref['rk'])**2 +
15
+ (seg_density.to_f - ref['sd'])**2,
16
+ )
17
+ next unless d < best_dist
18
+ best_dist = d
19
+ best = ref
20
+ end
21
+ best ? best['sp'] : 181
22
+ end
23
+
24
+ def hysteresis_threshold(model_pav_h, m_val)
25
+ return 2.0 if m_val <= 0
26
+ return 2.0 if m_val <= model_pav_h[0][0]
27
+ return model_pav_h[-1][1] if m_val >= model_pav_h[-1][0]
28
+ model_pav_h.each_with_index do |(_xk, yk), i|
29
+ next unless i + 1 < model_pav_h.size
30
+ return yk if m_val <= model_pav_h[i + 1][0]
31
+ end
32
+ model_pav_h[-1][1]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -37,7 +37,7 @@ module GitFit
37
37
 
38
38
  def resolve_sources(names)
39
39
  names.map do |name|
40
- Sync::Base.adapters.find { |a| a.name.demodulize.downcase == name.to_s.downcase }
40
+ Sync::Base.adapters.find { |a| a.config_key == name.to_s }
41
41
  end.compact
42
42
  end
43
43
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GitFit
4
- VERSION = '0.18.2'
4
+ VERSION = '0.18.3'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-fit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.2
4
+ version: 0.18.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lax
@@ -296,6 +296,7 @@ files:
296
296
  - lib/git_fit/elevation/data/dem_coeff.json
297
297
  - lib/git_fit/elevation/data/dem_lookup.json
298
298
  - lib/git_fit/elevation/terrain_coeff.rb
299
+ - lib/git_fit/elevation/terrain_lookup.rb
299
300
  - lib/git_fit/elevation/train/collector.rb
300
301
  - lib/git_fit/elevation/train/fitter.rb
301
302
  - lib/git_fit/elevation/train/runner.rb