QGIS/external/untwine/bu/VoxelInfo.hpp
Martin Dobias 1513f0ab93 Upgrade untwine to the latest upstream improvements
We are now using the code from "qgis" branch:
https://github.com/hobu/untwine/tree/qgis
It is in sync with "main" branch of untwine as of today, just with a couple
of small patches to make it work with PDAL older than 2.4.

The new version of untwine includes:
- indexing to COPC (in addition to EPT)
- fixes to bugs that were reported in QGIS
- error reporting

Untwine now also directly links to lazperf library (in addition to PDAL).
2022-03-24 12:06:55 -07:00

166 lines
5.0 KiB
C++

/*****************************************************************************
* Copyright (c) 2020, Hobu, Inc. (info@hobu.co) *
* *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
****************************************************************************/
#pragma once
#include <array>
#include <unordered_map>
#include "../untwine/FileDimInfo.hpp"
#include "../untwine/GridKey.hpp"
#include "../untwine/Point.hpp"
#include "../untwine/VoxelKey.hpp"
#include "OctantInfo.hpp"
namespace untwine
{
namespace bu
{
class VoxelInfo
{
public:
// This probably needs a data structure geared for sparse data as I *think* that many
// of our lookups will fail.
using Grid = std::unordered_map<GridKey, int>;
VoxelInfo(const pdal::BOX3D& fullBounds, const VoxelKey& key) :
m_fullBounds(fullBounds), m_octant(key)
{
//ABELL - This shouldn't be necessary. The key should be in the children
// when they're pulled out of the queue.
for (int i = 0; i < 8; ++i)
m_children[i].setKey(key.child(i));
int cells = (int)std::pow(2, key.level());
m_xWidth = (fullBounds.maxx - fullBounds.minx) / cells;
m_yWidth = (fullBounds.maxy - fullBounds.miny) / cells;
m_zWidth = (fullBounds.maxz - fullBounds.minz) / cells;
// Calculate the bounds of this voxel.
m_bounds.minx = fullBounds.minx + (key.x() * m_xWidth);
m_bounds.maxx = m_bounds.minx + m_xWidth;
m_bounds.miny = fullBounds.miny + (key.y() * m_yWidth);
m_bounds.maxy = m_bounds.miny + m_yWidth;
m_bounds.minz = fullBounds.minz + (key.z() * m_zWidth);
m_bounds.maxz = m_bounds.minz + m_zWidth;
// Determine spacing between points.
m_spacing = maxWidth() / CellCount;
// Make the spacing smaller than what we expect as the final spacing since we're
// going to select points from the grid for the parent.
if (key != VoxelKey(0, 0, 0, 0))
m_spacing *= 1.5;
m_squareSpacing = m_spacing * m_spacing;
static const double sqrt3 = std::sqrt(3);
m_gridCellWidth = m_spacing / sqrt3;
m_gridXCount = (int)std::ceil((m_bounds.maxx - m_bounds.minx) / m_gridCellWidth);
m_gridYCount = (int)std::ceil((m_bounds.maxy - m_bounds.miny) / m_gridCellWidth);
m_gridZCount = (int)std::ceil((m_bounds.maxz - m_bounds.minz) / m_gridCellWidth);
}
VoxelKey key() const
{ return m_octant.key(); }
OctantInfo& operator[](int dir)
{ return m_children[dir]; }
OctantInfo& octant()
{ return m_octant; }
size_t numPoints() const
{
size_t cnt = 0;
for (const OctantInfo& oi : m_children)
cnt += oi.numPoints();
return cnt;
}
bool hasPoints() const
{
for (const OctantInfo& oi : m_children)
if (oi.hasPoints())
return true;
return false;
}
double spacing() const
{ return m_spacing; }
double squareSpacing() const
{ return m_squareSpacing; }
double minWidth() const
{ return (std::min)((std::min)(m_xWidth, m_yWidth), m_zWidth); }
double maxWidth() const
{ return (std::max)((std::max)(m_xWidth, m_yWidth), m_zWidth); }
double xWidth() const
{ return m_xWidth; }
double yWidth() const
{ return m_yWidth; }
double zWidth() const
{ return m_zWidth; }
GridKey gridKey(const Point& p) const
{
double x = p.x() - m_bounds.minx;
double y = p.y() - m_bounds.miny;
double z = p.z() - m_bounds.minz;
return GridKey((int)(x / m_gridCellWidth), (int)(y / m_gridCellWidth),
(int)(z / m_gridCellWidth));
}
//ABELL - Really torn WRT making Grid its own thing.
Grid& grid()
{ return m_grid; }
int gridXCount() const
{ return m_gridXCount; }
int gridYCount() const
{ return m_gridYCount; }
int gridZCount() const
{ return m_gridZCount; }
pdal::BOX3D bounds() const
{ return m_bounds; }
private:
pdal::BOX3D m_fullBounds;
pdal::BOX3D m_bounds;
double m_xWidth;
double m_yWidth;
double m_zWidth;
double m_gridCellWidth;
int m_gridXCount;
int m_gridYCount;
int m_gridZCount;
std::array<OctantInfo, 8> m_children;
OctantInfo m_octant;
double m_spacing;
double m_squareSpacing;
Grid m_grid;
};
} // namespace bu
} // namespace untwine