]> granicus.if.org Git - postgis/commitdiff
Encoded Polyline of EMPTY
authorDarafei Praliaskouski <me@komzpa.net>
Fri, 12 Jan 2018 08:48:50 +0000 (08:48 +0000)
committerDarafei Praliaskouski <me@komzpa.net>
Fri, 12 Jan 2018 08:48:50 +0000 (08:48 +0000)
Pull in from trunk

Closes #3982

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

NEWS
liblwgeom/cunit/cu_out_encoded_polyline.c
liblwgeom/lwout_encoded_polyline.c

diff --git a/NEWS b/NEWS
index d6663b39f835eaaa218d7cd93f650bba210ca7cf..9c713fd1f4979e1e921013a2ab63d9716acd5dab 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,9 @@ PostGIS 2.4.3
   - #3965, ST_ClusterKMeans used to lose some clusters on initialization
            (Darafei Praliaskouski)
   - #3956, Brin opclass object does not upgrade properly (Sandro Santilli)
+  - #3982, ST_AsEncodedPolyline supports LINESTRING EMPTY and MULTIPOINT EMPTY
+           (Darafei Praliaskouski)
+
  * Enhancements *
   - #3944, Update to EPSG register v9.2 (Even Rouault)
 
index 95c12e941fd704b6ddee0e23bf5825d364a53a3b..0cdcc1f599b63fa82ef56ea6100675124e7f806b 100644 (file)
@@ -1,15 +1,15 @@
 /**********************************************************************
-*
-* PostGIS - Spatial Types for PostgreSQL
-* http://postgis.net
-*
-* Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
-*                Shoaib Burq <saburq@gmail.com>
-*
-* This is free software; you can redistribute and/or modify it under
-* the terms of the GNU General Public Licence. See the COPYING file.
-*
-**********************************************************************/
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.net
+ *
+ * Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
+ *                Shoaib Burq <saburq@gmail.com>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "liblwgeom_internal.h"
 #include "cu_tester.h"
 
-static void do_encoded_polyline_test(char * in, int precision, char * out)
+static void
+do_encoded_polyline_test(char* in, int precision, char* out)
 {
-       LWGEOM *g;
-       char * h;
+       LWGEOMg;
+       char* h;
 
        g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE);
        h = lwgeom_to_encoded_polyline(g, precision);
@@ -36,66 +37,65 @@ static void do_encoded_polyline_test(char * in, int precision, char * out)
        lwfree(h);
 }
 
-
-static void out_encoded_polyline_test_geoms(void)
+static void
+out_encoded_polyline_test_geoms(void)
 {
        /* Magic Linestring */
        do_encoded_polyline_test(
-           "SRID=4326;LINESTRING(33.6729 38.7071,33.6692 38.701,33.6673 38.6972,33.6626 38.6871)",
-           5,
-           "k~fkFsvolEbe@bVvVzJb~@j\\");
-               return;
+               "SRID=4326;LINESTRING(33.6729 38.7071,33.6692 38.701,"
+               "33.6673 38.6972,33.6626 38.6871)",
+               5,
+               "k~fkFsvolEbe@bVvVzJb~@j\\");
 
        /* Linestring */
        do_encoded_polyline_test(
-           "LINESTRING(-120.2 38.5,-120.95 40.7,-126.453 43.252)",
-           5,
-           "_p~iF~ps|U_ulLnnqC_mqNvxq`@");
+               "LINESTRING(-120.2 38.5,-120.95 40.7,-126.453 43.252)",
+               5,
+               "_p~iF~ps|U_ulLnnqC_mqNvxq`@");
+       do_encoded_polyline_test("LINESTRING EMPTY", 5, "");
 
        /* MultiPoint */
        do_encoded_polyline_test(
-           "MULTIPOINT(-120.2 38.5,-120.95 40.7)",
-           5,
-           "_p~iF~ps|U_ulLnnqC");
+               "MULTIPOINT(-120.2 38.5,-120.95 40.7)", 5, "_p~iF~ps|U_ulLnnqC");
+       do_encoded_polyline_test("MULTIPOINT EMPTY", 5, "");
 }
 
