1

If I have a cable route linear referenced and stored in a LinestringM with M value is the length (in meters) from the start of the route - for example:

LINESTRING M (0 0 0, 10 0 20, 12 0 40, 20 0 50, 21 0 70)

Now I know the cable route is broken at 45 meters from start point, that would be in the middle of two points (12 0 40) and (20 0 50) (see the M value). With Postgis, how can I get the broken point coordinate - which should be POINT (16 0) in this case?

5
  • Use postgis.refractions.net/documentation/manual-2.0/… based on the M values at the start and end? I'm having a bit of trouble understanding this design - why didn't you just use the length of the linestring as the length value?
    – BradHards
    Commented Nov 7, 2013 at 9:52
  • @BradHards: for cable routes, there will be slack loops (excess cable coiled for future use) which can not be drawn accurately in the linestring, so I have to store cable sheath length in M value and calculate from it. Commented Nov 7, 2013 at 10:09
  • So are those slack loops only present on the start/end node or can they be in between if there are more points in the linestring? If this is the catch then example should include that. Commented Nov 7, 2013 at 13:39
  • @JakubKania: Those slack loops can be any where on the cable route, most notably when the cable must cross big streets, there will be larger chance that the cable will be broken by oversized trucks. And when that happens, you will have excess cable to use right away. Commented Nov 8, 2013 at 0:38
  • @JakubKania: I updated the example to clarify my idea. Commented Nov 8, 2013 at 0:49

2 Answers 2

2

The function needed is ST_LocateAlong

From the manual page example, I thought it just works with measures that already exists in the LinestringM but after testing, this works:

SELECT ST_AsEWKT((ST_Dump(the_geom)).geom)
    FROM
    (SELECT ST_LocateAlong(
            ST_GeomFromEWKT('LINESTRINGM (0 0 0, 10 0 20, 12 0 40, 20 0 50, 21 0 70)'), 45) As the_geom) As foo;

Returns:

"POINTM(16 0 45)"
0

Here is an example working for a line with only two points in it. If you have more than 2 points in your line, you will have to loop through the points and sum the Z value.

Anyway, You can use ST_Line_Interpolate_Point to get the point from a fraction of the total distance. Here you can calculate 10 / the_Z_dimension_of_the_end_point:

SELECT 
  ST_AsText(
    ST_Line_Interpolate_Point(
      geom,
      (10 / ST_Z(ST_EndPoint(geom)))
    )
  )
FROM
  (SELECT ST_LineFromText('LINESTRING(0 0 0, 10 0 20)') as geom) as yourline

This will give you:

"POINT Z (5 0 10)"

PS: Note that in 2.1 the function seems to have been renamed ST_LineInterpolatePoint

3
  • I updated the question. Can you show me how to do in this case? Thanks. Commented Nov 8, 2013 at 1:35
  • It's not a Z value, those are 2d points with an extra information as the third value. Commented Nov 8, 2013 at 7:48
  • That's right, ST_LocateAlong is the way to go. Commented Nov 8, 2013 at 14:11

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.