I am using mongoDB to store GPS locations data as this GeoJSON document
{"type" : "Point", "coordinates" : [33.313183, 44.465632]}
{"type" : "Point", "coordinates" : [33.2926487, 44.4159651]}
Update: I also ensured 2dspher index like follow
db.test.ensureIndex( { loc : "2dsphere" } )
I got the coordinates from Google maps
Now if I search using this command I cant convert the distances in result to kilometers
db.runCommand({geoNear: 'test', spherical: true, near: {type: "Point" , coordinates: [33.2926487, 44.4159651]}})
the result is as follow
"results" : [
{
"dis" : 0.0033427770982422957,
"obj" : {
"_id" : ObjectId("54a96f348fa05fcaed637a22"),
"loc" : {
"type" : "Point",
"coordinates" : [
33.2926487,
44.4159651
]
}
}
},
{
"dis" : 5764.7060911604085,
"obj" : {
"_id" : ObjectId("54a96f4c8fa05fcaed637a23"),
"loc" : {
"type" : "Point",
"coordinates" : [
33.313183,
44.465632
]
}
}
}
]
the first result is expected to be Zero since its the same point that I want to get the distance from source = destination coordinates, but still has value.
the second value I cant convert to Kilometers, in Google distance calculator is about 5.26KM.
As I continued my research about this issue I found this
there is two types of storing type for points
legacy point as this format
db.test2.insert({location: [33.313183, 44.465632]})
and GeoJSON point as this format
db.test.insert({location: {"type" : "Point", "coordinates" : [33.313183, 44.465632]}})
if we are using the legacy point the result would be in radian so we would convert it to kilometers using this statement
db.runCommand({geoNear: 'test2', spherical: true, near: [33.2926487, 44.4159651], distanceMultiplier: 6371})
if we are using GeoJSON point the result would be in meters so we would convert it to kilometers using this statement as this answer to this question
db.runCommand({geoNear: 'test', spherical: true, near: {type: "Point" , coordinates: [33.2926487, 44.4159651]}, distanceMultiplier: 0.001})
solution in case of GeoJSON point format
for more details check this link, a bug report to MongoDB that explains it all.
The distances are being returned in meters. To convert to kilometers, divide by 1000. You can have MongoDB do this using the distanceMultiplier option:
db.runCommand({ "geoNear" : "test", "spherical" : true, "distanceMultiplier" : 0.001, "near" : { "type" : "Point" , "coordinates" : [33.2926487, 44.4159651] } })
Did you index the field as a 2dsphere. That could explain the discrepancy since you're querying as sphere: true
Related
When I am firing this query on MongoDB, I am getting all the places in the proximity of 500 miles to the specified co-ordinates. But I want to know the exact distance between the specified co-ordinates and the result location.
db.new_stores.find({ "geometry": { $nearSphere: { $geometry: { type: "Point", coordinates: [ -81.093699, 32.074673 ] }, $maxDistance: 500 * 3963 } } } ).pretty()
My Output looks like:
{
"_id" : ObjectId("565172058bc200b0db0f75b1"),
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [
-80.148826,
25.941116
]
},
"properties" : {
"Name" : "Anthony's Coal Fired Pizza",
"Address" : "17901 Biscayne Blvd, Aventura, FL"
}
}
I also want to know the distance of this place from the specified co-ordinate. I created 2dsphere index on geometry.
You can use the $geoNear aggregate pipeline stage to produce a distance from the queried point:
db.new_stores.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -81.093699, 32.074673 ]
},
"maxDistance": 500 * 1609,
"key" : "myLocation",
"spherical": true,
"distanceField": "distance",
"distanceMultiplier": 0.000621371
}}
]).pretty()
This allows you to specify "distanceField" which will produce another field in the output documents containing the distance from the queried point. You can also use "distanceMultiplier" to apply any conversion to the output distance as required ( i.e meters to miles, and noting that all GeoJSON distances are returned in meters )
There is also the geoNear command with similar options, but it of course does not return a cursor as output.
if you have more than one 2dsphere, you should specify a "key".
MongoDB provides a $geoNear aggregator for calculating the distance of documents in a collection with GeoJson coordinates.
Let us understand it with a simple example.
Consider a simple collection shops
1. Create Collection
db.createCollection('shops')
2. Insert documents in shops collections
db.shops.insert({name:"Galaxy store",address:{type:"Point",coordinates:[28.442894,77.341299]}})
db.shops.insert({name:"A2Z store",address:{type:"Point",coordinates:[28.412894,77.311299]}})
db.shops.insert({name:"Mica store",address:{type:"Point",coordinates:[28.422894,77.342299]}})
db.shops.insert({name:"Full Stack developer",address:{type:"Point",coordinates:[28.433894,77.334299]}})
3. create GeoIndex on "address" fields
db.shops.createIndex({address: "2dsphere" } )
4. Now use a $geoNear aggregator
to find out the documents with distance.
db.shops.aggregate([{$geoNear:{near:{type:"Point",coordinates:[28.411134,77.331801]},distanceField: "shopDistance",$maxDistance:150000,spherical: true}}]).pretty()
Here coordinates:[28.411134,77.331801] is the center position or quired position from where documents will be fetched.
distanceField:"shopDistance" , $geoNear Aggregator return shopDistance as fields in result.
Result:
{ "_id" : ObjectId("5ef047a4715e6ae00d0893ca"), "name" : "Full Stack developer", "address" : { "type" : "Point", "coordinates" : [ 28.433894, 77.334299 ] }, "shopDistance" : 621.2848190449148 }
{ "_id" : ObjectId("5ef0479e715e6ae00d0893c9"), "name" : "Mica store", "address" : { "type" : "Point", "coordinates" : [ 28.422894, 77.342299 ] }, "shopDistance" : 1203.3456146763526 }
{ "_id" : ObjectId("5ef0478a715e6ae00d0893c7"), "name" : "Galaxy store", "address" : { "type" : "Point", "coordinates" : [ 28.442894, 77.341299 ] }, "shopDistance" : 1310.9612119555288 }
{ "_id" : ObjectId("5ef04792715e6ae00d0893c8"), "name" : "A2Z store", "address" : { "type" : "Point", "coordinates" : [ 28.412894, 77.311299 ] }, "shopDistance" : 2282.6640175038788 }
Here shopDistance will be in meter.
maxDistance -> Optional. The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point.
Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs.
In the docs it says if you use legacy pairs , eg : near : [long , lat] , then specify the maxDistance in radians.
If you user GeoJSON , eg : near : { type : "Point" , coordinates : [long ,lat] },
then specify the maxDistance in meters.
Use $geoNear to get the distance between a given location and users.
db.users.aggregate([
{"$geoNear": {
"near": {
"type": "Point",
"coordinates": [ longitude, latitude]
},
"distanceField": "distance",
"distanceMultiplier": 1/1000,
"query": {/* userConditions */},
}}
]).pretty()
How Could i get longitude and lattitude using mongodb query from mongo collection
based on disatnce and certain coordinates.
{
"_id" : ObjectId("5a559b13ae201d0c05cb6f6a"),
"id" : "99623",
"city" : "Wasilla",
"cnty" : "Matanuska Susitna",
"cntyFips" : null,
"st" : "AK",
"stName" : "Alaska",
"areaCode" : "907",
"lat" : 61.5816,
"long" : -149.4393,
"rgn" : "West",
"__v" : 0
}
in this document "lat" is for latitude and "long" is for longitude.
so basically i have to get all ids based on present id lat and long which comes in a particular miles distance range.
Mongo supports GeoJSON which should allow you to perform basic queries easily on these kind of data. Examples include $geoWithin for your particular use-case.
We need a little more information on the structure of the documents that you are querying, but here is a simple example of the query available in the Mongo documentation here.
It's worth noting that you require a 2dsphere index for location data defined as GeoJSON points in order for this to be effective.
{
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ <longitude>, <latitude> ]
},
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}
I need to calculate the total distance traveled between a collection of points. They all have a timestamp to get them in the right order. I'm only allowed to use MongoDB.
Sample collection:
{
"_id" : ObjectId("596cd354241aa3174056fb98"),
"spelerID" : 1,
"timestamp" : ISODate("2017-02-01T19:00:00.000Z"),
"coordinates" : {
"type" : "Point",
"coordinates" : [
4.29870386367084,
50.8357637566422
]
}
}
/* 2 */
{
"_id" : ObjectId("596cd354241aa3174056fbb4"),
"spelerID" : 1,
"timestamp" : ISODate("2017-02-01T19:00:01.000Z"),
"coordinates" : {
"type" : "Point",
"coordinates" : [
4.29868458167181,
50.8357575419868
]
}
}
/* 3 */
{
"_id" : ObjectId("596cd354241aa3174056fbce"),
"spelerID" : 1,
"timestamp" : ISODate("2017-02-01T19:00:02.000Z"),
"coordinates" : {
"type" : "Point",
"coordinates" : [
4.29867536067721,
50.8357376028214
]
}
}
I have no idea how to calculate the distance between those points in the right order.
MongoDB can performance the distance between two points by using $near or $geoNear.
Returns documents in order of proximity to a specified point, from the nearest to farthest. geoNear requires a geospatial index.
https://docs.mongodb.com/manual/reference/command/geoNear/
In your case I don't think this will resolve the issue since you want to perform multiple distance calculation between multiple points.
MongoDB can be instruct to create very complex algorithm by using MapReduce. Even if I'm not expert in GIS application you could try to create a MapReduce routine with a Function that compute the distance between multiple points ordered as you like.
MongoDB - MapReduce
This link can help you to write a JS function to be used in Map Reduce:
Calculate distance between two latitude-longitude points? (Haversine formula)
Good Luck!
When I am firing this query on MongoDB, I am getting all the places in the proximity of 500 miles to the specified co-ordinates. But I want to know the exact distance between the specified co-ordinates and the result location.
db.new_stores.find({ "geometry": { $nearSphere: { $geometry: { type: "Point", coordinates: [ -81.093699, 32.074673 ] }, $maxDistance: 500 * 3963 } } } ).pretty()
My Output looks like:
{
"_id" : ObjectId("565172058bc200b0db0f75b1"),
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [
-80.148826,
25.941116
]
},
"properties" : {
"Name" : "Anthony's Coal Fired Pizza",
"Address" : "17901 Biscayne Blvd, Aventura, FL"
}
}
I also want to know the distance of this place from the specified co-ordinate. I created 2dsphere index on geometry.
You can use the $geoNear aggregate pipeline stage to produce a distance from the queried point:
db.new_stores.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -81.093699, 32.074673 ]
},
"maxDistance": 500 * 1609,
"key" : "myLocation",
"spherical": true,
"distanceField": "distance",
"distanceMultiplier": 0.000621371
}}
]).pretty()
This allows you to specify "distanceField" which will produce another field in the output documents containing the distance from the queried point. You can also use "distanceMultiplier" to apply any conversion to the output distance as required ( i.e meters to miles, and noting that all GeoJSON distances are returned in meters )
There is also the geoNear command with similar options, but it of course does not return a cursor as output.
if you have more than one 2dsphere, you should specify a "key".
MongoDB provides a $geoNear aggregator for calculating the distance of documents in a collection with GeoJson coordinates.
Let us understand it with a simple example.
Consider a simple collection shops
1. Create Collection
db.createCollection('shops')
2. Insert documents in shops collections
db.shops.insert({name:"Galaxy store",address:{type:"Point",coordinates:[28.442894,77.341299]}})
db.shops.insert({name:"A2Z store",address:{type:"Point",coordinates:[28.412894,77.311299]}})
db.shops.insert({name:"Mica store",address:{type:"Point",coordinates:[28.422894,77.342299]}})
db.shops.insert({name:"Full Stack developer",address:{type:"Point",coordinates:[28.433894,77.334299]}})
3. create GeoIndex on "address" fields
db.shops.createIndex({address: "2dsphere" } )
4. Now use a $geoNear aggregator
to find out the documents with distance.
db.shops.aggregate([{$geoNear:{near:{type:"Point",coordinates:[28.411134,77.331801]},distanceField: "shopDistance",$maxDistance:150000,spherical: true}}]).pretty()
Here coordinates:[28.411134,77.331801] is the center position or quired position from where documents will be fetched.
distanceField:"shopDistance" , $geoNear Aggregator return shopDistance as fields in result.
Result:
{ "_id" : ObjectId("5ef047a4715e6ae00d0893ca"), "name" : "Full Stack developer", "address" : { "type" : "Point", "coordinates" : [ 28.433894, 77.334299 ] }, "shopDistance" : 621.2848190449148 }
{ "_id" : ObjectId("5ef0479e715e6ae00d0893c9"), "name" : "Mica store", "address" : { "type" : "Point", "coordinates" : [ 28.422894, 77.342299 ] }, "shopDistance" : 1203.3456146763526 }
{ "_id" : ObjectId("5ef0478a715e6ae00d0893c7"), "name" : "Galaxy store", "address" : { "type" : "Point", "coordinates" : [ 28.442894, 77.341299 ] }, "shopDistance" : 1310.9612119555288 }
{ "_id" : ObjectId("5ef04792715e6ae00d0893c8"), "name" : "A2Z store", "address" : { "type" : "Point", "coordinates" : [ 28.412894, 77.311299 ] }, "shopDistance" : 2282.6640175038788 }
Here shopDistance will be in meter.
maxDistance -> Optional. The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point.
Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs.
In the docs it says if you use legacy pairs , eg : near : [long , lat] , then specify the maxDistance in radians.
If you user GeoJSON , eg : near : { type : "Point" , coordinates : [long ,lat] },
then specify the maxDistance in meters.
Use $geoNear to get the distance between a given location and users.
db.users.aggregate([
{"$geoNear": {
"near": {
"type": "Point",
"coordinates": [ longitude, latitude]
},
"distanceField": "distance",
"distanceMultiplier": 1/1000,
"query": {/* userConditions */},
}}
]).pretty()
I have a question about distance measuring in a $maxDistance. I have document:
{
"location": {
{ "type" : "Point", "coordinates" : [ 38.8993487, -77.0145665 ] }
}
}
Making a query in a shell:
db.places.find({"location": {"$nearSphere": {"$geometry": {"type":"Point", "coordinates": [38.888684, -77.0047189]}, "$maxDistance": 1129 } }})[0].location
Returns a
{ "type" : "Point", "coordinates" : [ 38.8993487, -77.0145665 ] }
But distance measurement made by gpsvisualizer.com shows me 1.4600 km. Mongo have a result with maxDistance set to 1129 meters
So my question is - what did I miss ?:D
I think you missing the fact that mongoDB’s 2d spherical index operators only recognize [longitude, latitude] ordering. Correct link would be: gpsvisualiser. As you can see, distance between those points is about 1,13km :)