copc-lib
copc-lib is a library which provides an easy-to-use reader and writer interface for COPC point clouds. This project provides a complete interface for handling COPC files, so that no additional LAZ or LAS libraries are required.
Build from source
Dependencies
copc-lib has the following dependencies:
- laz-perf>=3.0.0
- Catch2
- Pybind11
To install dependencies:
conda install -c conda-forge "laz-perf>=3.0" Catch2 pybind11
C++
git clone https://github.com/RockRobotic/copc-lib.git
cd copc-lib
mkdir build && cd build
cmake ..
cmake --build .
sudo cmake --install .
Python
git clone https://github.com/RockRobotic/copc-lib.git
pip install ./copc-lib
Usage
The Reader
and Writer
objects provide the primary means of interfacing with your COPC files. For more complex use cases, we also provide additional objects such as LAZ Compressors and Decompressors (see example/example-writer.cpp).
For common use cases, see the example
and test
folders for full examples.
C++
copc-lib is compatible with CMake. Assuming copc-lib and lazperf are installed on the system, you can link with them in your CMakeLists.txt
:
find_package(COPCLIB REQUIRED)
find_package(LAZPERF REQUIRED)
add_executable(funlib fun-main.cpp)
target_link_libraries(funlib COPCLIB::copc-lib LAZPERF::lazperf)
Example Files & Unit Tests
To build the copc-lib examples and unit tests along with the main library, you must enable them:
mkdir build && cd build
cmake .. -DWITH_TESTS=ON
cmake --build .
Then, you can run the unit tests and the examples:
ctest # All tests should pass
cd bin
./example_reader
./example_writer
Alternatively, you can build the test and example files from their respective CMakeLists, assuming copc-lib is already installed.
Python
import copclib as copc
# Create a reader object
reader = copc.FileReader("autzen-classified.copc.laz")
# Get the node metadata from the hierarchy
node = reader.FindNode(copc.VoxelKey(0, 0, 0, 0))
# Fetch the points of a node
points = reader.GetPoints(node)
# Iterate through each point
for point in points.Get():
print(point)
Coming Soon
- Basic C++ Reader Interface
- Return Point structures from the reader rather than raw char* arrays, to support a more familiar laspy-like interface.
- Add writer for COPC data
- Python bindings
- JavaScript bindings (not planned, see below)
- Spatial querying for nodes (given spatial coordinates, retrieve the appropriate Entry object)
- Conda and pip packages
Conformity to Spec
This version of copc-lib is pinned to a draft version of COPC respective of the state at COPC.io.
extended stats
VLR
User ID | Record ID |
---|---|
rock_robotic |
10001 |
We additionally add an extended stats extents
VLR to store mean and (population) variance values for each dimension. This VLR can be parsed in the same way as the extents
VLR defined by the COPC spec.
struct CopcExtentExtended
{
double mean; // replaces minimum
double var; // replaces maximum
}
This VLR is optional to process existing COPC files. If present, mean/variance are set appropriately for each dimension in CopcExtents
; if not, CopcExtents
will have default values of mean=0
and var=1
.
This VLR is only written by the Writer
if the flag has_extended_stats
is true in CopcConfigWriter::CopcExtents
.
Helpful Links
- COPC Spec
- copc.js - TypeScript library for reading COPC files
- copc.js for browser - Webpacked version of copc.js for the browser
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
Naming Convention
C++
We mostly use Google's Style Guide.
namespace name
{
class ClassName
{
public:
// Default constructor
ClassName() = default;
ClassName(int public_variable, int private_variable, bool private_read_only)
: public_variable(public_variable), private_variable_(private_variable),
private_read_only_(private_read_only){};
int public_variable{};
// Getters and Setters
void PrivateVariable(int private_variable) { private_variable_ = private_variable; }
int PrivateVariable() const { return private_variable_; }
bool PrivateReadOnly() const { return private_read_only_; }
// Any other function
int PrivateVariablePlusOne() const { return private_variable_ + 1; }
int SumPublicAndPrivate() const { return public_variable + private_variable_; }
static std::string ReturnEmptyString() { return {}; }
private:
int private_variable_{};
bool private_read_only_{false};
};
} // namespace name
Python
test_class = ClassName(public_variable=1,private_variable=2,private_read_only=True)
# using pybind .def_readwrite
test_class.public_variable = 4
assert test_class.public_variable == 4
# using pybind .def_property
test_class.private_variable = 5
assert test_class.private_variable == 5
# using pybind .def_property_readonly
assert test_class.private_read_only == True
# using pybind .def
assert test_class.PrivateVariablePlusOne() == 6
assert test_class.SumPublicAndPrivate() == 9
# using pybind .def_static
assert test_class.ReturnEmptyString == ""
Note that dimension names for points follow the laspy naming scheme, with the exception of scan_angle
.
License
Please see LICENSE.md
Credits
copc-lib is created and maintained by Chris Lee, Leo Stanislas and other members of RockRobotic.
The COPC file format is created and maintained by HOBU Inc. Some code has been adopted from PDAL and lazperf, both of which are maintained by HOBU Inc.