mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
Add PC_Explode for patches
This commit is contained in:
parent
17e0134305
commit
070609ef87
@ -96,5 +96,13 @@ SELECT PC_Envelope(pa) from pa_test;
|
||||
\x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f
|
||||
(2 rows)
|
||||
|
||||
SELECT PC_AsText(PC_Explode(PC_Patch(pt))) FROM pt_test;
|
||||
pc_astext
|
||||
-----------------------------
|
||||
( 1 : 0.01, 0.02, 0.03, 4 )
|
||||
( 1 : 0.02, 0.03, 0.03, 5 )
|
||||
( 1 : 0.03, 0.04, 0.03, 6 )
|
||||
(3 rows)
|
||||
|
||||
--DROP TABLE pt_test;
|
||||
--DROP TABLE pa_test;
|
||||
|
||||
@ -22,6 +22,9 @@ Datum pcpoint_agg_transfn(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_abs_in(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_abs_out(PG_FUNCTION_ARGS);
|
||||
|
||||
/* Deaggregation functions */
|
||||
Datum pcpatch_unnest(PG_FUNCTION_ARGS);
|
||||
|
||||
/**
|
||||
* Read a named dimension from a PCPOINT
|
||||
* PC_Get(point pcpoint, dimname text) returns Numeric
|
||||
@ -49,6 +52,20 @@ Datum pcpoint_get_value(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_DATUM(DirectFunctionCall1(float8_numeric, Float8GetDatum(double_result)));
|
||||
}
|
||||
|
||||
static bool
|
||||
array_get_isnull(const bits8 *nullbitmap, int offset)
|
||||
{
|
||||
if (nullbitmap == NULL)
|
||||
{
|
||||
return false; /* assume not null */
|
||||
}
|
||||
if (nullbitmap[offset / 8] & (1 << (offset % 8)))
|
||||
{
|
||||
return false; /* not null */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpatch_from_pcpoint_array);
|
||||
Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS)
|
||||
{
|
||||
@ -88,7 +105,7 @@ Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS)
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
/* Only work on non-NULL entries in the array */
|
||||
if ( (bitmap && (*bitmap & bitmask)) || !bitmap )
|
||||
if ( ! array_get_isnull(bitmap, i) )
|
||||
{
|
||||
SERIALIZED_POINT *serpt = (SERIALIZED_POINT *)(ARR_DATA_PTR(array)+offset);
|
||||
PCPOINT *pt;
|
||||
@ -113,16 +130,6 @@ Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS)
|
||||
offset += INTALIGN(VARSIZE(serpt));
|
||||
}
|
||||
|
||||
/* Advance NULL bitmap */
|
||||
if (bitmap)
|
||||
{
|
||||
bitmask <<= 1;
|
||||
if (bitmask == 0x100)
|
||||
{
|
||||
bitmap++;
|
||||
bitmask = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pl->npoints == 0 )
|
||||
@ -254,4 +261,75 @@ Datum pcpoint_agg_final_pcpatch(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_DATUM(result_final);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpatch_unnest);
|
||||
Datum pcpatch_unnest(PG_FUNCTION_ARGS)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
int nextelem;
|
||||
int numelems;
|
||||
PCPOINTLIST *pointlist;
|
||||
} pcpatch_unnest_fctx;
|
||||
|
||||
FuncCallContext *funcctx;
|
||||
pcpatch_unnest_fctx *fctx;
|
||||
MemoryContext oldcontext;
|
||||
|
||||
/* stuff done only on the first call of the function */
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
PCPATCH *patch;
|
||||
SERIALIZED_PATCH *serpatch;
|
||||
|
||||
/* create a function context for cross-call persistence */
|
||||
funcctx = SRF_FIRSTCALL_INIT();
|
||||
|
||||
/*
|
||||
* switch to memory context appropriate for multiple function calls
|
||||
*/
|
||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||
|
||||
/*
|
||||
* Get the patch value and detoast if needed. We can't do this
|
||||
* earlier because if we have to detoast, we want the detoasted copy
|
||||
* to be in multi_call_memory_ctx, so it will go away when we're done
|
||||
* and not before. (If no detoast happens, we assume the originally
|
||||
* passed array will stick around till then.)
|
||||
*/
|
||||
serpatch = PG_GETARG_SERPATCH_P(0);
|
||||
patch = pc_patch_deserialize(serpatch);
|
||||
|
||||
/* allocate memory for user context */
|
||||
fctx = (pcpatch_unnest_fctx *) palloc(sizeof(pcpatch_unnest_fctx));
|
||||
|
||||
/* initialize state */
|
||||
fctx->nextelem = 0;
|
||||
fctx->numelems = patch->npoints;
|
||||
fctx->pointlist = pc_patch_to_points(patch);
|
||||
|
||||
/* save user context, switch back to function context */
|
||||
funcctx->user_fctx = fctx;
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
|
||||
/* stuff done on every call of the function */
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
fctx = funcctx->user_fctx;
|
||||
|
||||
if (fctx->nextelem < fctx->numelems)
|
||||
{
|
||||
Datum elem;
|
||||
PCPOINT *pt = fctx->pointlist->points[fctx->nextelem];
|
||||
SERIALIZED_POINT *serpt = pc_point_serialize(pt);
|
||||
fctx->nextelem++;
|
||||
elem = PointerGetDatum(serpt);
|
||||
SRF_RETURN_NEXT(funcctx, elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* do when there is no more left */
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ CREATE OR REPLACE FUNCTION PC_SchemaIsValid(xml text)
|
||||
|
||||
-- Metadata table describing contents of pcpoints
|
||||
CREATE TABLE pointcloud_formats (
|
||||
pcid INTEGER PRIMARY KEY,
|
||||
pcid INTEGER PRIMARY KEY CHECK (pcid > 0),
|
||||
srid INTEGER, -- REFERENCES spatial_ref_sys(srid)
|
||||
schema TEXT
|
||||
CHECK ( PC_SchemaIsValid(schema) )
|
||||
@ -157,15 +157,8 @@ CREATE AGGREGATE PC_Point_Agg (
|
||||
FINALFUNC = pcpoint_agg_final_array
|
||||
);
|
||||
|
||||
|
||||
-- CREATE FUNCTION pcpoint_array_from_pcpatch(pcpatch)
|
||||
-- RETURNS pcpoint[] AS 'MODULE_PATHNAME', 'pcpoint_array_from_pcpatch'
|
||||
-- LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
CREATE FUNCTION PC_Explode(pcpatch)
|
||||
RETURNS setof pcpoint AS 'MODULE_PATHNAME', 'pcpatch_unnest'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- The enumeration function
|
||||
-- returns each element in a one dimensional integer array
|
||||
-- as a row.
|
||||
-- CREATE FUNCTION int_array_enum(int4[])
|
||||
-- RETURNS setof integer
|
||||
-- AS 'array_unnest'
|
||||
-- LANGUAGE INTERNAL IMMUTABLE STRICT;
|
||||
|
||||
|
||||
@ -72,5 +72,7 @@ INSERT INTO pa_test (pa) VALUES ('0000000001000000000000000200000006000000070000
|
||||
SELECT PC_AsText(pa) FROM pa_test;
|
||||
SELECT PC_Envelope(pa) from pa_test;
|
||||
|
||||
SELECT PC_AsText(PC_Explode(PC_Patch(pt))) FROM pt_test;
|
||||
|
||||
--DROP TABLE pt_test;
|
||||
--DROP TABLE pa_test;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user