Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into issue-2155
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed Aug 29, 2018
2 parents 8d98b58 + b244ba0 commit 19b0fe6
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 37 deletions.
2 changes: 1 addition & 1 deletion cmake/macros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ macro(PDAL_ADD_PLUGIN _name _type _shortname)
ARCHIVE DESTINATION ${PDAL_LIB_INSTALL_DIR})
if (APPLE)
set_target_properties(${${_name}} PROPERTIES
INSTALL_NAME_DIR "@loader_path/../lib")
INSTALL_NAME_DIR "@rpath")
endif()
endmacro(PDAL_ADD_PLUGIN)

Expand Down
25 changes: 22 additions & 3 deletions filters/AssignFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,21 @@ void AssignFilter::addArgs(ProgramArgs& args)
{
args.add("assignment", "Values to assign to dimensions based on range.",
m_assignments);
args.add("condition", "Condition for assignment based on range.",
m_condition);
}


void AssignFilter::prepared(PointTableRef table)
{
PointLayoutPtr layout(table.layout());

m_condition.m_id = layout->findDim(m_condition.m_name);
if (m_condition.m_id == Dimension::Id::Unknown)
m_doCondition = false;
else
m_doCondition = true;

for (auto& r : m_assignments)
{
r.m_id = layout->findDim(r.m_name);
Expand All @@ -142,9 +150,20 @@ void AssignFilter::prepared(PointTableRef table)

bool AssignFilter::processOne(PointRef& point)
{
for (AssignRange& r : m_assignments)
if (r.valuePasses(point.getFieldAs<double>(r.m_id)))
point.setField(r.m_id, r.m_value);
if (m_doCondition)
{
bool condition = m_condition.valuePasses(point.getFieldAs<double>(m_condition.m_id));
for (AssignRange& r : m_assignments)
if (r.valuePasses(point.getFieldAs<double>(r.m_id)) &&
condition)
point.setField(r.m_id, r.m_value);
} else
{

for (AssignRange& r : m_assignments)
if (r.valuePasses(point.getFieldAs<double>(r.m_id)) )
point.setField(r.m_id, r.m_value);
}
return true;
}

Expand Down
4 changes: 4 additions & 0 deletions filters/AssignFilter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include <pdal/Filter.hpp>
#include <pdal/Streamable.hpp>

#include "private/DimRange.hpp"

namespace pdal
{

Expand All @@ -60,6 +62,8 @@ class PDAL_DLL AssignFilter : public Filter, public Streamable
AssignFilter(const AssignFilter&) = delete;

std::vector<AssignRange> m_assignments;
DimRange m_condition;
bool m_doCondition;
};

} // namespace pdal
17 changes: 14 additions & 3 deletions pdal/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,21 @@ void Options::addConditional(const Option& option)
}


void Options::addConditional(const Options& options)
void Options::addConditional(const Options& other)
{
for (auto& o : options.m_options)
addConditional(o.second);
for (auto oi = other.m_options.begin(); oi != other.m_options.end();)
{
const std::string& name = oi->first;
if (m_options.find(name) == m_options.end())
{
do
{
m_options.insert(*oi++);
} while (oi != other.m_options.end() && name == oi->first);
}
else
oi++;
}
}


Expand Down
14 changes: 8 additions & 6 deletions pdal/Stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,15 @@ PointViewSet Stage::execute(PointTableRef table)

std::stack<Stage *> stages;
std::stack<Stage *> pending;
std::map<Stage *, Stage *> parents;
std::map<Stage *, Stage *> children;

m_log->get(LogLevel::Debug) << "Executing pipeline in standard mode." <<
std::endl;

pending.push(this);
parents[this] = nullptr;

// There is no child of the terminal stage.
children[this] = nullptr;

// Linearize stage execution.
Stage *s;
Expand All @@ -176,7 +178,7 @@ PointViewSet Stage::execute(PointTableRef table)
stages.push(s);
for (auto fi = s->m_inputs.begin(); fi != s->m_inputs.end(); ++fi)
{
parents[*fi] = s;
children[*fi] = s;
pending.push(*fi);
}
}
Expand All @@ -193,9 +195,9 @@ PointViewSet Stage::execute(PointTableRef table)
inViews.insert(PointViewPtr(new PointView(table)));
outViews = s->execute(table, inViews);

