Skip to content

Commit ec720f2

Browse files
authored
Merge pull request #220 from elemoine/pc_patch_from_float_array
Add PC_MakePatch(pcid integer, values float8[])
2 parents 22d8aa4 + 4f738eb commit ec720f2

9 files changed

Lines changed: 95 additions & 10 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,18 @@ Now that you have created two tables, you'll see entries for them in the `pointc
251251
> INSERT INTO patches (pa)
252252
> SELECT PC_Patch(pt) FROM points GROUP BY id/10;
253253
254+
255+
**PC_MakePatch(pcid integer, vals float8[])** returns **pcpatch**
256+
257+
> Given a valid `pcid` schema number and an array of doubles that matches the schema, construct a new `pcpatch`.
258+
> Array size must be a multiple of the number of dimensions.
259+
>
260+
> 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]));
261+
262+
> {"pcid":1,"pts":[
263+
> [-126.99,45.01,1,0],[-126.98,45.02,2,0],[-126.97,45.03,3,0]
264+
> ]}
265+
254266
**PC_NumPoints(p pcpatch)** returns **integer**
255267

256268
> Return the number of points in this patch.

lib/cunit/cu_pc_patch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ test_patch_hex_out()
187187
double d0[4] = { 0.02, 0.03, 0.05, 6 };
188188
double d1[4] = { 0.02, 0.03, 0.05, 8 };
189189

190-
PCPOINT *pt0 = pc_point_from_double_array(simpleschema, d0, 4);
191-
PCPOINT *pt1 = pc_point_from_double_array(simpleschema, d1, 4);
190+
PCPOINT *pt0 = pc_point_from_double_array(simpleschema, d0, 0, 4);
191+
PCPOINT *pt1 = pc_point_from_double_array(simpleschema, d1, 0, 4);
192192

193193
PCPATCH_UNCOMPRESSED *pa;
194194
uint8_t *wkb;

lib/pc_api.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ PCPOINT* pc_point_make(const PCSCHEMA *s);
322322
/** Create a new readonly PCPOINT on top of a data buffer */
323323
PCPOINT* pc_point_from_data(const PCSCHEMA *s, const uint8_t *data);
324324

325-
/** Create a new read/write PCPOINT from a double array */
326-
PCPOINT* pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems);
325+
/** Create a new read/write PCPOINT from a double array with an offset */
326+
PCPOINT* pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t offset, uint32_t stride);
327327

