Skip to content

Commit ed5451f

Browse files
committed
pc_bounds_to_geometry_wkb
1 parent 29fdb7c commit ed5451f

File tree

5 files changed

+101
-106
lines changed

5 files changed

+101
-106
lines changed

lib/cunit/cu_pc_patch.c

+19-3
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,12 @@ test_patch_wkb()
513513
PCPOINTLIST *pl1;
514514
PCPATCH_UNCOMPRESSED *pu1, *pu2;
515515
PCPATCH *pa1, *pa2, *pa3, *pa4;
516-
size_t z1, z2;
517-
uint8_t *wkb1, *wkb2;
516+
size_t z1, z2, z3;
517+
uint8_t *wkb1, *wkb2, *wkb3;
518+
char *hexwkb;
519+
520+
static char *hexresult_ndr = "01030000000100000005000000000000000000000000000000000000000000000000000000CDCCCCCCCC8C4B40EC51B81E852B4440CDCCCCCCCC8C4B40EC51B81E852B4440000000000000000000000000000000000000000000000000";
521+
static char *hexresult_xdr = "00000000030000000100000005000000000000000000000000000000000000000000000000404B8CCCCCCCCCCD40442B851EB851EC404B8CCCCCCCCCCD40442B851EB851EC000000000000000000000000000000000000000000000000";
518522

519523
pl1 = pc_pointlist_make(npts);
520524

@@ -533,6 +537,7 @@ test_patch_wkb()
533537
// str = pc_hexbytes_from_bytes(wkb1, z1);
534538
// printf("str\n%s\n",str);
535539
pa2 = pc_patch_from_wkb(simpleschema, wkb1, z1);
540+
pcfree(wkb1);
536541

537542
// printf("pa2\n%s\n",pc_patch_to_string(pa2));
538543

@@ -556,6 +561,18 @@ test_patch_wkb()
556561
CU_ASSERT_EQUAL(pu1->npoints, pu2->npoints);
557562
CU_ASSERT(memcmp(pu1->data, pu2->data, pu1->datasize) == 0);
558563

564+
wkb3 = pc_bounds_to_geometry_wkb(&pa1->bounds, simpleschema->srid, &z3);
565+
hexwkb = pc_hexbytes_from_bytes(wkb3, z3);
566+
if ( machine_endian() == PC_NDR )
567+
{
568+
CU_ASSERT_STRING_EQUAL(hexwkb, hexresult_ndr);
569+
}
570+
else
571+
{
572+
CU_ASSERT_STRING_EQUAL(hexwkb, hexresult_xdr);
573+
}
574+
pcfree(hexwkb);
575+
pcfree(wkb3);
559576

560577
pc_pointlist_free(pl1);
561578
pc_patch_free(pa1);
@@ -564,7 +581,6 @@ test_patch_wkb()
564581
pc_patch_free(pa4);
565582
pc_patch_free((PCPATCH*)pu1);
566583
pc_patch_free((PCPATCH*)pu2);
567-
pcfree(wkb1);
568584
}
569585

570586

lib/pc_api.h

+3
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,9 @@ int pc_patch_compute_extent(PCPATCH *patch);
441441
/** True/false if bounds intersect */
442442
int pc_bounds_intersects(const PCBOUNDS *b1, const PCBOUNDS *b2);
443443

444+
/** Return the bounds as an OGC WKB geometry */
445+
uint8_t *pc_bounds_to_geometry_wkb(const PCBOUNDS *bounds, uint32_t srid, size_t *wkbsize);
446+
444447
/** Returns OGC WKB of the bounding diagonal of XY bounds */
445448
uint8_t* pc_bounding_diagonal_wkb_from_bounds(const PCBOUNDS *bounds, const PCSCHEMA *schema, size_t *wkbsize);
446449

lib/pc_util.c

+77
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,83 @@ static uint32_t srid_mask = 0x20000000;
290290
static uint32_t m_mask = 0x40000000;
291291
static uint32_t z_mask = 0x80000000;
292292

