Skip to content

Commit e08c580

Browse files
authored
Remove JSON from public headers (PDAL#4723)
* Remove private functions from stac reader header. * Move interface functions out of EsriReader. * Make writeHierarchy a non-member. * Add missed file. * Move functions/data to Private.
1 parent 278f853 commit e08c580

File tree

4 files changed

+107
-94
lines changed

4 files changed

+107
-94
lines changed

io/EptAddonWriter.cpp

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,61 @@ namespace
5757
"http://pdal.io/stages/writers.ept.html",
5858
{ "ept_addon", "ept-addon" }
5959
};
60+
61+
} // unnamed namespace
62+
63+
struct EptAddonWriter::HierarchyWriter
64+
{
65+
public:
66+
HierarchyWriter(const ept::Hierarchy& hierarchy, uint64_t step,
67+
ThreadPool& pool, connector::Connector& conn) :
68+
m_hierarchy(hierarchy), m_step(step), m_pool(pool), m_connector(conn)
69+
{}
70+
71+
void write(const std::string& hierarchyDir, NL::json& curr, const ept::Key& key) const;
72+
73+
private:
74+
const ept::Hierarchy& m_hierarchy;
75+
uint64_t m_step;
76+
ThreadPool& m_pool;
77+
connector::Connector& m_connector;
78+
};
79+
80+
void EptAddonWriter::HierarchyWriter::write(const std::string& hierarchyDir, NL::json& curr,
81+
const ept::Key& key) const
82+
{
83+
auto it = m_hierarchy.find(key);
84+
if (it == m_hierarchy.end())
85+
return;
86+
87+
const ept::Overlap& overlap = *it;
88+
if (!overlap.m_count)
89+
return;
90+
91+
const std::string keyName = key.toString();
92+
if (m_step && key.d && (key.d % m_step == 0))
93+
{
94+
curr[keyName] = -1;
95+
96+
// Create a new hierarchy subtree.
97+
NL::json next {{ keyName, overlap.m_count }};
98+
99+
for (uint64_t dir(0); dir < 8; ++dir)
100+
write(hierarchyDir, next, key.bisect(dir));
101+
102+
std::string filename = hierarchyDir + keyName + ".json";
103+
std::string data = next.dump();
104+
m_pool.add([this, filename, data]()
105+
{
106+
m_connector.put(filename, data);
107+
});
108+
}
109+
else
110+
{
111+
curr[keyName] = overlap.m_count;
112+
for (uint64_t dir(0); dir < 8; ++dir)
113+
write(hierarchyDir, curr, key.bisect(dir));
114+
}
60115
}
61116

62117
CREATE_STATIC_STAGE(EptAddonWriter, s_info)
@@ -130,13 +185,15 @@ void EptAddonWriter::write(const PointViewPtr view)
130185
log()->get(LogLevel::Debug) << "Writing addon dimension " <<
131186
addon.name() << " to " << addon.filename() << std::endl;
132187

133-
writeOne(view, addon);
188+
HierarchyWriter writer(*m_hierarchy, m_hierarchyStep, *m_pool, *m_connector);
189+
writeOne(view, addon, writer);
134190

135191
log()->get(LogLevel::Debug) << "\tWritten" << std::endl;
136192
}
137193
}
138194

139-
void EptAddonWriter::writeOne(const PointViewPtr view, const ept::Addon& addon) const
195+
void EptAddonWriter::writeOne(const PointViewPtr view, const ept::Addon& addon,
196+
HierarchyWriter& writer) const
140197
{
141198
std::vector<std::vector<char>> buffers(m_hierarchy->size());
142199

@@ -196,7 +253,8 @@ void EptAddonWriter::writeOne(const PointViewPtr view, const ept::Addon& addon)
196253
std::string hierarchyDir = addon.hierarchyDir();
197254
m_connector->makeDir(hierarchyDir);
198255

199-
writeHierarchy(hierarchyDir, h, key);
256+
writer.write(hierarchyDir, h, key);
257+
200258
std::string filename = hierarchyDir + key.toString() + ".json";
201259
m_connector->put(filename, h.dump());
202260

@@ -212,42 +270,5 @@ void EptAddonWriter::writeOne(const PointViewPtr view, const ept::Addon& addon)
212270
m_connector->put("ept-addon.json", meta.dump());
213271
}
214272

