Class: Terraformer::Coordinate
- Inherits:
-
Object
- Object
- Terraformer::Coordinate
- Defined in:
- lib/terraformer/coordinate.rb
Constant Summary collapse
- EARTH_MEAN_RADIUS =
6371009.to_d
Instance Attribute Summary collapse
-
#ary ⇒ Object
array holding the numeric coordinate values.
-
#crs ⇒ Object
Returns the value of attribute crs.
Class Method Summary collapse
Instance Method Summary collapse
- #+(obj) ⇒ Object
- #-(obj) ⇒ Object
- #<=>(other) ⇒ Object
- #==(other) ⇒ Object
- #[](index) ⇒ Object
- #buffer(radius, resolution = DEFAULT_BUFFER_RESOLUTION) ⇒ Object
- #distance_and_bearing_to(obj) ⇒ Object
- #distance_to(obj) ⇒ Object
- #dup ⇒ Object
- #euclidean_distance_to(obj) ⇒ Object
- #final_bearing_to(obj) ⇒ Object
- #geographic? ⇒ Boolean
- #haversine_distance_to(other) ⇒ Object
- #initial_bearing_to(obj) ⇒ Object
-
#initialize(_x, _y = nil, _z = nil) ⇒ Coordinate
constructor
A new instance of Coordinate.
- #inspect ⇒ Object
- #mercator? ⇒ Boolean
- #squared_euclidean_distance_to(obj) ⇒ Object
- #to_geographic ⇒ Object
- #to_json(*args) ⇒ Object
- #to_mercator ⇒ Object
- #to_point ⇒ Object
- #to_s ⇒ Object
- #x ⇒ Object (also: #lon)
- #x=(_x) ⇒ Object
- #y ⇒ Object (also: #lat)
- #y=(_y) ⇒ Object
- #z ⇒ Object
- #z=(_z) ⇒ Object
Constructor Details
#initialize(_x, _y = nil, _z = nil) ⇒ Coordinate
Returns a new instance of Coordinate.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/terraformer/coordinate.rb', line 43 def initialize _x, _y = nil, _z = nil @ary = Array.new 3 case _x when Array raise ArgumentError if _y self.x = _x[0] self.y = _x[1] self.z = _x[2] if _x[2] when Coordinate raise ArgumentError if _y self.x = _x.x self.y = _x.y self.z = _x.z if _x.z when Numeric, String raise ArgumentError unless _y self.x = _x self.y = _y self.z = _z if _z else raise ArgumentError.new "invalid argument: #{_x}" end end |
Instance Attribute Details
#ary ⇒ Object
array holding the numeric coordinate values
12 13 14 |
# File 'lib/terraformer/coordinate.rb', line 12 def ary @ary end |
#crs ⇒ Object
Returns the value of attribute crs.
9 10 11 |
# File 'lib/terraformer/coordinate.rb', line 9 def crs @crs end |
Class Method Details
.big_decimal(n) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/terraformer/coordinate.rb', line 28 def big_decimal n case n when String BigDecimal(n) when BigDecimal n when Numeric BigDecimal(n.to_s) else raise ArgumentError end end |
.from_array(a) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/terraformer/coordinate.rb', line 16 def from_array a if Coordinate === a a.dup elsif Numeric === a[0] Coordinate.new a elsif Array === a a.map {|e| Coordinate.from_array e } else raise ArgumentError end end |
Instance Method Details
#+(obj) ⇒ Object
192 193 194 |
# File 'lib/terraformer/coordinate.rb', line 192 def + obj arithmetic :+, obj end |
#-(obj) ⇒ Object
196 197 198 |
# File 'lib/terraformer/coordinate.rb', line 196 def - obj arithmetic :-, obj end |
#<=>(other) ⇒ Object
169 170 171 172 173 174 175 176 177 178 |
# File 'lib/terraformer/coordinate.rb', line 169 def <=> other raise ArgumentError unless Coordinate === other dx = x - other.x dy = y - other.y case when dx > dy; 1 when dx < dy; -1 else; 0 end end |
#==(other) ⇒ Object
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/terraformer/coordinate.rb', line 102 def == other case other when Array @ary == other when Coordinate @ary == other.ary else false end end |
#[](index) ⇒ Object
98 99 100 |
# File 'lib/terraformer/coordinate.rb', line 98 def [] index @ary[index] end |
#buffer(radius, resolution = DEFAULT_BUFFER_RESOLUTION) ⇒ Object
158 159 160 161 162 163 164 165 166 167 |
# File 'lib/terraformer/coordinate.rb', line 158 def buffer radius, resolution = DEFAULT_BUFFER_RESOLUTION center = to_mercator unless mercator? coordinates = (1..resolution).map {|step| radians = step.to_d * (360.to_d / resolution.to_d) * PI / 180.to_d [center.x + radius.to_d * BigMath.cos(radians, PRECISION), center.y + radius.to_d * BigMath.sin(radians, PRECISION)] } coordinates << coordinates[0] Polygon.new(coordinates).to_geographic end |
#distance_and_bearing_to(obj) ⇒ Object
231 232 233 234 |
# File 'lib/terraformer/coordinate.rb', line 231 def distance_and_bearing_to obj raise ArgumentError unless Coordinate === obj Geodesic.compute_distance_and_bearing y, x, obj.y, obj.x end |
#distance_to(obj) ⇒ Object
236 237 238 |
# File 'lib/terraformer/coordinate.rb', line 236 def distance_to obj distance_and_bearing_to(obj)[:distance] end |
#dup ⇒ Object
68 69 70 |
# File 'lib/terraformer/coordinate.rb', line 68 def dup Coordinate.new @ary.dup end |
#euclidean_distance_to(obj) ⇒ Object
207 208 209 |
# File 'lib/terraformer/coordinate.rb', line 207 def euclidean_distance_to obj BigMath.sqrt squared_euclidean_distance_to(obj), PRECISION end |
#final_bearing_to(obj) ⇒ Object
244 245 246 |
# File 'lib/terraformer/coordinate.rb', line 244 def final_bearing_to obj distance_and_bearing_to(obj)[:bearing][:final] end |
#geographic? ⇒ Boolean
150 151 152 |
# File 'lib/terraformer/coordinate.rb', line 150 def geographic? crs.nil? or crs == GEOGRAPHIC_CRS end |
#haversine_distance_to(other) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/terraformer/coordinate.rb', line 211 def haversine_distance_to other raise ArgumentError unless Coordinate === other d_lat = (self.y - other.y).to_rad d_lon = (self.x - other.x).to_rad lat_r = self.y.to_rad other_lat_r = other.y.to_rad a = BigMath.sin(d_lat / 2, PRECISION)**2 + BigMath.sin(d_lon / 2, PRECISION)**2 * BigMath.cos(lat_r, PRECISION) * BigMath.cos(other_lat_r, PRECISION) y = BigMath.sqrt a, PRECISION x = BigMath.sqrt (1 - a), PRECISION c = 2 * BigMath.atan2(y, x, PRECISION) c * EARTH_MEAN_RADIUS end |
#initial_bearing_to(obj) ⇒ Object
240 241 242 |
# File 'lib/terraformer/coordinate.rb', line 240 def initial_bearing_to obj distance_and_bearing_to(obj)[:bearing][:initial] end |
#inspect ⇒ Object
113 114 115 |
# File 'lib/terraformer/coordinate.rb', line 113 def inspect "#<Terraformer::Coordinate lon=#{lon.to_s 'F'} lat=#{lat.to_s 'F'} #{z if z }>" end |
#mercator? ⇒ Boolean
154 155 156 |
# File 'lib/terraformer/coordinate.rb', line 154 def mercator? crs == MERCATOR_CRS end |
#squared_euclidean_distance_to(obj) ⇒ Object
200 201 202 203 204 205 |
# File 'lib/terraformer/coordinate.rb', line 200 def squared_euclidean_distance_to obj raise ArgumentError unless Coordinate === obj dx = obj.x - x dy = obj.y - y dx * dx + dy * dy end |
#to_geographic ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/terraformer/coordinate.rb', line 117 def to_geographic xerd = (x / EARTH_RADIUS).to_deg _x = xerd - (((xerd + 180.0) / 360.0).floor * 360.0) _y = ( (Math::PI / 2).to_d - (2 * BigMath.atan(BigMath.exp(-1.0 * y / EARTH_RADIUS, PRECISION), PRECISION)) ).to_deg geog = self.class.new _x.round(PRECISION), _y.round(PRECISION) geog.crs = GEOGRAPHIC_CRS geog end |
#to_json(*args) ⇒ Object
142 143 144 |
# File 'lib/terraformer/coordinate.rb', line 142 def to_json *args @ary.compact.to_json(*args) end |
#to_mercator ⇒ Object
129 130 131 132 133 134 135 136 |
# File 'lib/terraformer/coordinate.rb', line 129 def to_mercator _x = x.to_rad * EARTH_RADIUS syr = BigMath.sin y.to_rad, PRECISION _y = (EARTH_RADIUS / 2.0) * BigMath.log((1.0 + syr) / (1.0 - syr), PRECISION) merc = self.class.new _x.round(PRECISION), _y.round(PRECISION) merc.crs = MERCATOR_CRS merc end |
#to_point ⇒ Object
146 147 148 |
# File 'lib/terraformer/coordinate.rb', line 146 def to_point Point.new self end |
#to_s ⇒ Object
138 139 140 |
# File 'lib/terraformer/coordinate.rb', line 138 def to_s @ary.compact.join ',' end |
#x ⇒ Object Also known as: lon
72 73 74 |
# File 'lib/terraformer/coordinate.rb', line 72 def x @ary[0] end |
#x=(_x) ⇒ Object
77 78 79 |
# File 'lib/terraformer/coordinate.rb', line 77 def x= _x @ary[0] = Coordinate.big_decimal _x end |
#y ⇒ Object Also known as: lat
81 82 83 |
# File 'lib/terraformer/coordinate.rb', line 81 def y @ary[1] end |
#y=(_y) ⇒ Object
86 87 88 |
# File 'lib/terraformer/coordinate.rb', line 86 def y= _y @ary[1] = Coordinate.big_decimal _y end |
#z ⇒ Object
90 91 92 |
# File 'lib/terraformer/coordinate.rb', line 90 def z @ary[2] end |
#z=(_z) ⇒ Object
94 95 96 |
# File 'lib/terraformer/coordinate.rb', line 94 def z= _z @ary[2] = Coordinate.big_decimal _z end |