Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Printemps des cartes 2024

#1 Fri 10 June 2016 15:57

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

[Postgis] Volumétrie des données et temps de traitement

Bonjour,
Sur les conseils avisés d'un membre du forum, j'ouvre un sujet concernant la volumétrie des données et l'optimisation des temps de calcul.
Je travaille actuellement sur l'élaboration d'un grid couvrant les zones maritimes de toute la planètes. La maille unitaire de ce réseau est un carré auquel on ajoute ses diagonales.
Ayant réalisé un réseau couvrant toute la planète, à une maille relativement fine (le côté du carré est d'environ 3 km) avec une requête pgadmin, cela m'a pris de nombreuses heures.
Il faut maintenant que je découpe ce grid pour qu'il ne passe que par les zones maritimes.
J’ai déjà m'a requête, cependant étant donné que j'ai 622 066 000 lignes estimées dans ma table, je pense que cela va me prendre un temps fou à découper. Pourriez-vous m'aider à optimiser mes calculs?
Voici ma requête dans pgadmin III:

(mon grid actuel entier est la table "lng_grid_test", et mon grid découpé sera la table "lng_grid")

Code:

DROP TABLE IF EXISTS lng_grid; -- delete table, change table name to fit existing table

CREATE TABLE lng_grid(
        gid serial primary key,
        geom geometry(Linestring, 4326)
            );

DO $$ DECLARE

    _geom geometry;
    _lng_grid_id integer;
    _lng_grid_max_id integer;
    _country_id varchar;
    r record;

BEGIN

    _lng_grid_id := 1;

    _lng_grid_max_id := SELECT max(gid) FROM lng_grid_test AS lng_grid_max_id(gid integer));

    WHILE _lng_grid_id <= _lng_grid_max_id LOOP 

        _geom := (SELECT geom FROM 
                        (SELECT gid, geom FROM lng_grid_test)
            AS lng_grid_geom(gid integer, geom geometry(LineString, 4326)) WHERE lng_grid_geom.gid =  _lng_grid_id);

        FOR r IN SELECT geom FROM countries
                AS countries(geom geometry(Polygon, 4326)) WHERE ST_Intersects(_geom, countries.geom)
        LOOP

        _geom := ST_Difference(_geom, r.geom);

        END LOOP;

        INSERT INTO lng_grid(geom) SELECT (ST_Dump(_geom)).geom;

        RAISE NOTICE 'LNG grid id %, % percent completed, processing since %', _lng_grid_id, round((_lng_grid_id::numeric/_lng_grid_max_id::numeric)*100,1), clock_timestamp()-now();

        _lng_grid_id = _lng_grid_id + 1;

    
    END LOOP;

END$$;

Mais avant de lancer cette requête je souhaite d'abord mettre un index spatial.

Code:

DROP INDEX IF EXISTS lng_grid_test_idx;
CREATE INDEX lng_grid_test_idx
ON public.lng_grid_test
USING gist
(geom);

Malheureusement cela fait 1h20 minutes que ca tourne, et toujours rien.

Dernière modification par Nugg_00 (Fri 10 June 2016 17:30)

Hors ligne

 

#2 Sat 11 June 2016 10:23

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [Postgis] Volumétrie des données et temps de traitement

Bonjour,

