Class: Parse::GeoPoint
Overview
This class manages the GeoPoint data type that Parse provides to support geo-queries. To define a GeoPoint property, use the ‘:geopoint` data type. Please note that latitudes should not be between -90.0 and 90.0, and longitudes should be between -180.0 and 180.0.
Constant Summary collapse
- ATTRIBUTES =
The default attributes in a Parse GeoPoint hash.
{ __type: :string, latitude: :float, longitude: :float }.freeze
- FIELD_LAT =
The key field for latitude
"latitude".freeze
- FIELD_LNG =
The key field for longitude
"longitude".freeze
- LAT_MIN =
The minimum latitude value.
-90.0 # The maximum latitude value.
- LAT_MAX =
The maximum latitude value.
90.0- LNG_MIN =
The minimum longitude value.
-180.0 # The maximum longitude value.
- LNG_MAX =
The maximum longitude value.
180.0
Constants inherited from Model
Model::CLASS_AUDIENCE, Model::CLASS_INSTALLATION, Model::CLASS_JOB_SCHEDULE, Model::CLASS_JOB_STATUS, Model::CLASS_PRODUCT, Model::CLASS_PUSH_STATUS, Model::CLASS_ROLE, Model::CLASS_SCHEMA, Model::CLASS_SESSION, Model::CLASS_USER, Model::ID, Model::KEY_CLASS_NAME, Model::KEY_CREATED_AT, Model::KEY_OBJECT_ID, Model::KEY_UPDATED_AT, Model::OBJECT_ID, Model::TYPE_ACL, Model::TYPE_BYTES, Model::TYPE_DATE, Model::TYPE_FIELD, Model::TYPE_FILE, Model::TYPE_GEOPOINT, Model::TYPE_NUMBER, Model::TYPE_OBJECT, Model::TYPE_POINTER, Model::TYPE_POLYGON, Model::TYPE_RELATION
Instance Attribute Summary collapse
-
#latitude ⇒ Float
(also: #lat)
Latitude value between -90.0 and 90.0.
-
#longitude ⇒ Float
(also: #lng)
Longitude value between -180.0 and 180.0.
Class Method Summary collapse
-
.from_geojson(geojson) ⇒ Parse::GeoPoint
Build a GeoPoint from a GeoJSON ‘Point` geometry object.
- .parse_class ⇒ Model::TYPE_GEOPOINT
Instance Method Summary collapse
-
#==(g) ⇒ Boolean
True if two geopoints are equal based on lat and lng.
-
#attributes ⇒ Hash
Attributes for a Parse GeoPoint.
-
#attributes=(h) ⇒ Object
Setting lat and lng for an GeoPoint can be done using a hash with the attributes set or with an array of two items where the first is the lat and the second is the lng (ex. [32.22,-118.81]).
-
#distance_in_km(geopoint, lng = nil) ⇒ Float
Calculate the distance in kilometers to another GeoPoint using Haversine method.
-
#distance_in_miles(geopoint, lng = nil) ⇒ Float
Calculate the distance in miles to another GeoPoint using Haversine.
-
#estimated(precision = 2) ⇒ GeoPoint
Helper method for reducing the precision of a geopoint.
-
#initialize(latitude = nil, longitude = nil) ⇒ GeoPoint
constructor
The initializer can create a GeoPoint with a hash, array or values.
-
#max_kilometers(km) ⇒ Array
(also: #max_km)
Helper method for performing geo-queries with a radial kilometer constraint.
-
#max_miles(m) ⇒ Array
Helper method for performing geo-queries with radial miles constraints.
-
#max_radians(rad) ⇒ Array
Helper method for performing geo-queries with a radial radians constraint.
- #parse_class ⇒ Model::TYPE_GEOPOINT (also: #__type)
-
#to_a ⇒ Array
Returns a tuple containing latitude and longitude.
-
#to_geojson ⇒ Hash
GeoJSON (RFC 7946) representation of this point.
Methods inherited from Model
Methods included from Client::Connectable
Constructor Details
#initialize(latitude = nil, longitude = nil) ⇒ GeoPoint
The initializer can create a GeoPoint with a hash, array or values.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/parse/model/geopoint.rb', line 64 def initialize(latitude = nil, longitude = nil) @latitude = @longitude = 0.0 if latitude.is_a?(Hash) || latitude.is_a?(Array) self.attributes = latitude elsif latitude.is_a?(Numeric) && longitude.is_a?(Numeric) @latitude = latitude @longitude = longitude elsif latitude.is_a?(GeoPoint) @latitude = latitude.latitude @longitude = latitude.longitude end _validate_point end |
Instance Attribute Details
#latitude ⇒ Float Also known as: lat
Returns latitude value between -90.0 and 90.0.
30 31 32 |
# File 'lib/parse/model/geopoint.rb', line 30 def latitude @latitude end |
#longitude ⇒ Float Also known as: lng
Returns longitude value between -180.0 and 180.0.
32 33 34 |
# File 'lib/parse/model/geopoint.rb', line 32 def longitude @longitude end |
Class Method Details
.from_geojson(geojson) ⇒ Parse::GeoPoint
Build a Parse::GeoPoint from a GeoJSON ‘Point` geometry object. Accepts either symbol or string keys and the standard `[longitude, latitude]` axis order; performs the swap to Parse’s ‘[latitude, longitude]` internal storage.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/parse/model/geopoint.rb', line 190 def self.from_geojson(geojson) raise ArgumentError, "[Parse::GeoPoint] from_geojson expects a Hash." unless geojson.is_a?(Hash) hash = geojson.respond_to?(:symbolize_keys) ? geojson.symbolize_keys : geojson type = hash[:type] || hash["type"] coords = hash[:coordinates] || hash["coordinates"] # Mirror Parse::Polygon.from_geojson: require both coordinates to # be finite Numerics. Without this check, non-numeric entries # (`"evil"`, `{"$where": "..."}`, `nil`) silently coerce to 0.0 # via `.to_f`, producing a null-island point that matches # ACL-relevant proximity queries unintentionally. NaN / Infinity # similarly produce silent geo bugs and 2dsphere index errors. unless type.to_s == "Point" && coords.is_a?(Array) && coords.length == 2 && coords[0].is_a?(Numeric) && coords[1].is_a?(Numeric) && coords[0].finite? && coords[1].finite? raise ArgumentError, "[Parse::GeoPoint] from_geojson expects a GeoJSON Point with " \ "two finite numeric coordinates." end Parse::GeoPoint.new(coords[1].to_f, coords[0].to_f) end |
.parse_class ⇒ Model::TYPE_GEOPOINT
50 |
# File 'lib/parse/model/geopoint.rb', line 50 def self.parse_class; TYPE_GEOPOINT; end |
Instance Method Details
#==(g) ⇒ Boolean
Returns true if two geopoints are equal based on lat and lng.
150 151 152 153 |
# File 'lib/parse/model/geopoint.rb', line 150 def ==(g) return false unless g.is_a?(GeoPoint) @latitude == g.latitude && @longitude == g.longitude end |
#attributes ⇒ Hash
Returns attributes for a Parse GeoPoint.
93 94 95 |
# File 'lib/parse/model/geopoint.rb', line 93 def attributes ATTRIBUTES end |
#attributes=(h) ⇒ Object
Setting lat and lng for an GeoPoint can be done using a hash with the attributes set or with an array of two items where the first is the lat and the second is the lng (ex. [32.22,-118.81])
137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/parse/model/geopoint.rb', line 137 def attributes=(h) if h.is_a?(Hash) h = h.symbolize_keys @latitude = h[:latitude].to_f || h[:lat].to_f || @latitude @longitude = h[:longitude].to_f || h[:lng].to_f || @longitude elsif h.is_a?(Array) && h.count == 2 @latitude = h.first.to_f @longitude = h.last.to_f end _validate_point end |
#distance_in_km(geopoint, lng = nil) ⇒ Float
Calculate the distance in kilometers to another GeoPoint using Haversine method. You may also call this method with a latitude and longitude.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/parse/model/geopoint.rb', line 240 def distance_in_km(geopoint, lng = nil) unless geopoint.is_a?(Parse::GeoPoint) geopoint = Parse::GeoPoint.new(geopoint, lng) end dtor = Math::PI / 180 r = 6378.14 r_lat1 = self.latitude * dtor r_lng1 = self.longitude * dtor r_lat2 = geopoint.latitude * dtor r_lng2 = geopoint.longitude * dtor delta_lat = r_lat1 - r_lat2 delta_lng = r_lng1 - r_lng2 a = (Math::sin(delta_lat / 2.0) ** 2).to_f + (Math::cos(r_lat1) * Math::cos(r_lat2) * (Math::sin(delta_lng / 2.0) ** 2)) c = 2.0 * Math::atan2(Math::sqrt(a), Math::sqrt(1.0 - a)) d = r * c d end |
#distance_in_miles(geopoint, lng = nil) ⇒ Float
Calculate the distance in miles to another GeoPoint using Haversine. You may also call this method with a latitude and longitude. is longitude instead of a GeoPoint.
226 227 228 |
# File 'lib/parse/model/geopoint.rb', line 226 def distance_in_miles(geopoint, lng = nil) distance_in_km(geopoint, lng) * 0.621371 end |
#estimated(precision = 2) ⇒ GeoPoint
Helper method for reducing the precision of a geopoint.
158 159 160 |
# File 'lib/parse/model/geopoint.rb', line 158 def estimated(precision = 2) Parse::GeoPoint.new(@latitude.to_f.round(precision), @longitude.round(precision)) end |
#max_kilometers(km) ⇒ Array Also known as: max_km
Helper method for performing geo-queries with a radial kilometer constraint. Used with ‘:field.near => gp.max_kilometers(N)` to compile a `$nearSphere` + `$maxDistanceInKilometers` query against Parse Server.
108 109 110 111 |
# File 'lib/parse/model/geopoint.rb', line 108 def max_kilometers(km) km = 0 if km.nil? [@latitude, @longitude, km, :km] end |
#max_miles(m) ⇒ Array
Helper method for performing geo-queries with radial miles constraints
99 100 101 102 |
# File 'lib/parse/model/geopoint.rb', line 99 def max_miles(m) m = 0 if m.nil? [@latitude, @longitude, m] end |
#max_radians(rad) ⇒ Array
Helper method for performing geo-queries with a radial radians constraint. Used with ‘:field.near => gp.max_radians®` to compile a `$nearSphere` + `$maxDistance` query against Parse Server (raw `$maxDistance` is measured in radians). Convert from miles/km by dividing by mean-Earth-radius (~3958.8 miles or ~6371 km).
120 121 122 123 |
# File 'lib/parse/model/geopoint.rb', line 120 def max_radians(rad) rad = 0 if rad.nil? [@latitude, @longitude, rad, :radians] end |
#parse_class ⇒ Model::TYPE_GEOPOINT Also known as: __type
52 |
# File 'lib/parse/model/geopoint.rb', line 52 def parse_class; self.class.parse_class; end |
#to_a ⇒ Array
Returns a tuple containing latitude and longitude
164 165 166 |
# File 'lib/parse/model/geopoint.rb', line 164 def to_a [@latitude, @longitude] end |
#to_geojson ⇒ Hash
GeoJSON (RFC 7946) representation of this point. GeoJSON requires ‘[longitude, latitude]` axis order — the inverse of Parse’s wire format — so this method performs the swap. Useful when handing the value to Leaflet/Mapbox/PostGIS, or when constructing literals for MongoDB-direct geo queries (which use GeoJSON internally).
177 178 179 |
# File 'lib/parse/model/geopoint.rb', line 177 def to_geojson { "type" => "Point", "coordinates" => [@longitude, @latitude] } end |