Changes between Version 28 and Version 29 of Noeud - parcours RHT


Ignore:
Timestamp:
Jan 5, 2012 1:29:40 PM (13 years ago)
Author:
celine
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Noeud - parcours RHT

    v28 v29  
    260260}}} 
    261261 
     262== Distance source (Parcours source) 
     263{{{ 
     264#!sql 
     265-- script de calcul des distances sources 
     266set search_path to rht,public; 
     267select cast(ltree2text(subltree(chemin,0,1)) as integer) from rht_topology limit 10 
     268/* 
     269AJOUT D'UN INDEX 
     270ltree supports several types of indexes that can speed up the indicated operators: 
     271    B-tree index over ltree: <, <=, =, >=, > 
     272    GiST index over ltree: <, <=, =, >=, >, @>, <@, @, ~, ?  
     273*/ 
     274CREATE INDEX chemin_btee_index ON rht.rht_topology USING btree(chemin); --27688 ms 
     275VACUUM ANALYSE rht.rht_topology; 
     276CREATE INDEX chemin_gist_index ON rht.rht_topology USING GIST (chemin); -- fait planter mon serveur.... 
     277SELECT * from rht.rht_topology where chemin <@ '212340'; -- tronçon source de la Vilaine -- 2360 
     278SELECT chemin from rht.rht_topology where chemin <@ '212340' limit 1 
     279-- La distance source est la distance mer maximale de tous les chemins possibles en ne prenant que le dernier tronçon du chemin. 
     280Select max(dmer) from rht.rht_topology where id_drain in ( 
     281Select cast(ltree2text(subpath(chemin, -1, 1))as integer) as chenin_id_drain from rht.rht_topology where chemin ~ '*.212340.*'); 
     282--  travail sur les noeuds source et le recalcul des distances mer et source (voir fichier doc joint) 
     283-- en pratique les distances sont calculées a partir du milieu de chaque tronçon, elles prennent par contre toute la distance des tronçons autre que le tronçon considéré. 
     284 
     285alter table rht.rht_topology add column noeudsource boolean default FALSE; 
     286-- identification des noeuds source 
     287update rht.rht_topology set noeudsource=TRUE where id_drain in ( 
     288select id_drain from rht.rht_topology except ( 
     289select rt2.id_drain from rht.rht_topology rt1 join rht.rht_topology rt2 on rt1.nextdownid=rt2.id_drain) 
     290);-- 57533 
     291update rht.rht_topology set dmer=dmer+length/2;-- 114600 
     292alter table rht.rht_topology add column dsource numeric; 
     293update rht.rht_topology set dsource=length/2 where noeudsource;-- 57533 
     294-- voir schéma pour explications 
     295 
     296 
     297DROP FUNCTION IF EXISTS rht.distance_source(); 
     298 
     299CREATE OR REPLACE FUNCTION rht.distance_source(min integer, max integer) RETURNS integer AS $$ 
     300DECLARE 
     301    ligne integer; 
     302    nbligne integer;  
     303    id_drains record; 
     304BEGIN 
     305        ligne:=1; 
     306        DROP TABLE IF EXISTS sousselection; 
     307        DROP sequence IF EXISTS  seq; 
     308        CREATE sequence seq; 
     309        EXECUTE 'create temporary table sousselection as SELECT id_drain, nextval(''seq'') as num FROM (SELECT * FROM rht.rht_topology WHERE noeudsource=FALSE ORDER BY id_drain) as sub WHERE id_drain >='|| min || ' AND id_drain<='||max ; 
     310        SELECT COUNT(*) FROM sousselection INTO nbligne; 
     311        WHILE ligne <=nbligne LOOP 
     312                  -- pour vérification décommenter ensuite 
     313                  SELECT * from sousselection where num=ligne INTO id_drains; 
     314                  RAISE NOTICE 'distance_source for %', quote_ident(CAST(id_drains.id_drain as text)); 
     315                  EXECUTE 'INSERT INTO rht.distance_source SELECT '||id_drains.id_drain||', MAX(dmer+length/2) as dmer FROM rht.rht_topology WHERE id_drain IN ( 
     316                        SELECT CAST(ltree2text(subpath(chemin, -1, 1))as integer) FROM rht.rht_topology where chemin ~  ''*.'|| 
     317                        id_drains.id_drain 
     318                        || '.*'' )';   
     319                ligne=ligne+1;       
     320        END LOOP; 
     321    RETURN ligne; 
     322END; 
     323$$ LANGUAGE plpgsql; 
     324-- lancement de la requête 
     325DROP TABLE IF EXISTS rht.distance_source; 
     326CREATE TABLE rht.distance_source (id_drain integer,distance  numeric); 
     327select rht.distance_source(1,50000); 
     328 
     329-- pour essai pour voir ce qui se passe dans la requête 
     330 
     331SELECT 212340,  MAX(dmer+length/2) as dmer FROM rht.rht_topology WHERE id_drain IN ( 
     332                        SELECT CAST(ltree2text(subpath(chemin, -1, 1))as integer) FROM rht.rht_topology where chemin ~  '*.212340.*' ) 
     333-- il faudra enlever la dmer de 212340 
     334 
     335-- POUR LES LANCEMENTS FINAUX IL A FALLU LANCER UN INDEX ET RAJOUTER UNE CLE PRIMAIRE 
     336Alter table rht.rht_topology add constraint c_pk_id_drain primary key (id_drain); 
     337CREATE INDEX id_drain_index  ON rht.rht_topology 
     338  USING btree 
     339  (id_drain); 
     340 
     341select rht.distance_source(100000,200000); 
     342select rht.distance_source(200001,300000); 
     343select rht.distance_source(300001,400000); 
     344select rht.distance_source(400001,600000); 
     345 
     346-- pour essai pour voir ce qui se passe dans la requête 
     347 
     348SELECT 212340,  MAX(dmer+length/2) as dmer FROM rht.rht_topology WHERE id_drain IN ( 
     349                        SELECT CAST(ltree2text(subpath(chemin, -1, 1))as integer) FROM rht.rht_topology where chemin ~  '*.212340.*' ) 
     350 
     351 
     352select * from rht.rht_topology t join rht.distance_source s on s.id_drain=t.id_drain where distance is null; --323 
     353 
     354-- il faudra enlever la dmer de 212340 
     355 
     356-- requête finale pour calculer les distances source (à lancer) 
     357alter table rht.distance_source  add column distance_source numeric; 
     358select count(*) from rht.distance_source; --57067 que les noeuds non source 
     359 
     360-- mise à jour des distances source dans la table distance source (il faut encore enlever dmer) 
     361update rht.distance_source d set distance_source = sub.distance_source from ( 
     362select t.id_drain, distance-dmer as distance_source from rht.distance_source s join rht.rht_topology t on s.id_drain=t.id_drain) as sub 
     363where sub.id_drain=d.id_drain; --57067 
     364 
     365-- copie des valeurs de distance_source dans dsource de la table rht.rht_topology 
     366update rht.rht_topology t set dsource=distance_source 
     367from rht.distance_source d where d.id_drain=t.id_drain; --57067 
     368 
     369-- mise à jour des distances_source (pour l'instant valeurs = null) pour les noeuds source (pour les derniers c'est la moitié de la longueur du segment) 
     370update rht.rht_topology t set dsource=length/2 where noeudsource; 
     371-- nombre de  
     372select count(*)as count, noeudsource from rht.rht_topology where dsource is null group by noeudsource; 
     373}}} 
     374 
     375 
     376== Utilisation des donnees de parcours == 
     377En pratique nous n'aurons probablement besoin que du noeud le plus amont des parcours comme programmé ci dessus. Mais les scripts ci-dessous pourraient s'avérer utiles. [[BR]] 
     378Ci dessous la fonction utilise les expressions régulières ltree => vecteur => table 
     379 
     380{{{ 
     381#!sql 
     382/* 
     383regexp_split_to_array(string text, pattern text [, flags text ])        regexp_split_to_array('hello world', E'\\s+')   {hello,world} 
     384SELECT regexp_split_to_array('hello world', E'\\s+'); 
     385SELECT regexp_split_to_array('hello.world', E'\\.+'); 
     386*/ 
     387SELECT regexp_split_to_array(ltree2text(chemin),E'\\.+') from rht.rht_topology where chemin <@ '212340'; 
     388 
     389/* 
     390http://www.pgsql.cz/index.php/PostgreSQL_SQL_Tricks#Array_to_table 
     391SELECT (ARRAY[1,3,4,6,7])[idx.n] FROM generate_series(1,7) idx(n); 
     392CREATE OR REPLACE FUNCTION unpack(anyarray) 
     393RETURNS SETOF anyelement AS $$  
     394SELECT $1[i]  
     395   FROM generate_series(array_lower($1,1),  
     396                        array_upper($1,1)) g(i); 
     397$$ LANGUAGE sql STRICT IMMUTABLE; 
     398*/ 
     399CREATE OR REPLACE FUNCTION unpack(anyarray) 
     400RETURNS SETOF anyelement AS $$  
     401SELECT $1[i]  
     402   FROM generate_series(array_lower($1,1),  
     403                        array_upper($1,1)) g(i); 
     404$$ LANGUAGE sql STRICT IMMUTABLE; 
     405-- pour convertir un vecteur en table 
     406select unpack(vecteurchemin) from  
     407        (SELECT regexp_split_to_array(ltree2text(chemin),E'\\.+') as vecteurchemin from rht.rht_topology where chemin <@ '212340' limit 1) as sub 
     408-- j'avais pas vu il y a déjà une fonction magique unest... 
     409select cast(unnest(vecteurchemin) as integer) as chemin_id_drain from 
     410        (SELECT regexp_split_to_array(ltree2text(chemin),E'\\.+') as vecteurchemin from rht.rht_topology where chemin <@ '212340' limit 1) as sub 
     411-- Fonction qui renvoit les identifiants uniques des tronçons en amont d'un ouvrage 
     412 
     413 
     414CREATE OR REPLACE FUNCTION troncons(integer) 
     415RETURNS SETOF integer AS $$ 
     416select cast(unnest(vecteurchemin) as integer) as chemin_id_drain from 
     417        (SELECT regexp_split_to_array(ltree2text(chemin),E'\\.+') as vecteurchemin from rht.rht_topology where chemin <@ text2ltree(cast ($1 as text))  limit 1) as sub; 
     418$$ LANGUAGE sql STRICT IMMUTABLE;        
     419 
     420SELECT troncons_amont(212340); -- OK 
     421}}} 
     422