<!-- Converted by db4-upgrade version 1.1 -->
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="Linear_Referencing">
          <title>Linear Referencing</title><info>
          <abstract>
          <para>These functions measure and locate events along linear features.
          They support the classic linear referencing workflow of expressing
          positions as fractions or measures along routes and of projecting
          those measures back into spatial coordinates.</para>
          </abstract>
          </info>

		<refentry xml:id="ST_LineInterpolatePoint">
		  <refnamediv>
			<refname>ST_LineInterpolatePoint</refname>

			<refpurpose>Returns a point interpolated along a line at a fractional location.</refpurpose>
		  </refnamediv>

		  <refsynopsisdiv>
			<funcsynopsis>
			  <funcprototype>
				<funcdef>geometry <function>ST_LineInterpolatePoint</function></funcdef>
				<paramdef><type>geometry </type> <parameter>a_linestring</parameter></paramdef>
				<paramdef><type>float8 </type> <parameter>a_fraction</parameter></paramdef>
			  </funcprototype>

              <funcprototype>
                <funcdef>geography <function>ST_LineInterpolatePoint</function></funcdef>
                <paramdef><type>geography </type> <parameter>a_linestring</parameter></paramdef>
                <paramdef><type>float8 </type> <parameter>a_fraction</parameter></paramdef>
                <paramdef choice="opt"><type>boolean </type><parameter>use_spheroid = true</parameter></paramdef>
              </funcprototype>

			</funcsynopsis>
		  </refsynopsisdiv>

		  <refsection>
			<title>Description</title>

			<para>Returns a point interpolated along a line at a fractional location.
            First argument must be a LINESTRING.
            Second argument is a float between 0 and 1
			representing the fraction of line length
            where the point is to be located.
            The Z and M values are interpolated if present.
            </para>

			<para>See <xref linkend="ST_LineLocatePoint"/> for
			computing the line location nearest to a Point.</para>

			<note>
			  <para>This function computes points in 2D and then interpolates
              values for Z and M,
              while <xref linkend="ST_3DLineInterpolatePoint"/> computes points in 3D
              and only interpolates the M value.</para>
			</note>

			<note>
			  <para>Since release 1.1.1 this function also interpolates M and
			  Z values (when present), while prior releases set them to
			  0.0.</para>
			</note>
			<para role="availability" conformance="0.8.2">Availability: 0.8.2, Z and M supported added in 1.1.1</para>
			<para role="changed" conformance="2.1.0.">Changed: 2.1.0. Up to 2.0.x this was called ST_Line_Interpolate_Point.</para>
			<para>&Z_support;</para>
		  </refsection>


		  <refsection>
			<title>Examples</title>
			<para>This example returns the point 20 percent along a line.</para>
			<programlisting>SELECT ST_LineInterpolatePoint(
'LINESTRING(25 50,100 125,150 190)',
0.2);</programlisting>
<screen role="visual-primary text-primary">POINT(51.5974135047432 76.5974135047432)</screen>

<para>The mid-point of a 3D line:</para>
<programlisting>SELECT ST_LineInterpolatePoint(
'LINESTRING(1 2 3,4 5 6,6 7 8)',
0.5);</programlisting>
<screen role="visual-primary text-primary">POINT(3.5 4.5 5.5)</screen>

<para>The closest point on a line to a point:</para>
<programlisting>SELECT ST_LineInterpolatePoint(
    line.geom,
    ST_LineLocatePoint(line.geom, 'POINT(4 3)'))
