]> granicus.if.org Git - postgis/commitdiff
Expose ST_CPAWithin to SQL
authorSandro Santilli <strk@keybit.net>
Tue, 23 Jun 2015 18:56:11 +0000 (18:56 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 23 Jun 2015 18:56:11 +0000 (18:56 +0000)
Includes dox and regress test

git-svn-id: http://svn.osgeo.org/postgis/trunk@13694 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
doc/reference_temporal.xml
postgis/lwgeom_functions_temporal.c
postgis/postgis.sql.in
regress/temporal.sql
regress/temporal_expected

diff --git a/NEWS b/NEWS
index bef3afd3524f5c8e653cc5e74e4a9cf8635966aa..0fba1aa1a235bddf671fab97aa9a3b7079cbc52b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,7 @@ PostGIS 2.2.0
  * 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)
index 37d1f58d7591588838b3dafb682001ccb4ec5d64..ab325e621d25dc9469ea53d557f8ca4f507279dc 100644 (file)
@@ -212,6 +212,78 @@ SELECT ST_DistanceCPA(a,b) distance FROM inp;
 <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>
index 463fcc78caaabb21e76ff1914ae0ebddabc3f34d..ef3b3ccb5ea32d46078e15c86fe26d5843920c03 100644 (file)
@@ -89,4 +89,25 @@ Datum ST_DistanceCPA(PG_FUNCTION_ARGS)
   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 );
+}
 
index 6127f0b61ae3128666471d2c723e926240f6c4f0..9f3b4f8374edefcb9a4e907c2b09421c97640e3b 100644 (file)
@@ -3090,6 +3090,12 @@ CREATE OR REPLACE FUNCTION ST_DistanceCPA(geometry, geometry)
        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 
index ae4a4709078402b81405c6633cd74d1036edf190..d3b451ac69b551ff8a8ea4fb41c1cbea727d5d9a 100644 (file)
@@ -66,3 +66,29 @@ SELECT 'cpad4', ST_DistanceCPA('LINESTRINGM(0 0 0, 10 0 10)'::geometry
 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);
index 4877452085350eb8593234f1e0b8eefba06a4d03..64b3e221ee6f52b0bd8e96b7d3c3fb2e4839d8bd 100644 (file)
@@ -22,3 +22,13 @@ cpad2|1
 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