Vous pouvez peut etre utiliser une couche des océans déjà découpée ? (par exemple: http://www.naturalearthdata.com/downloa … vectors/).

Ensuite, pour aller plus vite, faite directement une requete SQL pour réaliser le découpage, plutot qu'une fonction qui itère sur des objets:
le SQL fera ces itérations à votre place.

Comment avez-vous produit la grille de découpage ?

Nicolas

Hors ligne

 

#3 Sat 11 June 2016 10:41

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

J'ai également produit la grille par itérations :

Code:

DROP TABLE IF EXISTS lng_grid_test;

CREATE TABLE lng_grid_test(
        gid serial primary key,
        geom geometry(LineString, 4326)
            );

CREATE INDEX lng_grid_test_idx ON lng_grid_test USING GIST(geom);

DO $$ DECLARE

    _processing_counter integer;
    _current_dot geometry(Point, 4326);
    _eastern_dot geometry(Point, 4326);
    _northern_dot geometry(Point, 4326);
    _diagonal_dot geometry(Point, 4326);
    _x double precision;
    _y double precision;

BEGIN
    _x := -180;
    _y := -90;
    _processing_counter := 1;

    WHILE _x <= 180 LOOP

        WHILE _y <= 90 LOOP

            _current_dot := ST_SetSrid(ST_MakePoint(_x, _y), 4326);
            _eastern_dot :=  ST_SetSrid(ST_MakePoint(_x+0.025, _y), 4326);
            _northern_dot := ST_SetSrid(ST_MakePoint(_x, _y+0.025), 4326);
            _diagonal_dot := ST_SetSrid(ST_MakePoint(_x+0.25,_y+0.025), 4326);

            INSERT INTO lng_grid_test(geom) SELECT ST_MakeLine(_current_dot, _eastern_dot);
            INSERT INTO lng_grid_test(geom) SELECT ST_MakeLine(_current_dot, _northern_dot);
            INSERT INTO lng_grid_test(geom) SELECT ST_MakeLine(_northern_dot, _eastern_dot);
            INSERT INTO lng_grid_test(geom) SELECT ST_MakeLine(_current_dot, _diagonal_dot);
            
            RAISE NOTICE 'Line id %, x: %, y: %, processing since %', _processing_counter, _x, _y, clock_timestamp()-now();

            _y := _y+0.025;
            _processing_counter := _processing_counter + 1;

        END LOOP;

        _y := -180;

    _x := _x+0.025;

    END LOOP;

END$$;

Ca c'est mon grid qui est donc étendu au monde entier de manière homogène.
Ensuite je veux le découper pour qu'il ne passe que par les zones maritimes.
Donc j'ai importé par postgis une couche shp de la base de données natural_earth, pour former la table "countries". Ce sont des multipolygons qui représentent chaque pays.
Et ensuite je réalisais la requêe que je vous ai montré dans mon message précédent.
L'itération pour le découpage permet de découper chaque élément du grid avec les différents éléments de countries. En faisant cé découpage "au fur et à mesure", je pensais que ca chargerait moins le calcul justement.
Parce que j'ai peur que si je lance directement le découpage de TOUT le grid (qui est constitué d'énormément de segments), par la table countries, cela risque de prendre encore plus de temps.
Mais en même temps, j'ai tenté de lancer le découpage par cette méthode itérative, et d'après mes calculs, cela me prendra en moyenne...300 jours. Donc je recherche désespérément un moyen de faire cela plus rapidement. (mettre un indice spatial sur ma table à déjà mis 2 heures)
Qu'en pensez vous?

Dernière modification par Nugg_00 (Sat 11 June 2016 10:46)

Hors ligne

 

#4 Sat 11 June 2016 11:36

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [Postgis] Volumétrie des données et temps de traitement

Il n'y aurait pas une coquille là ?:

Code:

_diagonal_dot := ST_SetSrid(ST_MakePoint(_x+0.25,_y+0.025), 4326);

_x+0.025 ?

Il y a une méthode plutot efficace pour créer une grille, postée sur le wiki postgis: https://trac.osgeo.org/postgis/wiki/Use … ateFishnet

Avec votre pas de 0.025°, ca ferait une grille de 7200x3600 polygones, soit 25 920 000 objets qd meme.

A partir de cette volumétrie, il n'y a pas trop de mystère: il faut une machine puissant pour aller vite (disque SSD ou raid, tablespace séparé pour le systeme et la base, de la ram, avec tuning qui va bien de PG (shared_buffers, effective_cache_size).
Il y a aussi des outils/scripts interessants pour cette problématique qui utilisent du multithread en découpant le dataset en zones traitées par des requetes différentes (cf. forum postgis users)