FROM (SELECT 'LINESTRING(1 2,4 5,6 7)'::geometry As geom) AS line;</programlisting>
<screen role="visual-primary text-primary">POINT(3 4)</screen>

	<para>An interpolated point can be offset to the left or right of a line by
	using <xref linkend="ST_OffsetCurve"/> before interpolation. This is useful
	for locating an address point beside a street centerline.</para>
	<programlisting><![CDATA[
WITH street AS (
    SELECT 'LINESTRING(0 0, 10 0)'::geometry AS geom,
           100 AS from_num,
           200 AS to_num
)
SELECT
    ST_LineInterpolatePoint(
        ST_OffsetCurve(geom, -2),
        (160 - from_num)::float8 / (to_num - from_num)
    ) AS interpolated_offset_point
FROM street;
]]></programlisting>
<screen> interpolated_offset_point
---------------------------
 POINT(6 -2)</screen>
		  </refsection>

		  <!-- Optionally add a "See Also" section -->
		  <refsection>
			<title>See Also</title>

			<para>
					<xref linkend="ST_LineInterpolatePoints"/>,
					<xref linkend="ST_3DLineInterpolatePoint"/>,
					<xref linkend="ST_LineLocatePoint"/>,
					<xref linkend="ST_OffsetCurve"/>
				</para>
		  </refsection>
		</refentry>

		<refentry xml:id="ST_3DLineInterpolatePoint">
		  <refnamediv>
			<refname>ST_3DLineInterpolatePoint</refname>

			<refpurpose>Returns a point interpolated along a 3D line at a fractional location.</refpurpose>
		  </refnamediv>

		  <refsynopsisdiv>
			<funcsynopsis>
			  <funcprototype>
				<funcdef>geometry <function>ST_3DLineInterpolatePoint</function></funcdef>
				<paramdef><type>geometry </type> <parameter>a_linestring</parameter></paramdef>
				<paramdef><type>float8 </type> <parameter>a_fraction</parameter></paramdef>
			  </funcprototype>
			</funcsynopsis>
		  </refsynopsisdiv>

		  <refsection>
			<title>Description</title>

			<para>Returns a point interpolated along a 3D line at a fractional location.
            First argument must be a LINESTRING. Second argument is a float between 0 and 1
			representing the point location as a fraction of line length.
            The M value is interpolated if present.
            </para>

			<note>
			  <para><xref linkend="ST_LineInterpolatePoint"/> computes points in 2D
              and then interpolates the values for Z and M,
              while this function computes points in 3D
              and only interpolates the M value.</para>
			</note>

			<para role="availability" conformance="3.0.0">Availability: 3.0.0</para>
            <para>&Z_support;</para>
		</refsection>


		  <refsection>
			<title>Examples</title>

			<para>Return point 20% along 3D line</para>
			<programlisting>SELECT ST_3DLineInterpolatePoint(
'LINESTRING(25 50 70,100 125 90,150 190 200)',
0.20);</programlisting>
<screen role="visual-primary text-primary">POINT Z (59.06758929108215 84.06758929108216 79.0846904776219)</screen>
		  </refsection>

		  <!-- Optionally add a "See Also" section -->
		  <refsection>
			<title>See Also</title>

			<para>
				<xref linkend="ST_LineInterpolatePoint"/>,
				<xref linkend="ST_LineInterpolatePoints"/>,
				<xref linkend="ST_LineLocatePoint"/>
			</para>
		  </refsection>
		</refentry>

		<refentry xml:id="ST_LineInterpolatePoints">
		  <refnamediv>
			<refname>ST_LineInterpolatePoints</refname>

			<refpurpose>
				Returns points interpolated along a line at a fractional interval.
			</refpurpose>
		  </refnamediv>

		  <refsynopsisdiv>
			<funcsynopsis>
			  <funcprototype>
				<funcdef>geometry <function>ST_LineInterpolatePoints</function></funcdef>
				<paramdef><type>geometry </type> <parameter>a_linestring</parameter></paramdef>
				<paramdef><type>float8 </type> <parameter>a_fraction</parameter></paramdef>
				<paramdef><type>boolean </type> <parameter>repeat</parameter></paramdef>
			  </funcprototype>

              <funcprototype>
                <funcdef>geography <function>ST_LineInterpolatePoints</function></funcdef>
                <paramdef><type>geography </type> <parameter>a_linestring</parameter></paramdef>
                <paramdef><type>float8 </type> <parameter>a_fraction</parameter></paramdef>
                <paramdef choice="opt"><type>boolean </type><parameter>use_spheroid = true</parameter></paramdef>
                <paramdef choice="opt"><type>boolean </type> <parameter>repeat = true</parameter></paramdef>
              </funcprototype>

			</funcsynopsis>
		  </refsynopsisdiv>

		  <refsection>
			<title>Description</title>

			<para>Returns one or more points interpolated along a line at a fractional interval.
            The first argument
			must be a LINESTRING. The second argument is a float8 between 0 and 1
			representing the spacing between the points as a fraction of
			line length. If the third argument is false, at most one point
			will be constructed (which is equivalent to <xref linkend="ST_LineInterpolatePoint"/>.)
		</para>

		<para>
			If the result has zero or one points, it is returned as a POINT.
			If it has two or more points, it is returned as a MULTIPOINT.
		</para>


			<para role="availability" conformance="2.5.0">Availability: 2.5.0</para>
			<para>&Z_support;</para>
			<para>&M_support;</para>
		  </refsection>

		  <refsection>
			<title>Examples</title>
			<para>This example returns points every 20 percent along a two-dimensional line.</para>
			<programlisting>SELECT ST_LineInterpolatePoints(
'LINESTRING(25 50,100 125,150 190)',
0.20);</programlisting>
<screen role="visual-primary text-primary">MULTIPOINT((51.5974135047432 76.5974135047432),(78.1948270094864 103.194827009486),(104.132163186446 130.37181214238),(127.066081593223 160.18590607119),(150 190))</screen>
		  </refsection>

		  <refsection>
			<title>See Also</title>

			<para>
				<xref linkend="ST_LineInterpolatePoint"/>,
				<xref linkend="ST_LineLocatePoint"/>
			</para>
		  </refsection>
		</refentry>

		<refentry xml:id="ST_LineLocatePoint">
		  <refnamediv>
			<refname>ST_LineLocatePoint</refname>

			<refpurpose>Returns the fractional location of
			the closest point on a line to a point.</refpurpose>
		  </refnamediv>

		  <refsynopsisdiv>
			<funcsynopsis>

			  <funcprototype>
				<funcdef>float8 <function>ST_LineLocatePoint</function></funcdef>
				<paramdef><type>geometry </type> <parameter>a_linestring</parameter></paramdef>
				<paramdef><type>geometry </type> <parameter>a_point</parameter></paramdef>
			  </funcprototype>

              <funcprototype>
                <funcdef>float8 <function>ST_LineLocatePoint</function></funcdef>
                <paramdef><type>geography </type> <parameter>a_linestring</parameter></paramdef>
                <paramdef><type>geography </type> <parameter>a_point</parameter></paramdef>
                <paramdef choice="opt"><type>boolean </type><parameter>use_spheroid = true</parameter></paramdef>
              </funcprototype>

			</funcsynopsis>
		  </refsynopsisdiv>

		  <refsection>
			<title>Description</title>

			 <para>Returns a float between 0 and 1 representing the location of
			the closest point on a LineString to the given Point, as a fraction
			of <link linkend="ST_Length2D">2d line</link> length.</para>

			<para>You can use the returned location to extract a Point (<xref linkend="ST_LineInterpolatePoint"/>) or
			a substring (<xref linkend="ST_LineSubstring"/>).</para>

			<para>This is useful for approximating numbers of addresses</para>

			<para role="availability" conformance="1.1.0">Availability: 1.1.0</para>
      <para role="changed" conformance="2.1.0.">Changed: 2.1.0. Up to 2.0.x this was called ST_Line_Locate_Point.</para>
		  </refsection>


		  <refsection>
			<title>Examples</title>

			<para>This example approximates the street number of a house by locating the closest point on a street line. The subquery generates sample house and street data, and <function>ST_DWithin</function> excludes houses that are too far from the street.</para>
			<programlisting>SELECT house_loc As as_text_house_loc,
    start_house_num +
        CAST( (end_house_num - start_house_num)
            * ST_LineLocatePoint(street_line, house_loc) As integer) As house_num
