From: Paul Ramsey Date: Thu, 25 Jun 2015 13:49:06 +0000 (+0000) Subject: #3178, EWKB emitter should emit complex empty geometry X-Git-Tag: 2.2.0rc1~333 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6fd47acfc2d81a9a05d74bc8792166395b5f773e;p=postgis #3178, EWKB emitter should emit complex empty geometry git-svn-id: http://svn.osgeo.org/postgis/trunk@13701 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/cunit/cu_out_wkb.c b/liblwgeom/cunit/cu_out_wkb.c index 0a85675e4..1df0aae6c 100644 --- a/liblwgeom/cunit/cu_out_wkb.c +++ b/liblwgeom/cunit/cu_out_wkb.c @@ -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) diff --git a/liblwgeom/lwout_wkb.c b/liblwgeom/lwout_wkb.c index 648668051..f4722ecd4 100644 --- a/liblwgeom/lwout_wkb.c +++ b/liblwgeom/lwout_wkb.c @@ -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 ) diff --git a/regress/tickets_expected b/regress/tickets_expected index a7863fee8..d919052da 100644 --- a/regress/tickets_expected +++ b/regress/tickets_expected @@ -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