* New Features *
- #3169, ST_ApproximateMedialAxis (Sandro Santilli)
+ - ST_CPAWithin (Sandro Santilli / Boundless)
- Add |=| operator with CPA semantic and KNN support with PgSQL 9.5+
(Sandro Santilli / Boundless)
- #3131, KNN support for the geography type (Paul Ramsey / CartoDB)
<xref linkend="ST_IsValidTrajectory" />,
<xref linkend="ST_ClosestPointOfApproach" />,
<xref linkend="ST_AddMeasure" />,
+<xref linkend="geometry_distance_cpa" />
+ </para>
+ </refsection>
+ </refentry>
+
+ <refentry id="ST_CPAWithin">
+
+ <refnamediv>
+ <refname>ST_CPAWithin</refname>
+ <refpurpose>
+Returns true if the trajectories' closest points of approach
+are within the specified distance.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>float8 <function>ST_CPAWithin</function></funcdef>
+ <paramdef><type>geometry </type> <parameter>track1</parameter></paramdef>
+ <paramdef><type>geometry </type> <parameter>track2</parameter></paramdef>
+ <paramdef><type>float8 </type> <parameter>maxdist</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsection>
+ <title>Description</title>
+
+ <para>
+Checks whether two moving objects have ever been within the
+specified max distance.
+ </para>
+ <para>
+Inputs must be valid trajectories as checked by
+<xref linkend="ST_IsValidTrajectory" />.
+False is returned if the trajectories do not overlap on the M range.
+ </para>
+
+ <para>Availability: 2.2.0</para>
+ <para>&Z_support;</para>
+ </refsection>
+
+
+ <refsection>
+ <title>Examples</title>
+<programlisting>
+WITH inp AS ( SELECT
+ ST_AddMeasure('LINESTRING Z (0 0 0, 10 0 5)'::geometry,
+ extract(epoch from '2015-05-26 10:00'::timestamptz),
+ extract(epoch from '2015-05-26 11:00'::timestamptz)
+ ) a,
+ ST_AddMeasure('LINESTRING Z (0 2 10, 12 1 2)'::geometry,
+ extract(epoch from '2015-05-26 10:00'::timestamptz),
+ extract(epoch from '2015-05-26 11:00'::timestamptz)
+ ) b
+)
+SELECT ST_CPAWithin(a,b,2), ST_DistanceCPA(a,b) distance FROM inp;
+
+ st_cpawithin | distance
+--------------+------------------
+ t | 1.96521473776207
+</programlisting>
+ </refsection>
+
+ <!-- Optionally add a "See Also" section -->
+ <refsection>
+ <title>See Also</title>
+ <para>
+<xref linkend="ST_IsValidTrajectory" />,
+<xref linkend="ST_ClosestPointOfApproach" />,
+<xref linkend="ST_DistanceCPA" />,
<xref linkend="geometry_distance_cpa" />
</para>
</refsection>
PG_RETURN_FLOAT8(mindist);
}
+/*
+ * Return true if the distance between two trajectories at their
+ * closest point of approach is within the given max.
+ */
+Datum ST_CPAWithin(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(ST_CPAWithin);
+Datum ST_CPAWithin(PG_FUNCTION_ARGS)
+{
+ GSERIALIZED *gs0 = PG_GETARG_GSERIALIZED_P(0);
+ GSERIALIZED *gs1 = PG_GETARG_GSERIALIZED_P(1);
+ double maxdist = PG_GETARG_FLOAT8(2);
+ /* All checks already performed by liblwgeom, not worth checking again */
+ LWGEOM *g0 = lwgeom_from_gserialized(gs0);
+ LWGEOM *g1 = lwgeom_from_gserialized(gs1);
+ int ret = lwgeom_cpa_within(g0, g1, maxdist);
+ lwgeom_free(g0);
+ lwgeom_free(g1);
+ PG_FREE_IF_COPY(gs0, 0);
+ PG_FREE_IF_COPY(gs1, 1);
+ PG_RETURN_BOOL( ret == LW_TRUE );
+}
AS 'MODULE_PATHNAME', 'ST_DistanceCPA'
LANGUAGE 'c' IMMUTABLE STRICT;
+-- Availability: 2.2.0
+CREATE OR REPLACE FUNCTION ST_CPAWithin(geometry, geometry, float8)
+ RETURNS bool
+ AS 'MODULE_PATHNAME', 'ST_CPAWithin'
+ LANGUAGE 'c' IMMUTABLE STRICT;
+
-- Availability: 2.2.0
CREATE OR REPLACE FUNCTION ST_IsValidTrajectory(geometry)
RETURNS bool
SELECT 'invalid', ST_DistanceCPA('LINESTRING(0 0 0, 1 0 0)'::geometry
,'LINESTRING(0 0 3 0, 1 0 2 1)'::geometry);
+
+----------------------------------------
+--
+-- ST_CPAWithin
+--
+----------------------------------------
+
+SELECT 'cpaw1', d, ST_CPAWithin(
+ 'LINESTRINGM(0 0 0, 1 0 1)'::geometry
+ ,'LINESTRINGM(0 0 0, 1 0 1)'::geometry, d)
+ FROM ( VALUES (0.0),(1) ) f(d) ORDER BY d;
+SELECT 'cpaw2', d, ST_CPAWithin(
+ 'LINESTRINGM(0 0 0, 1 0 1)'::geometry
+ ,'LINESTRINGM(0 0 1, 1 0 2)'::geometry, d)
+ FROM ( VALUES (0.5),(1),(1.2) ) f(d) ORDER BY d;
+SELECT 'cpaw3', d, ST_CPAWithin(
+ 'LINESTRING(0 0 0 0, 1 0 0 1)'::geometry
+ ,'LINESTRING(0 0 3 0, 1 0 2 1)'::geometry, d)
+ FROM ( VALUES (1.9),(2),(2.0001) ) f(d) ORDER BY d;
+-- temporary disjoint
+SELECT 'cpaw4', ST_CPAWithin(
+ 'LINESTRINGM(0 0 0, 10 0 10)'::geometry
+ ,'LINESTRINGM(10 0 11, 10 10 20)'::geometry, 1e15);
+SELECT 'cpaw_invalid', ST_CPAWithin(
+ 'LINESTRING(0 0 0, 1 0 0)'::geometry
+ ,'LINESTRING(0 0 3 0, 1 0 2 1)'::geometry, 1e16);
cpad3|2
cpad4|
ERROR: Both input geometries must have a measure dimension
+cpaw1|0.0|t
+cpaw1|1|t
+cpaw2|0.5|f
+cpaw2|1|t
+cpaw2|1.2|t
+cpaw3|1.9|f
+cpaw3|2|t
+cpaw3|2.0001|t
+cpaw4|f
+ERROR: Both input geometries must have a measure dimension