Writing with PDAL#
This tutorial will describe a complete example of using PDAL C++ objects to write a LAS file. The example will show fetching data from your own data source rather than interacting with a PDAL stage.
Note
If you implement your own Readers that conforms to
PDAL’s pdal::Stage
, you can implement a simple
read-filter-write pipeline using Pipeline and not have to
code anything explicit yourself.
Includes#
First, our code.
#include <pdal/PointView.hpp>
#include <pdal/PointTable.hpp>
#include <pdal/Dimension.hpp>
#include <pdal/Options.hpp>
#include <pdal/StageFactory.hpp>
#include <io/BufferReader.hpp>
#include <vector>
void fillView(pdal::PointViewPtr view)
{
struct Point
{
double x;
double y;
double z;
};
for (int i = 0; i < 1000; ++i)
{
Point p;
p.x = -93.0 + i*0.001;
p.y = 42.0 + i*0.001;
p.z = 106.0 + i;
view->setField(pdal::Dimension::Id::X, i, p.x);
view->setField(pdal::Dimension::Id::Y, i, p.y);
view->setField(pdal::Dimension::Id::Z, i, p.z);
}
}
int main(int argc, char* argv[])
{
using namespace pdal;
Options options;
options.add("filename", "myfile.las");
PointTable table;
table.layout()->registerDim(Dimension::Id::X);
table.layout()->registerDim(Dimension::Id::Y);
table.layout()->registerDim(Dimension::Id::Z);
PointViewPtr view(new PointView(table));
fillView(view);
BufferReader reader;
reader.addView(view);
StageFactory factory;
// StageFactory always "owns" stages it creates. They'll be destroyed with the factory.
Stage *writer = factory.createStage("writers.las");
writer->setInput(reader);
writer->setOptions(options);
writer->prepare(table);
writer->execute(table);
}
Take a closer look. We will need to include several PDAL headers.
#include <pdal/PointView.hpp>
#include <pdal/PointTable.hpp>
#include <pdal/Dimension.hpp>
#include <pdal/Options.hpp>
#include <pdal/StageFactory.hpp>
#include <io/BufferReader.hpp>
BufferReader
will not be required by all users. Here is it used to populate a
bare PointBuffer
. This will often be accomplished by a Reader
stage.
Instead of directly including headers for individual stages, e.g., LasWriter
,
we rely on the StageFactory
which has the ability to query available stages
at runtime and return pointers to the created stages.
We proceed by providing a mechanism for generating dummy data for the x, y, and z dimensions.
void fillView(pdal::PointViewPtr view)
{
struct Point
{
double x;
double y;
double z;
};
for (int i = 0; i < 1000; ++i)
{
Point p;
p.x = -93.0 + i*0.001;
p.y = 42.0 + i*0.001;
p.z = 106.0 + i;
view->setField(pdal::Dimension::Id::X, i, p.x);
view->setField(pdal::Dimension::Id::Y, i, p.y);
view->setField(pdal::Dimension::Id::Z, i, p.z);
int main(int argc, char* argv[])
{
using namespace pdal;
Options options;
options.add("filename", "myfile.las");
PointTable table;
Finally, the main code which creates the dummy data, puts it into a BufferReader and sends it to a writer.
int main(int argc, char* argv[])
{
using namespace pdal;
Options options;
options.add("filename", "myfile.las");
PointTable table;
table.layout()->registerDim(Dimension::Id::X);
table.layout()->registerDim(Dimension::Id::Y);
table.layout()->registerDim(Dimension::Id::Z);
PointViewPtr view(new PointView(table));
fillView(view);
BufferReader reader;
reader.addView(view);
StageFactory factory;
// StageFactory always "owns" stages it creates. They'll be destroyed with the factory.
Stage *writer = factory.createStage("writers.las");
writer->setInput(reader);
writer->setOptions(options);
writer->prepare(table);
writer->execute(table);
Compiling and running the program#
Note
Refer to Compilation for information on how to build PDAL.
To build this example, simply copy the files tutorial.cpp and CMakeLists.txt from the examples/writing directory of the PDAL source tree.
cmake_minimum_required(VERSION 3.6)
project(WritingTutorial)
find_package(PDAL 2.0.0 REQUIRED CONFIG)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(tutorial tutorial.cpp)
target_link_libraries(tutorial PRIVATE ${PDAL_LIBRARIES})
target_include_directories(tutorial PRIVATE
${PDAL_INCLUDE_DIRS}
${PDAL_INCLUDE_DIRS}/pdal)
Note
Refer to CMake for an explanation of the basic CMakeLists.
Begin by configuring your project using CMake (shown here on Unix) and building using make.
$ cd /PATH/TO/WRITING/TUTORIAL
$ mkdir build
$ cd build
$ cmake ..
$ make
After the project is built, you can run it by typing:
$ ./tutorial
Streaming#
Writing in streaming mode creates and writes the cloud one point at a time,
and the implementation is somewhat different. An example is given in
examples/writing-streamer
.