FROM
(SELECT 'LINESTRING(1 2,3 4)'::geometry As street_line,
    ST_Point(x*1.01, y*1.03) As house_loc, 10 As start_house_num,
        20 As end_house_num
FROM generate_series(1, 3) x CROSS JOIN generate_series(2, 4) As y)
As foo
WHERE ST_DWithin(street_line, house_loc, 0.2);</programlisting>
<screen> as_text_house_loc | house_num
-------------------+------------
 POINT(1.01 2.06)  |         10
 POINT(2.02 3.09)  |         15
 POINT(3.03 4.12)  |         20</screen>

<para>This example finds the closest point on a line to a point or other geometry.</para>
<programlisting>SELECT ST_LineInterpolatePoint(
    foo.the_line,
    ST_LineLocatePoint(foo.the_line, 'POINT(4 3)'::geometry))
FROM (SELECT 'LINESTRING(1 2,4 5,6 7)'::geometry As the_line) As foo;</programlisting>
<screen role="visual-primary text-primary">POINT(3 4)</screen>

<para>This example locates the closest segment and point on a LineString.</para>
<programlisting>WITH data AS (
  SELECT
    'LINESTRING (0 0, 10 10, 20 20, 30 30)'::geometry AS line,
    'POINT(15 15.1)'::geometry AS pt
),
segments AS (
  SELECT
    s.i,
    d.line,
    d.pt,
    ST_MakeLine(ST_PointN(d.line, s.i), ST_PointN(d.line, s.i + 1)) AS segment
  FROM data AS d
  CROSS JOIN LATERAL generate_series(1, ST_NumPoints(d.line) - 1) AS s(i)
)
SELECT
  i AS segment_number,
  round(ST_Distance(segment, pt)::numeric, 3) AS distance,
  ST_ClosestPoint(segment, pt) AS closest_point,
  ST_AddPoint(line, ST_ClosestPoint(segment, pt), i) AS line_with_closest_point
