[postgis-tickets] r16949 - ST_LocateBetween[Elevations]: Support GEOMETRYCOLLECTION

Daniel Baston dbaston at gmail.com
Wed Oct 24 15:04:45 PDT 2018


Looks like this commit brought in some unrelated changes (OpenMP??)
On Wed, Oct 24, 2018 at 5:56 PM Darafei <komzpa at gmail.com> wrote:
>
> Author: komzpa
> Date: 2018-10-24 14:56:42 -0700 (Wed, 24 Oct 2018)
> New Revision: 16949
>
> Modified:
>    trunk/NEWS
>    trunk/configure.ac
>    trunk/liblwgeom/cunit/cu_algorithm.c
>    trunk/liblwgeom/liblwgeom_internal.h
>    trunk/liblwgeom/lwgeom.c
>    trunk/liblwgeom/lwlinearreferencing.c
>    trunk/postgis/geography_inout.c
>    trunk/postgis/lwgeom_functions_lrs.c
>    trunk/regress/core/regress_lrs.sql
>    trunk/regress/core/regress_lrs_expected
> Log:
> ST_LocateBetween[Elevations]: Support GEOMETRYCOLLECTION
>
> References #4155
>
>
>
> Modified: trunk/NEWS
> ===================================================================
> --- trunk/NEWS  2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/NEWS  2018-10-24 21:56:42 UTC (rev 16949)
> @@ -27,6 +27,8 @@
>      Praliaskouski)
>    - #3457, Fix raster envelope shortcut in ST_Clip (Sai-bot)
>    - #4215, Use floating point compare in ST_DumpAsPolygons (Darafei Praliaskouski)
> +  - #4155, Support for GEOMETRYCOLLECTION in ST_LocateBetween (Darafei
> +    Praliaskouski)
>
>  PostGIS 2.5.0
>  2018/09/23
>
> Modified: trunk/configure.ac
> ===================================================================
> --- trunk/configure.ac  2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/configure.ac  2018-10-24 21:56:42 UTC (rev 16949)
> @@ -60,8 +60,11 @@
>
>  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-math-errno], [_cv_nomatherrno], [-fno-math-errno], [], [CFLAGS="$CFLAGS -fno-math-errno"], [])
>  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-signed-zeros], [_cv_nosignedzeros], [-fno-signed-zeros], [], [CFLAGS="$CFLAGS -fno-signed-zeros"], [])
> +AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fopenmp], [_cv_openmp], [-fopenmp], [], [CFLAGS="$CFLAGS -fopenmp"], [])
> +AC_LIBTOOL_LINKER_OPTION([if $compiler supports -fopenmp], [_cv_openmp], [-fopenmp], [], [LDFLAGS="-fopenmp $LDFLAGS"], [])
>  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -std=gnu99], [_cv_std], -std=gnu99, [], [CFLAGS="-std=gnu99 $CFLAGS"], [])
>
> +
>  dnl
>  dnl For GCC enable additional warning flags -Wall and -Wmissing-prototypes (using macro included with libtool)
>  dnl
>
> Modified: trunk/liblwgeom/cunit/cu_algorithm.c
> ===================================================================
> --- trunk/liblwgeom/cunit/cu_algorithm.c        2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/liblwgeom/cunit/cu_algorithm.c        2018-10-24 21:56:42 UTC (rev 16949)
> @@ -665,7 +665,7 @@
>         mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE);
>
>         /* Clip in the middle, mid-range. */
> -       c = lwmline_clip_to_ordinate_range(mline, 'Y', 1.5, 2.5);
> +       c = lwcollection_clip_to_ordinate_range((LWCOLLECTION *)mline, 'Y', 1.5, 2.5);
>         ewkt = lwgeom_to_ewkt((LWGEOM*)c);
>         //printf("c = %s\n", ewkt);
>         CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))");
> @@ -680,7 +680,7 @@
>         mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((1 0,1 1,1 2,1 3,1 4), (0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE);
>
>         /* Clip off the top. */
> -       c = lwmline_clip_to_ordinate_range(mline, 'Y', 3.5, 5.5);
> +       c = lwcollection_clip_to_ordinate_range((LWCOLLECTION *)mline, 'Y', 3.5, 5.5);
>         ewkt = lwgeom_to_ewkt((LWGEOM*)c);
>         //printf("c = %s\n", ewkt);
>         CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((1 3.5,1 4),(0 3.5,0 4))");
> @@ -695,7 +695,7 @@
>         mline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((1 0,1 -1,1 -2,1 -3,1 -4), (0 0,0 1,0 2,0 3,0 4))", LW_PARSER_CHECK_NONE);
>
>         /* Clip from 0 upwards.. */
> -       c = lwmline_clip_to_ordinate_range(mline, 'Y', 0.0, 2.5);
> +       c = lwcollection_clip_to_ordinate_range((LWCOLLECTION *)mline, 'Y', 0.0, 2.5);
>         ewkt = lwgeom_to_ewkt((LWGEOM*)c);
>         //printf("c = %s\n", ewkt);
>         CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 0),LINESTRING(0 0,0 1,0 2,0 2.5))");
>
> Modified: trunk/liblwgeom/liblwgeom_internal.h
> ===================================================================
> --- trunk/liblwgeom/liblwgeom_internal.h        2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/liblwgeom/liblwgeom_internal.h        2018-10-24 21:56:42 UTC (rev 16949)
> @@ -240,9 +240,9 @@
>  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 collection based on the from/to range of one of its ordinates. Use for m- and z- clipping
> + */
> +LWCOLLECTION *lwcollection_clip_to_ordinate_range(const LWCOLLECTION *col, 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
>
> Modified: trunk/liblwgeom/lwgeom.c
> ===================================================================
> --- trunk/liblwgeom/lwgeom.c    2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/liblwgeom/lwgeom.c    2018-10-24 21:56:42 UTC (rev 16949)
> @@ -2190,15 +2190,23 @@
>
>
>  /* Prototype for recursion */
> -static int lwgeom_subdivide_recursive(const LWGEOM *geom, uint8_t dimension, uint32_t maxvertices, uint32_t depth, LWCOLLECTION *col);
> +static void lwgeom_subdivide_recursive(const LWGEOM *geom,
> +                                      uint8_t dimension,
> +                                      uint32_t maxvertices,
> +                                      uint32_t depth,
> +                                      LWCOLLECTION *col);
>
> -static int
> -lwgeom_subdivide_recursive(const LWGEOM *geom, uint8_t dimension, uint32_t maxvertices, uint32_t depth, LWCOLLECTION *col)
> +static void
> +lwgeom_subdivide_recursive(const LWGEOM *geom,
> +                          uint8_t dimension,
> +                          uint32_t maxvertices,
> +                          uint32_t depth,
> +                          LWCOLLECTION *col)
>  {
>         const uint32_t maxdepth = 50;
>         GBOX clip, subbox1, subbox2;
>         uint32_t nvertices = 0;
> -       uint32_t i, n = 0;
> +       uint32_t i;
>         uint32_t split_ordinate;
>         double width;
>         double height;
> @@ -2205,7 +2213,6 @@
>         double pivot = DBL_MAX;
>         double center = DBL_MAX;
>         LWPOLY *lwpoly = NULL;
> -       LWGEOM *clipped;
>
>         gbox_duplicate(lwgeom_get_bbox(geom), &clip);
>         width = clip.xmax - clip.xmin;
> @@ -2217,12 +2224,8 @@
>         if ( width == 0.0 && height == 0.0 )
>         {
>                 if ( geom->type == POINTTYPE && dimension == 0)
> -               {
>                         lwcollection_add_lwgeom(col, lwgeom_clone_deep(geom));
> -                       return 1;
> -               }
> -               else
> -                       return 0;
> +               return;
>         }
>
>         if (width == 0.0)
> @@ -2242,12 +2245,11 @@
>         if ( lwgeom_is_collection(geom) && geom->type != MULTIPOINTTYPE )
>         {
>                 LWCOLLECTION *incol = (LWCOLLECTION*)geom;
> -               int n = 0;
>                 /* Don't increment depth yet, since we aren't actually
>                  * subdividing geometries yet */
>                 for ( i = 0; i < incol->ngeoms; i++ )
> -                       n += lwgeom_subdivide_recursive(incol->geoms[i], dimension, maxvertices, depth, col);
> -               return n;
> +                       lwgeom_subdivide_recursive(incol->geoms[i], dimension, maxvertices, depth, col);
> +               return;
>         }
>
>         if (lwgeom_dimension(geom) < dimension)
> @@ -2254,7 +2256,7 @@
>         {
>                 /* We've hit a lower dimension object produced by clipping at
>                  * a shallower recursion level. Ignore it. */
> -               return 0;
> +               return;
>         }
>
>         /* But don't go too far. 2^50 ~= 10^15, that's enough subdivision */
> @@ -2262,19 +2264,20 @@
>         if ( depth > maxdepth )
>         {
>                 lwcollection_add_lwgeom(col, lwgeom_clone_deep(geom));
> -               return 1;
> +               return;
>         }
>
>         nvertices = lwgeom_count_vertices(geom);
>
>         /* Skip empties entirely */
> -       if (nvertices == 0) return 0;
> +       if (nvertices == 0)
> +               return;
>
>         /* If it is under the vertex tolerance, just add it, we're done */
>         if (nvertices <= maxvertices)
>         {
>                 lwcollection_add_lwgeom(col, lwgeom_clone_deep(geom));
> -               return 1;
> +               return;
>         }
>
>         split_ordinate = (width > height) ? 0 : 1;
> @@ -2339,27 +2342,43 @@
>
>         ++depth;
>
> -       LWGEOM* subbox = (LWGEOM*) lwpoly_construct_envelope(geom->srid, subbox1.xmin, subbox1.ymin, subbox1.xmax, subbox1.ymax);
> -       clipped = lwgeom_intersection(geom, subbox);
> -       lwgeom_simplify_in_place(clipped, 0.0, LW_TRUE);
> -       lwgeom_free(subbox);
> -       if (clipped)
> +       LWCOLLECTION *col1 =
> +           lwcollection_construct_empty(COLLECTIONTYPE, geom->srid, lwgeom_has_z(geom), lwgeom_has_m(geom));
> +       LWCOLLECTION *col2 =
> +           lwcollection_construct_empty(COLLECTIONTYPE, geom->srid, lwgeom_has_z(geom), lwgeom_has_m(geom));
> +       //#pragma omp parallel sections
>         {
> -               n += lwgeom_subdivide_recursive(clipped, dimension, maxvertices, depth, col);
> -               lwgeom_free(clipped);
> +               //#pragma omp section
> +               {
> +                       LWGEOM *subbox = (LWGEOM *)lwpoly_construct_envelope(
> +                           geom->srid, subbox1.xmin, subbox1.ymin, subbox1.xmax, subbox1.ymax);
> +                       LWGEOM *clipped = lwgeom_intersection(geom, subbox);
> +                       lwgeom_simplify_in_place(clipped, 0.0, LW_TRUE);
> +                       lwgeom_free(subbox);
> +                       if (clipped)
> +                       {
> +                               lwgeom_subdivide_recursive(clipped, dimension, maxvertices, depth, col1);
> +                               lwgeom_free(clipped);
> +                       }
> +               }
> +               //#pragma omp section
> +               {
> +                       LWGEOM *subbox = (LWGEOM *)lwpoly_construct_envelope(
> +                           geom->srid, subbox2.xmin, subbox2.ymin, subbox2.xmax, subbox2.ymax);
> +                       LWGEOM *clipped = lwgeom_intersection(geom, subbox);
> +                       lwgeom_simplify_in_place(clipped, 0.0, LW_TRUE);
> +                       lwgeom_free(subbox);
> +                       if (clipped)
> +                       {
> +                               lwgeom_subdivide_recursive(clipped, dimension, maxvertices, depth, col2);
> +                               lwgeom_free(clipped);
> +                       }
> +               }
>         }
> -
> -       subbox = (LWGEOM*) lwpoly_construct_envelope(geom->srid, subbox2.xmin, subbox2.ymin, subbox2.xmax, subbox2.ymax);
> -       clipped = lwgeom_intersection(geom, subbox);
> -       lwgeom_simplify_in_place(clipped, 0.0, LW_TRUE);
> -       lwgeom_free(subbox);
> -       if (clipped)
> -       {
> -               n += lwgeom_subdivide_recursive(clipped, dimension, maxvertices, depth, col);
> -               lwgeom_free(clipped);
> -       }
> -
> -       return n;
> +       col = lwcollection_concat_in_place(col, col1);
> +       lwcollection_release(col1);
> +       col = lwcollection_concat_in_place(col, col2);
> +       lwcollection_release(col2);
>  }
>
>  LWCOLLECTION *
> @@ -2385,7 +2404,6 @@
>         return col;
>  }
>
> -
>  int
>  lwgeom_is_trajectory(const LWGEOM *geom)
>  {
>
> Modified: trunk/liblwgeom/lwlinearreferencing.c
> ===================================================================
> --- trunk/liblwgeom/lwlinearreferencing.c       2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/liblwgeom/lwlinearreferencing.c       2018-10-24 21:56:42 UTC (rev 16949)
> @@ -462,80 +462,45 @@
>  }
>
>  /**
> -* Clip an input MULTILINESTRING between two values, on any ordinate input.
> -*/
> -LWCOLLECTION*
> -lwmline_clip_to_ordinate_range(const LWMLINE *mline, char ordinate, double from, double to)
> + * Clip an input COLLECTION between two values, on any ordinate input.
> + */
> +LWCOLLECTION *
> +lwcollection_clip_to_ordinate_range(const LWCOLLECTION *icol, char ordinate, double from, double to)
>  {
>         LWCOLLECTION *lwgeom_out = NULL;
>
> -       if ( ! mline )
> +       if (!icol)
>         {
>                 lwerror("Null input geometry.");
>                 return NULL;
>         }
>
> -       if ( mline->ngeoms == 1)
> -       {
> -               lwgeom_out = lwline_clip_to_ordinate_range(mline->geoms[0], ordinate, from, to);
> -       }
> +       if (icol->ngeoms == 1)
> +               lwgeom_out = lwgeom_clip_to_ordinate_range(icol->geoms[0], ordinate, from, to, 0);
>         else
>         {
>                 LWCOLLECTION *col;
> -               char hasz = lwgeom_has_z(lwmline_as_lwgeom(mline));
> -               char hasm = lwgeom_has_m(lwmline_as_lwgeom(mline));
> -               uint32_t i, j;
> -               char homogeneous = 1;
> -               size_t geoms_size = 0;
> -               lwgeom_out = lwcollection_construct_empty(MULTILINETYPE, mline->srid, hasz, hasm);
> +               char hasz = lwgeom_has_z(lwcollection_as_lwgeom(icol));
> +               char hasm = lwgeom_has_m(lwcollection_as_lwgeom(icol));
> +               uint32_t i;
> +               lwgeom_out = lwcollection_construct_empty(icol->type, icol->srid, hasz, hasm);
>                 FLAGS_SET_Z(lwgeom_out->flags, hasz);
>                 FLAGS_SET_M(lwgeom_out->flags, hasm);
> -               for ( i = 0; i < mline->ngeoms; i ++ )
> +               for (i = 0; i < icol->ngeoms; i++)
>                 {
> -                       col = lwline_clip_to_ordinate_range(mline->geoms[i], ordinate, from, to);
> -                       if ( col )
> +                       col = lwgeom_clip_to_ordinate_range(icol->geoms[i], ordinate, from, to, 0);
> +                       if (col)
>                         {
> -                               /* Something was left after the clip. */
> -                               if ( lwgeom_out->ngeoms + col->ngeoms > geoms_size )
> -                               {
> -                                       geoms_size += 16;
> -                                       if ( lwgeom_out->geoms )
> -                                       {
> -                                               lwgeom_out->geoms = lwrealloc(lwgeom_out->geoms, geoms_size * sizeof(LWGEOM*));
> -                                       }
> -                                       else
> -                                       {
> -                                               lwgeom_out->geoms = lwalloc(geoms_size * sizeof(LWGEOM*));
> -                                       }
> -                               }
> -                               for ( j = 0; j < col->ngeoms; j++ )
> -                               {
> -                                       lwgeom_out->geoms[lwgeom_out->ngeoms] = col->geoms[j];
> -                                       lwgeom_out->ngeoms++;
> -                               }
> -                               if ( col->type != mline->type )
> -                               {
> -                                       homogeneous = 0;
> -                               }
> -                               /* Shallow free the struct, leaving the geoms behind. */
> -                               if ( col->bbox ) lwfree(col->bbox);
> -                               lwfree(col->geoms);
> -                               lwfree(col);
> +                               if (col->type != icol->type)
> +                                       lwgeom_out->type = COLLECTIONTYPE;
> +                               lwgeom_out = lwcollection_concat_in_place(lwgeom_out, col);
> +                               lwcollection_release(col);
>                         }
>                 }
> -               if ( lwgeom_out->bbox )
> -               {
> -                       lwgeom_refresh_bbox((LWGEOM*)lwgeom_out);
> -               }
> -
> -               if ( ! homogeneous )
> -               {
> -                       lwgeom_out->type = COLLECTIONTYPE;
> -               }
> +               if (lwgeom_out->bbox)
> +                       lwgeom_refresh_bbox((LWGEOM *)lwgeom_out);
>         }
> -
>         return lwgeom_out;
> -
>  }
>
>
> @@ -789,9 +754,6 @@
>         case LINETYPE:
>                 out_col = lwline_clip_to_ordinate_range((LWLINE*)lwin, ordinate, from, to);
>                 break;
> -       case MULTILINETYPE:
> -               out_col = lwmline_clip_to_ordinate_range((LWMLINE*)lwin, ordinate, from, to);
> -               break;
>         case MULTIPOINTTYPE:
>                 out_col = lwmpoint_clip_to_ordinate_range((LWMPOINT*)lwin, ordinate, from, to);
>                 break;
> @@ -798,9 +760,18 @@
>         case POINTTYPE:
>                 out_col = lwpoint_clip_to_ordinate_range((LWPOINT*)lwin, ordinate, from, to);
>                 break;
> +       // case TRIANGLETYPE:
> +       //      out_col = lwtriangle_clip_to_ordinate_range((LWTRIANGLE*)lwin, ordinate, from, to);
> +       //      break;
> +       case TINTYPE:
> +       case MULTILINETYPE:
> +       case MULTIPOLYGONTYPE:
> +       case COLLECTIONTYPE:
> +               out_col = lwcollection_clip_to_ordinate_range((LWCOLLECTION *)lwin, ordinate, from, to);
> +               break;
>         default:
>                 lwerror("This function does not accept %s geometries.", lwtype_name(lwin->type));
> -               return NULL;;
> +               return NULL;
>         }
>
>         /* Stop if result is NULL */
>
> Modified: trunk/postgis/geography_inout.c
> ===================================================================
> --- trunk/postgis/geography_inout.c     2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/postgis/geography_inout.c     2018-10-24 21:56:42 UTC (rev 16949)
> @@ -712,7 +712,7 @@
>         result = palloc(size_result + VARHDRSZ);
>         SET_VARSIZE(result, size_result + VARHDRSZ);
>         memcpy(VARDATA(result), wkb, size_result);
> -       pfree(wkb);
> +       lwfree(wkb);
>
>         PG_RETURN_POINTER(result);
>  }
>
> Modified: trunk/postgis/lwgeom_functions_lrs.c
> ===================================================================
> --- trunk/postgis/lwgeom_functions_lrs.c        2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/postgis/lwgeom_functions_lrs.c        2018-10-24 21:56:42 UTC (rev 16949)
> @@ -85,7 +85,7 @@
>         GSERIALIZED *gout;
>         LWGEOM *lwin = NULL, *lwout = NULL;
>         double measure = PG_GETARG_FLOAT8(1);
> -       double offset = PG_GETARG_FLOAT8(2);;
> +       double offset = PG_GETARG_FLOAT8(2);
>
>         lwin = lwgeom_from_gserialized(gin);
>         lwout = lwgeom_locate_along(lwin, measure, offset);
> @@ -160,7 +160,7 @@
>
>         if ( ! gserialized_has_z(geom_in) )
>         {
> -               elog(ERROR,"This function only accepts LINESTRING or MULTILINESTRING with Z dimensions.");
> +               elog(ERROR, "This function only accepts geometries with Z dimensions.");
>                 PG_RETURN_NULL();
>         }
>
>
> Modified: trunk/regress/core/regress_lrs.sql
> ===================================================================
> --- trunk/regress/core/regress_lrs.sql  2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/regress/core/regress_lrs.sql  2018-10-24 21:56:42 UTC (rev 16949)
> @@ -29,6 +29,9 @@
>  -- Multilinestrings
>  -- #3119 --
>  select '#3119b', ST_AsText(ST_LocateBetweenElevations('MULTILINESTRING Z((0 0 0, 10 10 10))'::geometry, 11, 11));
> +select '#4155.1', ST_AsText(ST_LocateBetweenElevations('GEOMETRYCOLLECTION(LINESTRING(0 0 0, 10 10 10))', 2, 5));
> +select '#4155.2', ST_AsText(ST_LocateBetweenElevations('TIN Z EMPTY', 2, 5));
> +select '#4155.3', ST_AsText(ST_LocateBetweenElevations('MULTIPOLYGON Z EMPTY', 2, 5));
>
>  --- line_locate_point
>
>
> Modified: trunk/regress/core/regress_lrs_expected
> ===================================================================
> --- trunk/regress/core/regress_lrs_expected     2018-10-24 14:04:14 UTC (rev 16948)
> +++ trunk/regress/core/regress_lrs_expected     2018-10-24 21:56:42 UTC (rev 16949)
> @@ -17,6 +17,9 @@
>  LINEZM_6|MULTIPOINT ZM (9.5 0.5 0.5 2)
>  #3119a|MULTILINESTRING Z EMPTY
>  #3119b|MULTILINESTRING Z EMPTY
> +#4155.1|MULTILINESTRING Z ((2 2 2,5 5 5))
> +#4155.2|TIN Z EMPTY
> +#4155.3|MULTIPOLYGON Z EMPTY
>  line_locate_point_1|0.528602749909894
>  line_locate_point_2|1
>  line_locate_point_3|0
>
> _______________________________________________
> postgis-tickets mailing list
> postgis-tickets at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/postgis-tickets


More information about the postgis-tickets mailing list