Bienvenue! Inscrivez-vous et rejoignez notre communauté :)
  • Login:

Bienvenue sur Forum SIG - Systèmes d'Information Géographique et Géomatique.

Bienvenue sur le forumSIG. S'il s'agit de votre première visite, assurez vous de faire une recherche préalable dans les FAQ SIG. Vous devez vous inscrire avant de pouvoir poster.

Affichage des résultats 1 à 6 sur 6
  1. #1

    Post Tracer une bissectrice

    Bonjour,

    Je cherche à tracer des bissectrices via postgis.
    J'ai utilisé le code ci-après, qui me permet de récupérer des informations quant à l'angle formé à la jointure de deux segments.


    Code:
    -- 3.- Create segments from points and calculate azimuth for each line. 
    --     two calls of generate_series for a single function wont work (azimuth). 
    
    select 
    id,        
    name,        
    polygon_num,       
    point_order as vertex,        
    
    --        
    
    case when point_order = 1          
      then last_value(ST_Astext(ST_Makeline(sp,ep))) over (partition by id, polygon_num)          
      else lag(ST_Astext(ST_Makeline(sp,ep)),1) over (partition by id, polygon_num order by point_order)        
    end ||' - '||ST_Astext(ST_Makeline(sp,ep)) as lines,       
     
    --        
    
    abs(abs(        
      case when point_order = 1          
        then last_value(degrees(ST_Azimuth(sp,ep))) over (partition by id, polygon_num)          
        else lag(degrees(ST_Azimuth(sp,ep)),1) over (partition by id, polygon_num order by point_order)        
      end - degrees(ST_Azimuth(sp,ep))) -180 ) as ang 
    from (-- 2.- extract the endpoints for every 2-point line segment for each linestring       
             --     Group polygons from multipolygon       
    
    select 
    id,              
    name,              
    coalesce(path[1],0) as polygon_num,              
    generate_series(1, ST_Npoints(geom)-1) as point_order,              
    ST_Pointn(geom, generate_series(1, ST_Npoints(geom)-1)) as sp,              
    ST_Pointn(geom, generate_series(2, ST_Npoints(geom)  )) as ep       
    
    from ( 
         -- 1.- Extract the individual linestrings and the Polygon number for later identification              
    
    select 
    id,                     
    name,                     
    (ST_Dump(ST_Boundary(the_geom))).geom as geom,                     
    (ST_Dump(ST_Boundary(the_geom))).path as path 
    
    -- To identify the polygon               
    
    from poly_and_multipoly ) as pointlist ) as segments;
    Source : https://stackoverflow.com/questions/...-multipolygons

    Ensuite je récupère une couche comprenant l'angle et les coordonnées des sommets à partir de la sélection précédente.

    Maintenant, j'aimerais trouver le moyen de tracer une ligne qui coupe cet angle en deux parties égales (bissectrice) sur une distance définie et dans la bonne orientation. De ce que je comprends, il faut désormais que je fasse un calcul vectoriel pour récupérer les coordonnées d'un point X'Y' que je pourrai relier au point XY pour tracer la bissectrice mais je dois faire une erreur dans mon code :

    Code:
    CREATE TABLE public.test_sommets_prime
    AS SELECT
    idu,
    x+distance*sin(ang/2) as xp,
    y+distance*cos(ang/2) as yp,
    idu_ilot,
    vertex,
    ang
    FROM public.test_sommets_principaux
    Mais le résultat n'est pas probant. Auriez-vous une aide à m'apporter svp ?


  2. #2

    Date d'inscription
    juin 2007
    Messages
    32

    Par défaut Re : Tracer une bissectrice

    il y a peut-être une bibliothèque (library) de topographie déjà existante quelque part ??

  3. #3

    Par défaut Re : Tracer une bissectrice

    Bonjour,

    Pour l'instant, je n'ai pas trouvé de librairie pour réaliser cette opération, mais je vois une autre méthode pour arriver à mon résultat. La construction d'une bissectrice se faisant au compas, j'imagine faire :
    - un premier buffer depuis mon sommet d'origine (point o)
    - récupérer les points d'intersection de mon buffer avec les deux segments qui composent mon angle [AO] et [BO]
    - réaliser un nouveau buffer depuis le point A et depuis le point B
    - récupérer le point d'intersection O' de ces deux buffer le plus loin du point d'orgine O
    - tracer un segment [OO']
    - prolonger le segment [OO'] de manière à atteindre une longueur souhaitée.

    Si je trouve une méthode qui fonctionne je vous la mets ici. Néanmoins, si vous avez déjà des idées, je suis preneur.

  4. #4

    Date d'inscription
    juin 2007
    Messages
    32

    Par défaut Re : Tracer une bissectrice

    il doit y avoir des outils de calcul géométrique COGO dans certains logiciels commerciaux payants comme AutoCAD ou ESRI ArcGIS (ArcInfo - ArcEditor).

    http://www.forumsig.org/search.php
    COGO

  5. #5

    Par défaut Re : Tracer une bissectrice

    Je vous remercie pour cette indication.

  6. #6

    Par défaut Re : Tracer une bissectrice

    Bonjour,

    Ci-après le code en entier, qui me permet d'arriver où j'en suis. Ma base est la table geo_parcelle issue du plugin cadastre de QGIS.


    -- Création de la couche des Ilots

    CREATE TABLE cadastre.s_ilots
    AS SELECT
    (ST_dump(ST_UNION(geo_parcelle.geom))).geom
    FROM cadastre_qgis.geo_parcelle;


    -- Ajout d'un numéro unique et précision sur géométrie

    ALTER TABLE cadastre.s_ilots
    ADD COLUMN id_ilot SERIAL PRIMARY KEY,
    ALTER COLUMN geom TYPE geometry(Polygon, 3949)


    -- Création de la couche domaine non cadastré appelé domaine public en attendant de déterminer le vrai domaine public
    -- A revoir avec exclusion des parcelles qui sont en fait de la voirie et l'exclusion du domaine privé non cadastré

    CREATE TABLE cadastre.s_domaine_public
    AS SELECT ST_DIFFERENCE(geo_commune.geom, ST_COLLECT(s_ilots.geom)) geom
    FROM cadastre_qgis.geo_commune, cadastre.s_ilots
    GROUP BY geo_commune.geom

    -- Ajout d'un numéro unique et précision sur géométrie

    ALTER TABLE cadastre.s_domaine_public
    ADD COLUMN id SERIAL PRIMARY KEY,
    ALTER COLUMN geom TYPE geometry(MultiPolygon, 3949)


    -- Création de la couche buffer à 6m pour les parcelles qui touchent le domaine public

    CREATE TABLE public.tb_buffer_initial
    AS SELECT t1.idu, ST_BUFFER(t1.geom, 6) geom
    FROM (SELECT idu, geo_parcelle.geom as geom
    FROM cadastre_qgis.geo_parcelle
    INNER JOIN cadastre.s_domaine_public
    ON ST_TOUCHES(geo_parcelle.geom, s_domaine_public.geom) IS TRUE
    ORDER BY idu) t1


    -- Création d'une couche testant la fonction ST_DIFFERENCE
    -- Necessité de s'occuper de la self intersection des buffers avant de faire le ST_DIFFERENCE

    CREATE TABLE public.test_dif AS SELECT
    ST_DIFFERENCE(tb_buffer_initial.geom, s_ilots.geom) geom
    FROM cadastre.s_ilots, public.tb_buffer_initial
    WHERE ST_INTERSECTS(tb_buffer_initial.geom, s_ilots.geom) IS TRUE and tb_buffer_initial.geom && s_ilots.geom


    -- Suppression de l'intérieur des parcelles

    CREATE TABLE public.tb_buffer_v2 AS SELECT
    idu,
    ST_DIFFERENCE(tb_buffer_initial.geom, s_ilots.geom) geom
    FROM cadastre.s_ilots, public.tb_buffer_initial
    WHERE ST_INTERSECTS(tb_buffer_initial.geom, s_ilots.geom) IS TRUE and tb_buffer_initial.geom && s_ilots.geom


    -- Création des sommets des parcelles qui touchent le domaine public
    -- Requête anormalement longue

    CREATE TABLE public.p_sommets AS
    SELECT
    row_number() OVER() as id_sommet,
    t1.id_angle,
    t1.id_ilot,
    t1.vertex,
    t1.sp as angle_geom,
    t3.x,
    t3.y,
    t1.segment1,
    t1.segment2,
    t3.idu
    FROM(
    select
    row_number() OVER () as id_angle,
    id_ilot,
    point_order as vertex,
    sp,
    --
    case when point_order = 1
    then last_value(ST_Astext(ST_Makeline(sp,ep))) over (partition by id_ilot)
    else lag(ST_Astext(ST_Makeline(sp,ep)),1) over (partition by id_ilot order by point_order) end as segment1,
    ST_Astext(ST_Makeline(sp,ep)) as segment2,
    --
    abs(abs(
    case when point_order = 1
    then last_value(degrees(ST_Azimuth(sp,ep))) over (partition by id_ilot)
    else lag(degrees(ST_Azimuth(sp,ep)),1) over (partition by id_ilot order by point_order)
    end - degrees(ST_Azimuth(sp,ep))) -180 ) as ang
    from (-- 2.- extract the endpoints for every 2-point line segment for each linestring
    -- Group polygons from multipolygon
    select id_ilot,
    generate_series(1, ST_Npoints(geom)-1) as point_order,
    ST_Pointn(geom, generate_series(1, ST_Npoints(geom)-1)) as sp,
    ST_Pointn(geom, generate_series(2, ST_Npoints(geom) )) as ep
    from ( -- 1.- Extract the individual linestrings and the Polygon number for later identification
    select id_ilot,
    (ST_Dump(ST_Boundary(geom))).geom as geom
    from cadastre.s_ilots ) as pointlist ) as segments) t1
    INNER JOIN (
    SELECT * FROM (
    WITH t AS -- Transfor polygons in sets of points
    (SELECT idu,
    st_dumppoints(geom) AS dump
    FROM cadastre_qgis.geo_parcelle),
    f AS -- Get the geometry and the indexes from the sets of points
    (SELECT t.idu,
    (t.dump).path[1] AS part,
    (t.dump).path[3] AS vertex,
    (t.dump).geom AS geom
    FROM t)
    -- Get all points filtering the last point for each geometry part
    SELECT row_number() OVER () AS gid, -- Creating a unique id
    f.idu,
    f.part,
    f.vertex,
    ST_X(f.geom) as x, -- Get point's X coordinate
    ST_Y(f.geom) as y, -- Get point's Y coordinate
    f.geom::geometry('POINT',3949) as geom -- make sure of the resulting geometry type
    FROM f
    WHERE (f.idu, f.part, f.vertex) NOT IN
    (SELECT f.idu,
    f.part,
    max(f.vertex) AS max
    FROM f
    GROUP BY f.idu,
    f.part)) t2) t3
    ON ST_EQUALS(t1.sp, t3.geom)
    WHERE ST_EQUALS(t1.sp, t3.geom) AND t1.sp && t3.geom
    ORDER BY t3.idu

    -- Création de la couche des point d'origine de la bissectrice

    CREATE TABLE public.p_obis AS
    SELECT
    row_number() OVER () AS id_origine,
    a.id_sommet,
    a.idu as idu_1,
    b.idu as idu_2,
    a.x,
    a.y,
    a.angle_geom,
    a.id_angle,
    a.id_ilot,
    a.segment1,
    a.segment2
    FROM
    public.p_sommets as a
    INNER JOIN
    public.p_sommets as b
    ON (a.x = b.x and a.y = b.y)
    WHERE a.idu != b.idu;

    -- Définition du SRID de p_obis

    ALTER TABLE public.p_obis
    ALTER COLUMN angle_geom TYPE geometry(point, 3949)
    USING ST_SetSRID(angle_geom,3949);


    -- Création de la couche des segments

    CREATE TABLE public.l_segments AS
    SELECT
    id_origine,
    id_sommet,
    id_angle,
    ST_GeomFromText(segment1) as geom,
    ST_Length(ST_GeomFromText(segment1)) as longueur
    FROM public.p_obis t1
    UNION SELECT
    id_origine,
    id_sommet,
    id_angle,
    ST_GeomFromText(segment2) as geom,
    ST_Length(ST_GeomFromText(segment2)) as longueur
    FROM public.p_obis t2;


    -- Définition du SRID de l_segments

    ALTER TABLE public.l_segments
    ALTER COLUMN geom TYPE geometry(LineString, 3949)
    USING ST_SetSRID(geom,3949);


    -- Vérification des segments

    SELECT * FROM public.p_obis
    WHERE p_obis.id_angle NOT IN (SELECT id_angle FROM public.l_segments);

    SELECT id_sommet, count(*) as nb FROM public.l_segments GROUP BY id_sommet ORDER BY nb ASC;


    -- Création de la couche des points d'intersection entre le buffer du point d'origine et la couche des segments

    CREATE TABLE public.p_buf1 AS
    WITH d AS
    (SELECT id_origine,
    MIN(longueur) as rayon
    FROM public.l_segments
    GROUP BY id_origine)
    SELECT
    row_number() OVER () as id_buf1,
    t1.id_origine,
    d.rayon,
    ST_INTERSECTION(ST_BOUNDARY(ST_BUFFER(t1.angle_geo m, (0.95*d.rayon))),t2.geom) geom
    FROM public.p_obis t1, public.l_segments t2, d
    WHERE ST_INTERSECTS(ST_BUFFER(t1.angle_geom, (0.95*d.rayon)), t2.geom) IS TRUE AND t1.angle_geom && t2.geom AND t1.id_origine = t2.id_origine AND d.id_origine = t1.id_origine;


    -- Contrôle du buffer1
    -- Manque 10 points d'intersection

    SELECT * FROM l_segments WHERE id_origine NOT IN (SELECT id_origine FROM public.p_buf1);
    SELECT id_origine, count(*) as nb FROM public.p_buf1 GROUP BY id_origine ORDER BY nb ASC;

    -- Création du deuxième buffer
    -- Attention sort en multipoint = pb

    CREATE TABLE public.p_buf2 AS SELECT
    row_number() OVER () as id_buf2,
    t1.id_origine,
    ST_INTERSECTION(ST_BOUNDARY(ST_BUFFER(t1.geom,0.95 *t1.rayon)),ST_BOUNDARY(ST_BUFFER(t2.geom,0.95*t1. rayon))) geom
    FROM
    public.p_buf1 as t1
    INNER JOIN
    public.p_buf1 as t2
    ON (t1.id_origine = t2.id_origine)
    WHERE t1.id_buf1 != t2.id_buf1;
    Mon problème actuel est que lorsque je créé mon deuxième buffer je me retrouve en fait avec un couche qui ne me sort pas uniquement des points dans QGIS mais également des lignes. Je pense que la dernière requête me génère des tangentes dans le cas où les angles mesurent 180°. Ce qui serait "normal" puisque je n'ai pas de véritable intersection entre les buffers.
    Aussi, je souhaiterais trouver le moyen de récupérer les 2 extrémités des tangentes, dans la même requête si c'est possible ; chaque extrémité devant correspondre à la colonne geom de ma dernière requête.

    Je vous remercie pour votre aide.

 

 

Discussions similaires

  1. [GPS] Tracer des randonnées
    Par benoit.charlier dans le forum Espace GPS et Solutions Nomades
    Réponses: 4
    Dernier message: 09/09/2014, 13h42
  2. [MapInfo 7.x] Tracer un arc
    Par Fansinov dans le forum Programmation
    Réponses: 2
    Dernier message: 19/12/2008, 04h54
  3. [MapInfo 7.x] Tracer un arc de cercle
    Par Urbain dans le forum Programmation
    Réponses: 5
    Dernier message: 10/12/2008, 07h33
  4. [MapInfo 7.x] Tracer un azimuth
    Par Snoopy dans le forum Assistance Technique
    Réponses: 2
    Dernier message: 16/05/2007, 09h00
  5. [MapBasic 8.x] Tracer des parallèles
    Par stephane dans le forum Programmation
    Réponses: 10
    Dernier message: 30/03/2007, 10h48

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •