-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
dd34012
commit b2649a0
Showing
16 changed files
with
1,719 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
#include <iomanip> | ||
#include <regex> | ||
#include <set> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <pdal/util/FileUtils.hpp> | ||
#include <pdal/util/ProgramArgs.hpp> | ||
|
||
#include "BuPyramid.hpp" | ||
#include "FileInfo.hpp" | ||
#include "OctantInfo.hpp" | ||
#include "../untwine/Common.hpp" | ||
#include "../untwine/ProgressWriter.hpp" | ||
|
||
namespace untwine | ||
{ | ||
namespace bu | ||
{ | ||
|
||
/// BuPyramid | ||
|
||
BuPyramid::BuPyramid(BaseInfo& common) : m_b(common), m_manager(m_b) | ||
{} | ||
|
||
|
||
void BuPyramid::run(CellManager& cells) | ||
{ | ||
m_b.outputDir = options.outputDir; | ||
m_b.stats = options.stats; | ||
|
||
size_t count = queueWork(cells); | ||
|
||
std::thread runner(&PyramidManager::run, &m_manager); | ||
runner.join(); | ||
writeInfo(); | ||
} | ||
|
||
|
||
void BuPyramid::writeInfo() | ||
{ | ||
auto typeString = [](pdal::Dimension::BaseType b) | ||
{ | ||
using namespace pdal::Dimension; | ||
|
||
switch (b) | ||
{ | ||
case BaseType::Signed: | ||
return "signed"; | ||
case BaseType::Unsigned: | ||
return "unsigned"; | ||
case BaseType::Floating: | ||
return "float"; | ||
default: | ||
return ""; | ||
} | ||
}; | ||
|
||
std::ofstream out(m_b.outputDir + "/ept.json"); | ||
|
||
out << "{\n"; | ||
|
||
pdal::BOX3D& b = m_b.bounds; | ||
|
||
// Set fixed output for bounds output to get sufficient precision. | ||
out << std::fixed; | ||
out << "\"bounds\": [" << | ||
b.minx << ", " << b.miny << ", " << b.minz << ", " << | ||
b.maxx << ", " << b.maxy << ", " << b.maxz << "],\n"; | ||
|
||
pdal::BOX3D& tb = m_b.trueBounds; | ||
out << "\"boundsConforming\": [" << | ||
tb.minx << ", " << tb.miny << ", " << tb.minz << ", " << | ||
tb.maxx << ", " << tb.maxy << ", " << tb.maxz << "],\n"; | ||
// Reset to default float output to match PDAL option handling for now. | ||
out << std::defaultfloat; | ||
|
||
out << "\"dataType\": \"laszip\",\n"; | ||
out << "\"hierarchyType\": \"json\",\n"; | ||
out << "\"points\": " << m_manager.totalPoints() << ",\n"; | ||
out << "\"span\": 128,\n"; | ||
out << "\"version\": \"1.0.0\",\n"; | ||
out << "\"schema\": [\n"; | ||
for (auto di = m_b.dimInfo.begin(); di != m_b.dimInfo.end(); ++di) | ||
{ | ||
const FileDimInfo& fdi = *di; | ||
|
||
out << "\t{"; | ||
out << "\"name\": \"" << fdi.name << "\", "; | ||
out << "\"type\": \"" << typeString(pdal::Dimension::base(fdi.type)) << "\", "; | ||
if (fdi.name == "X") | ||
out << "\"scale\": " << m_b.scale[0] << ", \"offset\": " << m_b.offset[0] << ", "; | ||
if (fdi.name == "Y") | ||
out << "\"scale\": " << m_b.scale[1] << ", \"offset\": " << m_b.offset[1] << ", "; | ||
if (fdi.name == "Z") | ||
out << "\"scale\": " << m_b.scale[2] << ", \"offset\": " << m_b.offset[2] << ", "; | ||
out << "\"size\": " << pdal::Dimension::size(fdi.type); | ||
const Stats *stats = m_manager.stats(fdi.name); | ||
if (stats) | ||
{ | ||
const Stats::EnumMap& v = stats->values(); | ||
out << ", "; | ||
if (v.size()) | ||
{ | ||
out << "\"counts\": [ "; | ||
for (auto ci = v.begin(); ci != v.end(); ++ci) | ||
{ | ||
auto c = *ci; | ||
if (ci != v.begin()) | ||
out << ", "; | ||
out << "{\"value\": " << c.first << ", \"count\": " << c.second << "}"; | ||
} | ||
out << "], "; | ||
} | ||
out << "\"count\": " << m_manager.totalPoints() << ", "; | ||
out << "\"maximum\": " << stats->maximum() << ", "; | ||
out << "\"minimum\": " << stats->minimum() << ", "; | ||
out << "\"mean\": " << stats->average() << ", "; | ||
out << "\"stddev\": " << stats->stddev() << ", "; | ||
out << "\"variance\": " << stats->variance(); | ||
} | ||
out << "}"; | ||
if (di + 1 != m_b.dimInfo.end()) | ||
out << ","; | ||
out << "\n"; | ||
} | ||
out << "],\n"; | ||
|
||
out << "\"srs\": {\n"; | ||
if (m_b.srs.valid()) | ||
{ | ||
out << "\"wkt\": " << "\"" << pdal::Utils::escapeJSON(m_b.srs.getWKT()) << "\"\n"; | ||
} | ||
out << "}\n"; | ||
|
||
out << "}\n"; | ||
} | ||
|
||
|
||
size_t BuPyramid::queueWork() | ||
{ | ||
std::set<VoxelKey> needed; | ||
std::set<VoxelKey> parentsToProcess; | ||
std::vector<OctantInfo> have; | ||
const VoxelKey root; | ||
|
||
for (auto& kv : m_cells) | ||
{ | ||
VoxelKey k = kv.first; | ||
PointViewPtr cell = kv.second; | ||
|
||
// Stick an OctantInfo for this cell in the 'have' list. | ||
OctantInfo o(k); | ||
o.appendCell(cell); | ||
have.push_back(o); | ||
|
||
// Walk up the tree and make sure that we're populated for all children necessary | ||
// to process to the top level. We do this in order to facilitate processing -- | ||
// a parent node is ready to be processed when all its children have been processed, | ||
// so making sure a parent has all 8 children makes this easy. | ||
while (k != root) | ||
{ | ||
k = k.parent(); | ||
parentsToProcess.insert(k); | ||
for (int i = 0; i < 8; ++i) | ||
needed.insert(k.child(i)); | ||
} | ||
} | ||
|
||
// Now remove entries for the cells we have and their parents. | ||
for (const OctantInfo& o : have) | ||
{ | ||
VoxelKey k = o.key(); | ||
while (k != root) | ||
{ | ||
needed.erase(k); | ||
k = k.parent(); | ||
} | ||
} | ||
|
||
// Queue what we have. | ||
for (const OctantInfo& o : have) | ||
m_manager.queue(o); | ||
// Queue what we need but have no data for. | ||
for (const VoxelKey& k : needed) | ||
m_manager.queue(OctantInfo(k)); | ||
return parentsToProcess.size(); | ||
} | ||
|
||
} // namespace bu | ||
} // namespace untwine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/***************************************************************************** | ||
* 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 <string> | ||
#include <unordered_map> | ||
#include <vector> | ||
|
||
#include "PyramidManager.hpp" | ||
|
||
namespace pdal | ||
{ | ||
class ProgramArgs; | ||
} | ||
|
||
namespace untwine | ||
{ | ||
|
||
struct Options; | ||
class ProgressWriter; | ||
|
||
namespace bu | ||
{ | ||
|
||
class FileInfo; | ||
|
||
class BuPyramid | ||
{ | ||
public: | ||
BuPyramid(BaseInfo& common); | ||
void run(const Options& options, ProgressWriter& progress); | ||
|
||
private: | ||
void getInputFiles(); | ||
void readBaseInfo(); | ||
size_t queueWork(); | ||
void writeInfo(); | ||
|
||
BaseInfo m_b; | ||
PyramidManager m_manager; | ||
std::unordered_map<VoxelKey, FileInfo> m_allFiles; | ||
}; | ||
|
||
} // namespace bu | ||
} // namespace untwine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/***************************************************************************** | ||
* Copyright (c) 2021, 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 "VoxelKey.hpp" | ||
|
||
#include <unordered_map> | ||
|
||
namespace pdal | ||
{ | ||
namespace ept | ||
{ | ||
|
||
class CellManager | ||
{ | ||
public: | ||
using Cells = std::unordered_map<VoxelKey, PointViewPtr>; | ||
using iterator = Cells::iterator; | ||
using const_iterator = Cells::const_iterator; | ||
|
||
CellManager(PointViewPtr sourceView) : m_sourceView(sourceView) | ||
{} | ||
|
||
PointViewPtr& get(VoxelKey key) | ||
{ | ||
PointViewPtr& v = m_cells[key]; | ||
if (!v) | ||
v = m_sourceView->makeNew(); | ||
return v; | ||
} | ||
|
||
iterator erase(iterator it) | ||
{ | ||
return m_cells.erase(it); | ||
} | ||
|
||
const_iterator begin() const | ||
{ | ||
return m_cells.begin(); | ||
} | ||
|
||
const_iterator end() const | ||
{ | ||
return m_cells.end(); | ||
} | ||
|
||
iterator begin() | ||
{ | ||
return m_cells.begin(); | ||
} | ||
|
||
iterator end() | ||
{ | ||
return m_cells.end(); | ||
} | ||
|
||
// Note that C++17 has functions to do this. | ||
void merge(CellManager&& src) | ||
{ | ||
for (auto& kv : src) | ||
m_cells.insert(std::move(kv)); | ||
} | ||
|
||
private: | ||
Cells m_cells; | ||
|
||
PointViewPtr m_sourceView; | ||
}; | ||
|
||
} // namespace ept | ||
} // namespace pdal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/***************************************************************************** | ||
* Copyright (c) 2021, 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 | ||
|
||
namespace pdal | ||
{ | ||
namespace ept | ||
{ | ||
|
||
static const int MaxPointsPerNode = 100000; | ||
|
||
} // namespace ept | ||
} // namespace pdal |
Oops, something went wrong.