Fastest Way to Find Distance Between Two Lat/Long Points

后端 未结 15 955
时光说笑
时光说笑 2020-11-21 10:12

I currently have just under a million locations in a mysql database all with longitude and latitude information.

I am trying to find the distance between one point a

相关标签:
15条回答
  • 2020-11-21 10:27
    SELECT * FROM (SELECT *,(((acos(sin((43.6980168*pi()/180)) * 
    sin((latitude*pi()/180))+cos((43.6980168*pi()/180)) * 
    cos((latitude*pi()/180)) * cos(((7.266903899999988- longitude)* 
    pi()/180))))*180/pi())*60*1.1515 ) as distance 
    FROM wp_users WHERE 1 GROUP BY ID limit 0,10) as X 
    ORDER BY ID DESC
    

    This is the distance calculation query between to points in MySQL, I have used it in a long database, it it working perfect! Note: do the changes (database name, table name, column etc) as per your requirements.

    0 讨论(0)
  • 2020-11-21 10:28

    I needed to solve similar problem (filtering rows by distance from single point) and by combining original question with answers and comments, I came up with solution which perfectly works for me on both MySQL 5.6 and 5.7.

    SELECT 
        *,
        (6371 * ACOS(COS(RADIANS(56.946285)) * COS(RADIANS(Y(coordinates))) 
        * COS(RADIANS(X(coordinates)) - RADIANS(24.105078)) + SIN(RADIANS(56.946285))
        * SIN(RADIANS(Y(coordinates))))) AS distance
    FROM places
    WHERE MBRContains
        (
        LineString
            (
            Point (
                24.105078 + 15 / (111.320 * COS(RADIANS(56.946285))),
                56.946285 + 15 / 111.133
            ),
            Point (
                24.105078 - 15 / (111.320 * COS(RADIANS(56.946285))),
                56.946285 - 15 / 111.133
            )
        ),
        coordinates
        )
    HAVING distance < 15
    ORDER By distance
    

    coordinates is field with type POINT and has SPATIAL index
    6371 is for calculating distance in kilometres
    56.946285 is latitude for central point
    24.105078 is longitude for central point
    15 is maximum distance in kilometers

    In my tests, MySQL uses SPATIAL index on coordinates field to quickly select all rows which are within rectangle and then calculates actual distance for all filtered places to exclude places from rectangles corners and leave only places inside circle.

    This is visualisation of my result:

    Gray stars visualise all points on map, yellow stars are ones returned by MySQL query. Gray stars inside corners of rectangle (but outside circle) were selected by MBRContains() and then deselected by HAVING clause.

    0 讨论(0)
  • 2020-11-21 10:29
    set @latitude=53.754842;
    set @longitude=-2.708077;
    set @radius=20;
    
    set @lng_min = @longitude - @radius/abs(cos(radians(@latitude))*69);
    set @lng_max = @longitude + @radius/abs(cos(radians(@latitude))*69);
    set @lat_min = @latitude - (@radius/69);
    set @lat_max = @latitude + (@radius/69);
    
    SELECT * FROM postcode
    WHERE (longitude BETWEEN @lng_min AND @lng_max)
    AND (latitude BETWEEN @lat_min and @lat_max);
    

    source

    0 讨论(0)
  • The following MySQL function was posted on this blog post. I haven't tested it much, but from what I gathered from the post, if your latitude and longitude fields are indexed, this may work well for you:

    DELIMITER $$
    
    DROP FUNCTION IF EXISTS `get_distance_in_miles_between_geo_locations` $$
    CREATE FUNCTION get_distance_in_miles_between_geo_locations(
      geo1_latitude decimal(10,6), geo1_longitude decimal(10,6), 
      geo2_latitude decimal(10,6), geo2_longitude decimal(10,6)) 
    returns decimal(10,3) DETERMINISTIC
    BEGIN
      return ((ACOS(SIN(geo1_latitude * PI() / 180) * SIN(geo2_latitude * PI() / 180) 
        + COS(geo1_latitude * PI() / 180) * COS(geo2_latitude * PI() / 180) 
        * COS((geo1_longitude - geo2_longitude) * PI() / 180)) * 180 / PI()) 
        * 60 * 1.1515);
    END $$
    
    DELIMITER ;
    

    Sample usage:

    Assuming a table called places with fields latitude & longitude:

    SELECT get_distance_in_miles_between_geo_locations(-34.017330, 22.809500,
    latitude, longitude) AS distance_from_input FROM places;
    
    0 讨论(0)
  • 2020-11-21 10:32

    if you are using MySQL 5.7.*, then you can use st_distance_sphere(POINT, POINT).

    Select st_distance_sphere(POINT(-2.997065, 53.404146 ), POINT(58.615349, 23.56676 ))/1000  as distcance
    
    0 讨论(0)
  • 2020-11-21 10:32
       select
       (((acos(sin(('$latitude'*pi()/180)) * sin((`lat`*pi()/180))+cos(('$latitude'*pi()/180)) 
        * cos((`lat`*pi()/180)) * cos((('$longitude'- `lng`)*pi()/180))))*180/pi())*60*1.1515) 
        AS distance
        from table having distance<22;
    
    0 讨论(0)
提交回复
热议问题