quadtree 1.0.7 → 1.0.9
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 +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +9 -7
- data/Rakefile +18 -10
- data/VERSION +1 -1
- data/lib/quadtree/axis_aligned_bounding_box.rb +155 -108
- data/lib/quadtree/point.rb +161 -107
- data/lib/quadtree/quadtree.rb +222 -148
- data/lib/quadtree/unknown_type_error.rb +8 -7
- data/lib/quadtree/version.rb +7 -5
- data/lib/quadtree.rb +16 -14
- data/quadtree.gemspec +25 -32
- metadata +36 -26
- data/.editorconfig +0 -12
- data/.gitignore +0 -208
- data/.rspec +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3196d863c8fc7af5fe94d18fe481408c3ec38e008bdc5f778c8d1ea5125d8486
|
4
|
+
data.tar.gz: 971b02c0527fc9023d1fb04a50aaf4091129c933c4b937f8095c6624fc251424
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2140f02c514b1fc60fc9c2202065bdf6e9a9811efafd632a0b1b58e93eabdcc622f6d548e377c2a3b524a02dcca53a330100ab10c3c0fe9a38822ce405cfb7b0
|
7
|
+
data.tar.gz: ddc469e27f0f8c156687ad99810a73edbf54ceb15eaa7cd1f260073c7a9d308d1add9047cec4c0547c5c59d7319920d994b34cdb91f7da69d9f1b06bbb408661
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c)
|
3
|
+
Copyright (c) 2022 Jan Lindblom (janlindblom@fastmail.fm)
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# Quadtree
|
2
2
|
|
3
|
-