FROM segments
ORDER BY ST_Distance(segment, pt)
LIMIT 1;</programlisting>
<screen> segment_number | distance |   closest_point    |              line_with_closest_point
----------------+----------+--------------------+----------------------------------------------------
              2 |    0.071 | POINT(15.05 15.05) | LINESTRING(0 0,10 10,15.05 15.05,20 20,30 30)</screen>
		  </refsection>

		  <!-- Optionally add a "See Also" section -->
		  <refsection>
			<title>See Also</title>

			<para><xref linkend="ST_AddPoint"/>, <xref linkend="ST_ClosestPoint"/>, <xref linkend="ST_DWithin"/>, <xref linkend="ST_Length2D"/>, <xref linkend="ST_LineInterpolatePoint"/>, <xref linkend="ST_LineSubstring"/></para>
		  </refsection>
		</refentry>

		<refentry xml:id="ST_LineSubstring">
		  <refnamediv>
			<refname>ST_LineSubstring</refname>

			<refpurpose>Returns the part of a line between two fractional locations.</refpurpose>
		  </refnamediv>

		  <refsynopsisdiv>
			<funcsynopsis>
			  <funcprototype>
				<funcdef>geometry <function>ST_LineSubstring</function></funcdef>
				<paramdef><type>geometry </type> <parameter>a_linestring</parameter></paramdef>
				<paramdef><type>float8 </type> <parameter>startfraction</parameter></paramdef>
				<paramdef><type>float8 </type> <parameter>endfraction</parameter></paramdef>
			  </funcprototype>

              <funcprototype>
                <funcdef>geography <function>ST_LineSubstring</function></funcdef>
                <paramdef><type>geography </type> <parameter>a_linestring</parameter></paramdef>
                <paramdef><type>float8 </type> <parameter>startfraction</parameter></paramdef>
                <paramdef><type>float8 </type> <parameter>endfraction</parameter></paramdef>
              </funcprototype>

			</funcsynopsis>
		  </refsynopsisdiv>

		  <refsection>
			<title>Description</title>

			<para>Computes the line which is the section of the input line
			starting and ending at the given fractional locations.
            The first argument must be a LINESTRING.
			The second and third arguments are values in the range [0, 1]
            representing the start and end locations.
            For geometry inputs, the fractions are measured in 2D line length.
            The Z and M values are interpolated for added endpoints if present.
            </para>

			<para>If <varname>startfraction</varname> and <varname>endfraction</varname>
            have the same value this is equivalent
			to <xref linkend="ST_LineInterpolatePoint"/>.</para>

			<note>
			  <para>This only works with LINESTRINGs.
			    To use on contiguous MULTILINESTRINGs
                first join them with <xref linkend="ST_LineMerge"/>.</para>
			</note>

			<note>
			  <para>Since release 1.1.1 this function interpolates M and
			  Z values.  Prior releases set Z and M to
			  unspecified values.</para>
			</note>

			<para role="enhanced" conformance="3.4.0">Enhanced: 3.4.0 - Support for geography was introduced.</para>
			<para role="changed" conformance="2.1.0">Changed: 2.1.0. Up to 2.0.x this was called ST_Line_Substring.</para>
			<para role="availability" conformance="1.1.0">Availability: 1.1.0, Z and M supported added in 1.1.1</para>
			<para>&Z_support;</para>
		  </refsection>

		  <refsection>
			<title>Examples</title>
			<para>Extract the middle third of a LineString, from 0.333 to 0.666.</para>
	<programlisting language="sql">SELECT ST_LineSubstring(
'LINESTRING (20 180,50 20,90 80,120 40,180 150)',
0.333,
0.666);</programlisting>
<screen role="visual-overlay text-primary visual-primary">LINESTRING (45.17311810399485 45.74337011202746, 50 20, 90 80, 112.97593050157862 49.36542599789519)</screen>

<para>
If start and end locations are the same, the result is a POINT.
</para>
<programlisting language="sql">SELECT ST_LineSubstring(
'LINESTRING(25 50,100 125,150 190)',
0.333,
0.333);</programlisting>
<screen role="visual-overlay text-primary visual-primary">POINT(69.28469348539744 94.28469348539744)</screen>


<para>
A query to cut a LineString into sections of length 100 or shorter.
It uses <varname>generate_series()</varname> with a CROSS JOIN LATERAL
to produce the equivalent of a FOR loop.
</para>
<para>The final generated step is filtered out when the line length is an exact multiple of the requested section length.</para>
<programlisting language="sql"><![CDATA[WITH data(id, geom) AS (VALUES
        ( 'A', 'LINESTRING( 0 0, 200 0)'::geometry ),
        ( 'B', 'LINESTRING( 0 100, 350 100)'::geometry ),
        ( 'C', 'LINESTRING( 0 200, 50 200)'::geometry )
    )
SELECT id, i,
       ST_LineSubstring(geom, startfrac, LEAST( endfrac, 1 )) AS geom
FROM (
    SELECT id, geom, ST_Length(geom) len, 100 sublen FROM data
    ) AS d
CROSS JOIN LATERAL (
    SELECT i, (sublen * i) / len AS startfrac,
              (sublen * (i+1)) / len AS endfrac
    FROM generate_series(0, floor( len / sublen )::integer ) AS t(i)
    WHERE (sublen * i) / len <> 1.0
    ) AS d2;]]></programlisting>
<screen role="text-primary">
 id | i |            geom
----+---+-----------------------------
 A  | 0 | LINESTRING(0 0,100 0)
 A  | 1 | LINESTRING(100 0,200 0)
 B  | 0 | LINESTRING(0 100,100 100)
 B  | 1 | LINESTRING(100 100,200 100)
 B  | 2 | LINESTRING(200 100,300 100)
 B  | 3 | LINESTRING(300 100,350 100)
 C  | 0 | LINESTRING(0 200,50 200)
</screen>

<para>
Split a LineString by points by locating the points along the line, adding the
0 and 1 endpoints, and extracting substrings between adjacent locations.
</para>
<programlisting language="sql"><![CDATA[
WITH data AS (
  SELECT 'LINESTRING(0 0, 10 0)'::geometry AS line,
         'MULTIPOINT((2 0),(5 0),(8 0))'::geometry AS points
),
fractions AS (
  SELECT 0.0 AS fraction
  UNION ALL
  SELECT 1.0
  UNION ALL
  SELECT ST_LineLocatePoint(line, (dp).geom)
  FROM data
  CROSS JOIN LATERAL ST_Dump(points) AS dp
),
ordered AS (
  SELECT DISTINCT fraction
  FROM fractions
),
segments AS (
  SELECT fraction AS start_fraction,
         lead(fraction) OVER (ORDER BY fraction) AS end_fraction
  FROM ordered
)
SELECT row_number() OVER (ORDER BY start_fraction) AS segment_id,
       ST_LineSubstring(line, start_fraction, end_fraction) AS geom
FROM data
CROSS JOIN segments
WHERE end_fraction IS NOT NULL
  AND start_fraction <> end_fraction
ORDER BY start_fraction;
]]></programlisting>
<screen role="visual-overlay text-primary"> segment_id |         geom
------------+----------------------
          1 | LINESTRING(0 0,2 0)
          2 | LINESTRING(2 0,5 0)
          3 | LINESTRING(5 0,8 0)
          4 | LINESTRING(8 0,10 0)</screen>

<para>Geography implementation measures along a spheroid, geometry along a line</para>
<programlisting language="sql">SELECT ST_LineSubstring(
'LINESTRING(-118.2436 34.0522,-71.0570 42.3611)'::geography,
0.333,
0.666) AS geog_sub,
ST_LineSubstring(
    'LINESTRING(-118.2436 34.0522,-71.0570 42.3611)'::geometry,
    0.333,
    0.666) AS geom_sub;</programlisting>
<screen role="psql-expanded text-primary">-[ RECORD 1 ]----------
geog_sub | LINESTRING(-103.911641 38.931128,-87.941787 41.831072)
geom_sub | LINESTRING(-102.530462 36.819064,-86.817324 39.585927)</screen>

	<para>For geometry inputs, the fractional locations are based on the 2D
	length of the line, even when the input has Z values. The resulting Z values
	are interpolated along the selected 2D location.</para>
	<programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING Z (0 0 0,0 2 5,0 10 10)'::geometry AS geom
)
SELECT ST_Length(geom) AS length_2d,
       ST_3DLength(geom) AS length_3d,
       ST_LineSubstring(geom, 0, 0.5) AS substring
