PostGIS the spatial extension to the PostgreSQL database provides a host of functions for querying, creating and manipulating geometries within the database. ST_Dump allows you to disaggregate collection and multi geometries such as MultiPolygon and MultiLineSting easily. The example below demonstrates starting with a table that contains one row with a MultiLineString geometry and another with a LineString and running a query to disaggregate returning three rows all with a LineString geometry.
Create a table for our demo data:
CREATE TABLE complex
(
id serial,
"name" text,
geom geometry
);
Insert one row with a MultiLineString with two parts ('Bob') and another with a single LineString ('Harry')
INSERT INTO complex (name, geom)
VALUES (
'Bob',
ST_GeomFromEWKT('MULTILINESTRING((498376.89 651569.6,498372.28 651571.89),(498372.28 651571.89,498371.77 651576.05))')
);
INSERT INTO complex (name, geom)
VALUES (
'Harry',
ST_GeomFromEWKT('LINESTRING(598376.89 751569.6,398372.75 658771.03)')
);
Query to show we have two rows one of which has a MultiLineString geometry:
SELECT *, ST_GeometryType(geom) as geom_type, ST_AsEWKT(geom) as geom_wkt from complex;
Results:
id | name | geom | geom_type | geom_wkt |
---|---|---|---|---|
1 | Bob | 010500000002000000010200... | ST_MultiLineString | MULTILINESTRING((498376.89 651569.6,498372.28 651571.89),(498372.28 651571.89,498371.77 651576.05)) |
2 | Harry | 0102000000020000007B14AE... | ST_LineString | LINESTRING(598376.89 751569.6,598372.28 751571.89) |
Use the ST_Dump function to split the row with a MultiLineString into two rows each with a LineString and generate a decimal id composed of the original rows id and the LineString's position in the MultiLineString as the fractional part so that each row still has a unique id that's derived from it's original id:
SELECT
COALESCE((simple.id || '.' || simple.path[1]::text)::float, simple.id) as id,
simple.name,
simple.simple_geom as geom,
ST_GeometryType(simple.simple_geom) as geom_type,
ST_AsEWKT(simple.simple_geom) as geom_wkt
FROM (
SELECT
dumped.*,
(dumped.geom_dump).geom as simple_geom,
(dumped.geom_dump).path as path
FROM (
SELECT *, ST_Dump(geom) AS geom_dump FROM complex
) as dumped
) AS simple;
Results:
id | name | geom | geom_type | geom_wkt |
---|---|---|---|---|
1.1 | Bob | 010200000002000000F6285C... | ST_LineString | LINESTRING(498376.89 651569.6,498372.28 651571.89) |
1.2 | Bob | 010200000002000000EC51B8... | ST_LineString | LINESTRING(498372.28 651571.89,498371.77 651576.05) |
2 | Harry | 0102000000020000007B14AE... | ST_LineString | LINESTRING(598376.89 751569.6,598372.28 751571.89) |