|
4
|
-
[](https://bitbucket.org/janlindblom/ruby-quadtree)
|
5
3
|
[](https://rubygems.org/gems/quadtree)
|
6
4
|
[](http://www.rubydoc.info/gems/quadtree/frames)
|
7
5
|
|
@@ -17,11 +15,15 @@ gem 'quadtree'
|
|
17
15
|
|
18
16
|
And then execute:
|
19
17
|
|
20
|
-
|
18
|
+
```bash
|
19
|
+
bundle
|
20
|
+
```
|
21
21
|
|
22
22
|
Or install it yourself as:
|
23
23
|
|
24
|
-
|
24
|
+
```bash
|
25
|
+
gem install quadtree
|
26
|
+
```
|
25
27
|
|
26
28
|
## Usage
|
27
29
|
|
@@ -56,12 +58,12 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
56
58
|
|
57
59
|
## Contributing
|
58
60
|
|
59
|
-
Bug reports and pull requests are welcome on
|
61
|
+
Bug reports and pull requests are welcome on Github at <https://github.com/janlindblom/ruby-quadtree>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
60
62
|
|
61
63
|
## License
|
62
64
|
|
63
|
-
The gem is available as open source under the terms of the [MIT License](https://
|
65
|
+
The gem is available as open source under the terms of the [MIT License](https://github.com/janlindblom/ruby-quadtree/blob/master/LICENSE.txt).
|
64
66
|
|
65
67
|
## Code of Conduct
|
66
68
|
|
67
|
-
Everyone interacting in the Quadtree project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
69
|
+
Everyone interacting in the Quadtree project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/janlindblom/ruby-quadtree/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -18,14 +18,21 @@ spec = Gem::Specification.new do |s|
|
|
18
18
|
s.email = ["janlindblom@fastmail.fm"]
|
19
19
|
|
20
20
|
s.summary = %q{Quadtrees in Ruby.}
|
21
|
-
s.homepage = "https://
|
21
|
+
s.homepage = "https://github.com/janlindblom/ruby-quadtree"
|
22
22
|
s.license = "MIT"
|
23
23
|
|
24
24
|
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
25
|
-
f.match(%r{^(bin|test|spec|features)/}) ||
|
25
|
+
f.match(%r{^(bin|test|spec|features|.github)/}) ||
|
26
26
|
f == ".travis.yml" ||
|
27
|
+
f == ".gitignore" ||
|
28
|
+
f == ".editorconfig" ||
|
29
|
+
f == ".rspec" ||
|
27
30
|
f == "bitbucket-pipelines.yml" ||
|
28
|
-
f == "buildspec.yml"
|
31
|
+
f == "buildspec.yml" ||
|
32
|
+
f == ".gitlab-ci.yml" ||
|
33
|
+
f == ".rubocop.yml" ||
|
34
|
+
f == ".rubocop_todo.yml" ||
|
35
|
+
f == "Jenkinsfile"
|
29
36
|
end
|
30
37
|
s.bindir = "exe"
|
31
38
|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
@@ -33,14 +40,15 @@ spec = Gem::Specification.new do |s|
|
|
33
40
|
|
34
41
|
s.required_ruby_version = '>= 2.3.0'
|
35
42
|
|
36
|
-
s.add_development_dependency "bundler", "~>
|
37
|
-
s.add_development_dependency "rake", "~>
|
38
|
-
s.add_development_dependency "rspec", "~> 3
|
39
|
-
s.add_development_dependency "pry", "~> 0.
|
43
|
+
s.add_development_dependency "bundler", "~> 2"
|
44
|
+
s.add_development_dependency "rake", "~> 13"
|
45
|
+
s.add_development_dependency "rspec", "~> 3"
|
46
|
+
s.add_development_dependency "pry", "~> 0.14"
|
40
47
|
s.add_development_dependency "yard", "~> 0.9"
|
41
|
-
s.add_development_dependency "simplecov", "~> 0.
|
42
|
-
s.add_development_dependency "
|
43
|
-
s.
|
48
|
+
s.add_development_dependency "simplecov", "~> 0.21"
|
49
|
+
s.add_development_dependency "rspec_junit_formatter", "~> 0.6"
|
50
|
+
s.add_development_dependency "rubocop", "~> 1"
|
51
|
+
s.add_runtime_dependency "version", "~> 1"
|
44
52
|
end
|
45
53
|
|
46
54
|
Rake::VersionTask.new do |task|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.9
|
@@ -1,108 +1,155 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# @param
|
18
|
-
|
19
|
-
|
20
|
-
@
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
#
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
#
|
68
|
-
#
|
69
|
-
# @return [
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
#
|
76
|
-
#
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Quadtree
|
4
|
+
# Axis-aligned bounding box with half dimension and center.
|
5
|
+
class AxisAlignedBoundingBox
|
6
|
+
# Center {Point} of this instance.
|
7
|
+
#
|
8
|
+
# @return [Point] the {Point} marking the center of this instance.
|
9
|
+
attr_accessor :center
|
10
|
+
|
11
|
+
# Half dimension of this instance (distance from the center {Point} to the
|
12
|
+
# edge).
|
13
|
+
#
|
14
|
+
# @return [Float] distance from the center {Point} to the edge.
|
15
|
+
attr_accessor :half_dimension
|
16
|
+
|
17
|
+
# @param center [Point]
|
18
|
+
# @param half_dimension [Float]
|
19
|
+
def initialize(center, half_dimension)
|
20
|
+
@center = center
|
21
|
+
@half_dimension = half_dimension.to_f
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Create a Hash for this {AxisAlignedBoundingBox}.
|
26
|
+
#
|
27
|
+
# @return [Hash] Hash representation of this {AxisAlignedBoundingBox}.
|
28
|
+
#
|
29
|
+
def to_h
|
30
|
+
{
|
31
|
+
'center': center.to_h,
|
32
|
+
'half_dimension': half_dimension
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Create a Hash for this {AxisAlignedBoundingBox}.
|
38
|
+
#
|
39
|
+
# @return [Hash] Hash representation of this {AxisAlignedBoundingBox}.
|
40
|
+
#
|
41
|
+
def to_hash
|
42
|
+
to_h
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Create a JSON String representation of this {AxisAlignedBoundingBox}.
|
47
|
+
#
|
48
|
+
# @return [String] JSON String of this {AxisAlignedBoundingBox}.
|
49
|
+
#
|
50
|
+
def to_json(*_args)
|
51
|
+
require 'json'
|
52
|
+
to_h.to_json
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Create a String for this {AxisAlignedBoundingBox}.
|
57
|
+
#
|
58
|
+
# @return [String] String representation of this {AxisAlignedBoundingBox}.
|
59
|
+
#
|
60
|
+
def to_s
|
61
|
+
to_h.to_s
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Construct a {AxisAlignedBoundingBox} from a JSON String.
|
66
|
+
#
|
67
|
+
# @param [String] json_data input JSON String.
|
68
|
+
#
|
69
|
+
# @return [AxisAlignedBoundingBox] the {AxisAlignedBoundingBox} contained in the JSON String.
|
70
|
+
#
|
71
|
+
def self.from_json(json_data)
|
72
|
+
new(Point.from_json(json_data['center']), json_data['half_dimension'])
|
73
|
+
end
|
74
|
+
|
75
|
+
# Check if this instance contains a given {Point}.
|
76
|
+
#
|
77
|
+
# @param point [Point] the {Point} to check for.
|
78
|
+
# @return [Boolean] +true+ if given {Point} is contained, +false+
|
79
|
+
# otherwise.
|
80
|
+
def contains_point?(point)
|
81
|
+
if point.x >= center.x - half_dimension &&
|
82
|
+
point.x <= center.x + half_dimension
|
83
|
+
if point.y >= center.y - half_dimension &&
|
84
|
+
point.y <= center.y + half_dimension
|
85
|
+
return true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
false
|
89
|
+
end
|
90
|
+
|
91
|
+
# Check if this instance intersects with another instance.
|
92
|
+
#
|
93
|
+
# @param other [AxisAlignedBoundingBox] the other instance to check for.
|
94
|
+
# @return [Boolean] +true+ if these intersects, +false+ otherwise.
|
95
|
+
def intersects?(other)
|
96
|
+
other_lt_corner = Point.new(other.left, other.top)
|
97
|
+
other_rt_corner = Point.new(other.right, other.top)
|
98
|
+
other_lb_corner = Point.new(other.left, other.bottom)
|
99
|
+
other_rb_corner = Point.new(other.right, other.bottom)
|
100
|
+
|
101
|
+
[other_lt_corner, other_rt_corner, other_lb_corner, other_rb_corner].each do |corner|
|
102
|
+
return true if contains_point?(corner)
|
103
|
+
end
|
104
|
+
false
|
105
|
+
end
|
106
|
+
|
107
|
+
# Get the X coordinate of the left edge of this instance.
|
108
|
+
#
|
109
|
+
# @return [Float] the X coordinate of the left edge of this instance.
|
110
|
+
def left
|
111
|
+
@center.x - @half_dimension
|
112
|
+
end
|
113
|
+
|
114
|
+
# Get the X coordinate of the right edge of this instance.
|
115
|
+
#
|
116
|
+
# @return [Float] the X coordinate of the right edge of this instance.
|
117
|
+
def right
|
118
|
+
@center.x + @half_dimension
|
119
|
+
end
|
120
|
+
|
121
|
+
# Get the Y coordinate of the top edge of this instance.
|
122
|
+
#
|
123
|
+
# @return [Float] the Y coordinate of the top edge of this instance.
|
124
|
+
def top
|
125
|
+
@center.y + @half_dimension
|
126
|
+
end
|
127
|
+
|
128
|
+
# Get the Y coordinate of the bottom edge of this instance.
|
129
|
+
#
|
130
|
+
# @return [Float] the Y coordinate of the bottom edge of this instance.
|
131
|
+
def bottom
|
132
|
+
@center.y - @half_dimension
|
133
|
+
end
|
134
|
+
|
135
|
+
# Get the width of this instance.
|
136
|
+
#
|
137
|
+
# @return [Float]
|
138
|
+
def width
|
139
|
+
span
|
140
|
+
end
|
141
|
+
|
142
|
+
# Get the height of this instance.
|
143
|
+
#
|
144
|
+
# @return [Float]
|
145
|
+
def height
|
146
|
+
span
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def span
|
152
|
+
@half_dimension * 2
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
data/lib/quadtree/point.rb
CHANGED
@@ -1,107 +1,161 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Quadtree
|
4
|
+
# Simple coordinate object to represent points in some space.
|
5
|
+
class Point
|
6
|
+
# The X coordinate of this instance.
|
7
|
+
# @return [Float, Integer] X coordinate.
|
8
|
+
attr_accessor :x
|
9
|
+
|
10
|
+
# The Y coordinate of this instance.
|
11
|
+
# @return [Float, Integer] Y coordinate.
|
12
|
+
attr_accessor :y
|
13
|
+
|
14
|
+
# Optional payload attached to this instance.
|
15
|
+
# @return [Object] payload attached to this instance.
|
16
|
+
attr_accessor :data
|
17
|
+
|
18
|
+
# @param x [Float, Integer] X coordinate.
|
19
|
+
# @param y [Float, Integer] Y coordinate.
|
20
|
+
# @param data [Object] payload payload attached to this instance
|
21
|
+
# (optional).
|
22
|
+
# @raise [UnknownTypeError] if one or more input parameters (+x+ and +y+)
|
23
|
+
# has the wrong type.
|
24
|
+
def initialize(x, y, data = nil)
|
25
|
+
self.x = get_typed_numeric(x)
|
26
|
+
self.y = get_typed_numeric(y)
|
27
|
+
|
28
|
+
self.data = data unless data.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Create a Hash for this {Point}.
|
33
|
+
#
|
34
|
+
# @return [Hash] Hash representation of this {Point}.
|
35
|
+
#
|
36
|
+
def to_h
|
37
|
+
{
|
38
|
+
'x': x,
|
39
|
+
'y': y,
|
40
|
+
'data': process_data(data)
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Create a Hash for this {Point}.
|
46
|
+
#
|
47
|
+
# @return [Hash] Hash representation of this {Point}.
|
48
|
+
#
|
49
|
+
def to_hash
|
50
|
+
to_h
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Create a JSON String representation of this {Point}.
|
55
|
+
#
|
56
|
+
# @return [String] JSON String of this {Point}.
|
57
|
+
#
|
58
|
+
def to_json(*_args)
|
59
|
+
require 'json'
|
60
|
+
to_h.to_json
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Create a String for this {Point}.
|
65
|
+
#
|
66
|
+
# @return [String] String representation of this {Point}.
|
67
|
+
#
|
68
|
+
def to_s
|
69
|
+
to_h.to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Construct a {Quadtree::Point} from a JSON String.
|
74
|
+
#
|
75
|
+
# @param [String] json_data input JSON String.
|
76
|
+
#
|
77
|
+
# @return [Quadtree::Point] the {Quadtree::Point} contained in the JSON String.
|
78
|
+
#
|
79
|
+
def self.from_json(json_data)
|
80
|
+
new(json_data['x'], json_data['y'], json_data['data'])
|
81
|
+
end
|
82
|
+
|
83
|
+
# This will calculate distance to another {Point}, given that they are
|
84
|
+
# both in the same 2D space.
|
85
|
+
#
|
86
|
+
# @param other [Point] the other {Point}.
|
87
|
+
# @return [Float] the distance to the other {Point}.
|
88
|
+
def distance_to(other)
|
89
|
+
Math.sqrt((other.x - x)**2 + (other.y - y)**2)
|
90
|
+
end
|
91
|
+
|
92
|
+
# This will calculate distance to another {Point} using the Haversine
|
93
|
+
# formula. This means that it will treat {#x} as longitude and {#y} as
|
94
|
+
# latitude!
|
95
|
+
#
|
96
|
+
# a = sin²(Δφ/2) + cos φ_1 ⋅ cos φ_2 ⋅ sin²(Δλ/2)
|
97
|
+
#
|
98
|
+
# c = 2 ⋅ atan2( √a, √(1−a) )
|
99
|
+
#
|
100
|
+
# d = R ⋅ c
|
101
|
+
#
|
102
|
+
# where φ is latitude, λ is longitude, R is earth’s radius (mean
|
103
|
+
# radius = 6 371 km);
|
104
|
+
# note that angles need to be in radians to pass to trig functions!
|
105
|
+
#
|
106
|
+
# @param other [Point] the other {Point}.
|
107
|
+
# @return [Float] the distance, in meters, to the other {Point}.
|
108
|
+
def haversine_distance_to(other)
|
109
|
+
lat1 = y * (Math::PI / 180.0)
|
110
|
+
lat2 = other.y * (Math::PI / 180.0)
|
111
|
+
dlat = (other.y - y) * (Math::PI / 180.0)
|
112
|
+
dlon = (other.x - x) * (Math::PI / 180.0)
|
113
|
+
|
114
|
+
# a = sin²(Δφ/2) + cos φ_1 ⋅ cos φ_2 ⋅ sin²(Δλ/2)
|
115
|
+
a = calculate_haversine_a(lat1, lat2, dlat, dlon)
|
116
|
+
# c = 2 ⋅ atan2( √a, √(1−a) )
|
117
|
+
c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
118
|
+
# d = R ⋅ c
|
119
|
+
6371 * 1000.0 * c
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def calculate_haversine_a(lat1, lat2, dlat, dlon)
|
125
|
+
Math.sin(dlat / 2.0) * Math.sin(dlat / 2.0) +
|
126
|
+
Math.cos(lat1) * Math.cos(lat2) *
|
127
|
+
Math.sin(dlon / 2.0) * Math.sin(dlon / 2.0)
|
128
|
+
end
|
129
|
+
|
130
|
+
def process_data(data)
|
131
|
+
data.nil? || data.is_a?(Array) || data.is_a?(String) || data.is_a?(Numeric) ? data : data.to_h
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_typed_numeric(any_input)
|
135
|
+
# Try integer first since float will parse integers too
|
136
|
+
return get_integer(any_input) unless get_integer(any_input).nil?
|
137
|
+
# Try Float next
|
138
|
+
return get_float(any_input) unless get_float(any_input).nil?
|
139
|
+
|
140
|
+
raise UnknownTypeError, "Unknown type for parameter: #{any_input.class}"
|
141
|
+
end
|
142
|
+
|
143
|
+
def get_integer(any_input)
|
144
|
+
return Integer(any_input) if any_input.is_a? String
|
145
|
+
return any_input if any_input.is_a? Integer
|
146
|
+
|
147
|
+
nil
|
148
|
+
rescue StandardError
|
149
|
+
nil
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_float(any_input)
|
153
|
+
return Float(any_input) if any_input.is_a? String
|
154
|
+
return any_input if any_input.is_a? Float
|
155
|
+
|
156
|
+
nil
|
157
|
+
rescue StandardError
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|