FROM data;</programlisting>
<screen role="visual-overlay text-primary"> length_2d |    length_3d     |              substring
-----------+------------------+-------------------------------------
        10 | 14.819145939191106 | LINESTRING Z (0 0 0,0 2 5,0 5 6.875)</screen>
		  </refsection>

		  <!-- Optionally add a "See Also" section -->
		  <refsection>
			<title>See Also</title>

			<para><xref linkend="ST_Length"/>, <xref linkend="ST_LineExtend"/>, <xref linkend="ST_LineInterpolatePoint"/>, <xref linkend="ST_LineLocatePoint"/>, <xref linkend="ST_LineMerge"/>, <xref linkend="ST_Split"/></para>
		  </refsection>
	</refentry>

	<refentry xml:id="ST_LocateAlong">
	  <refnamediv>
		<refname>ST_LocateAlong</refname>

		<refpurpose>Returns the point(s) on a geometry that match a measure value.</refpurpose>
	  </refnamediv>

	  <refsynopsisdiv>
		<funcsynopsis>
		  <funcprototype>
			<funcdef>geometry <function>ST_LocateAlong</function></funcdef>
			<paramdef><type>geometry </type> <parameter>geom_with_measure</parameter></paramdef>
			<paramdef><type>float8 </type> <parameter>measure</parameter></paramdef>
			<paramdef choice="opt"><type>float8 </type> <parameter>offset = 0</parameter></paramdef>
		  </funcprototype>
		</funcsynopsis>
	  </refsynopsisdiv>

	  <refsection>
		<title>Description</title>

		<para>Returns the location(s) along a measured geometry
		that have the given measure values.
        The result is a Point or MultiPoint.
        Polygonal inputs are not supported.</para>

		<para>If <varname>offset</varname> is provided, the result
        is offset to the left or right of the input line by the specified distance.
        A positive offset will be to the left, and a negative one to the right.</para>

		<note><para>Use this function only for linear geometries with an M component</para></note>

		<para>The semantic is specified by the <emphasis>ISO/IEC 13249-3 SQL/MM Spatial</emphasis> standard.</para>

		<para role="availability" conformance="1.1.0">Availability: 1.1.0 by old name ST_Locate_Along_Measure. </para>
		<para role="changed" conformance="2.0.0">Changed: 2.0.0 in prior versions this used to be called ST_Locate_Along_Measure.</para>

		<para>&M_support;</para>
        <para>&sqlmm_compliant; SQL-MM IEC 13249-3: 5.1.13</para>
	  </refsection>


	  <refsection>
		<title>Examples</title>
<programlisting language="sql">SELECT ST_LocateAlong(
'MULTILINESTRINGM((1 2 3, 3 4 2, 9 4 3),(1 2 3, 5 4 5))'::geometry,
3);</programlisting>
<screen role="visual-overlay text-primary visual-primary">MULTIPOINT M ((1 2 3),(9 4 3),(1 2 3))</screen>
	  </refsection>

	  <refsection>
		<title>See Also</title>

		<para><xref linkend="ST_LocateBetween"/>, <xref linkend="ST_LocateBetweenElevations"/>, <xref linkend="ST_InterpolatePoint"/> </para>
	  </refsection>
	</refentry>

	<refentry xml:id="ST_LocateBetween">
	  <refnamediv>
		<refname>ST_LocateBetween</refname>

		<refpurpose>Returns the portions of a geometry that match a measure range.</refpurpose>
	  </refnamediv>

	  <refsynopsisdiv>
		<funcsynopsis>
		  <funcprototype>
			<funcdef>geometry <function>ST_LocateBetween</function></funcdef>
			<paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
			<paramdef><type>float8 </type> <parameter>measure_start</parameter></paramdef>
			<paramdef><type>float8 </type> <parameter>measure_end</parameter></paramdef>
			<paramdef choice="opt"><type>float8 </type> <parameter>offset = 0</parameter></paramdef>
		  </funcprototype>

		</funcsynopsis>
	  </refsynopsisdiv>

	  <refsection>
		<title>Description</title>

		<para>Return a geometry (collection) with the portions of the input measured geometry
        that match the specified measure range (inclusively).</para>

		<para>If the <varname>offset</varname> is provided, the result
        is offset to the left or right of the input line by the specified distance.
        A positive offset will be to the left, and a negative one to the right.</para>

		<para>Clipping a non-convex POLYGON may produce invalid geometry.</para>

		<para>The semantic is specified by the <emphasis>ISO/IEC 13249-3 SQL/MM Spatial</emphasis> standard.</para>

		<para role="availability" conformance="1.1.0">Availability: 1.1.0 by old name ST_Locate_Between_Measures. </para>
		<para role="changed" conformance="2.0.0">Changed: 2.0.0 - in prior versions this used to be called ST_Locate_Between_Measures.</para>
		<para role="enhanced" conformance="3.0.0">Enhanced: 3.0.0 - added support for POLYGON, TIN, TRIANGLE.</para>

		<para>&M_support;</para>
        <para>&sqlmm_compliant; SQL-MM IEC 13249-3: 5.1</para>
	  </refsection>

	  <refsection>
		<title>Examples</title>