293+
uint8_t *
294+
pc_bounds_to_geometry_wkb(const PCBOUNDS *bounds, uint32_t srid, size_t *wkbsize)
295+
{
296+
/* Bounds! */
297+
double xmin = bounds->xmin;
298+
double ymin = bounds->ymin;
299+
double xmax = bounds->xmax;
300+
double ymax = bounds->ymax;
301+
302+
static uint32_t srid_mask = 0x20000000;
303+
static uint32_t npoints_by_type[] = { 0, 1, 2, 5 };
304+
/* WKB POINT, LINESTRING or POLYGON */
305+
uint32_t wkbtype = 1 + (xmin != xmax) + (ymin != ymax);
306+
uint32_t npoints = npoints_by_type[wkbtype];
307+
uint8_t *wkb, *ptr;
308+
/* endian + (type + nrings? + npoints?) + npoints dbl pt */
309+
size_t size = 1 + wkbtype * 4 + npoints * 2 * 8;
310+
311+
if ( srid )
312+
{
313+
wkbtype |= srid_mask;
314+
size += 4;
315+
}
316+
317+
wkb = pcalloc(size);
318+
ptr = wkb;
319+
320+
ptr = wkb_set_char(ptr, machine_endian()); /* Endian flag */
321+
322+
ptr = wkb_set_uint32(ptr, wkbtype); /* TYPE = POINT, LINESTRING or POLYGON */
323+
324+
if ( srid )
325+
{
326+
ptr = wkb_set_uint32(ptr, srid); /* SRID */
327+
}
328+
329+
switch ( wkbtype )
330+
{
331+
case 3 /* POLYGON */ : ptr = wkb_set_uint32(ptr, 1); /* NRINGS */
332+
case 2 /* LINESTRING */ : ptr = wkb_set_uint32(ptr, npoints); /* NPOINTS */
333+
}
334+
335+
/* Point 0 */
336+
ptr = wkb_set_double(ptr, xmin);
337+
ptr = wkb_set_double(ptr, ymin);
338+
339+
if ( wkbtype == 2 ) // LINESTRING
340+
{
341+
/* Point 1 */
342+
ptr = wkb_set_double(ptr, xmax);
343+
ptr = wkb_set_double(ptr, ymax);
344+
}
345+
else if( wkbtype == 3 ) // POLYGON
346+
{
347+
/* Point 1 */
348+
ptr = wkb_set_double(ptr, xmin);
349+
ptr = wkb_set_double(ptr, ymax);
350+
351+
/* Point 2 */
352+
ptr = wkb_set_double(ptr, xmax);
353+
ptr = wkb_set_double(ptr, ymax);
354+
355+
/* Point 3 */
356+
ptr = wkb_set_double(ptr, xmax);
357+
ptr = wkb_set_double(ptr, ymin);
358+
359+
/* Point 4 */
360+
ptr = wkb_set_double(ptr, xmin);
361+
ptr = wkb_set_double(ptr, ymin);
362+
}
363+
364+
if ( wkbsize )
365+
*wkbsize = size;
366+
367+
return wkb;
368+
}
369+
293370
uint8_t *
294371
pc_bounding_diagonal_wkb_from_bounds(
295372
const PCBOUNDS *bounds, const PCSCHEMA *schema, size_t *wkbsize)

pgsql/pc_inout.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,13 @@ Datum pcpatch_envelope_as_bytea(PG_FUNCTION_ARGS)
303303
SERIALIZED_PATCH *serpatch = PG_GETHEADER_SERPATCH_P(0);
304304
PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
305305

306-
bytes = pc_patch_to_geometry_wkb_envelope(serpatch, schema, &bytes_size);
306+
bytes = pc_bounds_to_geometry_wkb(&serpatch->bounds, schema->srid, &bytes_size);
307307
wkb_size = VARHDRSZ + bytes_size;
308308
wkb = palloc(wkb_size);
309309
memcpy(VARDATA(wkb), bytes, bytes_size);
310310
SET_VARSIZE(wkb, wkb_size);
311311

