Getting the greatest distance from the GPS coordinate group

So, I have a database with several GPS coordinate lines. I know how to calculate the distance from a given lat / lng from any of them in the database, but I want to basically look at the coordinates of the rowset and get two rows that are spaced apart. I would love it if I could do it in SQL, but if I need to do it in the application code that will work. Here is what I do to calculate the distance between two points:

ROUND(( 3960 * acos( cos( radians( :lat ) ) *
cos( radians( p.latitude ) ) * cos( radians(  p.longitude  ) - radians( :lng ) ) +
sin( radians( :lat ) ) * sin( radians(  p.latitude  ) ) ) ),1) AS distance

What we are trying to do is look at the GPS data for a specific user and make sure that they do not move wildly throughout the country. All coordinates for the user must be within a few miles of each other. A flag that contains malicious activity in our system is the coordinates throughout the country. Therefore, I would like to be able to quickly run data for a spicicic user and know what maximum distance they were.

I thought about just running Max / Min on lat and lng separately and setting an internal threshold for an acceptable one. And maybe it’s easier, but if what I asked in the first part, it might be better.

+4
source share
1 answer

SQL Server 2008 , GEOGRAPHY , :

DECLARE @lat1 DECIMAL(19,6) = 44.968046;
DECLARE @lon1 DECIMAL(19,6) = -94.420307;
DECLARE @lat2 DECIMAL(19,6) = 44.33328;
DECLARE @lon2 DECIMAL(19,6) = -89.132008;
SELECT GEOGRAPHY::Point(@lat1, @lon1, 4326).STDistance(GEOGRAPHY::Point(@lat2, @lon2, 4326));

?

lats/longs . , , , - :

DECLARE @UserGPS TABLE (
    UserId INT, --the user
    GPSId INT, --the incrementing unique id associated with this GPS reading (could link to a table with more details, e.g. time, date)
    Lat DECIMAL(19,6), --lattitude
    Lon DECIMAL(19,6)); --longitude
INSERT INTO @UserGPS SELECT 1, 1, 44.968046, -94.420307; --User #1 goes on a very long journey
INSERT INTO @UserGPS SELECT 1, 2, 44.33328, -89.132008;
INSERT INTO @UserGPS SELECT 1, 3, 34.12345, -92.21369;
INSERT INTO @UserGPS SELECT 1, 4, 44.978046, -94.430307;
INSERT INTO @UserGPS SELECT 2, 1, 44.968046, -94.420307; --User #2 doesn't get far
INSERT INTO @UserGPS SELECT 2, 2, 44.978046, -94.430307;

--Make a working table to store the distances between each set of co-ordinates
--This isn't strictly necessary; we could change this into a common-table expression
DECLARE @WorkTable TABLE (
    UserId INT, --the user
    GPSIdFrom INT, --the id of the first set of co-ordinates
    GPSIdTo INT, --the id of the second set of co-ordinates being compared
    Distance NUMERIC(19,6)); --the distance

--Get the distance between each and every combination of co-ordinates for each user
INSERT INTO
    @WorkTable
SELECT
    c1.UserId,
    c1.GPSId,
    c2.GPSId,
    GEOGRAPHY::Point(c1.Lat, c1.Lon, 4326).STDistance(GEOGRAPHY::Point(c2.Lat, c2.Lon, 4326))
FROM
    @UserGPS c1
    INNER JOIN @UserGPS c2 ON c2.UserId = c1.UserId AND c2.GPSId > c1.GPSId;
--Note this is a self-join, but single-tailed.  So we compare each set of co-ordinates to each other set of co-ordinates for a user
--This is handled by the "c2.GPSID > c1.GPSId" in the JOIN clause
--As an example, say we have three sets of co-ordinates for a user
--We would compare set #1 to set #2
--We would compare set #1 to set #3
--We would compare set #2 to set #3
--We wouldn't compare set #3 to anything (as we already did this)

--Determine the maximum distance between all the GPS co-ordinates per user
WITH MaxDistance AS (
    SELECT
        UserId,
        MAX(Distance) AS Distance
    FROM
        @WorkTable
    GROUP BY
        UserId)
--Report the results
SELECT
    w.UserId,
    g1.GPSId,
    g1.Lat,
    g1.Lon,
    g2.GPSId,
    g2.Lat,
    g2.Lon,
    md.Distance AS MaxDistance
FROM 
    MaxDistance md
    INNER JOIN @WorkTable w ON w.UserId = md.UserId AND w.Distance = md.Distance
    INNER JOIN @UserGPS g1 ON g1.UserId = md.UserId AND g1.GPSId = w.GPSIdFrom
    INNER JOIN @UserGPS g2 ON g2.UserId = md.UserId AND g2.GPSId = w.GPSIdTo;

:

UserId  GPSId   Lat Lon GPSId   Lat Lon MaxDistance
1   3   34.123450   -92.213690  4   44.978046   -94.430307  1219979.460185
2   1   44.968046   -94.420307  2   44.978046   -94.430307  1362.820895

, , . , , ?

+1

Source: https://habr.com/ru/post/1589226/


All Articles