diff --git a/README.md b/README.md index 39c2aeb..49d9a6c 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,14 @@ Now that you have created two tables, you'll see entries for them in the `pointc > > 4 +**PC_Get(pt pcpoint)** returns **float8[]** (from 2.0) + +> Return values of all dimensions in an array. +> +> SELECT PC_Get('010100000064CEFFFF94110000703000000400'::pcpoint); +> +> {-127,45,124,4} + **PC_Patch(pts pcpoint[])** returns **pcpatch** > Aggregate function that collects a result set of `pcpoint` values into a `pcpatch`. diff --git a/pgsql/expected/pointcloud.out b/pgsql/expected/pointcloud.out index 656f2c4..333cc34 100644 --- a/pgsql/expected/pointcloud.out +++ b/pgsql/expected/pointcloud.out @@ -126,6 +126,14 @@ SELECT Sum(PC_Get(pt, 'y')) FROM pt_test; 0.09 (1 row) +SELECT PC_Get(pt) FROM pt_test; + pc_get +-------------------- + {0.01,0.02,0.03,4} + {0.02,0.03,0.03,5} + {0.03,0.04,0.03,6} +(3 rows) + SELECT PC_AsText(pt) FROM pt_test; pc_astext ------------------------------------ diff --git a/pgsql/pc_access.c b/pgsql/pc_access.c index 99ca6b0..e38ca3a 100644 --- a/pgsql/pc_access.c +++ b/pgsql/pc_access.c @@ -15,6 +15,7 @@ /* General SQL functions */ 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_pcpatch_array(PG_FUNCTION_ARGS); Datum pcpatch_uncompress(PG_FUNCTION_ARGS); @@ -71,6 +72,39 @@ Datum pcpoint_get_value(PG_FUNCTION_ARGS) PG_RETURN_DATUM(DirectFunctionCall1(float8_numeric, Float8GetDatum(double_result))); } +/** +* Returns all the values of a point as a double precision array +* PC_Get(point pcpoint) returns Float8[] +*/ +PG_FUNCTION_INFO_V1(pcpoint_get_values); +Datum pcpoint_get_values(PG_FUNCTION_ARGS) +{ + SERIALIZED_POINT *serpt; + ArrayType *result; + PCSCHEMA *schema; + PCPOINT *pt; + Datum *elems; + int i; + double *vals; + + serpt = PG_GETARG_SERPOINT_P(0); + schema = pc_schema_from_pcid(serpt->pcid, fcinfo); + pt = pc_point_deserialize(serpt, schema); + if ( ! pt ) PG_RETURN_NULL(); + + elems = (Datum * )palloc(schema->ndims * sizeof(Datum) ); + vals = pc_point_to_double_array(pt); + i = schema->ndims; + while (i--) elems[i] = Float8GetDatum(vals[i]); + pcfree(vals); + result = construct_array(elems, schema->ndims, FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, 'd'); + + pc_point_free(pt); + PG_RETURN_ARRAYTYPE_P(result); +} + + static inline bool array_get_isnull(const bits8 *nullbitmap, int offset) { diff --git a/pgsql/pointcloud--1.0.sql b/pgsql/pointcloud--1.0.sql index 329f0c8..e34363c 100644 --- a/pgsql/pointcloud--1.0.sql +++ b/pgsql/pointcloud--1.0.sql @@ -81,6 +81,11 @@ CREATE OR REPLACE FUNCTION PC_Get(pt pcpoint, dimname text) RETURNS numeric AS 'MODULE_PATHNAME', 'pcpoint_get_value' LANGUAGE 'c' IMMUTABLE STRICT; +-- Availability: 2.0 +CREATE OR REPLACE FUNCTION PC_Get(pt pcpoint) + RETURNS float8[] AS 'MODULE_PATHNAME', 'pcpoint_get_values' + LANGUAGE 'c' IMMUTABLE STRICT; + CREATE OR REPLACE FUNCTION PC_MakePoint(pcid integer, vals float8[]) RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpoint_from_double_array' LANGUAGE 'c' IMMUTABLE STRICT; diff --git a/pgsql/sql/pointcloud.sql b/pgsql/sql/pointcloud.sql index 8f7eee3..89e7db8 100644 --- a/pgsql/sql/pointcloud.sql +++ b/pgsql/sql/pointcloud.sql @@ -109,6 +109,8 @@ INSERT INTO pt_test (pt) VALUES ('00000000010000000300000004000000030006'); SELECT PC_Get(pt, 'Intensity') FROM pt_test; SELECT Sum(PC_Get(pt, 'y')) FROM pt_test; +SELECT PC_Get(pt) FROM pt_test; + SELECT PC_AsText(pt) FROM pt_test; SELECT PC_AsText(PC_Patch(pt)) FROM pt_test;