]> granicus.if.org Git - postgis/commitdiff
#3178, EWKB emitter should emit complex empty geometry
authorPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 25 Jun 2015 13:49:06 +0000 (13:49 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 25 Jun 2015 13:49:06 +0000 (13:49 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@13701 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/cunit/cu_out_wkb.c
liblwgeom/lwout_wkb.c
regress/tickets_expected

index 0a85675e411b6040849de86876e3908f6758cc39..1df0aae6c949e2239c6e55be3015de9daf61be7f 100644 (file)
@@ -115,8 +115,10 @@ static void test_wkb_out_multipoint(void)
        CU_ASSERT_STRING_EQUAL(s,"00A000000400000004000000050080000001000000000000000000000000000000000000000000000000008000000100000000000000003FF0000000000000000000000000000000800000013FF00000000000003FF0000000000000000000000000000000800000013FF0000000000000000000000000000000000000000000000080000001000000000000000000000000000000000000000000000000");
 
        cu_wkb("MULTIPOINT(0 0 0, 0.26794919243112270647255365849413 1 3)");
-       //printf("WKB: %s",s);
        CU_ASSERT_STRING_EQUAL(s,"008000000400000002008000000100000000000000000000000000000000000000000000000000800000013FD126145E9ECD563FF00000000000004008000000000000");
+
+       cu_wkb("MULTIPOINT EMPTY");
+       CU_ASSERT_STRING_EQUAL(s,"000000000400000000");
 }
 
 static void test_wkb_out_multilinestring(void) {}
@@ -125,6 +127,9 @@ static void test_wkb_out_multipolygon(void)
 {
        cu_wkb("SRID=14;MULTIPOLYGON(((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((-1 -1 0,-1 2 0,2 2 0,2 -1 0,-1 -1 0),(0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)))");
        CU_ASSERT_STRING_EQUAL(s,"00A00000060000000E000000020080000003000000010000000500000000000000000000000000000000000000000000000000000000000000003FF000000000000000000000000000003FF00000000000003FF000000000000000000000000000003FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000030000000200000005BFF0000000000000BFF00000000000000000000000000000BFF0000000000000400000000000000000000000000000004000000000000000400000000000000000000000000000004000000000000000BFF00000000000000000000000000000BFF0000000000000BFF000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000003FF000000000000000000000000000003FF00000000000003FF000000000000000000000000000003FF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
+
+       cu_wkb("MULTIPOLYGON EMPTY");
+       CU_ASSERT_STRING_EQUAL(s,"000000000600000000");
 }
 
 static void test_wkb_out_collection(void)
@@ -134,6 +139,13 @@ static void test_wkb_out_collection(void)
 
        cu_wkb("GEOMETRYCOLLECTION EMPTY");
        CU_ASSERT_STRING_EQUAL(s,"000000000700000000");
+
+       cu_wkb("GEOMETRYCOLLECTION(LINESTRING EMPTY)");
+       CU_ASSERT_STRING_EQUAL(s,"000000000700000001000000000200000000");
+
+       cu_wkb("GEOMETRYCOLLECTION(LINESTRING EMPTY, MULTILINESTRING(EMPTY,EMPTY))");
+       // printf("%s\n",s );
+       CU_ASSERT_STRING_EQUAL(s,"000000000700000002000000000200000000000000000500000002000000000200000000000000000200000000");
 }
 
 static void test_wkb_out_circularstring(void) 
index 648668051e3ec44c3236a2989a65995afddb1663..f4722ecd4deb39b5cfb520adb7635682e4e3deac 100644 (file)
@@ -346,7 +346,7 @@ static uint8_t* ptarray_to_wkb_buf(const POINTARRAY *pa, uint8_t *buf, uint8_t v
 
        /* Bulk copy the coordinates when: dimensionality matches, output format */
        /* is not hex, and output endian matches internal endian. */
-       if ( (dims == pa_dims) && ! wkb_swap_bytes(variant) && ! (variant & WKB_HEX)  )
+       if ( pa->npoints && (dims == pa_dims) && ! wkb_swap_bytes(variant) && ! (variant & WKB_HEX)  )
        {
                size_t size = pa->npoints * dims * WKB_DOUBLE_SIZE;
                memcpy(buf, getPoint_internal(pa, 0), size);
@@ -378,6 +378,10 @@ static size_t lwpoint_to_wkb_size(const LWPOINT *pt, uint8_t variant)
        /* Endian flag + type number */
        size_t size = WKB_BYTE_SIZE + WKB_INT_SIZE;
 
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)pt) )
+               return empty_to_wkb_size((LWGEOM*)pt, variant);
+
        /* Extended WKB needs space for optional SRID integer */
        if ( lwgeom_wkb_needs_srid((LWGEOM*)pt, variant) )
                size += WKB_INT_SIZE;
