Find N Nearest LineString From A Point Using MySQL Spatial Extensions

前端 未结 3 767
醉梦人生
醉梦人生 2021-02-09 00:17

I\'m using MySQL Spatial Extensions to store data about roads and hotels. I store the hotel data as a Point while I store the road data as LineString. The tables look like this<

相关标签:
3条回答
  • 2021-02-09 00:41

    I have been also working on this issue, but unfortunately finding the nearest road for Hotels is an unfavorable solution. I have found that the entrance the road is on is the definitive answer. In other words the address. This means having an address table and matching points to nearest address road.

    0 讨论(0)
  • 2021-02-09 00:47

    This was a very useful answer for me, but I'm using MySQL 5.7.18, which has more advanced or just different geo query functions. The distance function posted isn't needed anymore- use ST_Distance_Sphere. So here's an update of the same code to make DistanceFromLine compliant with modern (5.7.6+) MySQL...

    DROP function IF EXISTS `DistanceFromLine`;
    delimiter //
        CREATE FUNCTION `DistanceFromLine`(
        route LINESTRING, point1 POINT
        ) RETURNS INT DETERMINISTIC
            BEGIN
            DECLARE a INT Default 0 ;
            DECLARE minDistance INT Default 0;
            DECLARE currentDistance INT Default 0;
            DECLARE currentpoint point ;
            DECLARE size INT Default 0 ;
            SET size =  ST_NumPoints(route);
                  simple_loop: LOOP
           SET a = a+1;
           SET currentpoint = ST_PointN(route,a);
           SET currentDistance = ST_Distance_Sphere(point1,currentpoint);
    
           IF a = 1 THEN
            SET minDistance = currentDistance;
               END IF;
    
           IF currentDistance < minDistance THEN
            SET minDistance = currentDistance;
           END IF;
           IF a=size THEN
                     LEAVE simple_loop;
           END IF;
              END LOOP simple_loop;
         RETURN (minDistance);
     END//
    
    0 讨论(0)
  • 2021-02-09 00:49

    You can create two functions in the database:

    1. Distance : This will give you distance between two points
    2. DistanceFromLine : Here distance will be calculated from each point in line, and will give you the shortest distance.

    Compare the distance between your point and lines and choose the shortest one.

    Here is the Distance function


    delimiter //
    
    CREATE FUNCTION distance (latA double, lonA double, latB double, LonB double)
    RETURNS double DETERMINISTIC
        BEGIN
            SET @RlatA = radians(latA);
            SET @RlonA = radians(lonA);
            SET @RlatB = radians(latB);
            SET @RlonB = radians(LonB);
            SET @deltaLat = @RlatA - @RlatB;
            SET @deltaLon = @RlonA - @RlonB;
            SET @d = SIN(@deltaLat/2) * SIN(@deltaLat/2) +
            COS(@RlatA) * COS(@RlatB) * SIN(@deltaLon/2)*SIN(@deltaLon/2);
            RETURN 2 * ASIN(SQRT(@d)) * 637101;
        END//
    

    Here is DistanceFromLine function:


    DROP function IF EXISTS `DistanceFromLine`;
    delimiter //
        CREATE FUNCTION `DistanceFromLine`(
        route LINESTRING, point1 POINT
        ) RETURNS INT DETERMINISTIC
            BEGIN
            DECLARE a INT Default 0 ;
            DECLARE minDistance INT Default 0;
            DECLARE currentDistance INT Default 0;
            DECLARE currentpoint point ;
            DECLARE size INT Default 0 ;
            SET size =  NumPoints(route);
                  simple_loop: LOOP
           SET a = a+1;
           SET currentpoint = PointN(route,a);
           SET currentDistance = Distance(X(point1), Y(point1),       
                   X(currentpoint),Y(currentpoint));
    
           IF a = 1 THEN
            SET minDistance = currentDistance;
               END IF;
    
           IF currentDistance < minDistance THEN
            SET minDistance = currentDistance;
           END IF;
           IF a=size THEN
                     LEAVE simple_loop;
           END IF;
              END LOOP simple_loop;
         RETURN (minDistance);
     END//
    

    0 讨论(0)
提交回复
热议问题