-static void out_encoded_polyline_test_srid(void)
+static void
+out_encoded_polyline_test_srid(void)
 {
 
        /* SRID - with PointArray */
        do_encoded_polyline_test(
-           "SRID=4326;LINESTRING(0 1,2 3)",
-           5,
-           "_ibE?_seK_seK");
+               "SRID=4326;LINESTRING(0 1,2 3)", 5, "_ibE?_seK_seK");
 
        /* wrong SRID */
        do_encoded_polyline_test(
-           "SRID=4327;LINESTRING(0 1,2 3)",
-           5,
-           "_ibE?_seK_seK");
+               "SRID=4327;LINESTRING(0 1,2 3)", 5, "_ibE?_seK_seK");
 }
 
-static void out_encoded_polyline_test_precision(void)
+static void
+out_encoded_polyline_test_precision(void)
 {
 
        /* Linestring */
        do_encoded_polyline_test(
-           "LINESTRING(-0.250691 49.283048,-0.250633 49.283376,-0.250502 49.283972,-0.251245 49.284028,-0.251938 49.284232,-0.251938 49.2842)",
-           6,
-           "o}~~|AdshNoSsBgd@eGoBlm@wKhj@~@?");
+               "LINESTRING(-0.250691 49.283048, -0.250633 49.283376,"
+               "-0.250502 49.283972, -0.251245 49.284028, -0.251938 "
+               "49.284232, -0.251938 49.2842)",
+               6,
+               "o}~~|AdshNoSsBgd@eGoBlm@wKhj@~@?");
 
        /* MultiPoint */
        do_encoded_polyline_test(
-           "MULTIPOINT(-120.2 38.5,-120.95 40.7)",
-           3,
-           "gejAnwiFohCzm@");
+               "MULTIPOINT(-120.2 38.5,-120.95 40.7)", 3, "gejAnwiFohCzm@");
 }
 
 /*
 ** Used by test harness to register the tests in this file.
 */
 void out_encoded_polyline_suite_setup(void);
-void out_encoded_polyline_suite_setup(void)
+void
+out_encoded_polyline_suite_setup(void)
 {
        CU_pSuite suite = CU_add_suite("encoded_polyline_output", NULL, NULL);
        PG_ADD_TEST(suite, out_encoded_polyline_test_geoms);
index 2f3a4aa3f06e5b3ae36468d09d3aa7f5888ea65d..011da60acbc7ed7edde7bbc4d7aafb4df0d31b7e 100644 (file)
  *
  **********************************************************************
  *
-* Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
+ * Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
+ *                Shoaib Burq <saburq@gmail.com>
  *
  **********************************************************************/
 
-
 #include "stringbuffer.h"
 #include "liblwgeom_internal.h"
 
-static char * lwline_to_encoded_polyline(const LWLINE*, int precision);
-static char * lwmmpoint_to_encoded_polyline(const LWMPOINT*, int precision);
-static char * pointarray_to_encoded_polyline(const POINTARRAY*, int precision);
+static char* lwline_to_encoded_polyline(const LWLINE*, int precision);
+static char* lwmmpoint_to_encoded_polyline(const LWMPOINT*, int precision);
+static char* pointarray_to_encoded_polyline(const POINTARRAY*, int precision);
 
 /* takes a GEOMETRY and returns an Encoded Polyline representation */
-extern char *
-lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
+extern char*
+lwgeom_to_encoded_polyline(const LWGEOMgeom, int precision)
 {
        int type = geom->type;
        switch (type)
@@ -42,53 +42,66 @@ lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
        case MULTIPOINTTYPE:
                return lwmmpoint_to_encoded_polyline((LWMPOINT*)geom, precision);
        default:
-               lwerror("lwgeom_to_encoded_polyline: '%s' geometry type not supported", lwtype_name(type));
+               lwerror("lwgeom_to_encoded_polyline: '%s' geometry type not supported",
+                               lwtype_name(type));
                return NULL;
        }
 }
 
