]> granicus.if.org Git - postgis/commitdiff
#3181, Output POINT EMPTY in WKB using NaN as coordinate values
authorPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 25 Jun 2015 20:07:31 +0000 (20:07 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 25 Jun 2015 20:07:31 +0000 (20:07 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@13707 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
liblwgeom/cunit/cu_in_wkb.c
liblwgeom/cunit/cu_libgeom.c
liblwgeom/cunit/cu_out_wkb.c
liblwgeom/lwin_wkb.c
liblwgeom/lwout_wkb.c

diff --git a/NEWS b/NEWS
index 0fba1aa1a235bddf671fab97aa9a3b7079cbc52b..b17d9ff3f9d1d415f8b13c3e77201c2663516553 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ PostGIS 2.2.0
   - #2567, ST_Count(tablename, rastercolumn, ...) uses ST_CountAgg()
   - By default, PostGIS raster disables all GDAL drivers affecting
     out-db rasters, ST_FromGDALRaster() and ST_AsGDALRaster() variants
+  - #3181, POINT EMPTY is now stored as POINT(NaN NaN) in WKB, instead of as MULTIPOINT EMPTY
 
  * Deprecated signatures *
 
index 0000a06889e96671eb228ce7b3d1e3c99e523f3f..19c21d7cedb866d1f75429ea4946e1d04b6aec67 100644 (file)
@@ -109,8 +109,23 @@ static void test_wkb_in_point(void)
        CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
 
        cu_wkb_in("SRID=4;POINTM(1 1 1)");
-//     printf("old: %s\nnew: %s\n",hex_a, hex_b);
        CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
+       
+       cu_wkb_in("POINT EMPTY");
+       CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
+
+       cu_wkb_in("SRID=4326;POINT EMPTY");
+       CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
+
+       cu_wkb_in("POINT Z EMPTY");
+       CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
+
+       cu_wkb_in("POINT M EMPTY");
+       CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
+
+       cu_wkb_in("POINT ZM EMPTY");
+       CU_ASSERT_STRING_EQUAL(hex_a, hex_b);
+
 }
 
 static void test_wkb_in_linestring(void)
index ea707cecf34299aca06d15787afa146261ed260d..8d27a4aaa0ad546010ef8b9bcc7601e45e42d585 100644 (file)
@@ -240,7 +240,6 @@ static void test_gbox_serialized_size(void)
 
 
 
-
 static void test_lwgeom_from_gserialized(void)
 {
        LWGEOM *geom;
index 1df0aae6c949e2239c6e55be3015de9daf61be7f..8094f87b53b9cb8032889e79afd2e526cf2e93d9 100644 (file)
@@ -73,6 +73,21 @@ static void test_wkb_out_point(void)
 
        cu_wkb("SRID=4;POINTM(1 1 1)");
        CU_ASSERT_STRING_EQUAL(s,"0060000001000000043FF00000000000003FF00000000000003FF0000000000000");
+       
+       cu_wkb("POINT EMPTY");
+       CU_ASSERT_STRING_EQUAL(s,"00000000017FF80000000000007FF8000000000000");
+
+       cu_wkb("SRID=4326;POINT EMPTY");
+       CU_ASSERT_STRING_EQUAL(s,"0020000001000010E67FF80000000000007FF8000000000000");
+
+       cu_wkb("POINT Z EMPTY");
+       CU_ASSERT_STRING_EQUAL(s,"00800000017FF80000000000007FF80000000000007FF8000000000000");
+
+       cu_wkb("POINT M EMPTY");
+       CU_ASSERT_STRING_EQUAL(s,"00400000017FF80000000000007FF80000000000007FF8000000000000");
+
+       cu_wkb("POINT ZM EMPTY");
+       CU_ASSERT_STRING_EQUAL(s,"00C00000017FF80000000000007FF80000000000007FF80000000000007FF8000000000000");
 }
 
 static void test_wkb_out_linestring(void)
index 5a90520d68c96b01170ab3e47ab56381a3b97e11..ba09e720bf849235f88b2158c61048fc1479021b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "liblwgeom_internal.h"
 #include "lwgeom_log.h"
+#include <math.h>
 
 /**
 * Used for passing the parse state between the parsing functions.
@@ -369,6 +370,7 @@ static LWPOINT* lwpoint_from_wkb_state(wkb_parse_state *s)
        POINTARRAY *pa = NULL;
        size_t pa_size;
        uint32_t ndims = 2;
+       const POINT2D *pt;
 
        /* Count the dimensions. */
        if( s->has_z ) ndims++;
@@ -397,7 +399,16 @@ static LWPOINT* lwpoint_from_wkb_state(wkb_parse_state *s)
                }
        }
        
