Skip to content

Commit

Permalink
Make sure scaling works for BPF and LAS when using multiple inputs and (
Browse files Browse the repository at this point in the history
#2273)

a single output.
Close #1983
  • Loading branch information
abellgithub committed Nov 29, 2018
1 parent adf6cfa commit 6018e6e
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 69 deletions.
8 changes: 6 additions & 2 deletions io/BpfWriter.cpp
Expand Up @@ -225,10 +225,14 @@ void BpfWriter::loadBpfDimensions(PointLayoutPtr layout)
}


void BpfWriter::writeView(const PointViewPtr dataShared)
void BpfWriter::prerunFile(const PointViewSet& pvSet)
{
m_scaling.setAutoXForm(dataShared);
m_scaling.setAutoXForm(pvSet);
}


void BpfWriter::writeView(const PointViewPtr dataShared)
{
// Avoid reference count overhead internally.
const PointView* data(dataShared.get());

Expand Down
1 change: 1 addition & 0 deletions io/BpfWriter.hpp
Expand Up @@ -80,6 +80,7 @@ class PDAL_DLL BpfWriter : public FlexWriter
virtual void prepared(PointTableRef table);
virtual void readyFile(const std::string& filename,
const SpatialReference& srs);
void prerunFile(const PointViewSet& pvSet);
virtual void writeView(const PointViewPtr data);
virtual void doneFile();

Expand Down
7 changes: 6 additions & 1 deletion io/LasWriter.cpp
Expand Up @@ -822,11 +822,16 @@ bool LasWriter::processPoint(PointRef& point)
}


void LasWriter::prerunFile(const PointViewSet& pvSet)
{
m_scaling.setAutoXForm(pvSet);
}


void LasWriter::writeView(const PointViewPtr view)
{
Utils::writeProgress(m_progressFd, "READYVIEW",
std::to_string(view->size()));
m_scaling.setAutoXForm(view);

point_count_t pointLen = m_lasHeader.pointLen();

Expand Down
1 change: 1 addition & 0 deletions io/LasWriter.hpp
Expand Up @@ -141,6 +141,7 @@ class PDAL_DLL LasWriter : public FlexWriter, public Streamable
const SpatialReference& srs);
virtual bool srsOverridden() const
{ return m_aSrs.valid(); }
void prerunFile(const PointViewSet& pvSet);
virtual void writeView(const PointViewPtr view);
virtual bool processOne(PointRef& point);
void spatialReferenceChanged(const SpatialReference& srs);
Expand Down
2 changes: 1 addition & 1 deletion pdal/DbWriter.cpp
Expand Up @@ -155,7 +155,7 @@ void DbWriter::setAutoXForm(const PointViewPtr view)
{
using namespace Dimension;

m_scaling.setAutoXForm(view);
m_scaling.setAutoXForm({view});
for (auto& xmlDim : m_dbDims)
{
if (xmlDim.m_dimType.m_id == Id::X)
Expand Down
14 changes: 14 additions & 0 deletions pdal/FlexWriter.hpp
Expand Up @@ -96,6 +96,8 @@ class PDAL_DLL FlexWriter : public Writer
virtual void ready(PointTableRef table) final
{
readyTable(table);

// Ready the file if we're writing a single file.
if (m_hashPos == std::string::npos)
{
if (!table.spatialReferenceUnique() && !srsOverridden())
Expand All @@ -106,6 +108,14 @@ class PDAL_DLL FlexWriter : public Writer
}
}

virtual void prerun(const PointViewSet& views) final
{
// If the output is a consolidation of all views, call
// prerun with all views.
if (m_hashPos == std::string::npos)
prerunFile(views);
}

// This essentially moves ready() and done() into write(), which means
// that they get executed once for each view. The check for m_hashPos
// is a test to see if the filename specification is a template. If it's
Expand All @@ -117,7 +127,9 @@ class PDAL_DLL FlexWriter : public Writer
{
if (view->size() == 0)
return;
// Ready the file - we're writing each view separately.
readyFile(generateFilename(), view->spatialReference());
prerunFile({view});
}
writeView(view);
if (m_hashPos != std::string::npos)
Expand All @@ -141,6 +153,8 @@ class PDAL_DLL FlexWriter : public Writer

virtual void readyFile(const std::string& filename,
const SpatialReference& srs) = 0;
virtual void prerunFile(const PointViewSet& pvSet)
{}
virtual void writeView(const PointViewPtr view) = 0;
virtual void doneFile()
{}
Expand Down
20 changes: 0 additions & 20 deletions pdal/PointView.cpp
Expand Up @@ -110,16 +110,6 @@ void PointView::calculateBounds(BOX2D& output) const
}


void PointView::calculateBounds(const PointViewSet& set, BOX2D& output)
{
for (auto iter = set.begin(); iter != set.end(); ++iter)
{
PointViewPtr buf = *iter;
buf->calculateBounds(output);
}
}


void PointView::calculateBounds(BOX3D& output) const
{
for (PointId idx = 0; idx < size(); idx++)
Expand All @@ -133,16 +123,6 @@ void PointView::calculateBounds(BOX3D& output) const
}


void PointView::calculateBounds(const PointViewSet& set, BOX3D& output)
{
for (auto iter = set.begin(); iter != set.end(); ++iter)
{
PointViewPtr buf = *iter;
buf->calculateBounds(output);
}
}


MetadataNode PointView::toMetadata() const
{
MetadataNode node;
Expand Down
2 changes: 0 additions & 2 deletions pdal/PointView.hpp
Expand Up @@ -192,9 +192,7 @@ class PDAL_DLL PointView : public PointContainer
\endverbatim
*/
void calculateBounds(BOX2D& box) const;
static void calculateBounds(const PointViewSet&, BOX2D& box);
void calculateBounds(BOX3D& box) const;
static void calculateBounds(const PointViewSet&, BOX3D& box);

void dump(std::ostream& ostr) const;
bool hasDim(Dimension::Id id) const
Expand Down
63 changes: 31 additions & 32 deletions pdal/Scaling.cpp
Expand Up @@ -51,45 +51,44 @@ void Scaling::addArgs(ProgramArgs& args)
}


void Scaling::setAutoXForm(const PointViewPtr view)
void Scaling::setAutoXForm(const PointViewSet& pvSet)
{
double xmin = (std::numeric_limits<double>::max)();
double xmax = (std::numeric_limits<double>::lowest)();
bool xmod = m_xXform.m_offset.m_auto || m_xXform.m_scale.m_auto;

double ymin = (std::numeric_limits<double>::max)();
double ymax = (std::numeric_limits<double>::lowest)();
bool ymod = m_yXform.m_offset.m_auto || m_yXform.m_scale.m_auto;

double zmin = (std::numeric_limits<double>::max)();
double zmax = (std::numeric_limits<double>::lowest)();
bool zmod = m_zXform.m_offset.m_auto || m_zXform.m_scale.m_auto;

if (!xmod && !ymod && !zmod)
return;
if (view->empty())
bool xmod = m_xXform.m_offset.m_auto || m_xXform.m_scale.m_auto;
bool ymod = m_yXform.m_offset.m_auto || m_yXform.m_scale.m_auto;
bool zmod = m_zXform.m_offset.m_auto || m_zXform.m_scale.m_auto;
if (!xmod && !ymod && !zmod)
return;

for (PointId idx = 0; idx < view->size(); idx++)
double xmin = (std::numeric_limits<double>::max)();
double xmax = (std::numeric_limits<double>::lowest)();
double ymin = (std::numeric_limits<double>::max)();
double ymax = (std::numeric_limits<double>::lowest)();
double zmin = (std::numeric_limits<double>::max)();
double zmax = (std::numeric_limits<double>::lowest)();

for (const PointViewPtr view : pvSet)
{
if (xmod)
{
double x = view->getFieldAs<double>(Dimension::Id::X, idx);
xmin = (std::min)(x, xmin);
xmax = (std::max)(x, xmax);
}
for (PointId idx = 0; idx < view->size(); idx++)
{
double x = view->getFieldAs<double>(Dimension::Id::X, idx);
xmin = (std::min)(x, xmin);
xmax = (std::max)(x, xmax);
}
if (ymod)
{
double y = view->getFieldAs<double>(Dimension::Id::Y, idx);
ymin = (std::min)(y, ymin);
ymax = (std::max)(y, ymax);
}
for (PointId idx = 0; idx < view->size(); idx++)
{
double y = view->getFieldAs<double>(Dimension::Id::Y, idx);
ymin = (std::min)(y, ymin);
ymax = (std::max)(y, ymax);
}
if (zmod)
{
double z = view->getFieldAs<double>(Dimension::Id::Z, idx);
zmin = (std::min)(z, zmin);
zmax = (std::max)(z, zmax);
}
for (PointId idx = 0; idx < view->size(); idx++)
{
double z = view->getFieldAs<double>(Dimension::Id::Z, idx);
zmin = (std::min)(z, zmin);
zmax = (std::max)(z, zmax);
}
}

if (m_xXform.m_offset.m_auto)
Expand Down
2 changes: 1 addition & 1 deletion pdal/Scaling.hpp
Expand Up @@ -74,7 +74,7 @@ class PDAL_DLL Scaling
\param view PointView on which scale should be computed.
*/
virtual void setAutoXForm(const PointViewPtr view);
virtual void setAutoXForm(const PointViewSet& pvSet);

/**
Add option/command-line arguments for transform variables.
Expand Down
1 change: 1 addition & 0 deletions pdal/Stage.cpp
Expand Up @@ -239,6 +239,7 @@ PointViewSet Stage::execute(PointTableRef table, PointViewSet& views)
// Do the ready operation and then start running all the views
// through the stage.
ready(table);
prerun(views);
for (auto const& it : views)
{
StageRunnerPtr runner(new StageRunner(this, it));
Expand Down
9 changes: 9 additions & 0 deletions pdal/Stage.hpp
Expand Up @@ -460,6 +460,15 @@ class PDAL_DLL Stage
virtual void ready(PointTableRef /*table*/)
{}

/**
Pass all the point views at once to the stage for cases where we need
such information. You normally shouldn't need to implement this call.
\param pvSet PointViewSet being processed for the stage.
*/
virtual void prerun(const PointViewSet& /*pvSet*/)
{}

/**
Process all points in a view. Implement in subclass.
Expand Down
4 changes: 0 additions & 4 deletions test/unit/PointViewTest.cpp
Expand Up @@ -285,10 +285,6 @@ TEST(PointViewTest, calcBounds)
BOX3D box_b2;
b2->calculateBounds(box_b2);
check_bounds(box_b2, 1.0, 3.0, 1.0, 3.0, 1.0, 3.0);

BOX3D box_bs;
PointView::calculateBounds(bs, box_bs);
check_bounds(box_bs, 0.0, 3.0, 0.0, 3.0, 0.0, 3.0);
}

TEST(PointViewTest, order)
Expand Down

0 comments on commit 6018e6e

Please sign in to comment.