Skip to content

Commit

Permalink
Add returns filter
Browse files Browse the repository at this point in the history
  • Loading branch information
chambbj committed Mar 19, 2018
1 parent 91bdbd2 commit 70ee281
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 0 deletions.
41 changes: 41 additions & 0 deletions doc/stages/filters.returns.rst
@@ -0,0 +1,41 @@
.. _filters.returns:

filters.returns
===============================================================================

The returns filter takes a single PointView as its input and creates a PointView
for each of the user-specified ``groups`` defined below.

``first`` is defined as those points whose ``ReturnNumber`` is 1 when the ``NumberOfReturns`` is greater than 1.

``intermediate`` is defined as those points whose ``ReturnNumber`` is greater than 1 and less than ``NumberOfReturns`` when ``NumberOfReturns`` is greater than 2.

``last`` is defined as those points whose ``ReturnNumber`` is equal to ``NumberOfReturns`` when ``NumberOfReturns`` is greater than 1.

``only`` is defined as those points whose ``NumberOfReturns`` is 1.

.. embed::

Example
-------

This example creates separate output files for the ``last`` and ``only`` returns.

.. code-block:: json
{
"pipeline":[
"input.las",
{
"type":"filters.returns",
"groups":"last,only"
},
"output_#.las"
]
}
Options
-------

groups
Comma-separated list of return number groupings ('first', 'last', 'intermediate', or 'only')
126 changes: 126 additions & 0 deletions filters/ReturnsFilter.cpp
@@ -0,0 +1,126 @@
/******************************************************************************
* Copyright (c) 2018, Bradley J Chambers (brad.chambers@gmail.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include "ReturnsFilter.hpp"

#include <pdal/util/ProgramArgs.hpp>

namespace pdal
{

static StaticPluginInfo const s_info{
"filters.returns", "Split data by return order",
"http://pdal.io/stages/filters.returns.html"};

CREATE_STATIC_STAGE(ReturnsFilter, s_info)

std::string ReturnsFilter::getName() const
{
return s_info.name;
}

void ReturnsFilter::addArgs(ProgramArgs& args)
{
args.add("groups",
"Comma-separated list of return number groupings ('first', "
"'last', 'intermediate', or 'only')",
m_returnsString, {"last"});
}

void ReturnsFilter::prepared(PointTableRef table)
{
const PointLayoutPtr layout(table.layout());
if (!layout->hasDim(Dimension::Id::ReturnNumber) ||
!layout->hasDim(Dimension::Id::NumberOfReturns))
{
log()->get(LogLevel::Warning)
<< "Could not find ReturnNumber or "
"NumberOfReturns. Proceeding with all returns.\n";
}
}

PointViewSet ReturnsFilter::run(PointViewPtr inView)
{
PointViewSet viewSet;
if (!inView->size())
return viewSet;

for (auto& r : m_returnsString)
{
Utils::trim(r);
if (r == "first")
m_outputTypes |= returnFirst;
else if (r == "intermediate")
m_outputTypes |= returnIntermediate;
else if (r == "last")
m_outputTypes |= returnLast;
else if (r == "only")
m_outputTypes |= returnOnly;
else
throwError("Invalid output type: '" + r + "'.");
}

PointViewPtr firstView = inView->makeNew();
PointViewPtr intermediateView = inView->makeNew();
PointViewPtr lastView = inView->makeNew();
PointViewPtr onlyView = inView->makeNew();

for (PointId idx = 0; idx < inView->size(); idx++)
{
PointRef p = inView->point(idx);
uint8_t rn = p.getFieldAs<uint8_t>(Dimension::Id::ReturnNumber);
uint8_t nr = p.getFieldAs<uint8_t>(Dimension::Id::NumberOfReturns);
if ((m_outputTypes & returnFirst) && (rn == 1) && (nr > 1))
firstView->appendPoint(*inView.get(), idx);
if ((m_outputTypes & returnIntermediate) && (rn > 1) && (rn < nr) &&
(nr > 2))
intermediateView->appendPoint(*inView.get(), idx);
if ((m_outputTypes & returnLast) && (rn == nr) && (nr > 1))
lastView->appendPoint(*inView.get(), idx);
if ((m_outputTypes & returnOnly) && (nr == 1))
onlyView->appendPoint(*inView.get(), idx);
}

if (firstView->size())
viewSet.insert(firstView);
if (intermediateView->size())
viewSet.insert(intermediateView);
if (lastView->size())
viewSet.insert(lastView);
if (onlyView->size())
viewSet.insert(onlyView);
return viewSet;
}

} // namespace pdal
78 changes: 78 additions & 0 deletions filters/ReturnsFilter.hpp
@@ -0,0 +1,78 @@
/******************************************************************************
* Copyright (c) 2018, Bradley J Chambers (brad.chambers@gmail.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#pragma once

#include <pdal/Filter.hpp>

#include <map>
#include <string>

extern "C" int32_t ReturnsFilter_ExitFunc();
extern "C" PF_ExitFunc ReturnsFilter_InitPlugin();

namespace pdal
{

class PointView;
class ProgramArgs;

class PDAL_DLL ReturnsFilter : public Filter
{
public:
ReturnsFilter() {}

static const int returnFirst = 1;
static const int returnIntermediate = 2;
static const int returnLast = 4;
static const int returnOnly = 8;

static void* create();
static int32_t destroy(void*);
std::string getName() const;

private:
std::map<uint64_t, PointViewPtr> m_viewMap;
StringList m_returnsString;
int m_outputTypes;

virtual void addArgs(ProgramArgs& args);
virtual void prepared(PointTableRef table);
virtual PointViewSet run(PointViewPtr view);

ReturnsFilter& operator=(const ReturnsFilter&); // not implemented
ReturnsFilter(const ReturnsFilter&); // not implemented
};

} // namespace pdal

0 comments on commit 70ee281

Please sign in to comment.