I am using Node.js and MongoDB.
Let say I have predefined few cities (e.g. Seattle, Miami, New York) with Lat & Lon. and there is a user click to my website and I know his IP address, and find out the lat & lon. Then I want to know which city that I've defined is the closest to the user.
I know I can do it using Mongo's geospatial feature. but it would be quite 'expensive' to use DB to calculate that for every web request.
Is there a Node.js NPM package that can do the geo feature as I described above?
How many "pre-defined" cities are you working with? If it's a small number, you could probably just store the list in memory and do a linear scan.
Also, you should probably just give the mongo geospatial query a try to get an idea of exactly how expensive it is, before assuming that it's unreasonable - if you index the city locations and the, it will be pretty fast..
If you are dealing with a lot of points, still don't want to rely on mongo geo-indexing, and need something really specialized, maybe an R-Tree would be worth experimenting with. Here's an r-tree implementation for javascript. https://github.com/imbcmdth/RTree
If you already have the user's location and the location of each city, it should be quite fast to compute the distance to the nearest. Check out this site: http://www.movable-type.co.uk/scripts/latlong.html
I have used the first algorithm a few times.
function getDistance(lat1,lat2,lon1,lon2){
var R = 6371; // km
var c = Math.PI / 180;
var dLat = (lat2-lat1) * c;
var dLon = (lon2-lon1) * c;
var lat1 = lat1 * c;
var lat2 = lat2 * c;
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;
}
var closest, dist = Number.MAX_VALUE;
for(var i = 0, l=cities.length;i<l;++i){
if(getDistance(cities[i].longitude, cities[i].latitude, user.longitude, user.latitude) < max){
closest = cities[i];
}
}
alert(closest.name + ' is the winner :)');
You might want to add some exception handling here :)
Related
I have two locations and I have the formula to get the distance between them but I want to calculate the travel time between them without using google maps or any API calling. Is there any formula to do that in flutter?
I think the real travel time depends on a lot of factors, for example the road you take or the speed limit.
Whitout some complex elaboration, which are usually perfomed by a backend, I don't think it is possible to calculate it.
Anyway, since you have got the distance, you could simply estimate it by giving a supposed speed and then using basic physics formulas.
time = distance / speed.
You cannot find the travel distance between two locations without using the Google API.
However you can get the air distance in meters using this formula in flutter.
double calculateDistance(
double lat1, double lon1, double lat2, double lon2) {
var p = 0.017453292519943295;
var c = cos;
var a = 0.5 -
c((lat2 - lat1) * p) / 2 +
c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p)) / 2;
var temp = 12742 * asin(sqrt(a));
return (temp * 1000);
}
How to calculate distance between two location in dart?
Without using plugin
double calculateDistance(lat1, lon1, lat2, lon2){
var p = 0.017453292519943295;
var c = cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * asin(sqrt(a));
}
result is KM. if you want meter just multiply by 1000. return 1000 * 12742 * asin(sqrt(a))
You can use geolocator plugin to calculate to distances between two coordinates:
An Example:
var _distanceInMeters = await Geolocator().distanceBetween(
_latitudeForCalculation,
_longitudeForCalculation,
_currentPosition.latitude,
_currentPosition.longitude,
);
Check out GeoLocator Plugin for more info.
Check out latlong. It's a package dedicated to work with coordinates and features sophisticated calculations.
Unlike packages like geolocator it does not come with integrated location services and can be used alongside packages specialized for that.
You can use latlong2 which is the continuation of latlong. It has features like distance calculation and path drawing. So you can get distance as path distance as well as direct distance.
My questions is related on what is the best way to handle data related gps points in a database (in my case nosql DB MongoDB) in order to returns only closest points.
I have a collections of users in my database.
Now I need to create a new "table" which associate users with gps points (an user can have more points). For example:
User,lat,long
ALFA,40,50
ALFA,30,50
BETA,42,33
...
The server should makes available a function that, given a position in input, returns a list of users which are associated to points near the input.
For example:
function nearestUsers(lat,lon){
var mindif = 10000;
var closest;
users = getAllRecordsFromDataBase(); //query for MongoDB that returnst all records of the new table
for ( i = 0 ; i < users.length; i++){
if(this.distance(lat,lon,users[i].lat,users[i].lon)>mindif) delete users[i];
}
return users;
}
The distance function is the following:
function distance(lat1, lon1, lat2, lon2) {
lat1 = Deg2Rad(lat1);
lat2 = Deg2Rad(lat2);
lon1 = Deg2Rad(lon1);
lon2 = Deg2Rad(lon2);
var R = 6371;
var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
var y = (lat2 - lat1);
var d = Math.sqrt(x * x + y * y) * R;
return d;
}
I'm afraid that, for big amount of data, this approch will result slow. Which is the best way to make more scalable the algorithm? Any suggestions?
Considering that this funcionality is inside my server in Node.js using a MongoDB, can I implement this function directly via query or using some special structure in my database?
You can use mongodb geospatial indexes and queries. Just store you points as GeoJSON points and perform queries using GeoJSON polylines as bbox-es and $geoWithin.
Is it possible to get places by latitude/longitude and radius using the Graph API (or by address/zip)? I don't see it anywhere in the documentation
The following format for the search URL will return a list of places near a location:
https://graph.facebook.com/search?type=place¢er=<lat>,<lon>&distance=1000&access_token=<token>
I'm not sure on the units of the "distance" parameter.
I don't know much about the facebook API, but if you can pull the lat/long of two places, you can calculate their distance quite easily. Here it is in JavaScript, but it's portable to about any language:
var R = 6371; // km .. use 3963 for miles
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1.toRad()) * Math.cos(lat2.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; // km
Hopefully this helps you with your endeavor.
I'd like to use Google maps static API to display a map with a path overlay indicating a boundary.
AFAICT the static API doesn't support polygons, so I intend to circumvent this by drawing the boundary using paths.
To do this I need to determine the points to draw the straight lines (paths) between; so I'd like an algorithm that returns the geographic location (i.e. WGS84 coordinates) a given bearing and distance from a known point.
Can anyone point me to such an algorithm. Preferably in C#, but other languages are acceptable?
I implemented and tested it in C#, using Degrees as input/output instead of radians:
static readonly double FullCircleDegrees = 360d;
static readonly double HalfCircleDegrees = FullCircleDegrees / 2d;
static readonly double DegreesToRadians = Math.PI / HalfCircleDegrees;
static readonly double RadiansToDegrees = 1 / DegreesToRadians;
public LatLng GetPointGivenRadialAndDistance(LatLng center, double radius, double azimuth)
{
var lat1 = center.Lat * DegreesToRadians;
var lng1 = center.Lng * DegreesToRadians;
var lat = Math.Asin( (Math.Sin(lat1) * Math.Cos(radius)) + Math.Cos(lat1) * Math.Sin(radius) * Math.Cos(azimuth * DegreesToRadians));
var lng = 0d;
if (Math.Cos(lat) == 0)
{
lng = lng1;
}
else
{
lng = ((lng1 + Math.PI - Math.Asin(Math.Sin(azimuth * DegreesToRadians) * Math.Sin(radius) / Math.Cos(lat1))) % (2 * Math.PI)) - Math.PI;
}
return new LatLng(lat * RadiansToDegrees, lng * RadiansToDegrees);
}
You can draw polygon on a KML file, and then show the KML on Google maps.
Here's KML on Google maps (From Google KML Samples) check the "Google Campus - Polygons" section in the content.
In (I think) every language I know, radians. Note that I think your example code is giving you co-ordinates based on a sphere, not on WGS84. Here's Java code for converting between co-ordinate systems.
Take a look at Gavaghan Geodesy C# library, it should be what you're looking for. And it's free.
Found this (here: http://williams.best.vwh.net/avform.htm#LL):
A point {lat,lon} is a distance d out on the tc radial from point 1 if:
lat=asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
IF (cos(lat)=0)
lon=lon1 // endpoint a pole
ELSE
lon=mod(lon1-asin(sin(tc)*sin(d)/cos(lat))+pi,2*pi)-pi
ENDIF
Will the radial be in radians or degrees?
Edit:
radians = degrees * PI / 180