]> granicus.if.org Git - postgis/commitdiff
Add support for MULTIPOINT and POINT to ST_LocateBetween
authorPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 12 Jan 2012 19:55:30 +0000 (19:55 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 12 Jan 2012 19:55:30 +0000 (19:55 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@8793 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/liblwgeom.h.in
liblwgeom/liblwgeom_internal.h
liblwgeom/lwlinearreferencing.c

index c0946375547dbfc220ce2c23db703a69eccb1bff..524861ddbe3b1fa38a7f1e0c3eabf42abedfbb2f 100644 (file)
@@ -1274,16 +1274,6 @@ int lwline_crossing_direction(const LWLINE *l1, const LWLINE *l2);
 */
 LWCOLLECTION* lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, double from, double to);
 
-/**
-* Clip a line based on the from/to range of one of its ordinates. Use for m- and z- clipping 
-*/
-LWCOLLECTION *lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, double to);
-
-/**
-* Clip a multi-line based on the from/to range of one of its ordinates. Use for m- and z- clipping 
-*/
-LWCOLLECTION *lwmline_clip_to_ordinate_range(const LWMLINE *mline, char ordinate, double from, double to);
-
 /*
  * Export functions
  */
index b770459f64e276a40fca1ee33b0ef01fcce27758..8e00dbc84821d5540bc672853452505c26cf73da 100644 (file)
@@ -218,6 +218,27 @@ void lwpoint_set_ordinate(POINT4D *p, char ordinate, double value);
 */
 int lwpoint_interpolate(const POINT4D *p1, const POINT4D *p2, POINT4D *p, int hasz, int hasm, char ordinate, double interpolation_value);
 
+
+/**
+* Clip a line based on the from/to range of one of its ordinates. Use for m- and z- clipping 
+*/
+LWCOLLECTION *lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, double to);
+
+/**
+* Clip a multi-line based on the from/to range of one of its ordinates. Use for m- and z- clipping 
+*/
+LWCOLLECTION *lwmline_clip_to_ordinate_range(const LWMLINE *mline, char ordinate, double from, double to);
+
+/**
+* Clip a multi-point based on the from/to range of one of its ordinates. Use for m- and z- clipping 
+*/
+LWCOLLECTION *lwmpoint_clip_to_ordinate_range(const LWMPOINT *mpoint, char ordinate, double from, double to);
+
+/**
+* Clip a point based on the from/to range of one of its ordinates. Use for m- and z- clipping 
+*/
+LWCOLLECTION *lwpoint_clip_to_ordinate_range(const LWPOINT *mpoint, char ordinate, double from, double to);
+
 /*
 * Geohash
 */
index 6391856dd3942e58f9cc37108cb82458d70aac5f..ae67086da05878404e39b2e333cbd92e3a6d5001 100644 (file)
@@ -330,6 +330,107 @@ int lwpoint_interpolate(const POINT4D *p1, const POINT4D *p2, POINT4D *p, int ha
        return 1;
 }
 
+
+/**
+* Clip an input POINT between two values, on any ordinate input.
+*/
+LWCOLLECTION*
+lwpoint_clip_to_ordinate_range(const LWPOINT *point, char ordinate, double from, double to)
+{
+       LWCOLLECTION *lwgeom_out = NULL;
+       char hasz, hasm;
+       POINT4D p4d;
+       double ordinate_value;
+
+       /* Nothing to do with NULL */
+       if ( ! point )
+               lwerror("Null input geometry.");
+
+       /* Ensure 'from' is less than 'to'. */
+       if ( to < from )
+       {
+               double t = from;
+               from = to;
+               to = t;
+       }
+
+       /* Read Z/M info */
+       hasz = lwgeom_has_z(lwpoint_as_lwgeom(point));
+       hasm = lwgeom_has_m(lwpoint_as_lwgeom(point));
+       
+       /* Prepare return object */
+       lwgeom_out = lwcollection_construct_empty(MULTIPOINTTYPE, point->srid, hasz, hasm);
+
+       /* Test if ordinate is in range */
+       lwpoint_getPoint4d_p(point, &p4d);      
+       ordinate_value = lwpoint_get_ordinate(&p4d, ordinate);
+       if ( from <= ordinate_value && to >= ordinate_value )
+       {
+               LWPOINT *lwp = lwpoint_clone(point);
+               lwcollection_add_lwgeom(lwgeom_out, lwpoint_as_lwgeom(lwp));
+       }
+       
+       /* Set the bbox */
+       lwgeom_drop_bbox((LWGEOM*)lwgeom_out);
+       lwgeom_add_bbox((LWGEOM*)lwgeom_out);
+
+       return lwgeom_out;
+}
+
+
+
+/**
+* Clip an input MULTIPOINT between two values, on any ordinate input.
+*/
+LWCOLLECTION*
+lwmpoint_clip_to_ordinate_range(const LWMPOINT *mpoint, char ordinate, double from, double to)
+{
+       LWCOLLECTION *lwgeom_out = NULL;
+       char hasz, hasm;
+       int i;
+
+       /* Nothing to do with NULL */
+       if ( ! mpoint )
+               lwerror("Null input geometry.");
+
+       /* Ensure 'from' is less than 'to'. */
+       if ( to < from )
+       {
+               double t = from;
+               from = to;
+               to = t;
+       }
+
+       /* Read Z/M info */
+       hasz = lwgeom_has_z(lwmpoint_as_lwgeom(mpoint));
+       hasm = lwgeom_has_m(lwmpoint_as_lwgeom(mpoint));
+       
+       /* Prepare return object */
+       lwgeom_out = lwcollection_construct_empty(MULTIPOINTTYPE, mpoint->srid, hasz, hasm);
+
+       /* For each point, is its ordinate value between from and to? */
+       for ( i = 0; i < mpoint->ngeoms; i ++ )
+       {
+               POINT4D p4d;
+               double ordinate_value;
+               
+               lwpoint_getPoint4d_p(mpoint->geoms[i], &p4d);
+               ordinate_value = lwpoint_get_ordinate(&p4d, ordinate);
+               
+               if ( from <= ordinate_value && to >= ordinate_value )
+               {
+                       LWPOINT *lwp = lwpoint_clone(mpoint->geoms[i]);
+                       lwcollection_add_lwgeom(lwgeom_out, lwpoint_as_lwgeom(lwp));
+               }
+       }
+       
+       /* Set the bbox */
+       lwgeom_drop_bbox((LWGEOM*)lwgeom_out);
+       lwgeom_add_bbox((LWGEOM*)lwgeom_out);
+
+       return lwgeom_out;
+}
+
 /**
 * Clip an input MULTILINESTRING between two values, on any ordinate input.
 */
@@ -650,8 +751,12 @@ lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, double from, do
                        return lwline_clip_to_ordinate_range((LWLINE*)lwin, ordinate, from, to);
                case MULTILINETYPE:
                        return lwmline_clip_to_ordinate_range((LWMLINE*)lwin, ordinate, from, to);
+               case MULTIPOINTTYPE:
+                       return lwmpoint_clip_to_ordinate_range((LWMPOINT*)lwin, ordinate, from, to);
+               case POINTTYPE:
+                       return lwpoint_clip_to_ordinate_range((LWPOINT*)lwin, ordinate, from, to);
                default:
-                       lwerror("This function only accepts LINESTRING or MULTILINESTRING as arguments.");
+                       lwerror("This function does not accept %s geometries.", lwtype_name(lwin->type));
        }
 
        return NULL;