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 Tue 07 July 2020 12:43

Lucie D.
Participant actif
Date d'inscription: 21 Oct 2013
Messages: 137

PostGIS - étendre une grille vecteur tout en conservant le calage

Bonjour à tous,

Je dispose d'une grille vecteur de 100x100m que je souhaite étendre à un périmètre plus large, tout ceci en conservant bien le calage des carreaux.

Auriez-vous une idée de script car là je sèche complètement. Je n'ai même pas de bout de code test à vous proposer cette fois-ci...:-/

Merci d'avance pour votre aide toujours aussi précieuse!

Bonne journée.

Bien cordialement,

Lucie D.

Hors ligne

 

#2 Tue 07 July 2020 13:03

Lucie D.
Participant actif
Date d'inscription: 21 Oct 2013
Messages: 137

Re: PostGIS - étendre une grille vecteur tout en conservant le calage

Proposition que je vais tester :

Je génère l'enveloppe englobante (boundingbox):
- de ma grille d'origine
- de mon périmètre d'étude

Je récupère les coordonnées exactes de ces deux boundingbox, ajoute aux coordonnées de la boundingbox de la grille un multiple de 100 pour coller au mieux à la boundingbox du périmètre d'étude. Avec ces nouvelles coordonnées, je crée une nouvelle grille.

C'est pas clair du tout désolée tongue, mais je fais un test et poste le script SQL s'il fonctionne.

Bien cordialement,

Lucie D.

Hors ligne

 

#3 Tue 07 July 2020 15:41

Lucie D.
Participant actif
Date d'inscription: 21 Oct 2013
Messages: 137

Re: PostGIS - étendre une grille vecteur tout en conservant le calage

Bon, j'ai le code, mais j'ai un léger décalage entre mes carreaux dû au fait que generate_series fonctionne avec des entiers...
Une idée de fonction qui me permettrait de générer des séries avec des coordonnées non entières?

Merci!! =^_^=

Code:

create index l_grille_origine_100m_geom_gist on a_detc_smabb_strategie_fonciere.l_grille_origine_100m using gist(geom);

drop table if exists a_detc_smabb_strategie_fonciere.l_grille_origine_100m_emprise;
create table a_detc_smabb_strategie_fonciere.l_grille_origine_100m_emprise
as select ST_Multi(ST_Envelope(ST_Union(geom)))::geometry(MultiPolygon,2154) as geom
from a_detc_smabb_strategie_fonciere.l_grille_origine_100m;

drop table if exists a_detc_smabb_strategie_fonciere.l_perimetre_etude_emprise;
create table a_detc_smabb_strategie_fonciere.l_perimetre_etude_emprise
as select ST_Multi(ST_Envelope(ST_Union(geom)))::geometry(MultiPolygon,2154) as geom
from a_detc_smabb_strategie_fonciere.l_perimetre_etude;


drop table if exists a_detc_smabb_strategie_fonciere.l_grille_origine_100m_extend;
create table a_detc_smabb_strategie_fonciere.l_grille_origine_100m_extend as
with coord as 
(
select ST_Xmin(b.geom) + (ceil((ST_Xmin(a.geom)-ST_Xmin(b.geom))::numeric/100)*100) as xmin,
ST_Xmax(b.geom) + (ceil((ST_Xmax(a.geom)-ST_Xmax(b.geom))::numeric/100)*100) as xmax,
ST_Ymin(b.geom) + (ceil((ST_Ymin(a.geom)-ST_Ymin(b.geom))::numeric/100)*100) as ymin,
ST_Ymax(b.geom) + (ceil((ST_Ymax(a.geom)-ST_Ymax(b.geom))::numeric/100)*100) as ymax
from a_detc_smabb_strategie_fonciere.l_perimetre_etude_emprise as a, a_detc_smabb_strategie_fonciere.l_grille_origine_100m_emprise as b
),
diagonale_simple as
(
select generate_series(xmin::integer,xmax::integer-1,100) AS xmin_box, generate_series(ymin::integer,ymax::integer-1,100) AS ymin_box
from coord
),
grille as
(
SELECT DISTINCT t1.xmin_box, t2.ymin_box
FROM diagonale_simple as t1 CROSS JOIN diagonale_simple as t2
)
select xmin_box||'_'||ymin_box::character varying(80) AS id,
ST_Multi(ST_SetSRID(ST_MakeBox2D(ST_Point(xmin_box,ymin_box),ST_Point(xmin_box + 100,ymin_box + 100)),2154))::geometry(MultiPolygon,2154) AS geom
FROM grille
WHERE xmin_box IS NOT NULL AND ymin_box IS NOT NULL;

Hors ligne

 

#4 Tue 07 July 2020 16:03

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

Re: PostGIS - étendre une grille vecteur tout en conservant le calage

Bonjour,

Pour ces gestions de grilles régulières, j'utilise une fonction venant du forum postgis users:

Code:

-- AUTHOR            :  Mike Toews,
-- SYNOPSYS          :    Creates a polygonal grid with specified dimensions
-- IN                :    nrow: number of grid rows
--                   :  ncol: number of grid columns
--                   :  xsize: grid cell width
--                   :  ysize: grid cell height
--                   :  x0: x-origin of grid
--                   :  y0: y-origin of grid
--
-- OUT               :    row: int: row index
--                   :  col: int col index
--                   :  geom: geometry grid cell polygon
--
-- OUTCALL           :    Néant
--
-- USAGE             :    SELECT * from fn_createFishnet(100, 100, 1, 1, -180, -90)
--                   :     as (row int, col int, geom geometry)
--
--                   : Code from Postgis User list:
--                   : http://trac.osgeo.org/postgis/wiki/UsersWikiCreateFishnet
CREATE OR REPLACE FUNCTION st_CreateFishnet(
      nrow  integer, ncol integer,
      xsize float8, ysize float8,
      x0    float8 DEFAULT 0, y0 float8 DEFAULT 0,
  OUT "row" integer, OUT col integer,
  OUT geom  geometry)
  RETURNS SETOF record AS
$$
SELECT
  i + 1                                        AS row,
  j + 1                                        AS col,
  ST_Translate(cell, j * $3 + $5, i * $4 + $6) AS geom
FROM generate_series(0, $1 - 1) AS i,
      generate_series(0, $2 - 1) AS j,
  (
    SELECT ('POLYGON((0 0, 0 ' || $4 || ', ' || $3 || ' ' || $4 || ', ' || $3 || ' 0,0 0))') :: geometry AS cell
  ) AS foo;
$$
LANGUAGE sql
IMMUTABLE
STRICT;

En donnant en paramètre le point de votre grille à partir duquel vous voulez étendre la grille, plus les paramètres de la grille, vous devriez pouvoir étendre votre grille

Hors ligne

 

#5 Wed 08 July 2020 12:13

Lucie D.
Participant actif
Date d'inscription: 21 Oct 2013
Messages: 137

Re: PostGIS - étendre une grille vecteur tout en conservant le calage

Bonjour et merci pour ce code!

Je n'avais pas vu votre post du coup j'ai persévéré et voici donc mon code :

Code:

-- Création des enveloppes englobantes de la grille d'origine et du périmètre d'étude

-- Grille 100x100m d'origine
drop table if exists a_detc_smabb_strategie_fonciere.l_grille_origine_100m_emprise;
create table a_detc_smabb_strategie_fonciere.l_grille_origine_100m_emprise
as select ST_Multi(ST_Envelope(ST_Union(geom)))::geometry(MultiPolygon,2154) as geom
from a_detc_smabb_strategie_fonciere.l_grille_origine_100m;

comment on table a_detc_smabb_strategie_fonciere.l_grille_origine_100m_emprise is 'Enveloppe englobante de la grille 100x100m d''origine.';

-- Périmètre d'étude
drop table if exists a_detc_smabb_strategie_fonciere.l_perimetre_etude_emprise;
create table a_detc_smabb_strategie_fonciere.l_perimetre_etude_emprise
as select ST_Multi(ST_Envelope(ST_Union(geom)))::geometry(MultiPolygon,2154) as geom
from a_detc_smabb_strategie_fonciere.l_perimetre_etude;

comment on table a_detc_smabb_strategie_fonciere.l_perimetre_etude_emprise is 'Enveloppe englobante du périmètre d''étude.';

-- Création de la nouvelle grille 100x100m élargie à l'enveloppe englobante du périmètre d'étude

drop table if exists a_detc_smabb_strategie_fonciere.l_grille_origine_100m_extend;
create table a_detc_smabb_strategie_fonciere.l_grille_origine_100m_extend as
-- Récupération des coordonnées x,y des enveloppes englobantes
-- La différence entre ces coordonnées est transformée en entier multiple de 100 pour conserver le calage des carreaux
-- Extension des coordonnées de la grille 100x100m d'origine avec cette différence (positive ou négative) pour qu'elles englobent l'intégralité du périmètre d'étude
with coord as 
(
select
case
    when (ST_Xmin(b.geom)-ST_Xmin(a.geom)) < 0 then ST_Xmin(b.geom)
    when (ST_Xmin(b.geom)-ST_Xmin(a.geom)) > 0 then ST_Xmin(b.geom) - ceil((ST_Xmin(b.geom)-ST_Xmin(a.geom))::numeric/100)*100
end::double precision as xmin,
case
    when (ST_Xmax(b.geom)-ST_Xmax(a.geom)) < 0 then ST_Xmax(b.geom) + ceil((ABS(ST_Xmax(b.geom)-ST_Xmax(a.geom)))::numeric/100)*100
    when (ST_Xmax(b.geom)-ST_Xmax(a.geom)) > 0 then ST_Xmax(b.geom)
end::double precision as xmax,
 case
     when (ST_Ymin(b.geom)-ST_Ymin(a.geom)) < 0 then ST_Ymin(b.geom)
     when (ST_Ymin(b.geom)-ST_Ymin(a.geom)) > 0 then ST_Ymin(b.geom) - ceil((ST_Ymin(b.geom)-ST_Ymin(a.geom))::numeric/100)*100
 end::double precision as ymin,
case
    when (ST_Ymax(b.geom)-ST_Ymax(a.geom)) < 0 then ST_Ymax(b.geom) + ceil((ABS(ST_Ymax(b.geom)-ST_Ymax(a.geom)))::numeric/100)*100
    when (ST_Ymax(b.geom)-ST_Ymax(a.geom)) > 0 then ST_Ymax(b.geom)
end::double precision as ymax
from a_detc_smabb_strategie_fonciere.l_perimetre_etude_emprise as a, a_detc_smabb_strategie_fonciere.l_grille_origine_100m_emprise as b
),
-- Création de séries de coordonnées avec un pas de 100m (= pas de la grille d'origine)
diagonale_simple as
(
select generate_series(xmin::numeric,xmax::numeric-1,100) AS xmin_box, generate_series(ymin::numeric,ymax::numeric-1,100) AS ymin_box
from coord
),
-- Suppression des carreaux en doublon
grille as
(
select distinct t1.xmin_box, t2.ymin_box
from diagonale_simple as t1 cross join diagonale_simple as t2
)
-- Création de la grille grâce à la fonction ST_MakeBox2D
select xmin_box||'_'||ymin_box::character varying(80) AS id,
ST_Multi(ST_SetSRID(ST_MakeBox2D(ST_Point(xmin_box,ymin_box),ST_Point(xmin_box + 100,ymin_box + 100)),2154))::geometry(MultiPolygon,2154) AS geom
from grille
where xmin_box is not null and ymin_box is not null;

comment on table a_detc_smabb_strategie_fonciere.l_grille_origine_100m_extend is 'Grille de 100x100m élargie à l''enveloppe englobante du périmètre d''étude et calée sur la grille 100x100m d''origine.';

Tout est dans le

Code:

select generate_series(xmin::numeric,xmax::numeric-1,100) AS xmin_box, generate_series(ymin::numeric,ymax::numeric-1,100) AS ymin_box

Au début je "castais" mes coordonnées en integer (xmin::integer), donc l'arrondi me créait un léger décalage...décalage que je n'ai plus grâce au ::numeric.

Je vais tester votre fonction, beaucoup plus concise que la mienne, si je puis dire!!! ;-)
Merci beaucoup!

Bien cordialement,

Lucie D.

Dernière modification par Lucie D. (Wed 08 July 2020 12:13)

Hors ligne

 

Pied de page des forums

Powered by FluxBB