diff --git a/README.md b/README.md index b96f961..f35ea19 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,8 @@ Now that you have created two tables, you'll see entries for them in the `pointc ## Functions ## +### PcPoint Functions + **PC_MakePoint(pcid integer, vals float8[])** returns **pcpoint** > Given a valid `pcid` schema number and an array of doubles that matches the schema, construct a new `pcpoint`. @@ -238,14 +240,6 @@ Now that you have created two tables, you'll see entries for them in the `pointc > > 1 -**PC_AsBinary(p pcpoint)** returns **bytea** - -> Return the OGC "well-known binary" format for the point. -> -> SELECT PC_AsBinary('010100000064CEFFFF94110000703000000400'::pcpoint); -> -> \x01010000800000000000c05fc000000000008046400000000000005f40 - **PC_Get(pt pcpoint, dimname text)** returns **numeric** > Return the numeric value of the named dimension. The dimension name @@ -263,6 +257,8 @@ Now that you have created two tables, you'll see entries for them in the `pointc > > {-127,45,124,4} +### PcPatch Functions + **PC_Patch(pts pcpoint[])** returns **pcpatch** > Aggregate function that collects a result set of `pcpoint` values into a `pcpatch`. @@ -285,19 +281,7 @@ Now that you have created two tables, you'll see entries for them in the `pointc > SELECT PC_PCId(pa) FROM patches LIMIT 1; > > 1 - -**PC_Envelope(p pcpatch)** returns **bytea** -> Return the OGC "well-known binary" format for *bounds* of the patch. -> Useful for performing intersection tests with geometries. -> -> SELECT PC_Envelope(pa) FROM patches LIMIT 1; -> -> \x0103000000010000000500000090c2f5285cbf5fc0e17a -> 14ae4781464090c2f5285cbf5fc0ec51b81e858b46400ad7 -> a3703dba5fc0ec51b81e858b46400ad7a3703dba5fc0e17a -> 14ae4781464090c2f5285cbf5fc0e17a14ae47814640 - **PC_AsText(p pcpatch)** returns **text** > Return a JSON version of the data in that patch. @@ -402,7 +386,7 @@ Now that you have created two tables, you'll see entries for them in the `pointc > > 45.5 -**PC_PatchAvg(p pcpatch,)** returns **pcpoint** (from 1.1.0) +**PC_PatchAvg(p pcpatch)** returns **pcpoint** (from 1.1.0) > Returns a PcPoint with the *average* values of each dimension in the patch. > @@ -486,6 +470,28 @@ Now that you have created two tables, you'll see entries for them in the `pointc > Returns a patch containing *n* points. These points are selected from the *start*-th point with 1-based indexing. +### OGC "well-known binary" Functions + +**PC_AsBinary(p pcpoint)** returns **bytea** + +> Return the OGC "well-known binary" format for the point. +> +> SELECT PC_AsBinary('010100000064CEFFFF94110000703000000400'::pcpoint); +> +> \x01010000800000000000c05fc000000000008046400000000000005f40 + +**PC_EnvelopeAsBinary(p pcpatch)** returns **bytea** + +> Return the OGC "well-known binary" format for the 2D *bounds* of the patch. +> Useful for performing 2D intersection tests with geometries. +> +> SELECT PC_EnvelopeAsBinary(pa) FROM patches LIMIT 1; +> +> \x0103000000010000000500000090c2f5285cbf5fc0e17a +> 14ae4781464090c2f5285cbf5fc0ec51b81e858b46400ad7 +> a3703dba5fc0ec51b81e858b46400ad7a3703dba5fc0e17a +> 14ae4781464090c2f5285cbf5fc0e17a14ae47814640 + ## PostGIS Integration ## The `pointcloud_postgis` extension adds functions that allow you to use PostgreSQL Pointcloud with PostGIS, converting PcPoint and PcPatch to Geometry and doing spatial filtering on point cloud data. The `pointcloud_postgis` extension depends on both the `postgis` and `pointcloud` extensions, so they must be installed first: @@ -525,13 +531,23 @@ The `pointcloud_postgis` extension adds functions that allow you to use PostgreS **Geometry(pcpoint)** returns **geometry**
**pcpoint::geometry** returns **geometry** -> Cast PcPoint to the PostGIS geometry equivalent, placing the x/y/z of the -> PcPoint into the x/y/z of the PostGIS point. +> Casts PcPoint to the PostGIS geometry equivalent, placing the x/y/z/m of the +> PcPoint into the x/y/z/m of the PostGIS point. > > SELECT ST_AsText(PC_MakePoint(1, ARRAY[-127, 45, 124.0, 4.0])::geometry); > > POINT Z (-127 45 124) +**PC_Envelope(pcpatch)** returns **geometry** + +> Returns the 2D *bounds* of the patch as a PostGIS Polygon 2D. +> Useful for performing 2D intersection tests with PostGIS geometries. +> +> SELECT ST_AsText(PC_Envelope(pa)) FROM patches LIMIT 1; +> +> POLYGON((-126.99 45.01,-126.99 45.09,-126.91 45.09,-126.91 45.01,-126.99 45.01)) + + ## Compressions ## One of the issues with LIDAR data is that there is a lot of it. To deal with data volumes, PostgreSQL Pointcloud allows schemas to declare their preferred compression method in the `` block of the schema document. In the example schema, we declared our compression as follows: diff --git a/pgsql/expected/pointcloud.out b/pgsql/expected/pointcloud.out index 57f8b0a..3b5acfe 100644 --- a/pgsql/expected/pointcloud.out +++ b/pgsql/expected/pointcloud.out @@ -291,8 +291,8 @@ SELECT PC_AsText(pa) FROM pa_test; {"pcid":1,"pts":[[0.06,0.07,0.05,6],[0.09,0.1,0.05,10]]} (4 rows) -SELECT PC_Envelope(pa) from pa_test; - pc_envelope +SELECT PC_EnvelopeAsBinary(pa) from pa_test; + pc_envelopeasbinary ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \x010300000001000000050000007b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f7b14ae47e17a943fb81e85eb51b89e3f \x01030000000100000005000000b81e85eb51b8ae3fec51b81e85ebb13fb81e85eb51b8ae3f9a9999999999b93f0ad7a3703d0ab73f9a9999999999b93f0ad7a3703d0ab73fec51b81e85ebb13fb81e85eb51b8ae3fec51b81e85ebb13f diff --git a/pgsql/pc_inout.c b/pgsql/pc_inout.c index 674717b..fd734cc 100644 --- a/pgsql/pc_inout.c +++ b/pgsql/pc_inout.c @@ -292,8 +292,8 @@ Datum pcpoint_as_bytea(PG_FUNCTION_ARGS) PG_RETURN_BYTEA_P(wkb); } -PG_FUNCTION_INFO_V1(pcpatch_bytea_envelope); -Datum pcpatch_bytea_envelope(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(pcpatch_envelope_as_bytea); +Datum pcpatch_envelope_as_bytea(PG_FUNCTION_ARGS) { uint8 *bytes; size_t bytes_size; diff --git a/pgsql/pointcloud.sql.in b/pgsql/pointcloud.sql.in index 59c5852..5909482 100644 --- a/pgsql/pointcloud.sql.in +++ b/pgsql/pointcloud.sql.in @@ -194,8 +194,8 @@ CREATE OR REPLACE FUNCTION PC_AsText(p pcpatch) RETURNS text AS 'MODULE_PATHNAME', 'pcpatch_as_text' LANGUAGE 'c' IMMUTABLE STRICT; -CREATE OR REPLACE FUNCTION PC_Envelope(p pcpatch) - RETURNS bytea AS 'MODULE_PATHNAME', 'pcpatch_bytea_envelope' +CREATE OR REPLACE FUNCTION PC_EnvelopeAsBinary(p pcpatch) + RETURNS bytea AS 'MODULE_PATHNAME', 'pcpatch_envelope_as_bytea' LANGUAGE 'c' IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION PC_Uncompress(p pcpatch) @@ -446,4 +446,3 @@ CREATE OR REPLACE FUNCTION PC_Explode(p pcpatch) ------------------------------------------------------------------- -- SQL Utility Functions ------------------------------------------------------------------- - diff --git a/pgsql/sql/pointcloud.sql b/pgsql/sql/pointcloud.sql index 205e34b..6d38e4d 100644 --- a/pgsql/sql/pointcloud.sql +++ b/pgsql/sql/pointcloud.sql @@ -228,7 +228,7 @@ INSERT INTO pa_test (pa) VALUES ('0000000001000000000000000200000006000000070000 SELECT PC_Uncompress(pa) FROM pa_test LIMIT 1; SELECT PC_AsText(pa) FROM pa_test; -SELECT PC_Envelope(pa) from pa_test; +SELECT PC_EnvelopeAsBinary(pa) from pa_test; SELECT PC_AsText(PC_Union(pa)) FROM pa_test; SELECT sum(PC_NumPoints(pa)) FROM pa_test; diff --git a/pgsql_postgis/pointcloud_postgis--1.0.sql b/pgsql_postgis/pointcloud_postgis--1.0.sql index 1e6367c..e37f2a0 100644 --- a/pgsql_postgis/pointcloud_postgis--1.0.sql +++ b/pgsql_postgis/pointcloud_postgis--1.0.sql @@ -16,14 +16,14 @@ CREATE OR REPLACE FUNCTION PC_Intersection(pcpatch, geometry) ----------------------------------------------------------------------------- -- Cast from pcpatch to polygon -- -CREATE OR REPLACE FUNCTION geometry(pcpatch) +CREATE OR REPLACE FUNCTION PC_Envelope(pcpatch) RETURNS geometry AS $$ - SELECT ST_GeomFromEWKB(PC_Envelope($1)) + SELECT ST_GeomFromEWKB(PC_EnvelopeAsBinary($1)) $$ LANGUAGE 'sql'; -CREATE CAST (pcpatch AS geometry) WITH FUNCTION geometry(pcpatch); +CREATE CAST (pcpatch AS geometry) WITH FUNCTION PC_Envelope(pcpatch); ----------------------------------------------------------------------------- -- Cast from pcpoint to point @@ -44,7 +44,7 @@ CREATE CAST (pcpoint AS geometry) WITH FUNCTION geometry(pcpoint); CREATE OR REPLACE FUNCTION PC_Intersects(pcpatch, geometry) RETURNS boolean AS $$ - SELECT ST_Intersects($2, geometry($1)) + SELECT ST_Intersects($2, PC_Envelope($1)) $$ LANGUAGE 'sql'; @@ -54,4 +54,3 @@ CREATE OR REPLACE FUNCTION PC_Intersects(geometry, pcpatch) SELECT PC_Intersects($2, $1) $$ LANGUAGE 'sql'; -