geospatial 1.9.0 → 1.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d26cdfa5dc37ae8c5babc8fe2f9b75de730d8a77457eeedfd46e19fd78c26cf2
4
- data.tar.gz: 87f0287c0c44849e126ed8787342d29bec1d234f53aa4e3a10ed2e211cc1f9c2
3
+ metadata.gz: 7b9278cfa60e44d9e04909e2b6b8a7525c736a7598b19a04d33765d628b7b0ad
4
+ data.tar.gz: 109c4077b0697a1725320a006aa3a3a2478ba0974dac557ec6be93e50e4b96be
5
5
  SHA512:
6
- metadata.gz: 06d18d27fae0ff6effafa7113c95d6a85716b92c0f0c5e228bb5e32e089f2846f46086790e0800f3aabfc4abee36d4e0e58ad5f0b8b24634153e70e652301049
7
- data.tar.gz: d77dd4410904c5dc17f0226fd226cec6c394d8fbf291e6cbfc068a167e2b551e2d64b5411d4e20c05c59639ca63efbccc84b559de35dff69a589fc9639b0509b
6
+ metadata.gz: 86c0acee5bd439284b99d27d1ee8cb86d1d7caed9acadda62ff057f3dc7afe00d4f79685e519360ed1eae3a847360445e8ce585a58155e095a42e5aa983bb883
7
+ data.tar.gz: 37b7366f03b68f2cca3cc28e36b5160954dfa921ec2a00613a5d8d1a862f1bfb48e52836a822d8ab04b91a1fa1f0286bd83b312e2d124774985d8dd855c5f29a
@@ -7,50 +7,61 @@
7
7
  module Geospatial
8
8
  # This location is specifically relating to a WGS84 coordinate on Earth.
9
9
  class Histogram
10
- def initialize(min = 0, max = 1, scale = 0.1)
10
+ def initialize(min: 0, max: 1, scale: 0.1)
11
11
  @min = min
12
12
  @max = max
13
13
  @scale = scale
14
14
 
15
- @count = ((@max - @min) / @scale).ceil
16
- @bins = [0] * @count
15
+ @count = 0
16
+
17
+ @size = ((@max - @min) / @scale).ceil
18
+ @bins = [0] * @size
17
19
  @offset = 0
18
20
  @scale = scale
19
21
  end
20
22
 
21
- attr :bins
23
+ attr_accessor :bins
24
+
25
+ attr :count
22
26
 
23
27
  attr :offset
24
28
  attr :scale
25
29
 
30
+ def [] index
31
+ @bins[index]
32
+ end
33
+
34
+ def size
35
+ @bins.size
36
+ end
37
+
26
38
  def map(value)
27
39
  ((value - @min) / @scale)
28
40
  end
29
41
 
30
42
  def unmap(index)
31
- @min + ((index + 0.5) * @scale)
43
+ @min + (index * @scale)
32
44
  end
33
45
 
34
46
  def add(value, amount = 1)
35
- index = map(value).floor
47
+ index = map(value).floor % @size
36
48
 
37
- if @bins[index]
49
+ if !block_given? or yield(index, value)
50
+ @count += 1
38
51
  @bins[index] += amount
39
- else
40
- @bins[index] = amount
41
52
  end
42
53
 
43
- return self
54
+ return index
44
55
  end
45
56
 
46
57
  def inspect
47
58
  buffer = String.new("\#<#{self.class}")
48
59
 
49
60
  @bins.each_with_index do |bin, index|
50
- buffer << "\n#{unmap(index).to_s.rjust(8)}: #{bin}"
61
+ buffer << " #{unmap(index)}: #{bin}"
51
62
  end
52
63
 
53
- buffer << "\n>"
64
+ buffer << ">"
54
65
  end
55
66
 
56
67
  def each
@@ -60,11 +71,15 @@ module Geospatial
60
71
  yield unmap(index), value
61
72
  end
62
73
  end
74
+
75
+ def peaks
76
+ Peaks.new(self)
77
+ end
63
78
  end
64
79
 
65
80
  class RadialHistogram < Histogram
66
- def initialize(center, min = -180, max = 180, scale = 10)
67
- super(min, max, scale)
81
+ def initialize(center, min: -180, max: 180, scale: 1)
82
+ super(min: min, max: max, scale: scale)
68
83
 
69
84
  @center = center
70
85
  end
@@ -73,4 +88,58 @@ module Geospatial
73
88
  super(point.bearing_from(@center), value)
74
89
  end
75
90
  end