-static
-char * lwline_to_encoded_polyline(const LWLINE *line, int precision)
+static char*
+lwline_to_encoded_polyline(const LWLINE* line, int precision)
 {
        return pointarray_to_encoded_polyline(line->points, precision);
 }
 
-static
-char * lwmmpoint_to_encoded_polyline(const LWMPOINT *mpoint, int precision)
+static char*
+lwmmpoint_to_encoded_polyline(const LWMPOINT* mpoint, int precision)
 {
-       LWLINE *line = lwline_from_lwmpoint(mpoint->srid, mpoint);
-       char *encoded_polyline = lwline_to_encoded_polyline(line, precision);
+       LWLINEline = lwline_from_lwmpoint(mpoint->srid, mpoint);
+       charencoded_polyline = lwline_to_encoded_polyline(line, precision);
 
        lwline_free(line);
        return encoded_polyline;
 }
 
-static
-char * pointarray_to_encoded_polyline(const POINTARRAY *pa, int precision)
+static char*
+pointarray_to_encoded_polyline(const POINTARRAY* pa, int precision)
 {
        int i;
-       const POINT2D *prevPoint;
-       int *delta = lwalloc(2*sizeof(int)*pa->npoints);
-       char *encoded_polyline = NULL;
-       stringbuffer_t *sb;
-       double scale = pow(10,precision);
+       const POINT2D* prevPoint;
+       int* delta;
+       char* encoded_polyline = NULL;
+       stringbuffer_t* sb;
+       double scale = pow(10, precision);
+
+       /* Empty input is empty string */
+       if (pa->npoints == 0) {
+               encoded_polyline = lwalloc(1 * sizeof(char));
+               encoded_polyline[0] = 0;
+               return encoded_polyline;
+       }
+
+       delta = lwalloc(2 * sizeof(int) * pa->npoints);
 
-       /* Take the double value and multiply it by 1x10^precision, rounding the result */
+       /* Take the double value and multiply it by 1x10^precision, rounding the
+        * result */
        prevPoint = getPoint2d_cp(pa, 0);
-       delta[0] = round(prevPoint->y*scale);
-       delta[1] = round(prevPoint->x*scale);
+       delta[0] = round(prevPoint->y * scale);
+       delta[1] = round(prevPoint->x * scale);
 
-       /*  points only include the offset from the previous point */
-       for (i=1; i<pa->npoints; i++)
+       /* Points only include the offset from the previous point */
+       for (i = 1; i < pa->npoints; i++)
        {
-               const POINT2D *point = getPoint2d_cp(pa, i);
-               delta[2*i] = round(point->y*scale) - round(prevPoint->y*scale);
-               delta[(2*i)+1] = round(point->x*scale) - round(prevPoint->x*scale);
+               const POINT2D* point = getPoint2d_cp(pa, i);
+               delta[2 * i] = round(point->y * scale) - round(prevPoint->y * scale);
+               delta[(2 * i) + 1] =
+                       round(point->x * scale) - round(prevPoint->x * scale);
                prevPoint = point;
        }
 
-       /* value to binary: a negative value must be calculated using its two's complement */
-       for (i=0; i<pa->npoints*2; i++)
+       /* value to binary: a negative value must be calculated using its two's
+        * complement */
+       for (i = 0; i < pa->npoints * 2; i++)
        {
                /* Multiply by 2 for a signed left shift */
                delta[i] *= 2;
@@ -99,11 +112,12 @@ char * pointarray_to_encoded_polyline(const POINTARRAY *pa, int precision)
        }
 
        sb = stringbuffer_create();
-       for (i=0; i<pa->npoints*2; i++)
+       for (i = 0; i < pa->npoints * 2; i++)
        {
                int numberToEncode = delta[i];
 
-               while (numberToEncode >= 0x20) {
+               while (numberToEncode >= 0x20)
+               {
                        /* Place the 5-bit chunks into reverse order or
                         each value with 0x20 if another bit chunk follows and add 63*/
                        int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;