215-
void EptAddonWriter::writeHierarchy(const std::string& directory,
216-
NL::json& curr, const ept::Key& key) const
217-
{
218-
auto it = m_hierarchy->find(key);
219-
if (it == m_hierarchy->end())
220-
return;
221-
222-
const ept::Overlap& overlap = *it;
223-
if (!overlap.m_count)
224-
return;
225-
226-
const std::string keyName = key.toString();
227-
if (m_hierarchyStep && key.d && (key.d % m_hierarchyStep == 0))
228-
{
229-
curr[keyName] = -1;
230-
231-
// Create a new hierarchy subtree.
232-
NL::json next {{ keyName, overlap.m_count }};
233-
234-
for (uint64_t dir(0); dir < 8; ++dir)
235-
writeHierarchy(directory, next, key.bisect(dir));
236-
237-
std::string filename = directory + keyName + ".json";
238-
std::string data = next.dump();
239-
m_pool->add([this, filename, data]()
240-
{
241-
m_connector->put(filename, data);
242-
});
243-
}
244-
else
245-
{
246-
curr[keyName] = overlap.m_count;
247-
for (uint64_t dir(0); dir < 8; ++dir)
248-
writeHierarchy(directory, curr, key.bisect(dir));
249-
}
250-
}
251-
252273
}
253274

io/EptAddonWriter.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,8 @@ class PDAL_EXPORT EptAddonWriter : public NoFilenameWriter
8080
virtual void ready(PointTableRef table) override;
8181
virtual void write(const PointViewPtr view) override;
8282

83-
void writeOne(const PointViewPtr view, const ept::Addon& addon) const;
84-
void writeHierarchy(const std::string& hierarchyDir, NL::json& hier,
85-
const ept::Key& key) const;
83+
struct HierarchyWriter;
84+
void writeOne(const PointViewPtr view, const ept::Addon& addon, HierarchyWriter& writer) const;
8685
std::string getTypeString(Dimension::Type t) const;
8786

8887
Dimension::Id m_nodeIdDim = Dimension::Id::Unknown;

io/EptReader.cpp

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ const StaticPluginInfo s_info
6666
{ "ept" }
6767
};
6868

69-
void reprogrow(BOX3D& b, SrsTransform& xform, double x, double y, double z)
69+
void reprogrow(BOX3D& b, const SrsTransform& xform, double x, double y, double z)
7070
{
7171
xform.transform(x, y, z);
7272
b.grow(x, y, z);
7373
}
7474

75-
BOX3D reprojectBoundsViaCorner(BOX3D src, SrsTransform& xform)
75+
BOX3D reprojectBoundsViaCorner(BOX3D src, const SrsTransform& xform)
7676
{
7777
if (!xform.valid())
7878
return src;
@@ -91,7 +91,7 @@ BOX3D reprojectBoundsViaCorner(BOX3D src, SrsTransform& xform)
9191
return b;
9292
}
9393

94-
BOX3D reprojectBoundsBcbfToLonLat(BOX3D src, SrsTransform& xform)
94+
BOX3D reprojectBoundsBcbfToLonLat(BOX3D src, const SrsTransform& xform)
9595
{
9696
if (!xform.valid())
9797
return src;
@@ -172,11 +172,21 @@ struct EptReader::Private
172172
std::unique_ptr<ept::Hierarchy> hierarchy;
173173
std::queue<ept::TileContents> contents;
174174
ept::AddonList addons;
175-
std::mutex mutex;
175+
mutable std::mutex mutex;
176176
std::condition_variable contentsCv;
177177
std::vector<PolyXform> polys;
178178
BoxXform bounds;
179179
SrsTransform llToBcbfTransform;
180+
uint64_t depthEnd {0}; // Zero indicates selection of all depths.
181+
uint64_t hierarchyStep {0};
182+
uint64_t nodeId;
183+
184+
void overlaps(ept::Hierarchy& target, const NL::json& hier, const ept::Key& key);
185+
bool passesSpatialFilter(const BOX3D& tileBounds) const;
186+
bool hasSpatialFilter() const
187+
{
188+
return !polys.empty() || bounds.box.valid();
189+
}
180190
};
181191