@@ -389,6 +393,10 @@ static size_t lwpoint_to_wkb_size(const LWPOINT *pt, uint8_t variant)
 
 static uint8_t* lwpoint_to_wkb_buf(const LWPOINT *pt, uint8_t *buf, uint8_t variant)
 {
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)pt) )
+               return empty_to_wkb_buf((LWGEOM*)pt, buf, variant);
+
        /* Set the endian flag */
        LWDEBUGF(4, "Entering function, buf = %p", buf);
        buf = endian_to_wkb_buf(buf, variant);
@@ -416,6 +424,10 @@ static size_t lwline_to_wkb_size(const LWLINE *line, uint8_t variant)
        /* Endian flag + type number */
        size_t size = WKB_BYTE_SIZE + WKB_INT_SIZE;
 
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)line) )
+               return empty_to_wkb_size((LWGEOM*)line, variant);
+
        /* Extended WKB needs space for optional SRID integer */
        if ( lwgeom_wkb_needs_srid((LWGEOM*)line, variant) )
                size += WKB_INT_SIZE;
@@ -427,6 +439,10 @@ static size_t lwline_to_wkb_size(const LWLINE *line, uint8_t variant)
 
 static uint8_t* lwline_to_wkb_buf(const LWLINE *line, uint8_t *buf, uint8_t variant)
 {
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)line) )
+               return empty_to_wkb_buf((LWGEOM*)line, buf, variant);
+
        /* Set the endian flag */
        buf = endian_to_wkb_buf(buf, variant);
        /* Set the geometry type */
@@ -447,6 +463,10 @@ static size_t lwtriangle_to_wkb_size(const LWTRIANGLE *tri, uint8_t variant)
        /* endian flag + type number + number of rings */
        size_t size = WKB_BYTE_SIZE + WKB_INT_SIZE + WKB_INT_SIZE;
 
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)tri) )
+               return empty_to_wkb_size((LWGEOM*)tri, variant);
+
        /* Extended WKB needs space for optional SRID integer */
        if ( lwgeom_wkb_needs_srid((LWGEOM*)tri, variant) )
                size += WKB_INT_SIZE;
@@ -459,6 +479,10 @@ static size_t lwtriangle_to_wkb_size(const LWTRIANGLE *tri, uint8_t variant)
 
 static uint8_t* lwtriangle_to_wkb_buf(const LWTRIANGLE *tri, uint8_t *buf, uint8_t variant)
 {
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)tri) )
+               return empty_to_wkb_buf((LWGEOM*)tri, buf, variant);
+
        /* Set the endian flag */
        buf = endian_to_wkb_buf(buf, variant);
        
@@ -486,6 +510,10 @@ static size_t lwpoly_to_wkb_size(const LWPOLY *poly, uint8_t variant)
        /* endian flag + type number + number of rings */
        size_t size = WKB_BYTE_SIZE + WKB_INT_SIZE + WKB_INT_SIZE;
        int i = 0;
+       
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)poly) )
+               return empty_to_wkb_size((LWGEOM*)poly, variant);
 
        /* Extended WKB needs space for optional SRID integer */
        if ( lwgeom_wkb_needs_srid((LWGEOM*)poly, variant) )
@@ -504,6 +532,10 @@ static uint8_t* lwpoly_to_wkb_buf(const LWPOLY *poly, uint8_t *buf, uint8_t vari
 {
        int i;
 
+       /* Only process empty at this level in the EXTENDED case */
+       if ( (variant & WKB_EXTENDED) && lwgeom_is_empty((LWGEOM*)poly) )
+               return empty_to_wkb_buf((LWGEOM*)poly, buf, variant);
+
        /* Set the endian flag */
        buf = endian_to_wkb_buf(buf, variant);
        /* Set the geometry type */
@@ -582,7 +614,7 @@ static size_t lwgeom_to_wkb_size(const LWGEOM *geom, uint8_t variant)
                return 0;
 
        /* Short circuit out empty geometries */
-       if ( lwgeom_is_empty(geom) )
+       if ( (!(variant & WKB_EXTENDED)) && lwgeom_is_empty(geom) )
        {
                return empty_to_wkb_size(geom, variant);
        }
@@ -636,7 +668,8 @@ static size_t lwgeom_to_wkb_size(const LWGEOM *geom, uint8_t variant)
 static uint8_t* lwgeom_to_wkb_buf(const LWGEOM *geom, uint8_t *buf, uint8_t variant)
 {
 
-       if ( lwgeom_is_empty(geom) )
+       /* Do not simplify empties when outputting to canonical form */
+       if ( lwgeom_is_empty(geom) & ! (variant & WKB_EXTENDED) )
                return empty_to_wkb_buf(geom, buf, variant);
 
        switch ( geom->type )
index a7863fee808dab7f52f069cfd67cbd74aade9afb..d919052dafaa452f70fd24823a812ca098f7464d 100644 (file)
@@ -111,7 +111,7 @@ NOTICE:  IllegalArgumentException: Invalid number of points in LinearRing found
 #684,#2109|SRID=4326;POINT EMPTY
 #2109|SRID=3395;POINT EMPTY
 #685|0103000020e610000000000000
-#686|0107000020e610000000000000
+#686|0107000020e610000002000000010300000000000000011100000000000000
 #687|f
 #689|f
 #690