问题
I'm programming an application where I save GPS location (lat and long) into each user info. I need to search the nearest users, I can only search using a between() function provided by my database, this function only checks if a number is between a range min and max, it's a very limited tool.
Can I use this to find near users?
This is a pseudo-code example of what I could do, this example finds users that their lat and long values are not more or less than 2 comparing with the target user:
lon.is(between(user.lon - 2, user.lon + 2).and(
lat.is(between(user.lat - 2, user.lat + 2))
I don't care about accuracy, I only want to get the closest users in maximum distance of like a city size approximately, that is all I need.
Is this going to work? I'm not familiar with geolocation math and coordinate problems in general.
When I store the GPS data I can convert the data into another format using all the math required without problems, so a coordinte system convertion is available, but for searching I can only use that function.
回答1:
If you have the differences in latitude and longitude in decimal degrees, you can do a quick calculation for distance.
Considering the mean Earth radius to be 6,371 km, meaning that each degree covers approximately:
(2*pi*6371)/360 = 111.19 Km,
all you have to do is to take the resultant of the latitude and longitude differences as:
sqrt((lat1-lat2)^2 + (lon1-lon2)^2),
and multiply it for 119.19 to have the distance in Km.
This is a very rough calculation as you requested, but should be enough if we're talking about city-level precision.
Update:
Your pseudocode would look like this:
#City radius in Km
city_radius = 60
#City radius in degrees
city_radius_degree = 60/111.19
lon.is.NOT(between(user.lon - city_radius_degree, user.lon + city_radius_degree).or(
lat.is.NOT(between(user.lat - city_radius_degree, user.lat + city_radius_degree))
You're checking if, in any direction, the users are within the same circle. See that I changed the query from and to or, since both don;t have to be true at the same time for the distance to be above a certain threshold.
Again, this is a very rough approximation, but probably good enough for your intentions.
回答2:
First of all, Gremlin does support complex math calculations using the math
step.
For simplicity I used the Equirectangular approximation formula:
x = Δλ ⋅ cos φm
y = Δφ
d = R ⋅ √x² + y²
To get the distance between user (id = 0) and her connected users, assuming GPS coordinates are stored in Degrees, you can use this query:
g.V(0).as("ln1","lt1").out().as("ln2","lt2")
.math("sqrt (((ln2 - ln1) * 3.141 / 180 * cos ((lt1 + lt2) * 3.141 / 360))^2 + ((lt2 - lt1) * 3.141 / 180)^2) * 6371")
.by("lon").by("lon").by("lat").by("lat")
Where 3.141 stands for PI, and 6371 is the average radius of earth (in km).
If GPS values were stored in Radians (R = D * PI / 180
) it becomes much cleaner:
g.V(0).as("ln1","lt1").out().as("ln2","lt2")
.math("sqrt (((ln2 - ln1) * cos ((lt1 + lt2) / 2))^2 + (lt2 - lt1)^2) * 6371")
.by("lon").by("lon").by("lat").by("lat")
Finally, to get only those within a specific distance (i.e. 20km), you can append .is(lt(20))
to the query. To get the users vertices you can move the math
step inside a where
step.
来源:https://stackoverflow.com/questions/59380318/measure-gps-distance-between-two-points-without-using-almost-any-math-accuracy