182192
EptReader::EptReader() : m_args(new EptReader::Args), m_p(new EptReader::Private),
@@ -289,7 +299,7 @@ void EptReader::initialize()
289299
// Figure out our max depth.
290300
const double queryResolution(m_args->m_resolution);
291301
//reseting depthEnd if initialize() has been called before
292-
m_depthEnd = 0;
302+
m_p->depthEnd = 0;
293303
if (queryResolution)
294304
{
295305
double currentResolution =
@@ -299,17 +309,17 @@ void EptReader::initialize()
299309

300310
// To select the current resolution level, we need depthEnd to be one
301311
// beyond it - this is a non-inclusive parameter.
302-
++m_depthEnd;
312+
++m_p->depthEnd;
303313

304314
while (currentResolution > queryResolution)
305315
{
306316
currentResolution /= 2;
307-
++m_depthEnd;
317+
++m_p->depthEnd;
308318
}
309319

310320
debug << "Query resolution: " << queryResolution << "\n";
311321
debug << "Actual resolution: " << currentResolution << "\n";
312-
debug << "Depth end: " << m_depthEnd << "\n";
322+
debug << "Depth end: " << m_p->depthEnd << "\n";
313323
}
314324

315325
debug << "Query bounds: " << m_p->bounds.box << "\n";
@@ -461,7 +471,7 @@ QuickInfo EptReader::inspect()
461471
// If there is a spatial filter from an explicit --bounds, an origin query,
462472
// or polygons, then we'll limit our number of points to be an upper bound,
463473
// and clip our bounds to the selected region.
464-
if (hasSpatialFilter())
474+
if (m_p->hasSpatialFilter())
465475
{
466476
log()->get(LogLevel::Debug) <<
467477
"Determining overlapping point count" << std::endl;
@@ -643,58 +653,50 @@ void EptReader::overlaps()
643653
key.b = m_p->info->bounds();
644654

645655
{
646-
m_nodeId = 1;
656+
m_p->nodeId = 1;
647657
std::string filename = m_p->info->hierarchyDir() + key.toString() + ".json";
648658

649659
// First, determine the overlapping nodes from the EPT resource.
650-
overlaps(*m_p->hierarchy, m_p->connector->getJson(filename), key);
660+
m_p->overlaps(*m_p->hierarchy, m_p->connector->getJson(filename), key);
651661
}
652662
m_p->pool->await();
653663

654664
// Determine the addons that exist to correspond to tiles.
655665
for (auto& addon : m_p->addons)
656666
{
657-
m_nodeId = 1;
667+
m_p->nodeId = 1;
658668
std::string filename = addon.hierarchyDir() + key.toString() + ".json";
659-
overlaps(addon.hierarchy(), m_p->connector->getJson(filename), key);
669+
m_p->overlaps(addon.hierarchy(), m_p->connector->getJson(filename), key);
660670
m_p->pool->await();
661671
}
662672
}
663673

664674

