28

I have a multiline string and want to convert it to a linestring in order to use some functions that only work with linestrings. I used ST_Dump() and got a collection of my geometries. If I merge them back together, I still get the multilinestring.

Should I get the Npoints and combine them together or something, in order to end up with a simple linestring? ST_LineMerge() also does not work on my multilinestring, it returns the same.

my example,

MULTILINESTRING((-3.16420835153456 55.9269166007097,-3.164222 55.926918),(-3.1642070167833 55.9269296196706,-3.16421351659546 55.9268662214904),(-3.16421351659546 55.9268662214904,-3.16421636372824 55.9268384509897),(-3.16421636372824 55.9268384509897,-3.16422182573761 55.9267851753802),(-3.16422182573761 55.9267851753802,-3.16422870102352 55.926718114886),(-3.16422870102352 55.926718114886,-3.16423309121073 55.926675293667),(-3.16423309121073 55.926675293667,-3.16423565148822 55.9266503211093),(-3.16423565148822 55.9266503211093,-3.16424103159897 55.9265978443265),(-3.16424103159897 55.9265978443265,-3.16424680776317 55.9265415044985),(-3.16424680776317 55.9265415044985,-3.16425267254583 55.9264843002995),(-3.16425267254583 55.9264843002995,-3.16425541048045 55.9264575949012),(-3.16425541048045 55.9264575949012,-3.16426111146586 55.9264019883556),(-3.16426111146586 55.9264019883556,-3.1642667032531 55.9263474469124),(-3.1642667032531 55.9263474469124,-3.16426957768543 55.9263194101362),(-3.16426957768543 55.9263194101362,-3.16427488261739 55.9262676666359),(-3.16427488261739 55.9262676666359,-3.16428009893088 55.9262167875066),(-3.16428009893088 55.9262167875066,-3.164282741107 55.9261910161221),(-3.1642875546472 55.9261440655823,-3.164282741107 55.9261910161221),(-3.1642875546472 55.9261440655823,-3.16429466890915 55.9260746741522),(-3.16429466890915 55.9260746741522,-3.16430092974527 55.9260136069079),(-3.16430092974527 55.9260136069079,-3.16430822838418 55.9259424170929),(-3.16430822838418 55.9259424170929,-3.16431547242401 55.925871759829),(-3.16431547242401 55.925871759829,-3.16431448732505 55.9258328901507),(-3.16431770120536 55.9257327846001,-3.16431547242401 55.925871759829),(-3.164339 55.925777,-3.16431770120536 55.9257327846001))

1
  • Give us an example of these multilinestring you want to convert so we can test them.
    – CaptDragon
    Feb 6, 2012 at 17:40

5 Answers 5

33

Are you sure that all your MultiLines you want to convert can be converted?

a simple geometry is one that has no anomalous geometric points, such as self intersection or self tangency and primarily refers to 0 or 1-dimensional geometries

Otherwise, ST_LineMerge should work:

SELECT ST_AsText(ST_LineMerge(ST_GeomFromText('MULTILINESTRING((-29 -27,-30 -29.7,-36 -31,-45 -33),(-45 -33,-46 -32))')));

UPDATE

So this is the Multilinestring you provided. Looks valid from up here.:

enter image description here

But upon zooming in close for inspection you can clearly see this cannot be converted into a valid linestring.

enter image description here enter image description here

VALID:

enter image description here enter image description here

INVALID:

enter image description here enter image description here

But take a VALID subset of your points and it works just fine:

SELECT ST_AsText(ST_LineMerge(ST_GeomFromText('MULTILINESTRING((-3.16422182573761 55.9267851753802,-3.16422870102352 55.926718114886),(-3.16422870102352 55.926718114886,-3.16423309121073 55.926675293667),(-3.16423309121073 55.926675293667,-3.16423565148822 55.9266503211093),(-3.16423565148822 55.9266503211093,-3.16424103159897 55.9265978443265),(-3.16424103159897 55.9265978443265,-3.16424680776317 55.9265415044985),(-3.16424680776317 55.9265415044985,-3.16425267254583 55.9264843002995),(-3.16425267254583 55.9264843002995,-3.16425541048045 55.9264575949012),(-3.16425541048045 55.9264575949012,-3.16426111146586 55.9264019883556),(-3.16426111146586 55.9264019883556,-3.1642667032531 55.9263474469124),(-3.1642667032531 55.9263474469124,-3.16426957768543 55.9263194101362),(-3.16426957768543 55.9263194101362,-3.16427488261739 55.9262676666359),(-3.16427488261739 55.9262676666359,-3.16428009893088 55.9262167875066))')));
2
  • This isn't actually correct. LineStrings with self-intersections are still OGC-valid. The reason the original MultiLineString can't be converted to a single LineString is that it contains 3 disjoint sets of connected vertices.
    – dr_jts
    Sep 3, 2019 at 3:58
  • @dr_jts Right, So It's not that the LineString is invalid but the input is invalid. you cannot convert intersecting lines. So a valid input of linestrings is one without intersections.
    – CaptDragon
    Sep 3, 2019 at 20:21
11

You could also use ST_SnapToGrid to sort of fix your data, but you'll need to play around with the parameters to get it right.

