Skip to main content
added 155 characters in body
Source Link
John Powell
  • 13.7k
  • 5
  • 48
  • 62

ST_Line_Locate_point only works with Linestrings, not MultiLinestrings. This makes sense, as the return value is the percentage distance along the line that the point occurs, which wouldn't make sense with a MultiLinestring, as you wouldn't know which of the constituent Linestrings was being referred to. You can fix this by using ST_Dump.

WITH lines (geom) AS 
  (SELECT (ST_Dump(multiline)).geom 
     FROM ST_GeomFromText(
             'MULTILINESTRING((0 0, 10 0), (10 10, 20 20))') AS multiline
 )
 SELECT ST_LineLocatePoint(geom, ST_MakePoint(5,0)) FROM lines;

which returns:

  0.5
    0

However, you need to be a bit careful here, as the 2nd Linesting does not intersect the point at all, and 0, simply means the closest point, ie, the start point. You could exclude the 2nd line by using ST_DWithin with a small tolerance, eg, with a tolerance of 1,

WITH 
  lines (geom) AS 
     (SELECT (ST_Dump(multiline)).geom 
        FROM ST_GeomFromText(
          'MULTILINESTRING((0 0, 10 0),(10 10, 20 20))') as multiline), 
  point (geom) AS 
    (SELECT ST_MakePoint(5,0) as geom)
 SELECT 
    ST_LineLocatePoint(lines.geom, point.geom) 
   FROM lines, point 
  WHERE ST_DWithin(lines.geom, point.geom, 1);

which now only returns

0.5

ST_DWithin works better than ST_Intersects, as it is a radius search and interesting a point with a linestring will often fail due to precision issues.

If you need to know which of the Linestrings is being referenced, you can either use the path part of the set ((geom, path)) returned by ST_Dump, which will give you a 1-based index for each linestring in the dumped MultiLinestring or you could return the linestring itself and feed this to another function -- but this, probably, goes beyond what you asked.

ST_Line_Locate_point only works with Linestrings, not MultiLinestrings. This makes sense, as the return value is the percentage distance along the line that the point occurs, which wouldn't make sense with a MultiLinestring, as you wouldn't know which of the constituent Linestrings was being referred to. You can fix this by using ST_Dump.

WITH lines (geom) AS 
  (SELECT (ST_Dump(multiline)).geom 
     FROM ST_GeomFromText(
             'MULTILINESTRING((0 0, 10 0), (10 10, 20 20))') AS multiline
 )
 SELECT ST_LineLocatePoint(geom, ST_MakePoint(5,0)) FROM lines;

which returns:

  0.5
    0

However, you need to be a bit careful here, as the 2nd Linesting does not intersect the point at all, and 0, simply means the closest point, ie, the start point. You could exclude the 2nd line by using ST_DWithin with a small tolerance, eg, with a tolerance of 1,

WITH 
  lines (geom) AS 
     (SELECT (ST_Dump(multiline)).geom 
        FROM ST_GeomFromText(
          'MULTILINESTRING((0 0, 10 0),(10 10, 20 20))') as multiline), 
  point (geom) AS 
    (SELECT ST_MakePoint(5,0) as geom)
 SELECT 
    ST_LineLocatePoint(lines.geom, point.geom) 
   FROM lines, point 
  WHERE ST_DWithin(lines.geom, point.geom, 1);

which now only returns

0.5

If you need to know which of the Linestrings is being referenced, you can either use the path part of the set ((geom, path)) returned by ST_Dump, which will give you a 1-based index for each linestring in the dumped MultiLinestring or you could return the linestring itself and feed this to another function -- but this, probably, goes beyond what you asked.

ST_Line_Locate_point only works with Linestrings, not MultiLinestrings. This makes sense, as the return value is the percentage distance along the line that the point occurs, which wouldn't make sense with a MultiLinestring, as you wouldn't know which of the constituent Linestrings was being referred to. You can fix this by using ST_Dump.