328328
/**
329329
* Return an allocated double array of doubles representing point values

lib/pc_point.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,9 @@ pc_point_to_string(const PCPOINT *pt)
217217
return str;
218218
}
219219

220+
220221
PCPOINT *
221-
pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems)
222+
pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t offset, uint32_t stride)
222223
{
223224
int i;
224225
PCPOINT *pt;
@@ -229,9 +230,9 @@ pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems)
229230
return NULL;
230231
}
231232

232-
if ( s->ndims != nelems )
233+
if ( stride != s->ndims )
233234
{
234-
pcerror("number of elements in schema and array differ in pc_point_from_double_array");
235+
pcerror("number of elements in schema and array do not match in pc_point_from_double_array");
235236
return NULL;
236237
}
237238

@@ -241,9 +242,9 @@ pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems)
241242
pt->schema = s;
242243
pt->readonly = PC_FALSE;
243244

244-
for ( i = 0; i < nelems; i++ )
245+
for ( i = 0; i < stride; i++ )
245246
{
246-
if ( PC_FAILURE == pc_point_set_double_by_index(pt, i, array[i]) )
247+
if ( PC_FAILURE == pc_point_set_double_by_index(pt, i, array[offset + i]) )
247248
{
248249
pcerror("failed to write value into dimension %d in pc_point_from_double_array", i);
249250
return NULL;

pgsql/expected/pointcloud.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,4 +728,11 @@ FROM ( SELECT PC_Patch(PC_MakePoint(1, ARRAY[-1,0,4862413,1])) p ) foo;
728728
{"pcid":10,"pts":[[-1,0,1,1,1,1,1]]} | "none"
729729
(1 row)
730730

731+
-- test PC_Patch from float8 array
732+
SELECT pc_astext(PC_MakePatch(1, ARRAY[-1,0,5,1, -1,0,6,1, -1,0,7,1]));
733+
pc_astext
734+
-----------------------------------------------------
735+
{"pcid":1,"pts":[[-1,0,5,1],[-1,0,6,1],[-1,0,7,1]]}
736+
(1 row)
737+
731738
TRUNCATE pointcloud_formats;

pgsql/pc_access.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void pc_cstring_array_free(const char **array, int nelems);
2323
Datum pcpoint_get_value(PG_FUNCTION_ARGS);
2424
Datum pcpoint_get_values(PG_FUNCTION_ARGS);
2525
Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS);
26+
Datum pcpatch_from_float_array(PG_FUNCTION_ARGS);
2627
Datum pcpatch_from_pcpatch_array(PG_FUNCTION_ARGS);
2728
Datum pcpatch_uncompress(PG_FUNCTION_ARGS);
2829
Datum pcpatch_compress(PG_FUNCTION_ARGS);
@@ -329,6 +330,60 @@ Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS)
329330
PG_RETURN_POINTER(serpa);
330331
}
331332

333+
334+
PG_FUNCTION_INFO_V1(pcpatch_from_float_array);
335+
Datum pcpatch_from_float_array(PG_FUNCTION_ARGS)
336+
{
337+
int i, ndims, nelems, npoints;
338+
float8 *vals;
339+
PCPATCH *pa;
340+
PCPOINTLIST *pl;
341+
SERIALIZED_PATCH *serpa;
342+
uint32 pcid = PG_GETARG_INT32(0);
343+
ArrayType *arrptr = PG_GETARG_ARRAYTYPE_P(1);
344+
PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
345+
346+
if ( ! schema )
347+
elog(ERROR, "unable to load schema for pcid = %d", pcid);
348+
349+
if ( ARR_ELEMTYPE(arrptr) != FLOAT8OID )
350+
elog(ERROR, "array must be of float8[]");
351+
352+
if ( ARR_NDIM(arrptr) != 1 )
353+
elog(ERROR, "float8[] must have one dimension");
354+
355+
if ( ARR_HASNULL(arrptr) )
356+
elog(ERROR, "float8[] must not have null elements");
357+
358+
ndims = schema->ndims;
359+
nelems = ARR_DIMS(arrptr)[0];
360+
361+
if ( nelems % ndims != 0 ) {
362+
elog(ERROR, "array dimensions do not match schema dimensions of pcid = %d", pcid);
363+
}
364+
365+
npoints = nelems / ndims;
366+
367+
vals = (float8*) ARR_DATA_PTR(arrptr);
368+
pl = pc_pointlist_make(nelems);
369+
370+
for ( i = 0; i < npoints; ++i ) {
371+
372+
PCPOINT* pt = pc_point_from_double_array(schema, vals, i * ndims, ndims);
373+
pc_pointlist_add_point(pl, pt);
374+
}
375+
376+
pa = pc_patch_from_pointlist(pl);
377+
pc_pointlist_free(pl);
378+
if ( ! pa )
379+
PG_RETURN_NULL();
380+
381+
serpa = pc_patch_serialize(pa, NULL);
382+
383+
pc_patch_free(pa);
384+
PG_RETURN_POINTER(serpa);
385+
}
386+
332387
typedef struct
333388
{
334389
ArrayBuildState *s;

pgsql/pc_inout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ Datum pcpoint_from_double_array(PG_FUNCTION_ARGS)
224224
elog(ERROR, "array dimensions do not match schema dimensions of pcid = %d", pcid);
225225

226226
vals = (float8*) ARR_DATA_PTR(arrptr);
227-
pt = pc_point_from_double_array(schema, vals, nelems);
227+
pt = pc_point_from_double_array(schema, vals, 0, nelems);
228228

229229
serpt = pc_point_serialize(pt);
230230
pc_point_free(pt);

pgsql/pointcloud.sql.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ CREATE OR REPLACE FUNCTION PC_AsBinary(p pcpoint)
229229
-- PCPATCH
230230
-------------------------------------------------------------------
231231

232+
233+
CREATE OR REPLACE FUNCTION PC_MakePatch(pcid integer, vals float8[])
234+
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_from_float_array'
235+
LANGUAGE 'c' IMMUTABLE STRICT;
236+
232237
CREATE OR REPLACE FUNCTION pcpatch_in(cstring)
233238
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_in'
234239
LANGUAGE 'c' IMMUTABLE STRICT;

pgsql/sql/pointcloud.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,9 @@ SELECT
451451
PC_AsText(PC_Transform(p, 10, 1.0)) t, PC_Summary(PC_Transform(p, 10, 1.0))::json->'compr' c
452452
FROM ( SELECT PC_Patch(PC_MakePoint(1, ARRAY[-1,0,4862413,1])) p ) foo;
453453

454+
455+
-- test PC_Patch from float8 array
456+
SELECT pc_astext(PC_MakePatch(1, ARRAY[-1,0,5,1, -1,0,6,1, -1,0,7,1]));
457+
458+
454459
TRUNCATE pointcloud_formats;

0 commit comments

Comments
 (0)