Skip to content

Commit

Permalink
Locate filter can now locate min or max value
Browse files Browse the repository at this point in the history
  • Loading branch information
chambbj committed Dec 21, 2016
1 parent 52b7a02 commit 67fed24
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 29 deletions.
@@ -1,7 +1,7 @@
.. _filters.locatemax:
.. _filters.locate:

===============================================================================
filters.locatemax
filters.locate
===============================================================================

The Locate Max filter searches the specified ``dimension`` for the maximum value
Expand All @@ -20,8 +20,9 @@ This example returns the point at the highest elevation.
"pipeline":[
"input.las",
{
"type":"filters.locatemax",
"dimension":"Z"
"type":"filters.locate",
"dimension":"Z",
"minmax":"max"
},
"output.las"
]
Expand All @@ -31,4 +32,7 @@ Options
-------

dimension
Name of the dimension in which to search for max value.
Name of the dimension in which to search for min/max value.

minmax
Whether to return the minimum or maximum value in the dimension.
37 changes: 25 additions & 12 deletions filters/LocateMaxFilter.cpp → filters/LocateFilter.cpp
Expand Up @@ -32,51 +32,55 @@
* OF SUCH DAMAGE.
****************************************************************************/

#include "LocateMaxFilter.hpp"
#include "LocateFilter.hpp"

#include <pdal/pdal_macros.hpp>
#include <pdal/util/ProgramArgs.hpp>
#include <pdal/util/Utils.hpp>

namespace pdal
{

static PluginInfo const s_info =
PluginInfo("filters.locatemax",
"Return a single point with max value in the named dimension.",
"http://pdal.io/stages/filters.locatemax.html");
PluginInfo("filters.locate",
"Return a single point with min/max value in the named dimension.",
"http://pdal.io/stages/filters.locate.html");

CREATE_STATIC_PLUGIN(1, 0, LocateMaxFilter, Filter, s_info)
CREATE_STATIC_PLUGIN(1, 0, LocateFilter, Filter, s_info)

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

void LocateMaxFilter::addArgs(ProgramArgs& args)
void LocateFilter::addArgs(ProgramArgs& args)
{
args.add("dimension", "Dimension in which to locate max", m_dimName);
args.add("minmax", "Whether to search for the minimum or maximum value",
m_minmax, "max");
}

void LocateMaxFilter::prepared(PointTableRef table)
void LocateFilter::prepared(PointTableRef table)
{
PointLayoutPtr layout(table.layout());
m_dimId = layout->findDim(m_dimName);
if (m_dimId == Dimension::Id::Unknown)
{
std::ostringstream oss;
oss << "Invalid dimension name in filters.locatemax 'dimension' "
oss << "Invalid dimension name in filters.locate 'dimension' "
"option: '" << m_dimName << "'.";
throw pdal_error(oss.str());
}
}

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

PointId maxidx;
PointId minidx, maxidx;
double minval = std::numeric_limits<double>::max();
double maxval = std::numeric_limits<double>::lowest();

for (PointId idx = 0; idx < inView->size(); idx++)
Expand All @@ -87,10 +91,19 @@ PointViewSet LocateMaxFilter::run(PointViewPtr inView)
maxval = val;
maxidx = idx;
}
if (val < minval)
{
minval = val;
minidx = idx;
}
}

PointViewPtr outView = inView->makeNew();
outView->appendPoint(*inView.get(), maxidx);

if (Utils::iequals("min", m_minmax))
outView->appendPoint(*inView.get(), minidx);
if (Utils::iequals("max", m_minmax))
outView->appendPoint(*inView.get(), maxidx);

viewSet.insert(outView);
return viewSet;
Expand Down
13 changes: 7 additions & 6 deletions filters/LocateMaxFilter.hpp → filters/LocateFilter.hpp
Expand Up @@ -40,19 +40,19 @@
#include <map>
#include <string>

extern "C" int32_t LocateMaxFilter_ExitFunc();
extern "C" PF_ExitFunc LocateMaxFilter_InitPlugin();
extern "C" int32_t LocateFilter_ExitFunc();
extern "C" PF_ExitFunc LocateFilter_InitPlugin();