665-
bool EptReader::hasSpatialFilter() const
666-
{
667-
return !m_p->polys.empty() || m_p->bounds.box.valid();
668-
}
669-
670-
671675
// Determine if an EPT tile overlaps our query boundary
672-
bool EptReader::passesSpatialFilter(const BOX3D& tileBounds) const
676+
bool EptReader::Private::passesSpatialFilter(const BOX3D& tileBounds) const
673677
{
674678
auto boxOverlaps = [this, &tileBounds]() -> bool
675679
{
676-
if (!m_p->bounds.box.valid())
680+
if (!bounds.box.valid())
677681
return true;
678682

679-
if (m_p->llToBcbfTransform.valid())
683+
if (llToBcbfTransform.valid())
680684
{
681-
return reprojectBoundsBcbfToLonLat(m_p->bounds.box, m_p->llToBcbfTransform)
682-
.overlaps(tileBounds);
685+
return reprojectBoundsBcbfToLonLat(bounds.box, llToBcbfTransform).overlaps(tileBounds);
683686
}
684687

685688
// If the reprojected source bounds doesn't overlap our query bounds, we're done.
686-
return reprojectBoundsViaCorner(tileBounds, m_p->bounds.xform)
687-
.overlaps(m_p->bounds.box);
689+
return reprojectBoundsViaCorner(tileBounds, bounds.xform).overlaps(bounds.box);
688690
};
689691

690692
// Check the box of the key against our query polygon(s). If it doesn't overlap,
691693
// we can skip
692694
auto polysOverlap = [this, &tileBounds]() -> bool
693695
{
694-
if (m_p->polys.empty())
696+
if (polys.empty())
695697
return true;
696698

697-
for (auto& ps : m_p->polys)
699+
for (auto& ps : polys)
698700
if (!ps.poly.disjoint(reprojectBoundsViaCorner(tileBounds, ps.xform)))
699701
return true;
700702
return false;
@@ -707,12 +709,12 @@ bool EptReader::passesSpatialFilter(const BOX3D& tileBounds) const
707709
// This lock is here because if a bunch of threads are using the transform
708710
// at the same time, it seems to get corrupted. There may be other instances
709711
// that need to be locked.
710-
std::lock_guard<std::mutex> lock(m_p->mutex);
712+
std::lock_guard<std::mutex> lock(mutex);
711713
return boxOverlaps() && polysOverlap();
712714
}
713715

714716

715-
void EptReader::overlaps(ept::Hierarchy& target, const NL::json& hier, const ept::Key& key)
717+
void EptReader::Private::overlaps(ept::Hierarchy& target, const NL::json& hier, const ept::Key& key)
716718
{
717719
// If our key isn't in the hierarchy, we've totally traversed this tree
718720
// branch (there are no lower nodes).
@@ -722,7 +724,7 @@ void EptReader::overlaps(ept::Hierarchy& target, const NL::json& hier, const ept
722724

723725
// If our query geometry doesn't overlap the tile or we're past the end of the requested
724726
// depth, return.
725-
if (!passesSpatialFilter(key.b) || (m_depthEnd && key.d >= m_depthEnd))
727+
if (!passesSpatialFilter(key.b) || (depthEnd && key.d >= depthEnd))
726728
return;
727729

728730

@@ -736,37 +738,37 @@ void EptReader::overlaps(ept::Hierarchy& target, const NL::json& hier, const ept
736738

737739
if (numPoints == -1)
738740
{
739-
if (!m_hierarchyStep)
740-
m_hierarchyStep = key.d;
741+
if (!hierarchyStep)
742+
hierarchyStep = key.d;
741743

742744
// If the hierarchy points value here is -1, then we need to fetch the
743745
// hierarchy subtree corresponding to this root.
744-
m_p->pool->add([this, &target, key]()
746+
pool->add([this, &target, key]()
745747
{
746748
try
747749
{
748-
std::string filename = m_p->info->hierarchyDir() + key.toString() + ".json";
749-
const auto subRoot(m_p->connector->getJson(filename));
750+
std::string filename = info->hierarchyDir() + key.toString() + ".json";
751+
const auto subRoot(connector->getJson(filename));
750752
overlaps(target, subRoot, key);
751753
}
752754
catch (const arbiter::ArbiterError& err)
753755
{
754-
throwError(err.what());
756+
throw pdal_error(err.what());
755757
}
756758
});
757759
}
758760
else if (numPoints < 0)
759761
{
760-
throwError("Invalid point count for key '" + key.toString() + "'.");
762+
throw pdal_error("Invalid point count for key '" + key.toString() + "'.");
761763
}
762764
else
763765
{
764766
// Note that when processing addons, we set node IDs which may
765767
// not match the base hierarchy, but it doesn't matter since
766768
// they are never used.
767769
{
768-
std::lock_guard<std::mutex> lock(m_p->mutex);
769-
target.emplace(key, (point_count_t)numPoints, m_nodeId++);
770+
std::lock_guard<std::mutex> lock(mutex);
771+
target.emplace(key, (point_count_t)numPoints, nodeId++);
770772
}
771773

772774
for (uint64_t dir(0); dir < 8; ++dir)
@@ -837,7 +839,7 @@ bool EptReader::processPoint(PointRef& dst, const ept::TileContents& tile)
837839
double z = p.getFieldAs<double>(Id::Z);
838840

839841
// If there is a spatial filter, make sure it passes.
840-
if (hasSpatialFilter())
842+
if (m_p->hasSpatialFilter())
841843
if (!passesBoundsFilter(x, y, z) || !passesPolyFilter(x, y, z))
842844
return false;
843845

@@ -916,7 +918,7 @@ point_count_t EptReader::read(PointViewPtr view, point_count_t count)
916918
{
917919
ept::ArtifactPtr artifact
918920
(new ept::Artifact(std::move(m_p->info), std::move(m_p->hierarchy),
919-
std::move(m_p->connector), m_hierarchyStep));
921+
std::move(m_p->connector), m_p->hierarchyStep));
920922
m_artifactMgr->put("ept", artifact);
921923
}
922924

0 commit comments

Comments
 (0)