Stage *parent = parents[s];
if (parent)
sets[parent].insert(outViews.begin(), outViews.end());
Stage *child = children[s];
if (child)
sets[child].insert(outViews.begin(), outViews.end());
// Allow previous point views to be freed.
sets.erase(s);
}
Expand Down
58 changes: 39 additions & 19 deletions plugins/python/io/NumpyReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,28 @@

#include "../plang/Environment.hpp"


std::string toString(PyObject *pname)
{
std::stringstream mssg;
PyObject* r = PyObject_Str(pname);
if (!r)
throw pdal::pdal_error("couldn't make string representation value");
#if PY_MAJOR_VERSION >= 3
Py_ssize_t size;
const char *d = PyUnicode_AsUTF8AndSize(r, &size);
#else
const char *d = PyString_AsString(r);
#endif
mssg << d;
return mssg.str();
}


namespace pdal
{

static PluginInfo const s_info
static PluginInfo const s_info
{
"readers.numpy",
"Read data from .npy files.",
Expand Down Expand Up @@ -89,6 +107,16 @@ std::istream& operator >> (std::istream& in, NumpyReader::Order& order)
}


void NumpyReader::setArray(PyObject* array)
{
plang::Environment::get();
if (!PyArray_Check(array))
throw pdal::pdal_error("object provided to setArray is not a python numpy array!");

m_array = (PyArrayObject*)array;
Py_XINCREF(m_array);
}

PyArrayObject* load_npy(std::string const& filename)
{

Expand Down Expand Up @@ -128,17 +156,21 @@ void NumpyReader::initialize()
m_ndims = 0;

m_iter = NULL;
m_array = NULL;

p_data = NULL;
m_dataptr = NULL;
m_strideptr = NULL;
m_innersizeptr = NULL;
m_dtype = NULL;

m_array = load_npy(m_filename);
if (!PyArray_Check(m_array))
throw pdal::pdal_error("Object in file '" + m_filename +
"' is not a numpy array");
if (m_filename.size())
{
m_array = load_npy(m_filename);
}
if (m_array)
if (!PyArray_Check(m_array))
throw pdal::pdal_error("Object in file '" + m_filename +
"' is not a numpy array");
}


Expand Down Expand Up @@ -242,18 +274,6 @@ Dimension::Id NumpyReader::registerDim(PointLayoutPtr layout,
namespace
{

std::string toString(PyObject *pname)
{
if (!pname)
return std::string();

#if PY_MAJOR_VERSION >= 3
return PyBytes_AsString(PyUnicode_AsUTF8String(pname));
#else
return PyString_AsString(pname);
#endif
}


Dimension::Type getType(PyArray_Descr *dtype, const std::string& name)
{
Expand Down Expand Up @@ -282,7 +302,7 @@ void NumpyReader::createFields(PointLayoutPtr layout)
int offset;

m_numFields = 0;
if (m_dtype->fields)
if (m_dtype->fields != Py_None)
m_numFields = PyDict_Size(m_dtype->fields);

// Array isn't structured - just a bunch of data.
Expand Down
3 changes: 2 additions & 1 deletion plugins/python/io/NumpyReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ class PDAL_DLL NumpyReader : public Reader, public Streamable
public:
NumpyReader& operator=(const NumpyReader&) = delete;
NumpyReader(const NumpyReader&) = delete;
NumpyReader()
NumpyReader() : m_array(NULL)
{}

void setArray(PyObject* array);
std::string getName() const;

private:
Expand Down
1 change: 1 addition & 0 deletions scripts/ci/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ make install
pip install packaging
git clone https://github.com/PDAL/python.git pdal-python
cd pdal-python
git checkout 2.0.0
python setup.py build
echo "current path: " `pwd`
export PDAL_TEST_DIR=/pdal/_build/test
Expand Down
2 changes: 1 addition & 1 deletion scripts/docker/ubuntu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MAINTAINER Howard Butler <howard@hobu.co>

RUN git clone https://github.com/PDAL/PDAL.git /pdal; \
cd /pdal; \
git checkout 1.7-maintenance; \
git checkout master; \
mkdir -p _build; \
cd _build; \
cmake .. \
Expand Down
35 changes: 32 additions & 3 deletions test/unit/apps/TranslateTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static int runTranslate(std::string const& cmdline, std::string& output)
return Utils::run_shell_command(cmd + " " + cmdline, output);
}

TEST(translateTest, t1)
TEST(TranslateTest, t1)
{
std::string output;

Expand All @@ -72,7 +72,7 @@ TEST(translateTest, t1)
}

// Tests for processing JSON input.
TEST(translateTest, t2)
TEST(TranslateTest, t2)
{
std::string output;

Expand Down Expand Up @@ -190,7 +190,7 @@ TEST(translateTest, t2)
output), 0);
}

TEST(translateTest, t3)
TEST(TranslateTest, t3)
{
std::string output;

Expand All @@ -206,3 +206,32 @@ TEST(translateTest, t3)
EXPECT_EQ(std::stoi(output), 1);
#endif
}

// Make sure that repeated inputs ("groups" in this case), are propagated
// to stage.
TEST(TranslateTest, issue_2114)
{
FileUtils::deleteFile(Support::temppath("out1.las"));
FileUtils::deleteFile(Support::temppath("out2.las"));
FileUtils::deleteFile(Support::temppath("out3.las"));
FileUtils::deleteFile(Support::temppath("out4.las"));

std::string output;
std::string in = Support::datapath("las/autzen_trim.las");
std::string out = Support::temppath("out#.las");

EXPECT_FALSE(FileUtils::fileExists(Support::temppath("out1.las")));
EXPECT_FALSE(FileUtils::fileExists(Support::temppath("out2.las")));
EXPECT_FALSE(FileUtils::fileExists(Support::temppath("out3.las")));
EXPECT_FALSE(FileUtils::fileExists(Support::temppath("out4.las")));

EXPECT_EQ(runTranslate(in + " " + out + " -f returns "
"--filters.returns.groups=last --filters.returns.groups=first",
output), 0);

EXPECT_TRUE(FileUtils::fileExists(Support::temppath("out1.las")));
EXPECT_TRUE(FileUtils::fileExists(Support::temppath("out2.las")));
EXPECT_FALSE(FileUtils::fileExists(Support::temppath("out3.las")));
EXPECT_FALSE(FileUtils::fileExists(Support::temppath("out4.las")));
}

39 changes: 39 additions & 0 deletions test/unit/filters/AssignFilterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,42 @@ TEST(AssignFilterTest, t2)
EXPECT_EQ(i6, 3);
EXPECT_EQ(i8, 5);
}

TEST(AssignFilterTest, test_condition)
{
StageFactory factory;

Stage& r = *factory.createStage("readers.las");
Stage& f = *factory.createStage("filters.assign");

// utm17.las contains 5 points with intensity of 280, 3 of 260 and 2 of 240
Options ro;
ro.add("filename", Support::datapath("las/utm17.las"));
r.setOptions(ro);

Options fo;
fo.add("condition", "Intensity[260:260]");
fo.add("assignment", "PointSourceId[:]=6");

f.setInput(r);
f.setOptions(fo);

PointTable t;
f.prepare(t);
PointViewSet s = f.execute(t);
PointViewPtr v = *s.begin();

int ielse = 0;
int i6 = 0;
for (PointId i = 0; i < v->size(); ++i)
{
int ii = v->getFieldAs<int>(Dimension::Id::PointSourceId, i);
if (ii == 6)
i6++;
else
ielse++;
}
EXPECT_EQ(i6, 3);
EXPECT_EQ(v->size(), 10u);
EXPECT_EQ(ielse, 7);
}

0 comments on commit 19b0fe6

Please sign in to comment.