Class: Osgb::Point
- Inherits:
-
Object
- Object
- Osgb::Point
- Defined in:
- lib/osgb/point.rb
Instance Attribute Summary collapse
-
#datum ⇒ Object
Returns the value of attribute datum.
-
#lat ⇒ Object
Returns the latitude of the point, rounded to the specified precision.
-
#lng ⇒ Object
Returns the longitude of the point, rounded to the specified precision.
-
#precision ⇒ Object
Returns the value of attribute precision.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Tests the equivalence of two points, however they are specified.
-
#initialize(lat, lng, datum = nil, precision = nil) ⇒ Point
constructor
Usage: Osgb::Point.new(lat, lng, datum, precision).
-
#to_a ⇒ Object
Returns the point as a [lat,lng] array.
-
#to_s ⇒ Object
Returns the point as a “lat,lng” string.
-
#transform_to(target_datum) ⇒ Object
Remaps the point onto another datum.
-
#valid? ⇒ Boolean
Returns true if the coordinates are both specified and within the acceptable range.
Constructor Details
#initialize(lat, lng, datum = nil, precision = nil) ⇒ Point
Usage:
Osgb::Point.new(lat[float], lng[float], datum[symbol], precision[integer])
Default datum is :osgb36. For most web use you will be using WGS84 points, since that’s the standard for most GPS applications and used by google maps:
Osgb::Point.new(54.196915, -3.094684, :wgs84)
Osgb::Point.new(54.196763, -3.093320).transform_to(:wgs84)
20 21 22 23 24 25 |
# File 'lib/osgb/point.rb', line 20 def initialize(lat, lng, datum=nil, precision=nil) @lat = lat.to_f @lng = lng.to_f @datum = datum || :osgb36 @precision = precision || 6 end |
Instance Attribute Details
#datum ⇒ Object
Returns the value of attribute datum.
9 10 11 |
# File 'lib/osgb/point.rb', line 9 def datum @datum end |
#lat ⇒ Object
Returns the latitude of the point, rounded to the specified precision
29 30 31 |
# File 'lib/osgb/point.rb', line 29 def lat round(@lat) end |
#lng ⇒ Object
Returns the longitude of the point, rounded to the specified precision
35 36 37 |
# File 'lib/osgb/point.rb', line 35 def lng round(@lng) end |
#precision ⇒ Object
Returns the value of attribute precision.
9 10 11 |
# File 'lib/osgb/point.rb', line 9 def precision @precision end |
Instance Method Details
#==(other) ⇒ Object
Tests the equivalence of two points, however they are specified. If given two Point objects, they can lie on different datums:
Osgb::Point.new(54.196763, -3.093320, :osgb36) == Osgb::Point.new(54.196915, -3.094684, :wgs84) # -> true
When comparing a point with a string or array representation they are assumed to lie on the same datum:
Osgb::Point.new(54.196763, -3.093320) == "54.196763, -3.093320" # -> true
Osgb::Point.new(54.196763, -3.093320) == [54.196763, -3.093320] # -> true
Osgb::Point.new(54.196763, -3.093320) == "SD28687846" # -> true
Two points with different precisions will not be considered equivalent.
90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/osgb/point.rb', line 90 def ==(other) case other when Osgb::Point other = other.transform_to(self.datum) unless other.datum == self.datum self.lat == other.lat && self.lng == other.lng && self.datum == other.datum when Array self.to_a == other when String self == other.to_latlng(:datum => self.datum) # serves to normalise string representation end end |
#to_a ⇒ Object
Returns the point as a [lat,lng] array.
51 52 53 |
# File 'lib/osgb/point.rb', line 51 def to_a [lat, lng] end |
#to_s ⇒ Object
Returns the point as a “lat,lng” string.
46 47 48 |
# File 'lib/osgb/point.rb', line 46 def to_s "#{lat},#{lng}" end |
#transform_to(target_datum) ⇒ Object
Remaps the point onto another datum. If you’re turning OS grid references into GPS coordinates you have to remap from OSGB36 to WGS84:
point = "SD28687846".to_latlng.transform_to(:wgs84)
or more concisely:
point = "SD28687846".to_wgs84
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/osgb/point.rb', line 64 def transform_to(target_datum) return self if datum == target_datum if helmert = Osgb::Helmert[:"#{self.datum}_to_#{target_datum}"] cartesian_coordinates = Osgb::Ellipsoid[self.datum].polar_to_cartesian(@lat.to_radians,@lng.to_radians) transformed = helmert.transform(*cartesian_coordinates) phi, lambda = Osgb::Ellipsoid[target_datum].cartesian_to_polar(*transformed) self.class.new(phi.to_degrees, lambda.to_degrees, target_datum, precision) else raise Osgb::TransformationError, "Missing helmert transformation for #{self.datum} to #{target_datum}" end end |
#valid? ⇒ Boolean
Returns true if the coordinates are both specified and within the acceptable range.
41 42 43 |
# File 'lib/osgb/point.rb', line 41 def valid? lat && lng && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180 end |