<programlisting language="sql">SELECT ST_LocateBetween(
'MULTILINESTRING M ((1 2 3,3 4 2,9 4 3),(1 2 3,5 4 5))'::geometry,
1.5,
3);</programlisting>
<screen role="visual-overlay text-primary visual-primary">GEOMETRYCOLLECTION M (LINESTRING M (1 2 3,3 4 2,9 4 3),POINT M (1 2 3))</screen>

		<para>Extract the section between measures 2 and 8, offset to the left. Because the clipped line and the offset result share the same coordinate space, this example is intended for a single overlay panel rather than separate side-by-side figures.</para>
<programlisting language="sql">SELECT ST_LocateBetween(
ST_AddMeasure(
    'LINESTRING (20 180,50 20,100 120,180 20)',
    0,
    10),
2,
8,
20);</programlisting>
<screen role="visual-overlay text-primary visual-primary geometry-output-precision-6">MULTILINESTRING((54.49835 104.53427,58.700561 82.122481,82.111456 128.944272,84.248937 132.324934,87.01637 135.21267,90.303073 137.491987,93.977598 139.071724,97.892984 139.888702,101.892639 139.910247,105.816599 139.135495,109.507928 137.595434,112.818995 135.351657,115.617376 132.493901,145.310173 95.377905))</screen>

	  </refsection>

	  <refsection>
		<title>See Also</title>

		<para><xref linkend="ST_LocateAlong"/>, <xref linkend="ST_LocateBetweenElevations"/></para>
	  </refsection>
	</refentry>

	<refentry xml:id="ST_LocateBetweenElevations">
	  <refnamediv>
		<refname>ST_LocateBetweenElevations</refname>

		<refpurpose>Returns the portions of a geometry
			that lie in an elevation (Z) range.</refpurpose>
	  </refnamediv>

	  <refsynopsisdiv>
		<funcsynopsis>
		  <funcprototype>
			<funcdef>geometry <function>ST_LocateBetweenElevations</function></funcdef>
			<paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
			<paramdef><type>float8 </type> <parameter>elevation_start</parameter></paramdef>
			<paramdef><type>float8 </type> <parameter>elevation_end</parameter></paramdef>
		  </funcprototype>

		</funcsynopsis>
	  </refsynopsisdiv>

	  <refsection>
		<title>Description</title>

		<para>Returns a geometry (collection) with the portions of a geometry
		that lie in an elevation (Z) range.</para>

		<para>Clipping a non-convex POLYGON may produce invalid geometry.</para>

		<para role="availability" conformance="1.4.0">Availability: 1.4.0</para>
		<para role="enhanced" conformance="3.0.0">Enhanced: 3.0.0 - added support for POLYGON, TIN, TRIANGLE.</para>

		<para>&Z_support;</para>
	  </refsection>

	  <refsection>
		<title>Examples</title>