-       return lwpoint_construct(s->srid, NULL, pa);
+       /* Check for POINT(NaN NaN) ==> POINT EMPTY */
+       pt = getPoint2d_cp(pa, 0);
+       if ( isnan(pt->x) && isnan(pt->y) )
+       {
+               return lwpoint_construct_empty(s->srid, s->has_z, s->has_m);
+       }
+       else
+       {
+               return lwpoint_construct(s->srid, NULL, pa);
+       }
 }
 
 /**
index f4722ecd4deb39b5cfb520adb7635682e4e3deac..dc1aa6863bf70453991897e9fb843f5d2c57f04d 100644 (file)
@@ -9,6 +9,8 @@
  *
  **********************************************************************/
 
+#include <math.h>
+
 #include "liblwgeom_internal.h"
 #include "lwgeom_log.h"
 
@@ -274,11 +276,25 @@ static uint8_t* double_to_wkb_buf(const double d, uint8_t *buf, uint8_t variant)
 */
 static size_t empty_to_wkb_size(const LWGEOM *geom, uint8_t variant)
 {
-       size_t size = WKB_BYTE_SIZE + WKB_INT_SIZE + WKB_INT_SIZE;
+       /* endian byte + type integer */
+       size_t size = WKB_BYTE_SIZE + WKB_INT_SIZE;
 
+       /* optional srid integer */
        if ( lwgeom_wkb_needs_srid(geom, variant) )
                size += WKB_INT_SIZE;
 
+       /* Represent POINT EMPTY as POINT(NaN NaN) */
+       if ( geom->type == POINTTYPE )
+       {
+               const LWPOINT *pt = (LWPOINT*)geom;
+               size += WKB_DOUBLE_SIZE * FLAGS_NDIMS(pt->point->flags);                
+       }
+       /* num-elements */
+       else
+       {
+               size += WKB_INT_SIZE;
+       }
+
        return size;
 }
 
@@ -286,13 +302,6 @@ static uint8_t* empty_to_wkb_buf(const LWGEOM *geom, uint8_t *buf, uint8_t varia
 {
        uint32_t wkb_type = lwgeom_wkb_type(geom, variant);
 
-       if ( geom->type == POINTTYPE )
-       {
-               /* Change POINT to MULTIPOINT */
-               wkb_type &= ~WKB_POINT_TYPE;     /* clear POINT flag */
-               wkb_type |= WKB_MULTIPOINT_TYPE; /* set MULTIPOINT flag */
-       }
-
        /* Set the endian flag */
        buf = endian_to_wkb_buf(buf, variant);
 
@@ -303,8 +312,24 @@ static uint8_t* empty_to_wkb_buf(const LWGEOM *geom, uint8_t *buf, uint8_t varia
        if ( lwgeom_wkb_needs_srid(geom, variant) )
                buf = integer_to_wkb_buf(geom->srid, buf, variant);
 
-       /* Set nrings/npoints/ngeoms to zero */
-       buf = integer_to_wkb_buf(0, buf, variant);
+       /* Represent POINT EMPTY as POINT(NaN NaN) */
+       if ( geom->type == POINTTYPE )
+       {
+               const LWPOINT *pt = (LWPOINT*)geom;
+               static double nn = NAN;
+               int i;
+               for ( i = 0; i < FLAGS_NDIMS(pt->point->flags); i++ )
+               {
+                       buf = double_to_wkb_buf(nn, buf, variant);
+               }
+       }
+       /* Everything else is flagged as empty using num-elements == 0 */
+       else
+       {
+               /* Set nrings/npoints/ngeoms to zero */
+               buf = integer_to_wkb_buf(0, buf, variant);
+       }
+       
        return buf;
 }