Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pc_bounds_to_geometry_wkb #229

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions lib/cunit/cu_pc_patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,12 @@ test_patch_wkb()
PCPOINTLIST *pl1;
PCPATCH_UNCOMPRESSED *pu1, *pu2;
PCPATCH *pa1, *pa2, *pa3, *pa4;
size_t z1, z2;
uint8_t *wkb1, *wkb2;
size_t z1, z2, z3;
uint8_t *wkb1, *wkb2, *wkb3;
char *hexwkb;

static char *hexresult_ndr = "01030000000100000005000000000000000000000000000000000000000000000000000000CDCCCCCCCC8C4B40EC51B81E852B4440CDCCCCCCCC8C4B40EC51B81E852B4440000000000000000000000000000000000000000000000000";
static char *hexresult_xdr = "00000000030000000100000005000000000000000000000000000000000000000000000000404B8CCCCCCCCCCD40442B851EB851EC404B8CCCCCCCCCCD40442B851EB851EC000000000000000000000000000000000000000000000000";

pl1 = pc_pointlist_make(npts);

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

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

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

wkb3 = pc_bounds_to_geometry_wkb(&pa1->bounds, simpleschema->srid, &z3);
hexwkb = pc_hexbytes_from_bytes(wkb3, z3);
if ( machine_endian() == PC_NDR )
{
CU_ASSERT_STRING_EQUAL(hexwkb, hexresult_ndr);
}
else
{
CU_ASSERT_STRING_EQUAL(hexwkb, hexresult_xdr);
}
pcfree(hexwkb);
pcfree(wkb3);

pc_pointlist_free(pl1);
pc_patch_free(pa1);
Expand All @@ -564,7 +581,6 @@ test_patch_wkb()
pc_patch_free(pa4);
pc_patch_free((PCPATCH*)pu1);
pc_patch_free((PCPATCH*)pu2);
pcfree(wkb1);
}


Expand Down
3 changes: 3 additions & 0 deletions lib/pc_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@ int pc_patch_compute_extent(PCPATCH *patch);
/** True/false if bounds intersect */
int pc_bounds_intersects(const PCBOUNDS *b1, const PCBOUNDS *b2);

/** Return the bounds as an OGC WKB geometry */
uint8_t *pc_bounds_to_geometry_wkb(const PCBOUNDS *bounds, uint32_t srid, size_t *wkbsize);

/** Returns OGC WKB of the bounding diagonal of XY bounds */
uint8_t* pc_bounding_diagonal_wkb_from_bounds(const PCBOUNDS *bounds, const PCSCHEMA *schema, size_t *wkbsize);

Expand Down
77 changes: 77 additions & 0 deletions lib/pc_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,83 @@ static uint32_t srid_mask = 0x20000000;
static uint32_t m_mask = 0x40000000;
static uint32_t z_mask = 0x80000000;

uint8_t *
pc_bounds_to_geometry_wkb(const PCBOUNDS *bounds, uint32_t srid, size_t *wkbsize)
{
/* Bounds! */
double xmin = bounds->xmin;
double ymin = bounds->ymin;
double xmax = bounds->xmax;
double ymax = bounds->ymax;

static uint32_t srid_mask = 0x20000000;
static uint32_t npoints_by_type[] = { 0, 1, 2, 5 };
/* WKB POINT, LINESTRING or POLYGON */
uint32_t wkbtype = 1 + (xmin != xmax) + (ymin != ymax);
uint32_t npoints = npoints_by_type[wkbtype];
uint8_t *wkb, *ptr;
/* endian + (type + nrings? + npoints?) + npoints dbl pt */
size_t size = 1 + wkbtype * 4 + npoints * 2 * 8;

if ( srid )
{
wkbtype |= srid_mask;
size += 4;
}

wkb = pcalloc(size);
ptr = wkb;

ptr = wkb_set_char(ptr, machine_endian()); /* Endian flag */

ptr = wkb_set_uint32(ptr, wkbtype); /* TYPE = POINT, LINESTRING or POLYGON */

if ( srid )
{
ptr = wkb_set_uint32(ptr, srid); /* SRID */
}

switch ( wkbtype )
{
case 3 /* POLYGON */ : ptr = wkb_set_uint32(ptr, 1); /* NRINGS */
case 2 /* LINESTRING */ : ptr = wkb_set_uint32(ptr, npoints); /* NPOINTS */
}

/* Point 0 */
ptr = wkb_set_double(ptr, xmin);
ptr = wkb_set_double(ptr, ymin);

if ( wkbtype == 2 ) // LINESTRING
{
/* Point 1 */
ptr = wkb_set_double(ptr, xmax);
ptr = wkb_set_double(ptr, ymax);
}
else if( wkbtype == 3 ) // POLYGON
{
/* Point 1 */
ptr = wkb_set_double(ptr, xmin);
ptr = wkb_set_double(ptr, ymax);

/* Point 2 */
ptr = wkb_set_double(ptr, xmax);
ptr = wkb_set_double(ptr, ymax);

/* Point 3 */
ptr = wkb_set_double(ptr, xmax);
ptr = wkb_set_double(ptr, ymin);

/* Point 4 */
ptr = wkb_set_double(ptr, xmin);
ptr = wkb_set_double(ptr, ymin);
}

if ( wkbsize )
*wkbsize = size;

return wkb;
}

