Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 7 sur 7
  1. #1
    Membre du Club
    Inscrit en
    janvier 2006
    Messages
    174
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : janvier 2006
    Messages : 174
    Points : 43
    Points
    43

    Par défaut PostGIS multipolygone vers polygone

    Bonjour,

    Je travailles sous PostGreSQL 9.0 et son extension spatiale PostGIS (sous windows XP) avec 4 go de Ram.

    Je souhaite exécuter la requête suivante mais visiblement, j'arrive à saturation de la mémoire vive donc échec de la requête.

    Code :
    CREATE TABLE union_buff_eclat AS (SELECT st_geometryN(a.the_geom, generate_series(0, st_numgeometries(a.the_geom))) AS the_geom FROM "union_buff" a);
    Le multipolygone que j'essaye de transformer en polygone est assez volumineux, je vois ma mémoire vive se remplir petit à petit jusqu'a 2,5 go et là tout s'arrête.

    Je ne sais pas comment faire pour optimiser cette requête, ou si tout simplement je dois repenser ma façon de traiter ce multipolygone conséquent.

    Si quelqu'un a des idées, je suis preneur.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro Frédéric BROUARD
    Expert SGBDR & SQL
    Inscrit en
    mai 2002
    Messages
    13 069
    Détails du profil
    Informations personnelles :
    Nom : Homme Frédéric BROUARD
    Localisation : France

    Informations professionnelles :
    Activité : Expert SGBDR & SQL
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 13 069
    Points : 29 231
    Points
    29 231

    Par défaut

    1) passer à la version 9 en 64 bits et mettre plus de RAM sur le serveur
    2) tenter d'indexer, mais je suis pas sur que cela améliore les choses. Faites un essai
    3) passer par des traitements intermédiaires par exemple par paquet de 100 lignes puis refaire un traitement sur ces lignes

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
    http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  3. #3
    Membre du Club
    Inscrit en
    janvier 2006
    Messages
    174
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : janvier 2006
    Messages : 174
    Points : 43
    Points
    43

    Par défaut

    Merci pour la réponse mais:

    Je me répond tout seul, le:

    Code :
    generate_series(0, st_numgeometries(a.the_geom)
    N'est pas nécessaire car je n'ai qu'un multipolygone.

    Ma requête devient donc:

    Code :
    CREATE TABLE union_buff_eclat AS (SELECT st_geometryN(a.the_geom, 1) AS the_geom FROM "union_buff" a);
    Par contre je ne comprend pas pourquoi le generate_series sur une seule géométrie ne marche pas.

  4. #4
    Membre du Club
    Inscrit en
    janvier 2006
    Messages
    174
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : janvier 2006
    Messages : 174
    Points : 43
    Points
    43

    Par défaut

    En fait ma requête est totalement fausse, car elle ne génère qu'un seul polygone.

    J'ai fait un test, mes polygones peuvent être traités par paquet de 500. Donc il faut que je puisse faire une boucle pour traiter les polygones 500 par 500 (43000 polygones au total).

    Or je n'ai pas encore été aussi loin dans mon apprentissage de PostGIS.

    Comment feriez-vous pour créer une boucle qui ajouterait mes polygones dans une couche.

    Merci

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    janvier 2006
    Messages
    240
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : janvier 2006
    Messages : 240
    Points : 256
    Points
    256

    Par défaut

    bonjour , je créerai une fonction du type

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE OR REPLACE FUNCTION insert_poly(gid integer)
      RETURNS void AS
    $BODY$
    DECLARE
    nb integer;
    BEGIN
    execute 'select  NumGeometries(the_geom)from table_source where gid='||gid INTO nb;
    FOR i IN 1..nb LOOP
    execute 'insert into table_destination select geometryN(the_geom,'||i||') from table_source where gid='||gid ;
    END LOOP;
    RETURN;
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
    dans cette fonction j'ai supposé que le champs gid est un champs permettant de sélectionner un multipoly en particulier

  6. #6
    Membre du Club
    Inscrit en
    janvier 2006
    Messages
    174
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : janvier 2006
    Messages : 174
    Points : 43
    Points
    43

    Par défaut

    Merci pour cette réponse,

    Mais je n'ai pas de gid seule la géométrie m'intéresse...

    J'ai tenté a tout hasard d'écrire une fonction (je ne connais pas du tout pl/pgsql) qui est fausse à coup sur.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    CREATE OR REPLACE FUNCTION Poly_eclat()
    $BODY$
    DECLARE
         id integer DEFAULT 0;
         id_mem integer DEFAULT 0;
         id_big_loop integer DEFAULT 0;
    BEGIN
    WHILE id_big_loop <= 43848
         id_mem := id;
         LOOP
    	--Nous incrémentons par paquets de 500
              IF id > id_mem + 500 THEN
                  EXIT;
              END IF;
              INSERT INTO union_buff_eclat (the_geom) VALUES (SELECT st_geometryN(a.the_geom, generate_series(id, id + 500)) AS the_geom FROM "union_buff" a);
              id := id +1;
              id_big_loop := id_mem;
          END LOOP;
    END LOOP;
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
    Le gros problème c'est que je ne connais pas du tout la syntaxe...

    Si vous pouvez m'aiguiller..

  7. #7
    Membre du Club
    Inscrit en
    janvier 2006
    Messages
    174
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : janvier 2006
    Messages : 174
    Points : 43
    Points
    43

+ Répondre à la discussion
Cette discussion est résolue.

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
  •