First, for polygons, you want the outer boundary of the polygon as a line using ST_Boundary
.
Then you want a combination of ST_Intersection
and ST_SymDifference
So something like (untested):
WITH firststep AS( SELECT id, ST_BOUNDARY(geom) AS boundary
FROM polygons)
SELECT p.id, ST_Intersection(boundary, geom), o.id
FROM firststep p
INNER JOIN othergeoms o ON ST_INTERSECTS(boundary, geom)
UNION
SELECT p.id, ST_SymDifference(boundary, geom), o.id
FROM firststep p
INNER JOIN othergeoms o ON ST_INTERSECTS(boundary, geom)
SELECT a.id, (ST_Dump(a.the_geom)).path path , (ST_Dump(a.the_geom)).geom geom ,ST_GeometryType((ST_Dump(a.the_geom)).geom ) geomtype INTO b FROM a
Create table with id, path , geom and geomtype columns. id point to original geom , path points to where geom was in original geom and geom is geometry.
Now you can add geom2 column to table (type geometry) and create new line with line-offset. After that you can create MULTILINE again using id
(not tested)
ALTER TABLE b add geom2 geometry
UPDATE b SET geom2 = line-offset(geom, 2) -- something like that
SELECT id, ST_Linemerge(st_collect(geom)) from b group by id -- creates linestring or multiline
Or
SELECT id, ST_MULTI(st_collect(geom)) from b group by id -- creates Multiline
if order is has to same
SELECT b.id, ST_Multi(ST_Collect(b.geom)) FROM SELECT (id, path, geom from b order by id, path ) b GROUP BY b.id
EDIT: ST_Collect should be replaced with st_union or other. St_Multi and st_linemerge do not like GEOMETRYCOLLECTIONS
EDIT : about Additional Details
INSERT INTO complex (name, the_geom)
VALUES (
'Bob', ST_GeomFromEWKT('SRID=4236;MULTILINESTRING((498376.89
651569.6,498372.28 651571.89),(498372.28 651571.89,498371.77 651576.05))')
)
LINESTRING can be MULTILINESTRING , it is just a MULTI collection with one LINE
ANSWERS:
Question A: im not sure, but here is tested example.
SELECT * INTO complex FROM (
SELECT 'Harry' as name , ST_GeomFromEWKT('SRID=4236;MULTILINESTRING((498376.89
651569.6,498372.28 651571.89))')as the_geom
UNION
SELECT 'Bob' as name , ST_GeomFromEWKT('SRID=4236;MULTILINESTRING((498376.89
651569.6,498372.28 651571.89),(498372.28 651571.89,498371.77 651576.05))') as the_geom
) a
now this return 3 rows, Bob has 2 and Harry 1
SELECT *, ST_AsEWKT(simple_geom)
-- into test
FROM (
SELECT
dumped.*,
(dumped.geom_dump).geom as simple_geom,
(dumped.geom_dump).path as path
FROM (
SELECT *, ST_Dump(the_geom) AS geom_dump FROM complex
) as dumped
) AS simple
Now we have test table with 3 rows .
SELECT st_asEWKT((st_union(the_geom))) as geom from test group by name
OR
SELECT st_asEWKT(st_linemerge(st_union(the_geom))) as geom from test group by name
First one returns multi type, second tries to merge lines. In this case it will return 2 linestrings if it does not succeed it will return multilinestrings
Question B:
SELECT *, ST_Transform(geom,3857) as the_geom_webmercator from xxx
You need to set correct SRID to geoms first. Create them using EWKT with srid (like that example) or using ST_SetSRID(geom, srid) , example
UPDATE xxx set geom = ST_SetSRID(geom)
.. i hope this helps
Best Answer
You can test for a self-intersecting linestring with
ST_IsSimple(geom)
:Above image and below caption are from JTS TestBuilder (click "Simple?")
This can be fixed with
ST_UnaryUnion(geom)
(since PostGIS 2.0), which returns a valid/simple three piece multilinestring: