Problem to Solve
I was working on a project for geo-analytics dashboard, where I need to display a real-time user checked-in location in a map with some details.
Every time a user check-in, it will display a marker and an info window focusing on the user coordinates.
There is a particular request to display marker on the map and show the city name of the current user location.
Tools
I’m using:
MongoDB v4.0.10 (MongoDB Compass v1.20.1 included)
Robo 3T v1.3.1 (as an alternative MongoDB client to execute query)
Solution
1. Prepare Some Data
First, we need a master data for cities
collection_name = "cities"
You can grab some sample data from here with the coordinates
https://simplemaps.com/data/world-cities
For testing, you can insert 2 samples data as per below
{
"name": "Kuala Lumpur",
"location": {
"coordinates": [ 101.616949, 3.1385036 ],
"type": "Point"
}
},
{
"name": "Petaling Jaya",
"location": {
"coordinates": [ 101.5381381, 3.1379812 ],
"type": "Point"
}
}
The key “location” is an object as per MongoDB documentation
https://docs.mongodb.com/manual/reference/geojson/#geojson-point
location.type is set to Point, referring to the center coordinate of the city on the map.
location.coordinates is an array of [ longitude, latitude ].
Please make sure that the coordinates array items are in the correct order, or the result will be wrong.
2. Create Geospatial Index
Create geospatial index for cities.location
Set the index name then, at “Configure the index definition”, set it as “location” and set the index type as “2dsphere”
3. Test the Query
For testing, please pick some random coordinate from google map (assume it as the user current location) and it should not be too far from our defined city.
You can get the coordinate from the URL if you click at city/district name
I click at MONT KIARA and I get this → 3.1465815,101.6537527
Please take note that the above coordinate is showing latitude then longitude, so you need to put in a correct order to execute the query.
coordinates: [ 101.6537527, 3.1465815 ]
Execute the query using the below:
{
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ <longitude>, <latitude> ]
},
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}
The query above is searching for all city region that is intersecting or within the range of 8000m radius from the user location (in this example we are assuming user location is at MONT KIARA)
The query result might show more than one cities depends on the specified $maxDistance, because it might have few cities intersecting or within the range of the user radius. But the first result should be the closest one as the result by default ordered by distance.
The good strategy is to set a proper max-distance value, not too big and not too small, and get the first result of the query.
You can play around with the result by adding more city and its coordinates.
Good Luck!