WITH lines (geom) AS 
  (SELECT (ST_Dump(multiline)).geom 
     FROM ST_GeomFromText(
             'MULTILINESTRING((0 0, 10 0), (10 10, 20 20))') AS multiline
 )
 SELECT ST_LineLocatePoint(geom, ST_MakePoint(5,0)) FROM lines;

which returns:

  0.5
    0

However, you need to be a bit careful here, as the 2nd Linesting does not intersect the point at all, and 0, simply means the closest point, ie, the start point. You could exclude the 2nd line by using ST_DWithin with a small tolerance, eg, with a tolerance of 1,

WITH 
  lines (geom) AS 
     (SELECT (ST_Dump(multiline)).geom 
        FROM ST_GeomFromText(
          'MULTILINESTRING((0 0, 10 0),(10 10, 20 20))') as multiline), 
  point (geom) AS 
    (SELECT ST_MakePoint(5,0) as geom)
 SELECT 
    ST_LineLocatePoint(lines.geom, point.geom) 
   FROM lines, point 
  WHERE ST_DWithin(lines.geom, point.geom, 1);

which now only returns

0.5

ST_DWithin works better than ST_Intersects, as it is a radius search and interesting a point with a linestring will often fail due to precision issues.

If you need to know which of the Linestrings is being referenced, you can either use the path part of the set ((geom, path)) returned by ST_Dump, which will give you a 1-based index for each linestring in the dumped MultiLinestring or you could return the linestring itself and feed this to another function -- but this, probably, goes beyond what you asked.

added 361 characters in body
Source Link
John Powell
  • 13.7k
  • 5
  • 48
  • 62

ST_Line_Locate_point only works with Linestrings, not MultiLinestrings. This makes sense, as the return value is the percentage distance along the line that the point occurs, which wouldn't makesmake sense with a MultiLinestring, as you wouldn't know which of the constituent Linestrings was being referred to. You can fix this by using ST_Dump.

WITH lines (geom) AS 
  (SELECT (ST_Dump(multiline)).geom 
     FROM ST_GeomFromText(
             'MULTILINESTRING((0 0, 10 0), (10 10, 20 20))') AS multiline
 )
 SELECT ST_LineLocatePoint(geom, ST_MakePoint(5,0)) FROM lines;

which returns:

  0.5
    0

However, you need to be a bit careful here, as the 2nd Linesting does not intersect the point at all, and 0, simply means the closest point, ie, the start point. You could exclude the 2nd line by using ST_DWithin with a small tolerance, eg, with a tolerance of 1,

WITH 
  lines (geom) AS 
     (SELECT (ST_Dump(multiline)).geom 
        FROM ST_GeomFromText(
          'MULTILINESTRING((0 0, 10 0),(10 10, 20 20))') as multiline), 
  point (geom) AS 
    (SELECT ST_MakePoint(5,0) as geom)
 SELECT 
    ST_LineLocatePoint(lines.geom, point.geom) 
   FROM lines, point 
  WHERE ST_DWithin(lines.geom, point.geom, 1);

which will now only returns

0.5

If you need to know which of the Linestrings is being referenced, you can either use the path part of the set ((geom, path)) returned by ST_Dump, which will give you a 1-based index for each linestring in the dumped MultiLinestring or you could return 0.5the linestring itself and feed this to another function -- but this, probably, goes beyond what you asked.

ST_Line_Locate_point only works with Linestrings, not MultiLinestrings. This makes sense, as the return value is the percentage distance along the line that the point occurs, which wouldn't makes sense with a MultiLinestring, as you wouldn't know which of the constituent Linestrings was being referred to. You can fix this by using ST_Dump.

WITH lines (geom) AS 
  (SELECT (ST_Dump(multiline)).geom 
     FROM ST_GeomFromText(
             'MULTILINESTRING((0 0, 10 0), (10 10, 20 20))') AS multiline
 )
 SELECT ST_LineLocatePoint(geom, ST_MakePoint(5,0)) FROM lines;

which returns:

  0.5
    0

