8
votes

Trouver n LineString le plus proche à partir d'un point utilisant des extensions spatiales MySQL

J'utilise Extensions spatiales MySQL pour stocker des données sur les routes et hôtels. Je stocke les données de l'hôtel comme un point pendant que je stocke les données de la route telles que la lignes. Les tables ressemblent à ceci xxx

la visualisation d'une instance serait comme celle-ci.

 http://i.stack.imgur.com/8ivva.png

Mon problème est donné un numéro N et un point P, quelle est la requête SQL à trouver N routes les plus proches du point P? La distance est définie par la plus petite distance perpendiculaire entre un segment de la route jusqu'au point comme indiqué ci-dessus. (Bien que dans la réalité, la distance la plus proche doit être entre la porte de l'autoroute et un hôtel, mais dans ce cas, nous pouvons entrer dans l'autoroute à partir de n'importe quel point: p)

S'il n'y a pas de solution d'instruction SQL unique Pour ce problème, une requête SQL intermédiaire et un post-traitement sont acceptables pour moi. Mais quelle serait une requête SQL efficace et sur la manière de poster les données?


2 commentaires

Avez-vous déjà obtenu votre réponse? :)


Veuillez vous assurer que vous utilisez MySQL 5.5 sinon la fonctionnalité spatiale n'est pas suffisamment mise en œuvre pour répondre à votre question.


3 Réponses :


2
votes

Vous pouvez créer deux fonctions dans la base de données:

  1. Distance: Cela vous donnera la distance entre deux points li>
  2. DistanceFromLine: La distance ici sera calculée à partir de chaque point en ligne et vous donnera la distance la plus courte. Li> ol>

    comparer la distance entre votre point et vos lignes et choisissez le plus court la plus bref. p>

    Voici la fonction de distance p>


    xxx pré>

    Voici la fonction DistanceFromline: P>


    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 commentaires

1
votes

C'était une réponse très utile pour moi, mais j'utilise MySQL 5.7.18, qui a des fonctions plus avancées ou plus différentes de Geo Requête. La fonction de distance affichée n'est plus nécessaire. Utilisez ST_DISTANCE_SPHERE. Donc, voici une mise à jour du même code pour créer la distance en conformité avec moderne (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 commentaires

0
votes

J'ai également travaillé sur cette question, mais malheureusement, trouver la route la plus proche pour les hôtels est une solution défavorable. J'ai constaté que l'entrée de la route est la réponse définitive. En d'autres termes, l'adresse. Cela signifie avoir une table d'adresses et des points correspondants à route d'adresse la plus proche .


0 commentaires