91
+
92
+ class Peaks
93
+ include Enumerable
94
+
95
+ def initialize(values)
96
+ @values = values
97
+ @derivative = []
98
+
99
+ s = @values.size
100
+
101
+ @values.size.times do |i|
102
+ # Apply the Laplacian of Gaussians to compute the gradient changes:
103
+ # @derivative << (@values[i-2] * -1) + (@values[i-1] * -1) + (@values[i] * 4) + (@values[i+1-s] * -1) + (@values[i+2-s] * -1)
104
+ @derivative << (2.0 * @values[i-1]) + (-2.0 * @values[i+1-s])
105
+ end
106
+ end
107
+
108
+ attr :derivative
109
+
110
+ def each
111
+ return to_enum unless block_given?
112
+
113
+ @derivative.each_with_index do |y2, x2|
114
+ x1 = x2 - 1
115
+ y1 = @derivative[x1]
116
+
117
+ if (y1 <= 0 and y2 > 0) or (y1 > 0 and y2 <= 0)
118
+ # There has been a zero crossing, so we have a peak somewhere here:
119
+ g = (y2.to_f - y1.to_f)
120
+ m = (-y1.to_f / g)
121
+
122
+ yield x1 + m, g
123
+ end
124
+ end
125
+ end
126
+
127
+ def segments
128
+ return to_enum(:segments) unless block_given?
129
+
130
+ gradients = self.to_a
131
+
132
+ return if gradients.empty?
133
+
134
+ index, gradient = gradients.first
135
+
136
+ if gradient < 0
137
+ gradients.push gradients.shift
138
+ end
139
+
140
+ gradients.each_slice(2) do |up, down|
141
+ yield up, down
142
+ end
143
+ end
144
+ end
76
145
  end
@@ -158,10 +158,10 @@ module Geospatial
158
158
  # calculate distance in metres between us and something else
159
159
  # ref: http://codingandweb.blogspot.co.nz/2012/04/calculating-distance-between-two-points.html
160
160
  def distance_from(other)
161
- rlong1 = self.longitude * D2R
162
- rlat1 = self.latitude * D2R
163
- rlong2 = other.longitude * D2R
164
- rlat2 = other.latitude * D2R
161
+ rlong1 = self.longitude * D2R
162
+ rlat1 = self.latitude * D2R
163
+ rlong2 = other.longitude * D2R
164
+ rlat2 = other.latitude * D2R
165
165
 
166
166
  dlon = rlong1 - rlong2
167
167
  dlat = rlat1 - rlat2
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Geospatial
22
- VERSION = "1.9.0"
22
+ VERSION = "1.10.0"
23
23
  end
@@ -0,0 +1,30 @@
1
+ #
2
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
3
+ #
4
+ # This file is part of the "geospatial" project and is released under the MIT license.
5
+ #
6
+
7
+ require 'geospatial/histogram'
8
+
9
+ RSpec.describe Geospatial::Histogram do
10
+ subject do
11
+ described_class.new(min: -180, max: 180, scale: 10).tap do |histogram|
12
+ histogram.bins = [0, 80, 540, 101, 29, 1880, 41, 23, 115, 715, 362, 244, 358, 955, 50, 53, 11, 7, 151, 43, 353, 1514, 2, 2, 0, 0, 0, 0, 0, 6, 155, 1737, 959, 1482, 110, 0]
13
+ end
14
+ end
15
+
16
+ it "should generate appropriate peaks" do
17
+ peaks = subject.peaks
18
+
19
+ subject.bins.each_with_index do |v, i|
20
+ d = subject.peaks.derivative[i]
21
+ puts "#{i}, #{v}, #{d}"
22
+ end
23
+
24
+ peaks.each do |x, dx|
25
+ puts "Peak at #{x}: #{dx}"
26
+ end
27
+
28
+ puts peaks.segments.to_a.inspect
29
+ end
30
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geospatial
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-08 00:00:00.000000000 Z
11
+ date: 2018-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -92,6 +92,7 @@ files:
92
92
  - spec/geospatial/filter_spec.rb
93
93
  - spec/geospatial/hilbert_curve_spec.rb
94
94
  - spec/geospatial/hilbert_traverse_spec.rb
95
+ - spec/geospatial/histogram_spec.rb
95
96
  - spec/geospatial/index_spec.rb
96
97
  - spec/geospatial/location_spec.rb
97
98
  - spec/geospatial/map_index_spec.rb
@@ -134,6 +135,7 @@ test_files:
134
135
  - spec/geospatial/filter_spec.rb
135
136
  - spec/geospatial/hilbert_curve_spec.rb
136
137
  - spec/geospatial/hilbert_traverse_spec.rb
138
+ - spec/geospatial/histogram_spec.rb
137
139
  - spec/geospatial/index_spec.rb
138
140
  - spec/geospatial/location_spec.rb
139
141
  - spec/geospatial/map_index_spec.rb