However, you need to be a bit careful here, as the 2nd Linesting does not intersect the point at all, and 0, simply means the closest point, ie, the start point. You could exclude the 2nd line by using ST_DWithin with a small tolerance, eg, with a tolerance of 1,

WITH 
  lines (geom) AS 
     (SELECT (ST_Dump(multiline)).geom 
        FROM ST_GeomFromText(
          'MULTILINESTRING((0 0, 10 0),(10 10, 20 20))') as multiline), 
  point (geom) AS 
    (SELECT ST_MakePoint(5,0) as geom)
 SELECT 
    ST_LineLocatePoint(lines.geom, point.geom) 
   FROM lines, point 
  WHERE ST_DWithin(lines.geom, point.geom, 1);

which will now only return 0.5.

ST_Line_Locate_point only works with Linestrings, not MultiLinestrings. This makes sense, as the return value is the percentage distance along the line that the point occurs, which wouldn't make sense with a MultiLinestring, as you wouldn't know which of the constituent Linestrings was being referred to. You can fix this by using ST_Dump.

WITH lines (geom) AS 
  (SELECT (ST_Dump(multiline)).geom 
     FROM ST_GeomFromText(
             'MULTILINESTRING((0 0, 10 0), (10 10, 20 20))') AS multiline
 )
 SELECT ST_LineLocatePoint(geom, ST_MakePoint(5,0)) FROM lines;

which returns:

  0.5
    0

However, you need to be a bit careful here, as the 2nd Linesting does not intersect the point at all, and 0, simply means the closest point, ie, the start point. You could exclude the 2nd line by using ST_DWithin with a small tolerance, eg, with a tolerance of 1,

WITH 
  lines (geom) AS 
     (SELECT (ST_Dump(multiline)).geom 
        FROM ST_GeomFromText(
          'MULTILINESTRING((0 0, 10 0),(10 10, 20 20))') as multiline), 
  point (geom) AS 
    (SELECT ST_MakePoint(5,0) as geom)
 SELECT 
    ST_LineLocatePoint(lines.geom, point.geom) 
   FROM lines, point 
  WHERE ST_DWithin(lines.geom, point.geom, 1);

which now only returns

0.5

If you need to know which of the Linestrings is being referenced, you can either use the path part of the set ((geom, path)) returned by ST_Dump, which will give you a 1-based index for each linestring in the dumped MultiLinestring or you could return the linestring itself and feed this to another function -- but this, probably, goes beyond what you asked.

Source Link
John Powell
  • 13.7k
  • 5
  • 48
  • 62

ST_Line_Locate_point only works with Linestrings, not MultiLinestrings. This makes sense, as the return value is the percentage distance along the line that the point occurs, which wouldn't makes sense with a MultiLinestring, as you wouldn't know which of the constituent Linestrings was being referred to. You can fix this by using ST_Dump.

WITH lines (geom) AS 
  (SELECT (ST_Dump(multiline)).geom 
     FROM ST_GeomFromText(
             'MULTILINESTRING((0 0, 10 0), (10 10, 20 20))') AS multiline
 )
 SELECT ST_LineLocatePoint(geom, ST_MakePoint(5,0)) FROM lines;

which returns:

  0.5
    0

However, you need to be a bit careful here, as the 2nd Linesting does not intersect the point at all, and 0, simply means the closest point, ie, the start point. You could exclude the 2nd line by using ST_DWithin with a small tolerance, eg, with a tolerance of 1,

WITH 
  lines (geom) AS 
     (SELECT (ST_Dump(multiline)).geom 
        FROM ST_GeomFromText(
          'MULTILINESTRING((0 0, 10 0),(10 10, 20 20))') as multiline), 
  point (geom) AS 
    (SELECT ST_MakePoint(5,0) as geom)
 SELECT 
    ST_LineLocatePoint(lines.geom, point.geom) 
   FROM lines, point 
  WHERE ST_DWithin(lines.geom, point.geom, 1);

which will now only return 0.5.