Skip to content

Instantly share code, notes, and snippets.

@connormanning
Last active June 8, 2016 16:25
Show Gist options
  • Save connormanning/07da39dfdec9b3e964b2476b222781d3 to your computer and use it in GitHub Desktop.
Save connormanning/07da39dfdec9b3e964b2476b222781d3 to your computer and use it in GitHub Desktop.
Vector PointTable for PDAL
#include <iostream>
#include "vector-point-table.hpp"
namespace
{
void print(const pdal::PointRef& pointRef)
{
std::cout <<
pointRef.getFieldAs<double>(pdal::Dimension::Id::X) << ", " <<
pointRef.getFieldAs<double>(pdal::Dimension::Id::Y) << ", " <<
pointRef.getFieldAs<double>(pdal::Dimension::Id::Z) << std::endl;
}
const std::vector<char> binary(([]()
{
const std::vector<double> doubles({
0.1, 0.2, 0.3,
1.1, 1.2, 1.3,
2.1, 2.2, 2.3,
3.1, 3.2, 3.3,
4.1, 4.2, 4.3
});
return std::vector<char>(
reinterpret_cast<const char*>(doubles.data()),
reinterpret_cast<const char*>(doubles.data() + doubles.size()));
})());
}
int main()
{
pdal::PointLayout layout;
layout.registerDim(pdal::Dimension::Id::X);
layout.registerDim(pdal::Dimension::Id::Y);
layout.registerDim(pdal::Dimension::Id::Z);
layout.finalize();
// Seed 5 points with pre-existing binary data.
std::vector<char> data(binary);
pdal::VectorPointTable table(layout, std::move(data));
// Append points.
for (std::size_t i(0); i < 5; ++i)
{
auto pointRef(table.append());
pointRef.setField(pdal::Dimension::Id::X, 5.1 + i);
pointRef.setField(pdal::Dimension::Id::Y, 5.2 + i);
pointRef.setField(pdal::Dimension::Id::Z, 5.3 + i);
}
std::cout << "Table size: " << table.capacity() << std::endl;
// Print all.
std::size_t i(0);
for (const auto& pointRef : table)
{
std::cout << i++ << ": ";
print(pointRef);
}
// Print one.
std::cout << "\ntable.at(3): ";
print(table.at(3));
return 0;
}
#include <stdexcept>
#include <pdal/PointRef.hpp>
#include <pdal/PointTable.hpp>
namespace pdal
{
class VectorPointTable : public StreamPointTable
{
public:
VectorPointTable(PointLayout layout, std::size_t initialPointCapacity = 0)
: StreamPointTable(m_layout)
, m_data(initialPointCapacity * layout.pointSize(), 0)
, m_layout(layout)
{ }
VectorPointTable(PointLayout layout, std::vector<char>&& data)
: StreamPointTable(m_layout)
, m_data(std::move(data))
, m_layout(layout)
{ }
point_count_t capacity() const override
{
assert(m_data.size() % m_layout.pointSize() == 0);
return m_data.size() / m_layout.pointSize();
}
PointRef at(PointId index)
{
if (index >= capacity())
{
throw std::out_of_range("Invalid index to VectorPointTable::at");
}
return PointRef(*this, index);
}
PointRef append()
{
return PointRef(*this, addPoint());
}
virtual char* getPoint(PointId index) override
{
return m_data.data() + pointsToBytes(index);
}
virtual PointId addPoint() override
{
m_data.insert(m_data.end(), m_layout.pointSize(), 0);
return capacity() - 1;
}
std::vector<char>& data() { return m_data; }
const std::vector<char>& data() const { return m_data; }
class Iterator
{
public:
explicit Iterator(VectorPointTable& table, PointId index = 0)
: m_table(table)
, m_index(index)
, m_pointRef(m_table, m_index)
{ }
Iterator& operator++()
{
m_pointRef.setPointId(++m_index);
return *this;
}
Iterator operator++(int)
{
Iterator other(*this);
++other;
return other;
}
PointRef& operator*() { return m_pointRef; }
bool operator!=(const Iterator& rhs) { return m_index != rhs.m_index; }
char* data() { return m_table.getPoint(m_index); }
private:
VectorPointTable& m_table;
PointId m_index;
PointRef m_pointRef;
};
Iterator begin() { return Iterator(*this); }
Iterator end() { return Iterator(*this, capacity()); }
private:
std::vector<char> m_data;
PointLayout m_layout;
};
} // namespace pdal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment