pgpointcloud
repository·master·Indexed 19 days ago
https://github.com/pgpointcloud/pointcloudA PostgreSQL extension for the efficient storage and management of point cloud (LIDAR) data. It provides support for PcPoint and PcPatch objects, schema documents compatible with the PDAL library, and various compression methods including Dimensional (Run-length, Significant bits removal, and Deflate/zlib) and LAZ. The extension includes a Point Binary format for compact data representation and a portable sort_r function for parameterized array sorting.
What's inside pgpointcloud
- pgPointcloud is an open-source PostgreSQL extension designed for storing and managing point cloud (LIDAR) data. It integrates directly with PostGIS, allowing users to manage 3D point cloud data alongside other geospatial data types like vector and raster within a single common framework. This integration enables efficient storage and querying of accurate 3D points within a PostgreSQL database.
Overview of Pointcloud
masterPointcloud is a PostgreSQL extension designed for storing and managing point cloud (LIDAR) data. It allows developers to integrate large-scale spatial point cloud datasets directly into a PostgreSQL database environment. For detailed documentation and advanced usage, visit the official website: https://pgpointcloud.github.io/pointcloud/.Core capabilities of pgPointcloud
masterpgPointcloud is designed for efficient storage and querying of large-scale point cloud data within a PostgreSQL database.
Key features include:
- Efficient Storage: Points are stored in groups called
pcPointswithin structures known aspcPatch. This grouping allows for high-efficiency data compression. - Accelerated Spatial Queries: Each
pcPatchincludes a bounding box. This allows PostGIS spatial features to use these boxes to significantly accelerate queries. - Multi-Criteria Querying: You can query point clouds using:
- Spatial criteria: Finding points within a specific geographic area.
- Attribute criteria: Finding points where specific attributes fall within a certain range.
- Data Accessibility: Since data resides on the server, it can be easily processed, visualized, or streamed.
- Efficient Storage: Points are stored in groups called
What is sort_r and when to use it
masterThe
sort_rfunction provides a portable, reentrant alternative to the standardqsort().Standard
qsort()does not allow passing custom parameters to the comparison operator without using global variables, which makes it unsuitable for multithreaded code. Whileqsort_randqsort_sexist, they are not portable across different systems (GNU, BSD, and Windows all use different argument signatures).sort_rsolves this by providing a consistent, portable interface for sorting arrays with parameterized comparison functions.Understand the Patch Binary formats
masterPatch binary formats are used to transmit groups of points. They include additional header information to specify compression methods and the number of points included. There are three main types of patch formats: Uncompressed, Dimensional, and LAZ.
All patch formats share a common header structure for
endiannessandpcid.Explore system-provided point cloud metadata
masterThe extension provides two system-level objects to manage and inspect point cloud data:
pointcloud_formatstable: Stores all registeredpcidentries and their corresponding schema documents.pointcloud_columnsview: A system view that lists all columns in your database containing point cloud objects (pcpointorpcpatch).
You can query
pointcloud_columnsto verify that your tables and columns have been correctly recognized by the extension.SELECT * FROM pointcloud_columns;Use Run-length compression for dimensions
masterRun-length compression (type 1) reduces data by storing pairs of (repeat count, value). This is effective for dimensions with many repeating values.
Structure:
byte: number of times the word repeatsword: the value of the word being repeated
Note: The size of the
wordis determined by the schema.byte: number of times the word repeats word: value of the word being repeated .... repeated for the number of runsHow Dimensional Compression works
masterDimensional compression optimizes storage by transforming the patch representation from a list of $N$ points (each with $M$ dimensions) into a list of $M$ dimensions (each containing $N$ values).
This transformation allows the system to apply different compression schemes to each dimension based on its specific data characteristics:
- Run-length encoding: Used for dimensions with low variability (e.g., a dimension where many values are identical).
- Common bits removal: Used for dimensions where variability occurs within a narrow bit range.
- Raw deflate compression (zlib): Used for dimensions that do not fit the other two schemes.
For LIDAR data organized into patches of points sampling similar areas, the
dimensionalscheme typically achieves compression efficiencies between 3:1 and 5:1.// Original representation: List of N points containing M dimensions { "pcid": 1, "pts": [ [-126.99, 45.01, 1, 0], [-126.98, 45.02, 2, 0], [-126.97, 45.03, 3, 0], [-126.96, 45.04, 4, 0], [-126.95, 45.05, 5, 0], [-126.94, 45.06, 6, 0] ] } // Dimensional representation: List of M dimensions containing N values { "pcid": 1, "dims": [ [-126.99, -126.98, -126.97, -126.96, -126.95, -126.94], [45.01, 45.02, 45.03, 45.04, 45.05, 45.06], [1, 2, 3, 4, 5, 6], [0, 0, 0, 0, 0, 0] ] }Understanding the PcPatch object
masterA
PcPatchis a collection ofPcPointobjects stored together to optimize database efficiency. Because storing billions of individual point records is resource-intensive, LIDAR data is instead represented as a collection ofPcPatchrecords (typically in the tens of millions).To ensure performance, patches should ideally contain points that are spatially near each other.
When exported to a human-readable JSON format using
PC_AsText(pcpatch), aPcPatchconsists of:pcid: A foreign key reference to thepointcloud_formatstable.pts: A nested array where each inner array is a point's dimensions (theptarray of aPcPoint).
{ "pcid" : 1, "pts" : [ [0.02, 0.03, 0.05, 6], [0.02, 0.03, 0.05, 8] ] }Understanding the PcPoint object
masterA
PcPointis the fundamental unit of a point cloud. It represents a single point in space with a variable number of dimensions. At a minimum, it contains X and Y coordinates.When exported to a human-readable JSON format using
PC_AsText(pcpoint), aPcPointconsists of:pcid: A foreign key reference to thepointcloud_formatstable, which defines the meaning of each dimension.pt: An array of doubles representing the point's dimensions (e.g., coordinates, intensity, etc.).
Note that while underlying storage might use different types, the extracted data is represented as doubles after scaling and offsetting.
{ "pcid" : 1, "pt" : [0.01, 0.02, 0.03, 4] }How schema documents work in PostgreSQL Pointcloud
masterPostgreSQL Pointcloud uses a "schema document" to handle the variability of LIDAR data (e.g., different dimensions like X, Y, Z, Intensity, RGB, or return times). Because different sensors store data using different types (e.g.,
int32_tvsdouble) and different scaling/offsets, the schema document defines how to interpret the raw bytes stored in the database.Key concepts:
- Dimensions: Each point contains multiple dimensions. Each dimension has a name, a data type (
interpretation), a size, and optionalscaleandoffsetvalues to convert stored integers into actual physical values. - Format Compatibility: The schema document format is identical to the one used by the PDAL library.
- Storage: Schema documents are stored in the
pointcloud_formatstable. Instead of repeating the schema for every object, point cloud objects store apcid(pointcloud identifier), which acts as a foreign key to thepointcloud_formatstable, similar to howsridworks in PostGIS.
- Dimensions: Each point contains multiple dimensions. Each dimension has a name, a data type (
Use Deflate compression for dimensions
masterDeflate compression (type 3) uses the zlib algorithm for general-purpose compression of a dimension. The data area is a raw zlib buffer.
Implementation Details:
- The data can be passed directly to the
inflate()function. - The size of the input buffer is provided in the dimension header.
- The required output buffer size can be calculated as:
dimension word size * number of points in the patch.
- The data can be passed directly to the