diff --git a/doc/stages/filters.splitter.rst b/doc/stages/filters.splitter.rst
new file mode 100644
index 0000000000..28917dcafe
--- /dev/null
+++ b/doc/stages/filters.splitter.rst
@@ -0,0 +1,49 @@
+.. _filters.splitter:
+
+filters.splitter
+===============
+
+The splitter filter breaks a point cloud into square tiles of a size that
+you choose. The origin of the tiles is chosen arbitrarily unless specified
+as an option.
+
+The splitter takes a single PointView as its input and creates a PointView
+for each tile as its output.
+
+Splitting is usually applied to data read from files (which produce one large
+stream of points) before the points are written to a database (which prefer
+data segmented into smaller blocks).
+
+Example
+-------
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Options
+-------
+
+length
+ Length of the sides of the tiles that are created to hold points.
+ [Default: 1000]
+
+origin_x
+ X Origin of the tiles. [Default: none (chosen arbitarily)]
+
+origin_y
+ Y Origin of the tiles. [Default: none (chosen arbitarily)]
+
diff --git a/filters/splitter/SplitterFilter.cpp b/filters/splitter/SplitterFilter.cpp
index 43d96981e5..c1a20e995b 100644
--- a/filters/splitter/SplitterFilter.cpp
+++ b/filters/splitter/SplitterFilter.cpp
@@ -53,7 +53,11 @@ std::string SplitterFilter::getName() const { return s_info.name; }
void SplitterFilter::processOptions(const Options& options)
{
- m_length = options.getValueOrDefault("length", 1000);
+ m_length = options.getValueOrDefault("length", 1000.0);
+ m_xOrigin = options.getValueOrDefault("origin_x",
+ std::numeric_limits::quiet_NaN());
+ m_yOrigin = options.getValueOrDefault("origin_y",
+ std::numeric_limits::quiet_NaN());
}
@@ -94,24 +98,25 @@ PointViewSet SplitterFilter::run(PointViewPtr inView)
std::map viewMap(compare);
// Use the location of the first point as the origin.
- double xOrigin = inView->getFieldAs(Dimension::Id::X, 0);
- double yOrigin = inView->getFieldAs(Dimension::Id::Y, 0);
+ if (m_xOrigin == std::numeric_limits::quiet_NaN())
+ m_xOrigin = inView->getFieldAs(Dimension::Id::X, 0);
+ if (m_yOrigin == std::numeric_limits::quiet_NaN())
+ m_yOrigin = inView->getFieldAs(Dimension::Id::Y, 0);
// Overlay a grid of squares on the points (m_length sides). Each square
// corresponds to a new point buffer. Place the points falling in the
// each square in the corresponding point buffer.
for (PointId idx = 0; idx < inView->size(); idx++)
{
- int xpos = (inView->getFieldAs(Dimension::Id::X, idx) - xOrigin) /
- m_length;
- int ypos = (inView->getFieldAs(Dimension::Id::Y, idx) - yOrigin) /
- m_length;
+ double x = inView->getFieldAs(Dimension::Id::X, idx);
+ int xpos = (x - m_xOrigin) / m_length;
+ double y = inView->getFieldAs(Dimension::Id::Y, idx);
+ int ypos = (y - m_yOrigin) / m_length;
+
Coord loc(xpos, ypos);
PointViewPtr& outView = viewMap[loc];
if (!outView)
- {
outView = inView->makeNew();
- }
outView->appendPoint(*inView.get(), idx);
}
diff --git a/filters/splitter/SplitterFilter.hpp b/filters/splitter/SplitterFilter.hpp
index abebed433a..17486f0c05 100644
--- a/filters/splitter/SplitterFilter.hpp
+++ b/filters/splitter/SplitterFilter.hpp
@@ -55,7 +55,9 @@ class PDAL_DLL SplitterFilter : public pdal::Filter
Options getDefaultOptions();
private:
- uint32_t m_length;
+ double m_length;
+ double m_xOrigin;
+ double m_yOrigin;
virtual void processOptions(const Options& options);
virtual PointViewSet run(PointViewPtr view);