mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
Merge pull request #220 from elemoine/pc_patch_from_float_array
Add PC_MakePatch(pcid integer, values float8[])
This commit is contained in:
commit
ec720f21dd
12
README.md
12
README.md
@ -251,6 +251,18 @@ Now that you have created two tables, you'll see entries for them in the `pointc
|
||||
> INSERT INTO patches (pa)
|
||||
> SELECT PC_Patch(pt) FROM points GROUP BY id/10;
|
||||
|
||||
|
||||
**PC_MakePatch(pcid integer, vals float8[])** returns **pcpatch**
|
||||
|
||||
> Given a valid `pcid` schema number and an array of doubles that matches the schema, construct a new `pcpatch`.
|
||||
> Array size must be a multiple of the number of dimensions.
|
||||
>
|
||||
> SELECT PC_AsText(PC_MakePatch(1, ARRAY[-126.99,45.01,1,0, -126.98,45.02,2,0, -126.97,45.03,3,0]));
|
||||
|
||||
> {"pcid":1,"pts":[
|
||||
> [-126.99,45.01,1,0],[-126.98,45.02,2,0],[-126.97,45.03,3,0]
|
||||
> ]}
|
||||
|
||||
**PC_NumPoints(p pcpatch)** returns **integer**
|
||||
|
||||
> Return the number of points in this patch.
|
||||
|
||||
@ -187,8 +187,8 @@ test_patch_hex_out()
|
||||
double d0[4] = { 0.02, 0.03, 0.05, 6 };
|
||||
double d1[4] = { 0.02, 0.03, 0.05, 8 };
|
||||
|
||||
PCPOINT *pt0 = pc_point_from_double_array(simpleschema, d0, 4);
|
||||
PCPOINT *pt1 = pc_point_from_double_array(simpleschema, d1, 4);
|
||||
PCPOINT *pt0 = pc_point_from_double_array(simpleschema, d0, 0, 4);
|
||||
PCPOINT *pt1 = pc_point_from_double_array(simpleschema, d1, 0, 4);
|
||||
|
||||
PCPATCH_UNCOMPRESSED *pa;
|
||||
uint8_t *wkb;
|
||||
|
||||
@ -322,8 +322,8 @@ PCPOINT* pc_point_make(const PCSCHEMA *s);
|
||||
/** Create a new readonly PCPOINT on top of a data buffer */
|
||||
PCPOINT* pc_point_from_data(const PCSCHEMA *s, const uint8_t *data);
|
||||
|
||||
/** Create a new read/write PCPOINT from a double array */
|
||||
PCPOINT* pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems);
|
||||
/** Create a new read/write PCPOINT from a double array with an offset */
|
||||
PCPOINT* pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t offset, uint32_t stride);
|
||||
|
||||
/**
|
||||
* Return an allocated double array of doubles representing point values
|
||||
|
||||
@ -217,8 +217,9 @@ pc_point_to_string(const PCPOINT *pt)
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
PCPOINT *
|
||||
pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems)
|
||||
pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t offset, uint32_t stride)
|
||||
{
|
||||
int i;
|
||||
PCPOINT *pt;
|
||||
@ -229,9 +230,9 @@ pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( s->ndims != nelems )
|
||||
if ( stride != s->ndims )
|
||||
{
|
||||
pcerror("number of elements in schema and array differ in pc_point_from_double_array");
|
||||
pcerror("number of elements in schema and array do not match in pc_point_from_double_array");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -241,9 +242,9 @@ pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems)
|
||||
pt->schema = s;
|
||||
pt->readonly = PC_FALSE;
|
||||
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
for ( i = 0; i < stride; i++ )
|
||||
{
|
||||
if ( PC_FAILURE == pc_point_set_double_by_index(pt, i, array[i]) )
|
||||
if ( PC_FAILURE == pc_point_set_double_by_index(pt, i, array[offset + i]) )
|
||||
{
|
||||
pcerror("failed to write value into dimension %d in pc_point_from_double_array", i);
|
||||
return NULL;
|
||||
|
||||
@ -728,4 +728,11 @@ FROM ( SELECT PC_Patch(PC_MakePoint(1, ARRAY[-1,0,4862413,1])) p ) foo;
|
||||
{"pcid":10,"pts":[[-1,0,1,1,1,1,1]]} | "none"
|
||||
(1 row)
|
||||
|
||||
-- test PC_Patch from float8 array
|
||||
SELECT pc_astext(PC_MakePatch(1, ARRAY[-1,0,5,1, -1,0,6,1, -1,0,7,1]));
|
||||
pc_astext
|
||||
-----------------------------------------------------
|
||||
{"pcid":1,"pts":[[-1,0,5,1],[-1,0,6,1],[-1,0,7,1]]}
|
||||
(1 row)
|
||||
|
||||
TRUNCATE pointcloud_formats;
|
||||
|
||||
@ -23,6 +23,7 @@ void pc_cstring_array_free(const char **array, int nelems);
|
||||
Datum pcpoint_get_value(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_get_values(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_from_float_array(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_from_pcpatch_array(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_uncompress(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_compress(PG_FUNCTION_ARGS);
|
||||
@ -329,6 +330,60 @@ Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_POINTER(serpa);
|
||||
}
|
||||
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpatch_from_float_array);
|
||||
Datum pcpatch_from_float_array(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int i, ndims, nelems, npoints;
|
||||
float8 *vals;
|
||||
PCPATCH *pa;
|
||||
PCPOINTLIST *pl;
|
||||
SERIALIZED_PATCH *serpa;
|
||||
uint32 pcid = PG_GETARG_INT32(0);
|
||||
ArrayType *arrptr = PG_GETARG_ARRAYTYPE_P(1);
|
||||
PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
|
||||
|
||||
if ( ! schema )
|
||||
elog(ERROR, "unable to load schema for pcid = %d", pcid);
|
||||
|
||||
if ( ARR_ELEMTYPE(arrptr) != FLOAT8OID )
|
||||
elog(ERROR, "array must be of float8[]");
|
||||
|
||||
if ( ARR_NDIM(arrptr) != 1 )
|
||||
elog(ERROR, "float8[] must have one dimension");
|
||||
|
||||
if ( ARR_HASNULL(arrptr) )
|
||||
elog(ERROR, "float8[] must not have null elements");
|
||||
|
||||
ndims = schema->ndims;
|
||||
nelems = ARR_DIMS(arrptr)[0];
|
||||
|
||||
if ( nelems % ndims != 0 ) {
|
||||
elog(ERROR, "array dimensions do not match schema dimensions of pcid = %d", pcid);
|
||||
}
|
||||
|
||||
npoints = nelems / ndims;
|
||||
|
||||
vals = (float8*) ARR_DATA_PTR(arrptr);
|
||||
pl = pc_pointlist_make(nelems);
|
||||
|
||||
for ( i = 0; i < npoints; ++i ) {
|
||||
|
||||
PCPOINT* pt = pc_point_from_double_array(schema, vals, i * ndims, ndims);
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
}
|
||||
|
||||
pa = pc_patch_from_pointlist(pl);
|
||||
pc_pointlist_free(pl);
|
||||
if ( ! pa )
|
||||
PG_RETURN_NULL();
|
||||
|
||||
serpa = pc_patch_serialize(pa, NULL);
|
||||
|
||||
pc_patch_free(pa);
|
||||
PG_RETURN_POINTER(serpa);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ArrayBuildState *s;
|
||||
|
||||
@ -224,7 +224,7 @@ Datum pcpoint_from_double_array(PG_FUNCTION_ARGS)
|
||||
elog(ERROR, "array dimensions do not match schema dimensions of pcid = %d", pcid);
|
||||
|
||||
vals = (float8*) ARR_DATA_PTR(arrptr);
|
||||
pt = pc_point_from_double_array(schema, vals, nelems);
|
||||
pt = pc_point_from_double_array(schema, vals, 0, nelems);
|
||||
|
||||
serpt = pc_point_serialize(pt);
|
||||
pc_point_free(pt);
|
||||
|
||||
@ -229,6 +229,11 @@ CREATE OR REPLACE FUNCTION PC_AsBinary(p pcpoint)
|
||||
-- PCPATCH
|
||||
-------------------------------------------------------------------
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_MakePatch(pcid integer, vals float8[])
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_from_float_array'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION pcpatch_in(cstring)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_in'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
@ -451,4 +451,9 @@ SELECT
|
||||
PC_AsText(PC_Transform(p, 10, 1.0)) t, PC_Summary(PC_Transform(p, 10, 1.0))::json->'compr' c
|
||||
FROM ( SELECT PC_Patch(PC_MakePoint(1, ARRAY[-1,0,4862413,1])) p ) foo;
|
||||
|
||||
|
||||
-- test PC_Patch from float8 array
|
||||
SELECT pc_astext(PC_MakePatch(1, ARRAY[-1,0,5,1, -1,0,6,1, -1,0,7,1]));
|
||||
|
||||
|
||||
TRUNCATE pointcloud_formats;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user