IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Extensions PostgreSQL Discussion :

[PostGIS] Créer une ligne reliant un point au point le plus proche


Sujet :

Extensions PostgreSQL

  1. #1
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2016
    Messages : 67
    Points : 42
    Points
    42
    Par défaut [PostGIS] Créer une ligne reliant un point au point le plus proche
    Bonjour,
    Je m'explique:
    Je récupére des points depuis un formulaire dans une bdd postgreSQL, je veux créer un polygone a partir de ces points et le visualiser dans QGIS.

    le problème est que la ligne (st_makeline) relie les points aléatoirement alors que je veux par exemple:
    la ligne commence au point A et cherche quel point B est le plus proche du point A pour s'y attacher et ainsi de suite...

    avez vous une solution?

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 766
    Points : 52 563
    Points
    52 563
    Billets dans le blog
    5
    Par défaut
    Il faut itérer en cherchant le bon point suivant via un MIN(ST_Distance...)) puis ajouter ce point par construction de la chaine du polygone.



    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 766
    Points : 52 563
    Points
    52 563
    Billets dans le blog
    5
    Par défaut
    Inspirez vous de cette procédure écrite en Transact SQL (SQL Server) pour faire ce que je vous ait dit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    CREATE OR ALTER PROCEDURE F_POLYSMART 
       @MAXPNT SMALLINT,
       @MAXX   FLOAT,
       @MAXY   FLOAT
    AS
     
    SET NOCOUNT ON;
     
    DECLARE @I SMALLINT = 1;
     
    IF @MAXPNT < 3
    BEGIN
       RAISERROR ('Un polygone doit être définit par un minimum de trois points', 16, 1);
       RETURN;
    END;
     
    CREATE TABLE #PNT (ID SMALLINT IDENTITY PRIMARY KEY, POINT VARCHAR(128), DONE BIT DEFAULT 0)
     
    -- génération aléatoire de points pour définir un polygone
    WHILE @I <= @MAXPNT 
    BEGIN
       INSERT INTO #PNT (POINT) SELECT  + CAST(@MAXX * (CHECKSUM(NEWID()) / 2147483647.0) AS varchar(max)) + ' ' + 
                                          CAST(@MAXX * (CHECKSUM(NEWID()) / 2147483647.0) AS varchar(max)) ;
       SET @I = @I + 1;
    END;
     
    -- construction du polygone par raboutage des points dans l'ordre de génération
    WITH 
    T_PLG AS
    (SELECT CAST('POLYGON((' + POINT AS varchar(max)) AS GEO, ID, CAST(@MAXPNT AS bigint) AS N
     FROM   #PNT
     WHERE  ID = 1
     UNION ALL
     SELECT GEO + ', ' + POINT, #PNT.ID, N - 1
     FROM   T_PLG
            JOIN #PNT
                ON T_PLG.ID + 1 = #PNT.ID)
    SELECT CAST(GEO + ', ' + (SELECT POINT FROM #PNT WHERE ID = 1) + '))' AS geometry).MakeValid()
    FROM   T_PLG
    WHERE  N = 1;
     
    GO

    Dans votre cas, vous ne pourrez pas faire une requête récursive, mais une boucle cherchant le point suivant le plus proche et après chaque point utilisé le marquer comme déjà pris pour définir le périmètre du polygone.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 766
    Points : 52 563
    Points
    52 563
    Billets dans le blog
    5
    Par défaut
    Pour compléter je me suis amusé à le faire sous SQL Server :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    USE tempdb;
    GO
     
    CREATE OR ALTER PROCEDURE F_POLYSMART 
       @MAXPNT SMALLINT,
       @MAXX   FLOAT,
       @MAXY   FLOAT
    AS
     
    SET NOCOUNT ON;
     
    DECLARE @I SMALLINT = 1, @GEO GEOMETRY;
     
    IF @MAXPNT < 3
    BEGIN
       RAISERROR ('Un polygone doit être définit par un minimum de trois points', 16, 1);
       RETURN;
    END;
     
    CREATE TABLE #PNT (ID SMALLINT IDENTITY PRIMARY KEY, POINT VARCHAR(128), DONE BIT DEFAULT 0, NUM SMALLINT, D FLOAT)
     
    WHILE @I <= @MAXPNT 
    BEGIN
       INSERT INTO #PNT (POINT) SELECT  + CAST(@MAXX * (CHECKSUM(NEWID()) / 2147483647.0) AS varchar(max)) + ' ' + 
                                          CAST(@MAXX * (CHECKSUM(NEWID()) / 2147483647.0) AS varchar(max)) ;
       SET @I = @I + 1;
    END;
     
    WITH 
    T_PLG AS
    (SELECT CAST('POLYGON((' + POINT AS varchar(max)) AS GEO, ID, CAST(@MAXPNT AS bigint) AS N
     FROM   #PNT
     WHERE  ID = 1
     UNION ALL
     SELECT GEO + ', ' + POINT, #PNT.ID, N - 1
     FROM   T_PLG
            JOIN #PNT
                ON T_PLG.ID + 1 = #PNT.ID)
    SELECT @GEO = CAST(GEO + ', ' + (SELECT POINT FROM #PNT WHERE ID = 1) + '))' AS geometry).MakeValid()
    FROM   T_PLG
    WHERE  N = 1;
     
    SELECT @GEO AS GEO
     
    SELECT @GEO.STConvexHull() AS GEOHULL
     
    --> liaison avec les points les plus proches :
    DECLARE @GEOTEXT VARCHAR(max), @ID SMALLINT;
    SELECT @GEOTEXT = 'POLYGON((' + POINT, @I = 1 FROM #PNT WHERE ID = 1;
    UPDATE #PNT SET DONE = 1, NUM = 1 WHERE ID = 1;   
    WHILE EXISTS(SELECT * FROM #PNT WHERE DONE = 0)
    BEGIN
       UPDATE T
       SET    D = CAST('POINT(' + T0.POINT +')' AS GEOMETRY).STDistance(CAST('POINT(' + T.POINT +')' AS GEOMETRY))
       FROM   #PNT AS T
              CROSS JOIN #PNT AS T0
       WHERE  T.DONE = 0
         AND  T0.NUM = @I;
       SELECT TOP 1 @ID = ID FROM #PNT WHERE D = (SELECT MIN(D) FROM #PNT WHERE DONE = 0);
       SELECT @GEOTEXT = @GEOTEXT + ', ' + POINT FROM #PNT WHERE ID = @ID;
       UPDATE #PNT SET DONE = 1, NUM = @I + 1 WHERE ID = @ID; 
       SET @I = @I + 1;
    END;
     
    SELECT CAST(@GEOTEXT + ', ' + POINT + '))' AS geometry)
    FROM #PNT 
    WHERE ID = 1; 
     
    GO
    Il vous suffit de l'adapter à PostgreSQL...

    voici les 3 résultats dans SQL Server (SSMS) :
    Nom : Polygone aléatoire SQL Server Microsoft.jpg
Affichages : 573
Taille : 87,9 Ko
    Dans l'ordre des points,
    Dans l'ordre des points avec en sus calcul de l'enveloppe convexe
    Dans l'ordre de plus courte distance au point voisin.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. Réponses: 18
    Dernier message: 11/04/2007, 15h18
  2. [Tableaux] Créer une ligne dynamiquement
    Par Lenaick dans le forum Langage
    Réponses: 11
    Dernier message: 24/01/2007, 10h58
  3. [Tkinter] Créer une ligne en pointillée
    Par frky dans le forum Tkinter
    Réponses: 5
    Dernier message: 05/01/2006, 19h04
  4. Créer une ligne dans une table (en 1ere position)
    Par lipao17 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 12/12/2005, 11h09
  5. MFC - créer une ligne de séparation
    Par Amphitryon dans le forum MFC
    Réponses: 4
    Dernier message: 25/11/2004, 16h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo