Prendre un thé
Tapoter des doights
Monsieur fantôme
Quelle heure est-il ?
BazinGa's Tips & tuto IT
BazinGa's - Tips & tuto IT

Agréger des lignes : ST_Union, ST_Collect, ST_MakeLine ou ST_LineMerge ?

Lorsqu’il s’agit de fusionner des lignes, PostGIS n’est pas en reste et propose plusieurs fonctions. Cependant, le résultat de ces unions peut fortement varier.

Voici donc un petit récapitulatif.

Attention, ces qui est indiqué ici n’est valable que dans un contexte d’agrégation de géométrie de type LINESTRING ou MULTILINESTRING.

Contexte de fusion

Il existe plusieurs situations dans lesquelles une fusion peut être réalisée :

  • Dans le cadre d’une jointure.
  • Dans le cadre d’un regroupement des valeurs d’un tableau.
  • Dans le cadre d’une agrégation.

Quelques exemples avec la fonction ST_Collect() :

SELECT
	ST_Collect(t1.geom, t2.geom)
FROM
	ma_table_1 as t1
LEFT JOIN
	ma_table_2 as t2
	ON t1.ma_colonne = t2.ma_colonne
SELECT
	ST_Collect(ARRAY[ geom_1, geom_2, geom_3 ])
SELECT
	ST_Collect(geom)
FROM
	ma_table
GROUP BY
	ma_colonne

Les fonctions qui sont présentées ici peuvent toutes être utilisées dans ces 3 contextes.

Quelques fonctions

ST_Collect

Il s’agit de la fonction la plus simple, toutes les géométries en entrée sont agrégées en une seule multigéométrie sans aucun changement de celles-ci. Il s’agit simplement d’un regroupement des géométries.

Il en résulte une multigéométrie dont l’ordre des composants respecte l’ordre des géométries en entrées.

-- Requête
SELECT 
	-- Les lignes sont agrégées sans aucune modification de géométrie
	-- Ordre : conservé
	st_collect(geom ORDER BY ordre asc) as st_collect_asc,
	st_collect(geom ORDER BY ordre desc) as st_collect_desc
FROM (
	VALUES 
		('LINESTRING (0 0, 1 1)'::geometry, 1),
		('LINESTRING (1 1, 2 0)'::geometry, 2),
		('LINESTRING (3 0, 5 2)'::geometry, 3),
		('LINESTRING (4 1, 6 3)'::geometry, 4)
) AS t1 ("geom", "ordre")
;



-- Résultat
st_collect_asc          |st_collect_desc
------------------------+------------------------
MULTILINESTRING (       |MULTILINESTRING (
    (0 0, 1 1),         |    (4 1, 6 3),
    (1 1, 2 0),         |    (3 0, 5 2),
    (3 0, 5 2),         |    (1 1, 2 0),
    (4 1, 6 3)          |    (0 0, 1 1)
)                       |)

ST_Union

Les géométries en entrée sont fusionnées de façon à éviter tout chevauchement :

  • Les segments qui se joignent par leurs extrémités sont fusionnés.
  • Les segments qui se chevauchent sont découpés par leurs extrémités puis chaque doublon (= chaque chevauchement) est supprimé.
  • Les segments qui ne se touchent pas sont conservés tels quels.

Il en résulte une géométrie simple ou une multigéométrie selon les cas. L’ordre des composants est défini par la fonction sans possibilité d’influer celui-ci.

-- Requête
SELECT 
	-- Les superpositions sont fusionnées et les lignes sont découpées lorsqu'il y a une superposition de sommets
	-- Ordre non conservé
	st_union(geom ORDER BY ordre asc) as st_union_asc,
	st_union(geom ORDER BY ordre desc) as st_union_desc
FROM (
	VALUES 
		('LINESTRING (0 0, 1 1)'::geometry, 1),
		('LINESTRING (1 1, 2 0)'::geometry, 2),
		('LINESTRING (3 0, 5 2)'::geometry, 3),
		('LINESTRING (4 1, 6 3)'::geometry, 4)
) AS t1 ("geom", "ordre")
;



-- Résultat
st_union_asc            |st_union_desc
------------------------+------------------------
MULTILINESTRING (       |MULTILINESTRING (
    (0 0, 1 1),         |    (0 0, 1 1),
    (1 1, 2 0),         |    (1 1, 2 0),
    (3 0, 4 1),         |    (3 0, 4 1),
    (4 1, 5 2)          |    (4 1, 5 2),
    (5 2, 6 3)          |    (5 2, 6 3)
)                       |)

ST_MakeLine

Les géométries en entrée sont décomposées en leurs sommets puis une seule ligne est créée à partir de ces sommets.

Il en résulte une géométrie simple dont l’ordre des sommets respecte l’ordre des géométries en entrées.

-- Requête
SELECT 
	-- Les lignes sont décomposées en leur sommets puis ces derniers sont utilisés pour recréer une nouvelle ligne
	-- Ordre conservé
	st_makeline(geom ORDER BY ordre asc) as st_makeline_asc,
	st_makeline(geom ORDER BY ordre desc) as st_makeline_desc
FROM (
	VALUES 
		('LINESTRING (0 0, 1 1)'::geometry, 1),
		('LINESTRING (1 1, 2 0)'::geometry, 2),
		('LINESTRING (3 0, 5 2)'::geometry, 3),
		('LINESTRING (4 1, 6 3)'::geometry, 4)
) AS t1 ("geom", "ordre")
;



-- Résultat
st_makeline_asc         |st_makeline_desc
------------------------+------------------------
LINESTRING (            |LINESTRING (
    0 0,                |    4 1, 
    1 1,                |    6 3, 
    2 0,                |    3 0, 
    3 0,                |    5 2, 
    5 2,                |    1 1, 
    4 1,                |    2 0, 
    6 3                 |    0 0, 
)                       |    1 1
                        |)

ST_LineMerge

Cette fonction est un peu particulière. En effet, au lieu d’agir sur plusieurs géométries, elle requiert une seule multi-géométrie en entrée. Il faudra donc utiliser l’une des fonctions précédentes s’il faut agréger les géométries.

Les segments d’une multigéométrie sont fusionnés lorsqu’ils se touchent par leur extrémités. Les autres segments , qui se chevauchent ou qui ne se touchent pas, sont conservés tels quels.

Il en résulte une géométrie simple ou une multigéométrie selon les cas. L’ordre des composants est défini par la fonction sans possibilité d’influer celui-ci.

-- Requête
SELECT 
	-- Les lignes qui se touchent par leur extrémité sont cousues ensemble, les autres sont agrégées en multigéométrie
	-- Ordre non conservé
	st_linemerge(st_collect(geom ORDER BY ordre asc)),
	st_linemerge(st_collect(geom ORDER BY ordre desc))
FROM (
	VALUES 
		('LINESTRING (0 0, 1 1)'::geometry, 1),
		('LINESTRING (1 1, 2 0)'::geometry, 2),
		('LINESTRING (3 0, 5 2)'::geometry, 3),
		('LINESTRING (4 1, 6 3)'::geometry, 4)
) AS t1 ("geom", "ordre")
;



-- Résultat
st_linemerge_asc        |st_linemerge_desc
------------------------+------------------------
MULTILINESTRING (       |MULTILINESTRING (
    (0 0, 1 1, 2 0),    |    (0 0, 1 1, 2 0),
    (3 0, 5 2),         |    (3 0, 5 2),
    (4 1, 6 3),         |    (4 1, 6 3),
)                       |)

Cet article vous a plu ?

N'hésitez pas à le partager, il interessera surement certains de vos contacts.

Les thèmes suivants contiennent des articles en lien avec celui-ci, allez faire un tour :

BDDPostGISPostgreSQLSIG agrégationfusionjointureligne

50%