Merge pull request #220 from elemoine/pc_patch_from_float_array

Add PC_MakePatch(pcid integer, values float8[])
This commit is contained in:
Éric Lemoine 2018-06-14 19:07:09 +02:00 committed by GitHub
commit ec720f21dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 95 additions and 10 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;