312-
pfree(bytes);
312+
pcfree(bytes);
313313

314314
PG_RETURN_BYTEA_P(wkb);
315315
}

pgsql/pc_pgsql.c

-101
Original file line numberDiff line numberDiff line change
@@ -847,104 +847,3 @@ pc_patch_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schema)
847847
pcerror("%s: unsupported compression type", __func__);
848848
return NULL;
849849
}
850-
851-
852-
static uint8_t *
853-
pc_patch_wkb_set_double(uint8_t *wkb, double d)
854-
{
855-
memcpy(wkb, &d, 8);
856-
wkb += 8;
857-
return wkb;
858-
}
859-
860-
static uint8_t *
861-
pc_patch_wkb_set_int32(uint8_t *wkb, uint32_t i)
862-
{
863-
memcpy(wkb, &i, 4);
864-
wkb += 4;
865-
return wkb;
866-
}
867-
868-
static uint8_t *
869-
pc_patch_wkb_set_char(uint8_t *wkb, char c)
870-
{
871-
memcpy(wkb, &c, 1);
872-
wkb += 1;
873-
return wkb;
874-
}
875-
876-
/* 0 = xdr | big endian */
877-
/* 1 = ndr | little endian */
878-
static char
879-
machine_endian(void)
880-
{
881-
static int check_int = 1; /* dont modify this!!! */
882-
return *((char *) &check_int);
883-
}
884-
885-
uint8_t *
886-
pc_patch_to_geometry_wkb_envelope(const SERIALIZED_PATCH *pa, const PCSCHEMA *schema, size_t *wkbsize)
887-
{
888-
static uint32_t srid_mask = 0x20000000;
889-
static uint32_t nrings = 1;
890-
static uint32_t npoints = 5;
891-
uint32_t wkbtype = 3; /* WKB POLYGON */
892-
uint8_t *wkb, *ptr;
893-
int has_srid = false;
894-
size_t size = 1 + 4 + 4 + 4 + 2*npoints*8; /* endian + type + nrings + npoints + 5 dbl pts */
895-
896-
/* Bounds! */
897-
double xmin = pa->bounds.xmin;
898-
double ymin = pa->bounds.ymin;
899-
double xmax = pa->bounds.xmax;
900-
double ymax = pa->bounds.ymax;
901-
902-
/* Make sure they're slightly bigger than a point */
903-
if ( xmin == xmax ) xmax += xmax * 0.0000001;
904-
if ( ymin == ymax ) ymax += ymax * 0.0000001;
905-
906-
if ( schema->srid > 0 )
907-
{
908-
has_srid = true;
909-
wkbtype |= srid_mask;
910-
size += 4;
911-
}
912-
913-
wkb = palloc(size);
914-
ptr = wkb;
915-
916-
ptr = pc_patch_wkb_set_char(ptr, machine_endian()); /* Endian flag */
917-
918-
ptr = pc_patch_wkb_set_int32(ptr, wkbtype); /* TYPE = Polygon */
919-
920-
if ( has_srid )
921-
{
922-
ptr = pc_patch_wkb_set_int32(ptr, schema->srid); /* SRID */
923-
}
924-
925-
ptr = pc_patch_wkb_set_int32(ptr, nrings); /* NRINGS = 1 */
926-
ptr = pc_patch_wkb_set_int32(ptr, npoints); /* NPOINTS = 5 */
927-
928-
/* Point 0 */
929-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmin);
930-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymin);
931-
932-
/* Point 1 */
933-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmin);
934-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymax);
935-
936-
/* Point 2 */
937-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmax);
938-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymax);
939-
940-
/* Point 3 */
941-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmax);
942-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymin);
943-
944-
/* Point 4 */
945-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmin);
946-
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymin);
947-
948-
if ( wkbsize ) *wkbsize = size;
949-
return wkb;
950-
}

0 commit comments

Comments
 (0)