]> granicus.if.org Git - postgis/commitdiff
ST_DistanceCPA: return distance at closest point of approach
authorSandro Santilli <strk@keybit.net>
Tue, 9 Jun 2015 19:38:39 +0000 (19:38 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 9 Jun 2015 19:38:39 +0000 (19:38 +0000)
Includes regression test and docs.

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

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

diff --git a/NEWS b/NEWS
index 8d6e2de337eee719a124ea3081ca15f016889b2b..842851e6652a37a2950a46bd48d25efda3bfbb99 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,7 @@ PostGIS 2.2.0
   - #3139, ST_BoundingDiagonal (Sandro Santilli / Boundless)
   - #3129, ST_IsValidTrajectory (Sandro Santilli / Boundless)
   - #3128, ST_ClosestPointOfApproach (Sandro Santilli / Boundless)
+  - #3152, ST_DistanceCPA (Sandro Santilli / Boundless)
   - Canonical output for index key types
   - ST_SwapOrdinates (Sandro Santilli / Boundless)
   - #2918, Use GeographicLib functions for geodetics (Mike Toews)
index f3a34f7350dab6c912460f92d82983eb0fc4a647..5d688ea397557cf9507c707ffd2a709ecdfbb307 100644 (file)
@@ -142,7 +142,75 @@ FROM points, cpa;
                        <title>See Also</title>
                        <para>
 <xref linkend="ST_IsValidTrajectory" />,
+<xref linkend="ST_DistanceCPA" />,
 <xref linkend="ST_LocateAlong" />,
+<xref linkend="ST_AddMeasure" />
+                       </para>
+                 </refsection>
+               </refentry>
+
+               <refentry id="ST_DistanceCPA">
+
+                 <refnamediv>
+                       <refname>ST_DistanceCPA</refname>
+                       <refpurpose>
+Returns the distance between closest points of approach in two trajectories.
+      </refpurpose>
+                 </refnamediv>
+
+                 <refsynopsisdiv>
+                       <funcsynopsis>
+                         <funcprototype>
+                               <funcdef>float8 <function>ST_DistanceCPA</function></funcdef>
+                               <paramdef><type>geometry </type> <parameter>track1</parameter></paramdef>
+                               <paramdef><type>geometry </type> <parameter>track2</parameter></paramdef>
+                         </funcprototype>
+                       </funcsynopsis>
+                 </refsynopsisdiv>
+
+                 <refsection>
+                       <title>Description</title>
+
+                       <para>
+Returns the minimum distance two moving objects have ever been each-other.
+Inputs must be valid trajectories as checked by
+<xref linkend="ST_IsValidTrajectory" />.
+Null 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>
+-- Return the minimum distance of two objects moving between 10:00 and 11:00
+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_DistanceCPA(a,b) distance FROM inp;
+
+     distance
+------------------
+ 1.96036833151395
+</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_AddMeasure" />
                        </para>
                  </refsection>
index 212f8f1cb7477d3b1c7f061ae7ee9db1014cd0e3..7dc9681eb409fc136a2bd43df70374fa582b1043 100644 (file)
@@ -793,3 +793,27 @@ Datum ST_IsValidTrajectory(PG_FUNCTION_ARGS)
   lwgeom_free(g0);
   PG_RETURN_BOOL(ret == LW_TRUE);
 }
+
+/*
+ * Return the distance between two trajectories at their
+ * closest point of approach.
+ */
+Datum ST_DistanceCPA(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(ST_DistanceCPA);
+Datum ST_DistanceCPA(PG_FUNCTION_ARGS)
+{
+  GSERIALIZED *gs0 = PG_GETARG_GSERIALIZED_P(0);
+  GSERIALIZED *gs1 = PG_GETARG_GSERIALIZED_P(1);
+  /* All checks already performed by liblwgeom, not worth checking again */
+  LWGEOM *g0 = lwgeom_from_gserialized(gs0);
+  LWGEOM *g1 = lwgeom_from_gserialized(gs1);
+  double mindist;
+  double m = lwgeom_tcpa(g0, g1, &mindist);
+  lwgeom_free(g0);
+  lwgeom_free(g1);
+  PG_FREE_IF_COPY(gs0, 0);
+  PG_FREE_IF_COPY(gs1, 1);
+  PG_RETURN_FLOAT8(mindist);
+}
+
+
index 10692bcdda7e8a410c943153c43760de1fb6d971..efc2eb699d9a201ccbae09c2bd23cbe61a27ecbe 100644 (file)
@@ -3051,6 +3051,12 @@ CREATE OR REPLACE FUNCTION ST_ClosestPointOfApproach(geometry, geometry)
        AS 'MODULE_PATHNAME', 'ST_ClosestPointOfApproach' 
        LANGUAGE 'c' IMMUTABLE STRICT;
 
+-- Availability: 2.2.0
+CREATE OR REPLACE FUNCTION ST_DistanceCPA(geometry, geometry)
+       RETURNS float8 
+       AS 'MODULE_PATHNAME', 'gserialized_distance_cpa' -- ST_DistanceCPA
+       LANGUAGE 'c' IMMUTABLE STRICT;
+
 -- Availability: 2.2.0
 CREATE OR REPLACE FUNCTION ST_IsValidTrajectory(geometry)
        RETURNS bool 
index fa245472ea16a162d74ddf71336137356205589f..0f27248c9a5a495cbd6c4ffb6ad3389f4b056323 100644 (file)
@@ -47,3 +47,18 @@ WITH inp as ( SELECT
 SELECT 'cpa#3136',
 ST_ClosestPointOfApproach(g2,g1), ST_ClosestPointOfApproach(g1,g2)
 FROM inp;
+
+----------------------------------------
+--
+-- ST_DistanceCPA
+--
+----------------------------------------
+
+SELECT 'cpad1', ST_DistanceCPA('LINESTRINGM(0 0 0, 1 0 1)'::geometry
+          ,'LINESTRINGM(0 0 0, 1 0 1)'::geometry);
+SELECT 'cpad2', ST_DistanceCPA('LINESTRINGM(0 0 0, 1 0 1)'::geometry
+          ,'LINESTRINGM(0 0 1, 1 0 2)'::geometry);
+SELECT 'cpad3', ST_DistanceCPA('LINESTRING(0 0 0 0, 1 0 0 1)'::geometry
+          ,'LINESTRING(0 0 3 0, 1 0 2 1)'::geometry);
+SELECT 'invalid', ST_DistanceCPA('LINESTRING(0 0 0, 1 0 0)'::geometry
+            ,'LINESTRING(0 0 3 0, 1 0 2 1)'::geometry);
index 41a6136d6a61f7f0e012966788550a7085153b21..4eebe4dcc22c59a4cc38167ab1013d9056803d61 100644 (file)
@@ -17,3 +17,7 @@ cpa3|5.5
 cpa4|10
 cpa5|
 cpa#3136|80000002|80000002
+cpad1|0
+cpad2|1
+cpad3|2
+ERROR:  Both input geometries must have a measure dimension