Une option rapide également est de créer des unlogged tables pour les tables intermédiaires: ces unlogged tables sont bcp rapides a générer, mais elles sont vidées s'il y a un crash de la base ! A utiliser avec prudence. Il est possible de les transformer en tables normales apres coup avec pg 9.5.

Je ne construirais pas les diagonales tout de suite, pour alléger le premier process:

1) Grille de polygones
2) découpage de la grille par rapport au pays: pour gagner du temps, il faudrait découper les pays sur une grille grossiere, histoire de générer des petits pg pour les pays (postgis n'aime pas les gros polygones: ils sont longs a traiter, surtout s'il faut traiter bcp de petits polygone avec le même gros pays.)
3) construire les diagonales sur les pg de grille restants, en prenant la bbox de la grille pour calculer la diagonale.

Nicolas

Hors ligne

 

#5 Sat 11 June 2016 11:39

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [Postgis] Volumétrie des données et temps de traitement

Plutot que les pays, je prendrais la couche "land" de natural earch, redécoupée sur une grille de 1° par ex.

Hors ligne

 

#6 Sat 11 June 2016 18:36

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

J'essaie dans un premier temps de prendre la couche "ne_50m_admin_0_map_subunits" de natural earth (http://www.naturalearthdata.com/downloa … l-vectors/) et de ma découper avec une grille créée sous qgis de 1°.

La requête que j'ai lancé est :

Code:

CREATE TABLE countries AS
SELECT St_Split(ne_50m_admin_0_map_subunits.geom, grid_1_v3.geom)
FROM ne_50m_admin_0_map_subunits, grid_1_v3;

Mais j'ai l'impression que ca va prendre énormément de temps aussi.
Je suis un peu désespéré étant donné que je n'ai pas de super ordi à ma disposition et pas plusieurs semaines devant moi pour laisser les calculs se dérouler sur aussi longtemps.
Et je n'ai aucune idée de combien de emps cette prmière étape peut prendre...en espérant si elle finit, que cela me permette d'aller plus vote pour découper ensuite mon véritable grid avec ma table "countries" nouvellement formée!

Hors ligne

 

#7 Sat 11 June 2016 18:58

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [Postgis] Volumétrie des données et temps de traitement

Sans machine puissante, ca peut etre un peu long, mais pas non plus plusieurs jours.

Une option interessante pour ce genre de traitement serait de louer une instance Amazon ou Google un peu musclée pour qq heures et de lancer le traitement dessus.
En fin de traitement, rapatrier le tout sur la machine locale par dump direct de l'instance vers la machine locale.

J'ai fait qq tests (machine assez costaud: 32Gb de ram, SSD, I7 4 core):

• grille polygonale de 0.025° de coté générée en 16 min (fn st_createFishnet du wiki): elle contient 103M de polygones (sans diagonale).
Son index spatial a pris 20min.

