class JpmGeo::Point
Point
represents a latitude, longitude location
Constants
- DEG_TO_RAD
- MAX_LAT
- MAX_LON
- MIN_LAT
- MIN_LON
- PI
- PI_2
- RAD_TO_DEG
Attributes
lat[RW]
lon[RW]
radians[R]
radius[R]
Public Class Methods
from_degrees(lon:, lat:, radius: JpmGeo.radius)
click to toggle source
# File lib/jpm_geo/point.rb, line 23 def from_degrees(lon:, lat:, radius: JpmGeo.radius) new(lon: lon, lat: lat, radius: radius, radians: false) end
from_lonlat(lonlat, radius: JpmGeo.radius)
click to toggle source
# File lib/jpm_geo/point.rb, line 19 def from_lonlat(lonlat, radius: JpmGeo.radius) from_degrees(lon: lonlat.lon, lat: lonlat.lat, radius: radius) end
from_radians(lon:, lat:, radius: JpmGeo.radius, validate: true)
click to toggle source
# File lib/jpm_geo/point.rb, line 27 def from_radians(lon:, lat:, radius: JpmGeo.radius, validate: true) new(lon: lon, lat: lat, radius: radius, radians: true, validate: validate) end
new(lon:, lat:, radians: false, radius: JpmGeo.radius, validate: true)
click to toggle source
# File lib/jpm_geo/point.rb, line 133 def initialize(lon:, lat:, radians: false, radius: JpmGeo.radius, validate: true) raise ArgumentError, "invalid radius" if radius <= 0 @lon = lon @lat = lat @radius = radius @radians = radians raise ArgumentError, "invalid coordinates" if validate && !valid? end
to_deg(radians)
click to toggle source
# File lib/jpm_geo/point.rb, line 35 def to_deg(radians) radians * RAD_TO_DEG end
to_rad(degrees)
click to toggle source
# File lib/jpm_geo/point.rb, line 31 def to_rad(degrees) degrees * DEG_TO_RAD end
Public Instance Methods
==(other)
click to toggle source
# File lib/jpm_geo/point.rb, line 97 def ==(other) return false unless other.is_a?(JpmGeo::Point) point = radians ? other.to_radians : other.to_degrees point.lon == lon && point.lat == lat && point.radius == radius end
bounding_coordinates(distance)
click to toggle source
computes bounding coordinates all points that are within the great circle of the given distance from this Point
. distance is in the same units as the radius argument.
# File lib/jpm_geo/point.rb, line 66 def bounding_coordinates(distance) raise ArgumentError, "invalid distance" if distance <= 0 # angular distance in radians on a great circle raddist = distance / radius point = to_radians min = latlon(point.lat - raddist, 0) max = latlon(point.lat + raddist, 0) if min.lat > MIN_LAT && max.lat < MAX_LAT deltalon = Math.asin(Math.sin(raddist) / Math.cos(point.lat)) min.lon = point.lon - deltalon max.lon = point.lon + deltalon else # a pole is within the distance min.lat = [min.lat, MIN_LAT].max max.lat = [max.lat, MAX_LAT].min min.lon = MIN_LON max.lon = MAX_LON end bounds = bounds_from_min_max(min, max) radians ? bounds : bounds.to_degrees end
distance_to(point)
click to toggle source
# File lib/jpm_geo/point.rb, line 57 def distance_to(point) raise ArgumentError, "JpmGeo::Point expected" unless point.is_a?(JpmGeo::Point) radians_distance_to(to_radians, point.to_radians) end
to_degrees()
click to toggle source
# File lib/jpm_geo/point.rb, line 46 def to_degrees return self unless radians Point.from_degrees(lon: Point.to_deg(lon), lat: Point.to_deg(lat), radius: radius) end
to_radians()
click to toggle source
# File lib/jpm_geo/point.rb, line 40 def to_radians return self if radians Point.from_radians(lon: Point.to_rad(lon), lat: Point.to_rad(lat), radius: radius) end
to_s()
click to toggle source
# File lib/jpm_geo/point.rb, line 92 def to_s units = radians ? " rad" : "°" "JpmGeo::Point(#{lat}#{units}, #{lon}#{units})" end
valid?()
click to toggle source
# File lib/jpm_geo/point.rb, line 52 def valid? point = to_radians point.lat >= MIN_LAT && point.lat <= MAX_LAT && point.lon >= MIN_LON && point.lon <= MAX_LON end
Private Instance Methods
bounds_from_min_max(min, max)
click to toggle source
# File lib/jpm_geo/point.rb, line 112 def bounds_from_min_max(min, max) # http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#PolesAnd180thMeridian # when the 180th meridian is with the query circle, return two sets of bounding coordinates. if min.lon < MIN_LON # (latmin, lonmin + 2PI), (latmax, PI) and (latmin, -PI), (latmax, lonmax) Bounds.from_points(latlon(min.lat, min.lon + PI_2), latlon(max.lat, PI), latlon(min.lat, -PI), latlon(max.lat, max.lon)) elsif max.lon > MAX_LON # (latmin, lonmin), (latmax, PI) and (latmin, -PI), (latmax, lonmax - 2PI). Bounds.from_points(latlon(min.lat, min.lon), latlon(max.lat, PI), latlon(min.lat, -PI), latlon(max.lat, max.lon - PI_2)) else # does not cross 180th meridian Bounds.from_points(min, max) end end
latlon(lat, lon)
click to toggle source
# File lib/jpm_geo/point.rb, line 129 def latlon(lat, lon) Point.from_radians(lat: lat, lon: lon, radius: radius, validate: false) end
radians_distance_to(point1, point2)
click to toggle source
# File lib/jpm_geo/point.rb, line 106 def radians_distance_to(point1, point2) Math.acos(Math.sin(point1.lat) * Math.sin(point2.lat) + Math.cos(point1.lat) * Math.cos(point2.lat) * Math.cos(point1.lon - point2.lon)) * radius end