uint8_t *
pc_bounding_diagonal_wkb_from_bounds(
const PCBOUNDS *bounds, const PCSCHEMA *schema, size_t *wkbsize)
Expand Down
4 changes: 2 additions & 2 deletions pgsql/expected/pointcloud.out
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ SELECT PC_AsText(pa) FROM pa_test;
SELECT PC_EnvelopeAsBinary(pa) from pa_test;
pc_envelopeasbinary
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
\x010300000001000000050000007b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f
\x01010000007b14ae47e17a943fb81e85eb51b89e3f
\x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f
\x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f
\x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f
Expand All @@ -346,7 +346,7 @@ SELECT PC_EnvelopeAsBinary(pa) from pa_test;
SELECT PC_Envelope(pa) from pa_test;
pc_envelope
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
\x010300000001000000050000007b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f
\x01010000007b14ae47e17a943fb81e85eb51b89e3f
\x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f
\x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f
\x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f
Expand Down
4 changes: 2 additions & 2 deletions pgsql/pc_inout.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,13 @@ Datum pcpatch_envelope_as_bytea(PG_FUNCTION_ARGS)
SERIALIZED_PATCH *serpatch = PG_GETHEADER_SERPATCH_P(0);
PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);

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

pfree(bytes);
pcfree(bytes);

PG_RETURN_BYTEA_P(wkb);
}
Expand Down
101 changes: 0 additions & 101 deletions pgsql/pc_pgsql.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,104 +847,3 @@ pc_patch_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schema)
pcerror("%s: unsupported compression type", __func__);
return NULL;
}


static uint8_t *
pc_patch_wkb_set_double(uint8_t *wkb, double d)
{
memcpy(wkb, &d, 8);
wkb += 8;
return wkb;
}

static uint8_t *
pc_patch_wkb_set_int32(uint8_t *wkb, uint32_t i)
{
memcpy(wkb, &i, 4);
wkb += 4;
return wkb;
}

static uint8_t *
pc_patch_wkb_set_char(uint8_t *wkb, char c)
{
memcpy(wkb, &c, 1);
wkb += 1;
return wkb;
}

/* 0 = xdr | big endian */
/* 1 = ndr | little endian */
static char
machine_endian(void)
{
static int check_int = 1; /* dont modify this!!! */
return *((char *) &check_int);
}

uint8_t *
pc_patch_to_geometry_wkb_envelope(const SERIALIZED_PATCH *pa, const PCSCHEMA *schema, size_t *wkbsize)
{
static uint32_t srid_mask = 0x20000000;
static uint32_t nrings = 1;
static uint32_t npoints = 5;
uint32_t wkbtype = 3; /* WKB POLYGON */
uint8_t *wkb, *ptr;
int has_srid = false;
size_t size = 1 + 4 + 4 + 4 + 2*npoints*8; /* endian + type + nrings + npoints + 5 dbl pts */

/* Bounds! */
double xmin = pa->bounds.xmin;
double ymin = pa->bounds.ymin;
double xmax = pa->bounds.xmax;
double ymax = pa->bounds.ymax;

/* Make sure they're slightly bigger than a point */
if ( xmin == xmax ) xmax += xmax * 0.0000001;
if ( ymin == ymax ) ymax += ymax * 0.0000001;

if ( schema->srid > 0 )
{
has_srid = true;
wkbtype |= srid_mask;
size += 4;
}

wkb = palloc(size);
ptr = wkb;

ptr = pc_patch_wkb_set_char(ptr, machine_endian()); /* Endian flag */

ptr = pc_patch_wkb_set_int32(ptr, wkbtype); /* TYPE = Polygon */

if ( has_srid )
{
ptr = pc_patch_wkb_set_int32(ptr, schema->srid); /* SRID */
}

ptr = pc_patch_wkb_set_int32(ptr, nrings); /* NRINGS = 1 */
ptr = pc_patch_wkb_set_int32(ptr, npoints); /* NPOINTS = 5 */

/* Point 0 */
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmin);
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymin);

/* Point 1 */
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmin);
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymax);

/* Point 2 */
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmax);
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymax);

/* Point 3 */
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmax);
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymin);

/* Point 4 */
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.xmin);
ptr = pc_patch_wkb_set_double(ptr, pa->bounds.ymin);

if ( wkbsize ) *wkbsize = size;
return wkb;
}