Find Mongolian Geospatial Circles Containing a Point
I have Mongoid documents that represent the services offered by local merchants. They each have one or more locations (lat / lng point) with a service area (radius). Given the client's location (lat / lng dot), how can I find all the documents where the user's location falls within the service area?
class Service
include Mongoid::Document
# Data currently stored like this:
field :address, type: String
field :service_distance, type: Float
# Happy to geocdoe and store in another format
end
Most of the examples are based on finding points in a circle (where the radius is part of the query and the same for all documents) without finding the circles that intersect the point (where the circles have different radii).
source to share
Modeling a "circle" is a valid approach, specifying a "center" and "radius", but finding things "inside a circle" is usually simple, if not immediately obvious:
Service.collection.aggregate([
# Get the distance from the current location
{ "$geoNear" => {
"near" => {
"type" => "Point",
"coordinates" => [ 1, 1 ]
},
"distanceField" => "dist"
}},
# Find out if the "dist" is within the radius
{ "$project" => {
"address" => 1,
"service_distance" =>1,
"location" => 1, # the field with the co-ordinates you add
"dist" => 1,
"within" => { "$lt" => [ "$dist", "$service_distance" ] }
}},
# Then filter out anything not "within"
{ "$match" => { "within" => true } }
])
So, the aggregation operator not only finds documents "near" the specified point, but also "projects" a field in the document that represents the "distance" from that point in the query. $geoNear
Note that the "extra field" you requested here ("location") is the actual "coordinates" of the "Point" for the center of the circle where the "store" is located. This requires an additional field.
The next thing to do is to "compare" the calculated distance to the "radius" or "service_distance" contained in the document, and see if it is "less" or "inside" that distance.
Then, when this is the result true
, you save these documents and present them in your final answer.
The accessory .collection
here allows you to use native MongoDB methods such as .aggregate()
which allows you to perform such operations.
So how do you do it in server handling.