Find N Nearest LineString From A Point Using MySQL Spatial Extensions

前端 未结 3 765
醉梦人生
醉梦人生 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: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//
    

提交回复
热议问题