SELECT ST_AsText(
    ST_LineMerge(
        ST_SnapToGrid(
            ST_GeomFromText('MULTILINESTRING((-3.16420835153456 55.9269166007097,-3.164222 55.926918),(-3.1642070167833 55.9269296196706,-3.16421351659546 55.9268662214904),(-3.16421351659546 55.9268662214904,-3.16421636372824 55.9268384509897),(-3.16421636372824 55.9268384509897,-3.16422182573761 55.9267851753802),(-3.16422182573761 55.9267851753802,-3.16422870102352 55.926718114886),(-3.16422870102352 55.926718114886,-3.16423309121073 55.926675293667),(-3.16423309121073 55.926675293667,-3.16423565148822 55.9266503211093),(-3.16423565148822 55.9266503211093,-3.16424103159897 55.9265978443265),(-3.16424103159897 55.9265978443265,-3.16424680776317 55.9265415044985),(-3.16424680776317 55.9265415044985,-3.16425267254583 55.9264843002995),(-3.16425267254583 55.9264843002995,-3.16425541048045 55.9264575949012),(-3.16425541048045 55.9264575949012,-3.16426111146586 55.9264019883556),(-3.16426111146586 55.9264019883556,-3.1642667032531 55.9263474469124),(-3.1642667032531 55.9263474469124,-3.16426957768543 55.9263194101362),(-3.16426957768543 55.9263194101362,-3.16427488261739 55.9262676666359),(-3.16427488261739 55.9262676666359,-3.16428009893088 55.9262167875066),(-3.16428009893088 55.9262167875066,-3.164282741107 55.9261910161221),(-3.1642875546472 55.9261440655823,-3.164282741107 55.9261910161221),(-3.1642875546472 55.9261440655823,-3.16429466890915 55.9260746741522),(-3.16429466890915 55.9260746741522,-3.16430092974527 55.9260136069079),(-3.16430092974527 55.9260136069079,-3.16430822838418 55.9259424170929),(-3.16430822838418 55.9259424170929,-3.16431547242401 55.925871759829),(-3.16431547242401 55.925871759829,-3.16431448732505 55.9258328901507),(-3.16431770120536 55.9257327846001,-3.16431547242401 55.925871759829),(-3.164339 55.925777,-3.16431770120536 55.9257327846001))'),
            0.001)
        )
    );
2

The query below creates a linestring from the multilinestring provied.

select st_astext(st_makeline(geom))
from ST_Dump(ST_GeomFromText('MULTILINESTRING((-3.16420835153456 55.9269166007097,-3.164222 55.926918),(-3.1642070167833 55.9269296196706,-3.16421351659546 55.9268662214904),
(-3.16421351659546 55.9268662214904,-3.16421636372824 55.9268384509897),(-3.16421636372824 55.9268384509897,-3.16422182573761 55.9267851753802),(-3.16422182573761 55.9267851753802,-3.16422870102352 55.926718114886),
(-3.16422870102352 55.926718114886,-3.16423309121073 55.926675293667),(-3.16423309121073 55.926675293667,-3.16423565148822 55.9266503211093),(-3.16423565148822 55.9266503211093,-3.16424103159897 55.9265978443265),
(-3.16424103159897 55.9265978443265,-3.16424680776317 55.9265415044985),(-3.16424680776317 55.9265415044985,-3.16425267254583 55.9264843002995),(-3.16425267254583 55.9264843002995,-3.16425541048045 55.9264575949012),
(-3.16425541048045 55.9264575949012,-3.16426111146586 55.9264019883556),(-3.16426111146586 55.9264019883556,-3.1642667032531 55.9263474469124),(-3.1642667032531 55.9263474469124,-3.16426957768543 55.9263194101362),
(-3.16426957768543 55.9263194101362,-3.16427488261739 55.9262676666359),(-3.16427488261739 55.9262676666359,-3.16428009893088 55.9262167875066),(-3.16428009893088 55.9262167875066,-3.164282741107 55.9261910161221),
(-3.1642875546472 55.9261440655823,-3.164282741107 55.9261910161221),(-3.1642875546472 55.9261440655823,-3.16429466890915 55.9260746741522),(-3.16429466890915 55.9260746741522,-3.16430092974527 55.9260136069079),
(-3.16430092974527 55.9260136069079,-3.16430822838418 55.9259424170929),(-3.16430822838418 55.9259424170929,-3.16431547242401 55.925871759829),(-3.16431547242401 55.925871759829,-3.16431448732505 55.9258328901507),
(-3.16431770120536 55.9257327846001,-3.16431547242401 55.925871759829),(-3.164339 55.925777,-3.16431770120536 55.9257327846001))'))
1

Consider using ST_SubDivide to break large geometries into smaller one after release 2.2.0.

I have validated and tested this on MultiLineString to break them in LineString.

https://postgis.net/docs/ST_Subdivide.html

0

-- for line discontinued

SELECT
  ST_ASTEXT(
    ST_LineFromMultiPoint(
      ST_AsEWKT(
        ST_Boundary(
          ST_GeomFromEWKT(
            'MULTILINESTRING(
              (-62.6222206786248 -17.5184605090261,-62.6180716059959 -17.5177886147977),
              (-62.6139802509635 -17.5171260672651,-62.6130233702558 -17.5169711115239)
            )'
          )
        )
      )
    )
  );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.