I'm developing a node.js web-app where I'm using mongoose and MongoDB for storage. It's a gelocation app. so sometimes I have to find the 10 nearest places stored in database. I have this method to calculate this distance:
var haversine = function(p1, p2) {
var R = 6371; // km
var dLat = toRad(p2.lat-p1.lat);
var dLon = toRad(p2.lon-p1.lon);
var lat1 = toRad(p1.lat);
var lat2 = toRad(p2.lat);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
}
where p1 and p2 are points {lat: Integer, lon: Integer}.
So, How should I do to find the nearest places?
Apologies if I am not understanding the question, but if you have a lat and lon stored in MongoDB already, why not just ensure a Geo index on that key and use MongoDB itself to find the nearest points.
Assuming a Geo index on location key consisting of lat and lon, you can simply issue something similar to the following:
db.places.find( { location : { $near : [lon,lat] } } ).limit(10)
Which should find the nearest ten places in your database to the location defined at lon,lat.
You can find more information at the documentation for geospatial indexing.
Related
I'm having an issue with calculating distances.
I have installed postgis, and I'm saving Lng/Lat points in the database
CREATE TABLE geo (gid serial PRIMARY KEY, geo geography)
For inserting a record, this is what I do:
INSERT INTO geo (geo) VALUES (ST_MAKEPOINT(Lng,Lat)::geography))
When I do the following query with some Lng/Lat variables, I get the following output:
SELECT gid, ST_DISTANCE(geo, ST_MAKEPOINT(Lng2,Lat2)::geography) FROM geo;
----
OUTPUT: 1 424.02930940m
Secondly, when I do the exact same calculation with the following formula (haversine formula in javascript), I get a slightly different output.
/*
const coords1/2 = {
lat: // latitude,
lng: // longitude
};
*/
export const haversine = (coords1, coords2) => {
var R = 6371000;
var x1 = coords2.lat - coords1.lat;
var dLat = x1.toRad();
var x2 = coords2.lng - coords1.lng;
var dLon = x2.toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(coords1.lat.toRad()) * Math.cos(coords2.lat.toRad()) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
----
OUTPUT: 422.20392010m
It's a difference of 2 meters, but I need the most accurate of the 2. It's for an app for geocaching.
I'm currently using the haversine formula in my app, but I'm thinking about switching to postgis because it would simplify my queries a lot.
Which one can I rely on the most?
I have a JSON object of latitude and longitude locations. I want to list them in the order they are closest to my current lat and long. Is there a way to query using AJAX to get an array of locations in the order of their proximity to my current location. If not, what the best approach I can use.
You can enumerate yours array of coordinates with this function (from this answer):
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
Or you can divide yours coordinates array per sector like:
if lat1 is greater than 70.000 and lesser than 75.000 then this is sector A and so on.
Finally, when you have these sectors you can search in specific one to avoid long calculations.
I Want Compare my Current latitude & longitude to another latitude & longitude and found near location to me
how can i calculate this ?
my location :
51.510836, -0.127579
another :
51.547385, 0.020022
51.482876, -0.036542
51.511894, -0.248477
As i understand
you problem is to get closest location via lat long
And you want to calculate which one is closest from your location
if yes then one by one compare all these 3 lat, long with your location's lat long.
The nearest location is which one has lowest distance in km.
try this.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
where lat1, lon1 is your location and lat2,lon2 are those points you wanna compare simply apply it in loop and pass compared locations and finally a distance which is lowest is your answer.
I have a list of adresses in my database that i can put into array in JS, but from now I want to display distance between me and them, like
me: Warsaw
array[0]: Berlin
array[1]: Moscov
array[2]: Amsterdam
array[3]: London
(array elements contains precise adresses, examples above are just like pseudocode)
I already made a script that can get distance between 2 points on map, but I am rendering map to do this, and this takes some time so it is not acceptable way if I want to display 20 distance entries at once
It don't have to be distance data as this can be overhelming question, but I just want to know how to fetch any data without waiting the time of map rendering.
Why are you using the map at all for this? There are other approaches you can use.
See here: http://www.movable-type.co.uk/scripts/latlong.html
I've used the "haversine" method myself:
function haversine() {
var radians = Array.prototype.map.call(arguments, function(deg) { return deg/180.0 * Math.PI; });
var lat1 = radians[0], lon1 = radians[1], lat2 = radians[2], lon2 = radians[3];
var R = 6372.8; // km
var dLat = lat2 - lat1;
var dLon = lon2 - lon1;
var a = Math.sin(dLat / 2) * Math.sin(dLat /2) + Math.sin(dLon / 2) * Math.sin(dLon /2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.asin(Math.sqrt(a));
return R * c;
}
console.log(haversine(36.12, -86.67, 33.94, -118.40));
Is it possible to get nearby places, providing the Latitude and Longitude?
If, for example, I would like places around the provided Lat, Long within the range of 50 kms, how do I go about achieving that?
Is there any algorithm / formula ?
I'm using OpenStreetMap geolocations
Thank you.
You can use below formula to calculate distance between two given co-ordinates:
(lat1, lon1) and (lat2, lon2)
dist = arccos(sin(lat1) · sin(lat2) + cos(lat1) · cos(lat2) · cos(lon1 - lon2)) · R
Reference: Great-circle_distance
Now lets say you have all these co-ordinates saved in database, then you can run a query to find all the locations that are within 50km of range.
SELECT * FROM Places WHERE acos(sin(1.3963) * sin(Lat) + cos(1.3963) * cos(Lat) * cos(Lon - (-0.6981))) * 6371 <= 50;
It is also possible to do this in Javascript. You need to use some Math functions and iterate through an array which stores the co-oridinate to check the distance.
I think you can use this formula to find the distance between 2 points based on lat/lng. You can then use it for your purpose:
var kmBetween = function(a, b){
var e = Math, ra = e.PI/180;
var b = b.lat * ra, c = a.lat * ra, d = b - c;
var g = b.lng * ra - a.lng * ra;
var f = 2 * e.asin(e.sqrt(e.pow(e.sin(d/2), 2) + e.cos(b) * e.cos(c) * e.pow(e.sin(g/2), 2)));
return f * 6378.137;
}
var distance = kmBetween({
lat: 45.5,
lng: 33.4
},
{
lat: 44.3,
lng: 32.4
});