namespace pdal
{

class PointView;
class ProgramArgs;

class PDAL_DLL LocateMaxFilter : public Filter
class PDAL_DLL LocateFilter : public Filter
{
public:
LocateMaxFilter() : Filter()
LocateFilter() : Filter()
{}

static void * create();
Expand All @@ -62,13 +62,14 @@ class PDAL_DLL LocateMaxFilter : public Filter
private:
std::string m_dimName;
Dimension::Id m_dimId;
std::string m_minmax;

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

LocateMaxFilter& operator=(const LocateMaxFilter&); // not implemented
LocateMaxFilter(const LocateMaxFilter&); // not implemented
LocateFilter& operator=(const LocateFilter&); // not implemented
LocateFilter(const LocateFilter&); // not implemented
};

} // namespace pdal
4 changes: 2 additions & 2 deletions pdal/StageFactory.cpp
Expand Up @@ -53,7 +53,7 @@
#include <filters/HAGFilter.hpp>
#include <filters/IQRFilter.hpp>
#include <filters/KDistanceFilter.hpp>
#include <filters/LocateMaxFilter.hpp>
#include <filters/LocateFilter.hpp>
#include <filters/LOFFilter.hpp>
#include <filters/MADFilter.hpp>
#include <filters/MergeFilter.hpp>
Expand Down Expand Up @@ -252,7 +252,7 @@ StageFactory::StageFactory(bool no_plugins)
PluginManager::initializePlugin(HAGFilter_InitPlugin);
PluginManager::initializePlugin(IQRFilter_InitPlugin);
PluginManager::initializePlugin(KDistanceFilter_InitPlugin);
PluginManager::initializePlugin(LocateMaxFilter_InitPlugin);
PluginManager::initializePlugin(LocateFilter_InitPlugin);
PluginManager::initializePlugin(LOFFilter_InitPlugin);
PluginManager::initializePlugin(MADFilter_InitPlugin);
PluginManager::initializePlugin(MergeFilter_InitPlugin);
Expand Down
2 changes: 1 addition & 1 deletion test/unit/CMakeLists.txt
Expand Up @@ -87,7 +87,7 @@ PDAL_ADD_TEST(pdal_filters_decimation_test FILES
PDAL_ADD_TEST(pdal_filters_divider_test FILES filters/DividerFilterTest.cpp)
PDAL_ADD_TEST(pdal_filters_ferry_test FILES filters/FerryFilterTest.cpp)
PDAL_ADD_TEST(pdal_filters_groupby_test FILES filters/GroupByFilterTest.cpp)
PDAL_ADD_TEST(pdal_filters_locatemax_test FILES filters/LocateMaxFilterTest.cpp)
PDAL_ADD_TEST(pdal_filters_locate_test FILES filters/LocateFilterTest.cpp)
PDAL_ADD_TEST(pdal_filters_merge_test FILES filters/MergeTest.cpp)
PDAL_ADD_TEST(pdal_filters_additional_merge_test FILES
filters/AdditionalMergeTest.cpp)
Expand Down
Expand Up @@ -35,14 +35,14 @@
#include <pdal/pdal_test_main.hpp>

#include <pdal/Options.hpp>
#include <filters/LocateMaxFilter.hpp>
#include <filters/LocateFilter.hpp>
#include <io/LasReader.hpp>

#include "Support.hpp"

using namespace pdal;

TEST(LocateMaxTest, basic)
TEST(LocateTest, locate_max)
{
PointTable table;

Expand All @@ -53,8 +53,9 @@ TEST(LocateMaxTest, basic)

Options fo;
fo.add("dimension", "Z");
fo.add("minmax", "max");

LocateMaxFilter f;
LocateFilter f;
f.setInput(r);
f.setOptions(fo);
f.prepare(table);
Expand All @@ -66,3 +67,29 @@ TEST(LocateMaxTest, basic)

EXPECT_NEAR(586.38, view->getFieldAs<double>(Dimension::Id::Z, 0), 0.0001);
}

TEST(LocateTest, locate_min)
{
PointTable table;

Options ro;
ro.add("filename", Support::datapath("las/1.2-with-color.las"));
LasReader r;
r.setOptions(ro);

Options fo;
fo.add("dimension", "Z");
fo.add("minmax", "min");

LocateFilter f;
f.setInput(r);
f.setOptions(fo);
f.prepare(table);
PointViewSet viewSet = f.execute(table);
EXPECT_EQ(1u, viewSet.size());

PointViewPtr view = *viewSet.begin();
EXPECT_EQ(1u, view->size());

EXPECT_NEAR(406.59, view->getFieldAs<double>(Dimension::Id::Z, 0), 0.0001);
}

0 comments on commit 67fed24

Please sign in to comment.