• decoupage de la couche land de Natural Earth en petits polygones avec st_subdivide (bloqué dans le passé que j'etais, je ne pensais plus à cette nouvelle fonction TROP rapide pour découper des gros polygones en petits !!): qq ms pour découper le gros polygone des lands en petits bouts

• Suppression des grilles qui tombent dans les land (st_contains): 1m 14s pour supprimer 12M de grilles inutiles

• Découpage final de la table grille avec les lands (table land_grid): on vire a cette étape les grilles qui sont des geometrycollections: ce sont les grilles contenus dans les lands, en interaction avec plusieurs lands (donc non supprimées à l'étape précédente): 20min pour garder au final grilles.

Là, il faudrait reconstruire les diagonales des grilles, qui n'ont pas encore été créées. (Elles servent a quoi ces diagonales ?)
Ca peut se faire facilement a partir des bbox des grilles initiales et des lands.

Ca fait un traitement en 1h environ.

J'ai aussi testé https://github.com/Nicolasribot/fast_map_intersection: trop puissant ce script: ca parallelise des requetes SQL: ici, ca prend qq secondes pour découper les grilles par rapport aux lands !
Ca laisse cependant des doublons qu'il faut gérer ensuite (mais uniquement 1M environ vs 103M de grilles wink

Nico

Hors ligne

 

#8 Sat 11 June 2016 19:22

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

Nicolas Ribot a écrit:

Sans machine puissante, ca peut etre un peu long, mais pas non plus plusieurs jours.

Une option interessante pour ce genre de traitement serait de louer une instance Amazon ou Google un peu musclée pour qq heures et de lancer le traitement dessus.
En fin de traitement, rapatrier le tout sur la machine locale par dump direct de l'instance vers la machine locale.

J'ai fait qq tests (machine assez costaud: 32Gb de ram, SSD, I7 4 core):

• grille polygonale de 0.025° de coté générée en 16 min (fn st_createFishnet du wiki): elle contient 103M de polygones (sans diagonale).
Son index spatial a pris 20min.

• decoupage de la couche land de Natural Earth en petits polygones avec st_subdivide (bloqué dans le passé que j'etais, je ne pensais plus à cette nouvelle fonction TROP rapide pour découper des gros polygones en petits !!): qq ms pour découper le gros polygone des lands en petits bouts

• Suppression des grilles qui tombent dans les land (st_contains): 1m 14s pour supprimer 12M de grilles inutiles

• Découpage final de la table grille avec les lands (table land_grid): on vire a cette étape les grilles qui sont des geometrycollections: ce sont les grilles contenus dans les lands, en interaction avec plusieurs lands (donc non supprimées à l'étape précédente): 20min pour garder au final grilles.

Là, il faudrait reconstruire les diagonales des grilles, qui n'ont pas encore été créées. (Elles servent a quoi ces diagonales ?)
Ca peut se faire facilement a partir des bbox des grilles initiales et des lands.

Ca fait un traitement en 1h environ.

J'ai aussi testé https://github.com/Nicolasribot/fast_map_intersection: trop puissant ce script: ca parallelise des requetes SQL: ici, ca prend qq secondes pour découper les grilles par rapport aux lands !
Ca laisse cependant des doublons qu'il faut gérer ensuite (mais uniquement 1M environ vs 103M de grilles wink

Nico


Bonjour et merci beaucoup pour vos réponses précieuses.
Effectivement je ne pensais plus à st_subdivide qui a fait le job en quelques secondes pour quelque chose que je cherche à faire depuis plusieurs heures!

Je n'ai pas vraiment présenté mon projet (il est exposé dans le sujet "[PostGIS] Problème de résultat pgr_dijkstra - Pgrouting p" de la section Geo'BD si cela vous interesse.
La grille que j'ai généré est composé de segments, et non pas de polygones comme c'est le cas avec Fishnet. En effet, le but de cette grille est ensuite de la compléter un petit peu pour l'utiliser comme network avec pgrouting (l'aglorithme pgr_dijkstra plus précisément).
Comme je cherche à appliquer cela aux bateaux, j'ai besoin que la grille ne passe que par la mer, d'où la découpe.
Et les diagonales me permettent d'avoir une meilleur précision dans les trajets. De plus, j'utilise une maille assez fine (natural earth 50m), et donc certains segments une fois découpés se retrouvent isolés du reste de la grille, par exemple s'il y a une forte densité de petites iles.
J'ai créé une grille précédente ) maille un peu trop grossière et donc j'avais énormément de segments isolés à cause de ce problème. Or, comme je cherche à trouver le plus court chemin entre certains ports, si ceux-ci se rattachent à des segments isolés (st_shortestline pour lier les ports à la grille et ainsi pouvoir lancer pgr_dijkstra), l'algo pgr_dijkstra ne marche pas.

Aujourd'hui j'ai do,c créé une grille plus fine, pour voir si mes problèmes s'amélioreront.

Pour votre derier lien, je dois avouer que cela dépasse mes compétences. Le script est sans doute très utile mais je ne saurais absolument pas l'utiliser (parties à adapter, extensions à créer avant d'utiliser ca comme requête dans pgadmin...). Pour moi c'est un niveau un peu trop haut.

Dernière modification par Nugg_00 (Sat 11 June 2016 19:24)

Hors ligne

 

#9 Sat 11 June 2016 20:01

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [Postgis] Volumétrie des données et temps de traitement

Merci pour ces précisions. J'ai suivi le post sur djikstra.

La génération des polygones de grille découpés par rapport aux pays a pris environ 50min sur ma machine:
103M de pg dans la grille initiale, 77M dans la grille découpée, après suppression des grilles tombant dans des pays.

Sur une machine moins puissante, ca pourrait prendre qq heures.

Dans l'étape finale, il faudrait créer les lignes et diagonales à partir des polygones, ce qui sera "rapide":

pour les grilles non découpées, la diagonale sera facile a calculer pts 1 et 3 des pg.
Pour les grilles découpées, il faudra découper la diagonale de la grille par les pg de pays.
l'extraction des linestrings routables à partir des polygones se fait en prenant les bords gauche et bas de chaque grille.

En SQL, ca donne qqch comme: (la table land provient de Natural Earth, gros pg des lands à 10m)

Code:

DROP TABLE IF EXISTS grid;
CREATE unlogged TABLE grid AS (
  WITH tmp AS (
      SELECT st_createfishnet(
                 7200,
                 14400,
                 0.025,
                 0.025,
                 -180,
                 -90
             ) AS f
  ) SELECT
      row_number() over () as id,
      (t.f).row,
      (t.f).col,
      st_setSRID((t.f).geom, 4326) AS geom
    FROM tmp t
);
-- 16 min pour 103M de cells

create index grid_geom_gist on grid USING GIST (geom);
--20m40s  min pour 103M de cells

VACUUM ANALYSE grid;
-- 52s

-- découpage de land avec subDivide.
drop table if exists land_grid;
create unlogged table land_grid as (
    select st_subdivide(geom, 64) as geom
  from land l
);
-- qq ms !! ultra rapide par rapport à un découpage par grille

alter table land_grid add column id serial PRIMARY KEY;
create index land_grid_geom_gist on land_grid USING GIST (geom);
VACUUM ANALYSE land_grid;

delete from grid g
using land_grid l
where st_contains(l.geom, g.geom);
-- 33 498 701 rows affected in 3m 51s 524ms

VACUUM ANALYSE grid;

-- découpage des pg grid restants: left join pour prendre toutes les grilles:
-- union par grid id pour fusionner en un seul objet qd plusieurs lands intersectent
-- une grille: les grilles entierement contenues dans les lands seront supprimées par cette méthode
--
drop table if exists grid_cut;
create UNLOGGED table grid_cut as (
    SELECT
      g.id,
      st_difference(
          g.geom, coalesce(st_union(l.geom), 'GEOMETRYCOLLECTION EMPTY' :: GEOMETRY)
      ) AS geom
    FROM grid g LEFT JOIN land_grid l ON st_intersects(g.geom, l.geom)
    GROUP BY g.id, g.geom
);
--  pour 103M: completed in 16m 35s 187ms

-- suppression des grid vides (dans les lands)
delete from grid_cut
  where geometrytype(geom) = 'GEOMETRYCOLLECTION';

alter table grid_cut add PRIMARY KEY (id);
create index grid_cut_geom_gist on grid_cut USING GIST (geom);
VACUUM ANALYSE grid_cut;

En image: le pg des lands en vert (découpés avec subdivide), les grid découpées en bleu.

Nicolas


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#10 Sat 11 June 2016 22:17

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

J'ai essayé la requête "fishnet", en étant gourmand je l'avoue :

Code:

DROP TABLE IF EXISTS grid;
CREATE unlogged TABLE grid AS (
  WITH tmp AS (
      SELECT st_createfishnet(
                 18000,
                 36000,
                 0.01,
                 0.01,
                 -180,
                 -90
             ) AS f
  ) SELECT
      row_number() over () as id,
      (t.f).row,
      (t.f).col,
      st_setSRID((t.f).geom, 4326) AS geom
    FROM tmp t
);

Ca plante au bout de 1 heure en marquant :

NOTICE:  la table « grid » n'existe pas, poursuite du traitement
ERREUR:  mémoire épuisée
DETAIL:  Échec d'une requête de taille 149.
CONTEXT:  fonction SQL « st_createfishnet », instruction 1
********** Erreur **********

ERREUR: mémoire épuisée
État SQL :53200
Détail :Échec d'une requête de taille 149.
Contexte : fonction SQL « st_createfishnet », instruction 1

Je l'ai essayé sur mon ordinateur portable Dell
Processeur : Intel(R) Core(TM) i7-4510U CPU @2.00 GHz 2.6 GHz
RAM :8.00 Go
C'est peut être trop peu pour de tels calculs (impossible de rajouter de la ram)

Hors ligne

 

#11 Sat 11 June 2016 22:54

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [Postgis] Volumétrie des données et temps de traitement

~ 700M de cellules, c'est enorme.
Vous avez vraiment besoin de ce niveau de précision partout ?
Avec 100M de cellules, ca fait 1.8km de largeur de cellule.
Vous indiquiez que vous vouliez une précision de 3km, et maintenant bcp plus ?
Essayez déjà de faire un traitement complet avec un certain pas, et qd vous maitriserez, passez a un pas plus petit

Et oui, un portable est un peu juste pour ce genre de traitements smile
Faut découper en lots pour une telle volumétrie.

Nicolas

Hors ligne

 

#12 Sun 12 June 2016 21:12

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

Nicolas Ribot a écrit:

~ 700M de cellules, c'est enorme.
Vous avez vraiment besoin de ce niveau de précision partout ?
Avec 100M de cellules, ca fait 1.8km de largeur de cellule.
Vous indiquiez que vous vouliez une précision de 3km, et maintenant bcp plus ?
Essayez déjà de faire un traitement complet avec un certain pas, et qd vous maitriserez, passez a un pas plus petit

Et oui, un portable est un peu juste pour ce genre de traitements smile
Faut découper en lots pour une telle volumétrie.

Nicolas


Merci pour votre méthodologie, je l'essaierai demain avec un ordinateur ayant un peu plus de capacités.
J'ai essayé le createFishnet en essayant de le réaliser en plusieurs parties, mais ca n'a pas marché. Je tenterai en entier demain.

Pour l'instant, comme j'ai une grille réalisée avec des lignes de 0.025 pour le côté d'une maille carrée, j'ai :
- tout d'abord utilisé st_subdivide sur les polygones de la table natural_earth countries afin de diviser chaque polygone en 10 parties
- puis j'ai utilisé votre requête directe :

Code:

delete from lng_grid_test g
using subdivided_countries l
where st_contains(l.geom, g.geom);

Cependant, cela fait 5h30 que cela tourne...j'ai peur que cela fasse comme ma requête plsql utilisant st_difference et que cela mette 300 jours...sauf que cette fois je ne sais même pas où il en est dans le calcul!
Je n'ai pas de notion de ce que pourrait être le temps de calcul, auriez vous une idée?
Ma grille actuelle est estimée à 622 066 000 lignes (rows), et ma table de pg countries est constituée de 47 670 éléments.
Mon ordi est toujours le même, Processeur : Intel(R) Core(TM) i7-4510U CPU @2.00 GHz 2.6 GHz
RAM :8.00 Go.
Une idée d'ordre de grandeur pour le temps de calcul de ma dernière requête? Car c'est mon ordi perso et j'ai pas trop envie de le faire souffrir si c'est pour devoir arrêter la requête au bout de 3 jours... sad

Edit : Requête terminée :
Query returned successfully: 132941604 rows affected, 06:41:21608 hours execution time.
Apparemment c'est pas mal d'après ce que je vois sur QGIS, sauf que le st_contains couplé au subdivide fait que les segments se trouvant au bord de chaque polygone n'ont en revanche pas été éliminés.
Je pense que je vais relancer un delete/st_contains avec les polygones entiers cette fois pour éliminer les segments restants.

Dernière modification par Nugg_00 (Sun 12 June 2016 23:01)

Hors ligne

 

#13 Mon 13 June 2016 09:57

ChristopheV
Membre
Lieu: Ajaccio
Date d'inscription: 7 Sep 2005
Messages: 3169
Site web

Re: [Postgis] Volumétrie des données et temps de traitement

Bonjour,

Quand je traite un volume important de données j'essaie de faciliter la vie de postgres/gis.
Pour votre exemple :
Je commencerais par raisonner sur des BBox2D. La différence entre les cinq BBox des cinq continents et celle représentant l'ensemble de la carte est une zone maritime où il n'y a pas de traitement à faire (autre que générer la grille).
Puis je ferais la différence entre le MultiPolygone d'un continent et sa BBox, j'obtiens là les polygones où je dois traiter les problèmes d'intersection entre la grille "maritime" et la terre.


Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close

Hors ligne

 

#14 Thu 16 June 2016 12:39

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

Actualisation de la situation :
J'ai lancé une requête

Code:

DELETE FROM lng_grid_test g
USING ne_50m_land n
WHERE st_contains(n.geom, g.geom);

qui a aboutit :

Code:

Query returned successfully: 3588177 rows affected, 2 days, 01:2930:3610 hours execution time.

Du coup j'ai lancé un vacuum (full + analyze + freeze) sur la table.
Mais je commence à me demander si j'ai bien fait.
Cela fait plus d'une heure que je l'ai lancé et je n'ai que :

Code:

INFO:  exécution du VACUUM sur « public.lng_grid_test »
INFO:  « lng_grid_test » : 3588177 versions de ligne supprimables, 485535819 non supprimables
parmi 5042516 pages
DETAIL:  0 versions de lignes ne peuvent pas encore être supprimées.
CPU 106.20s/230.72u sec elapsed 402.26 sec.

Il y a beaucoup de lignes qui ont été supprimées depuis le début, et particulièrement lors de cette dernière requête, donc je pensais que ce serait vraiment utile. Mais ce full vacuum m'empêche de travailler sur la table, et il tourne déjà depuis plus d'une heure.
Est ce que vous auriez un conseil concernant le vaccum? Etant donné le nombre de lignes à supprimer, combien de temps (ordre de grandeur grossier) cela devrait il prendre pour arriver au bout du processus?

Hors ligne

 

#15 Thu 16 June 2016 16:23

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

Problème résolu, le full vacuum s'est terminé en 4h50 environ pour indication, si jamais cela peut donner un ordre d'idée à quelqu'un qui passerait.

Hors ligne

 

#16 Sat 18 June 2016 09:30

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

Bonjour à tous et toutes,

Je reviens vers vous toujours dans le cadre de mon projet exposé précédemment.
J'en suis à l'étape ou j'ai mon grid principal prêt (table nommée "lng_grid_test"), et il faut que je créée les lignes qui vont relier les points (représentant les terminaux de GNL) à ce grid principal.
Je souhaitais pour cela utiliser:

Code:

INSERT INTO collected_grid(geom) 
SELECT
ST_Collect(lng_grid_test.geom::geometry(LineString, 4326))
FROM lng_grid_test;

C'est une requête que j'avais utilisé avec mon précédent grid (un grid moins fin), et qui marchait parfaitement.
Cependant avec ce nouveau grid, j'obtiens le message d'erreur :

Code:

ERREUR:  invalid memory alloc request size 1073741824
********** Erreur **********

ERREUR: invalid memory alloc request size 1073741824
État SQL :XX000

J'ai la même erreur sur deux ordinateurs différent, donc je souhaitais savoir ce qu'il signifie et comment résoudre ce problème très gênant?
Je pense que cela vient du fait que j'ai maintenant 278 132 000  lignes environ, et que cela est trop gros pour être "collecté" d'un seul coup. Qu'en pensez vous?

Merci d'avance

Dernière modification par Nugg_00 (Sat 18 June 2016 09:36)

Hors ligne

 

#17 Sat 18 June 2016 09:54

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

Apparemment en faisant un st_collect par tranche de gid c'est accepté, ca prend juste plus d'étapes. Je teste actuellement cette méthode.

Edit : J'ai effectué les requêtes

Code:

INSERT INTO collected_grid(geom) 
SELECT
ST_Collect(lng_grid_test.geom::geometry(LineString, 4326))
FROM lng_grid_test
WHERE lng_grid_test.gid>=0 AND lng_grid_test.gid<=10000000;

ect...par tranches de 10 000 000 jusqu'à 278 millions environ.

Puis j'ai voulu regroupé tout dans une table collected_grid_final telle que :

Code:

CREATE TABLE collected_grid_final(gid serial primary key, geom geometry(Multilinestring, 4326));

INSERT INTO collected_grid_final(geom) 
SELECT
ST_Collect(collected_grid.geom::geometry(MultiLineString, 4326))
FROM collected_grid;

Malheureusement j'obtiens le message d'erreur :

Code:

ERREUR:  la taille du tableau dépasse le maximum permis (1073741823)
********** Erreur **********

ERREUR: la taille du tableau dépasse le maximum permis (1073741823)
État SQL :54000

Du coup j'avoue ne plus savoir comment m'en sortir...

Dernière modification par Nugg_00 (Sat 18 June 2016 10:32)

Hors ligne

 

#18 Sat 18 June 2016 10:09

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [Postgis] Volumétrie des données et temps de traitement

Bonjour,

J'avoue que je ne suis plus trop ce que vous cherchez a faire.
Du routing en mer, ca revient a calculer la traj entre deux points et eviter les terres, non ?
Faire autant d'objets, autant de gros process pour au final générer un truc régulier utilisé pour le routing, ca me parait bien lourd.

Là, votre requete st_collect crée juste un objet regroupant TOUS les objets de lng_grid_test dans une seule ligne.
PG n'est pas fait pour ca, mais bien pour avoir pleins de petits objets dans bcp de lignes. D'ou les pb de mémoire: vous demander de stocker en mémoire une telle volumétrie avant de l'écrire sur le disque.

Nicolas

Hors ligne

 

#19 Sat 18 June 2016 10:37

Nugg_00
Participant occasionnel
Date d'inscription: 7 Jun 2016
Messages: 32

Re: [Postgis] Volumétrie des données et temps de traitement

Pour utiliser pg routing il me faut un réseau complet liant chaque terminal GNL aux autres.
Pour l'instant j'ai un grid qui passe par les zones maritimes du globe. Par contre les points représentant les terminaux GNL ne sont pas reliés à ce grid pour l'instant.
Donc pour l'instant mon objectif est de créer les lignes qui vont relier ces points au grid.
Mais pour lancer le st_shortestline entre les points et le grid, il faut que je rassemble le grid dans une même entité, sinon le st_shortestline vne fonctionnera pas (j'avais précédemment testé).

Hors ligne

 

Pied de page des forums

Powered by FluxBB