<programlisting>SELECT ST_LocateBetweenElevations(
'LINESTRING(1 2 3,4 5 6)'::geometry,
2,
4);</programlisting>
<screen role="visual-primary text-primary">MULTILINESTRING Z ((1 2 3,2 3 4))</screen>
<programlisting>SELECT ST_LocateBetweenElevations(
'LINESTRING(1 2 6,4 5 -1,7 8 9)',
6,
9) As ewelev;</programlisting>
<screen role="visual-primary text-primary">GEOMETRYCOLLECTION Z (POINT Z (1 2 6),LINESTRING Z (6.1 7.1 6,7 8 9))</screen>
	  </refsection>

	  <refsection>
		<title>See Also</title>

		<para><xref linkend="ST_Dump"/>, <xref linkend="ST_LocateBetween"/></para>
	  </refsection>
	</refentry>


    <refentry xml:id="ST_InterpolatePoint">
        <refnamediv>
        <refname>ST_InterpolatePoint</refname>

        <refpurpose>Returns the interpolated measure of a geometry closest to a point.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
            <funcdef>float8 <function>ST_InterpolatePoint</function></funcdef>
            <paramdef><type>geometry </type> <parameter>linear_geom_with_measure</parameter></paramdef>
            <paramdef><type>geometry </type> <parameter>point</parameter></paramdef>
            </funcprototype>

        </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
        <title>Description</title>

            <para>Returns an interpolated measure value of a linear measured geometry
            at the location closest to the given point.</para>

            <note><para>Use this function only for linear geometries with an M component</para></note>

            <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>

        <para>&Z_support;</para>
        </refsection>

        <refsection>
        <title>Examples</title>

        <programlisting>SELECT ST_InterpolatePoint(
'LINESTRING M (0 0 0,10 0 20)',
'POINT(5 5)');</programlisting>
<screen>10</screen>
        </refsection>

        <refsection>
        <title>See Also</title>

        <para><xref linkend="ST_AddMeasure"/>, <xref linkend="ST_LocateAlong"/>, <xref linkend="ST_LocateBetween"/></para>
        </refsection>

    </refentry>

    <refentry xml:id="ST_3DInterpolatePoint">
        <refnamediv>
        <refname>ST_3DInterpolatePoint</refname>

        <refpurpose>Returns the interpolated measure of a geometry closest to a point in 3D.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
            <funcdef>float8 <function>ST_3DInterpolatePoint</function></funcdef>
            <paramdef><type>geometry </type> <parameter>linear_geom_with_measure</parameter></paramdef>
            <paramdef><type>geometry </type> <parameter>point</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
        <title>Description</title>

            <para>Returns the interpolated measure value of a linear ZM geometry
            at the location closest to the given point, using 3D (XYZ) distance
            for the projection.  Use this function when the geometry has
            significant Z variation, such as flight trajectories, where
            <xref linkend="ST_InterpolatePoint"/> would give incorrect results
            by ignoring the Z dimension.</para>

            <note><para>The line must have both Z and M dimensions.
            The point should have a Z dimension.</para></note>

            <para role="availability" conformance="3.7.0">Availability: 3.7.0</para>

        <para>&Z_support;</para>
        </refsection>

        <refsection>
        <title>Examples</title>

        <para>This example interpolates on a line rising diagonally in Z, using a point at the 3D midpoint.</para>
        <programlisting>SELECT ST_3DInterpolatePoint(
'LINESTRING ZM (0 0 0 0,10 0 10 20)',
'POINT Z (5 0 5)');</programlisting>
<screen>10</screen>

        <para>This example uses a vertical line with zero XY extent, where 3D projection works but 2D projection does not.</para>
        <programlisting>SELECT ST_3DInterpolatePoint(
'LINESTRING ZM (0 0 0 0,0 0 10 100)',
'POINT Z (5 5 5)');</programlisting>
<screen>50</screen>
        </refsection>

        <refsection>
        <title>See Also</title>
        <para><xref linkend="ST_InterpolatePoint"/>, <xref linkend="ST_AddMeasure"/>,
              <xref linkend="ST_LocateAlong"/>, <xref linkend="ST_LocateBetween"/></para>
        </refsection>

    </refentry>


	<refentry xml:id="ST_AddMeasure">
	  <refnamediv>
		<refname>ST_AddMeasure</refname>

		<refpurpose>Interpolates measures along a linear geometry.</refpurpose>
	  </refnamediv>

	  <refsynopsisdiv>
		<funcsynopsis>
		  <funcprototype>
			<funcdef>geometry <function>ST_AddMeasure</function></funcdef>
			<paramdef><type>geometry </type> <parameter>geom_mline</parameter></paramdef>
			<paramdef><type>float8 </type> <parameter>measure_start</parameter></paramdef>
			<paramdef><type>float8 </type> <parameter>measure_end</parameter></paramdef>
		  </funcprototype>

		</funcsynopsis>
	  </refsynopsisdiv>

	  <refsection>
		<title>Description</title>

		   <para>Return a derived geometry with measure values linearly interpolated between the start and end points. If the geometry has no measure dimension, one is added. If the geometry has a measure dimension, it is over-written with new values. Only LINESTRINGS and MULTILINESTRINGS are supported.</para>

			<para role="availability" conformance="1.5.0">Availability: 1.5.0</para>

		<para>&Z_support;</para>
	  </refsection>

	  <refsection>
		<title>Examples</title>

		<programlisting>SELECT ST_AddMeasure(
'LINESTRING(1 0,2 0,4 0)',
1,
4) As ewelev;</programlisting>
<screen role="visual-primary text-primary">LINESTRING M (1 0 1,2 0 2,4 0 4)</screen>
<programlisting>SELECT ST_AddMeasure(
'LINESTRING(1 0 4,2 0 4,4 0 4)',
10,
40) As ewelev;</programlisting>
<screen role="visual-primary text-primary">LINESTRING ZM (1 0 4 10,2 0 4 20,4 0 4 40)</screen>
<programlisting>SELECT ST_AddMeasure(
'LINESTRINGM(1 0 4, 2 0 4, 4 0 4)',
10,
40) As ewelev;</programlisting>
<screen role="visual-primary text-primary">LINESTRING M (1 0 10,2 0 20,4 0 40)</screen>
<programlisting>SELECT ST_AddMeasure(
'MULTILINESTRINGM((1 0 4, 2 0 4, 4 0 4),(1 0 4, 2 0 4, 4 0 4))',
10,
70) As ewelev;</programlisting>
<screen role="visual-primary text-primary">MULTILINESTRING M ((1 0 10,2 0 20,4 0 40),(1 0 40,2 0 50,4 0 70))</screen>
	  </refsection>

	</refentry>

  </section>
