class Terraformer::Coordinate
Constants
- EARTH_MEAN_RADIUS
Attributes
ary[RW]
array holding the numeric coordinate values
crs[RW]
Public Class Methods
big_decimal(n)
click to toggle source
# 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)
click to toggle source
# 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
new(_x, _y = nil, _z = nil)
click to toggle source
# 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
Public Instance Methods
+(obj)
click to toggle source
# File lib/terraformer/coordinate.rb, line 192 def + obj arithmetic :+, obj end
-(obj)
click to toggle source
# File lib/terraformer/coordinate.rb, line 196 def - obj arithmetic :-, obj end
<=>(other)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/terraformer/coordinate.rb, line 98 def [] index @ary[index] end
buffer(radius, resolution = DEFAULT_BUFFER_RESOLUTION)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/terraformer/coordinate.rb, line 236 def distance_to obj distance_and_bearing_to(obj)[:distance] end
dup()
click to toggle source
# File lib/terraformer/coordinate.rb, line 68 def dup Coordinate.new @ary.dup end
euclidean_distance_to(obj)
click to toggle source
# 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)
click to toggle source
# File lib/terraformer/coordinate.rb, line 244 def final_bearing_to obj distance_and_bearing_to(obj)[:bearing][:final] end
geographic?()
click to toggle source
# File lib/terraformer/coordinate.rb, line 150 def geographic? crs.nil? or crs == GEOGRAPHIC_CRS end
haversine_distance_to(other)
click to toggle source
# 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)
click to toggle source
# File lib/terraformer/coordinate.rb, line 240 def initial_bearing_to obj distance_and_bearing_to(obj)[:bearing][:initial] end
inspect()
click to toggle source
# 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?()
click to toggle source
# File lib/terraformer/coordinate.rb, line 154 def mercator? crs == MERCATOR_CRS end
squared_euclidean_distance_to(obj)
click to toggle source
# 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()
click to toggle source
# 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)
click to toggle source
# File lib/terraformer/coordinate.rb, line 142 def to_json *args @ary.compact.to_json(*args) end
to_mercator()
click to toggle source
# 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()
click to toggle source
# File lib/terraformer/coordinate.rb, line 146 def to_point Point.new self end
to_s()
click to toggle source
# File lib/terraformer/coordinate.rb, line 138 def to_s @ary.compact.join ',' end
x()
click to toggle source
# File lib/terraformer/coordinate.rb, line 72 def x @ary[0] end
Also aliased as: lon
x=(_x)
click to toggle source
# File lib/terraformer/coordinate.rb, line 77 def x= _x @ary[0] = Coordinate.big_decimal _x end
y()
click to toggle source
# File lib/terraformer/coordinate.rb, line 81 def y @ary[1] end
Also aliased as: lat
y=(_y)
click to toggle source
# File lib/terraformer/coordinate.rb, line 86 def y= _y @ary[1] = Coordinate.big_decimal _y end
z()
click to toggle source
# File lib/terraformer/coordinate.rb, line 90 def z @ary[2] end
z=(_z)
click to toggle source
# File lib/terraformer/coordinate.rb, line 94 def z= _z @ary[2] = Coordinate.big_decimal _z end
Private Instance Methods
arithmetic(operator, obj)
click to toggle source
# File lib/terraformer/coordinate.rb, line 180 def arithmetic operator, obj case obj when Array _x = self.x.__send__ operator, obj[0] if obj[0] _y = self.y.__send__ operator, obj[1] if obj[1] Coordinate.new((_x || x), (_y || y)) else raise NotImplementedError end end