@@ -66,13 +66,13 @@ const StaticPluginInfo s_info
66
66
{ " ept" }
67
67
};
68
68
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)
70
70
{
71
71
xform.transform (x, y, z);
72
72
b.grow (x, y, z);
73
73
}
74
74
75
- BOX3D reprojectBoundsViaCorner (BOX3D src, SrsTransform& xform)
75
+ BOX3D reprojectBoundsViaCorner (BOX3D src, const SrsTransform& xform)
76
76
{
77
77
if (!xform.valid ())
78
78
return src;
@@ -91,7 +91,7 @@ BOX3D reprojectBoundsViaCorner(BOX3D src, SrsTransform& xform)
91
91
return b;
92
92
}
93
93
94
- BOX3D reprojectBoundsBcbfToLonLat (BOX3D src, SrsTransform& xform)
94
+ BOX3D reprojectBoundsBcbfToLonLat (BOX3D src, const SrsTransform& xform)
95
95
{
96
96
if (!xform.valid ())
97
97
return src;
@@ -172,11 +172,21 @@ struct EptReader::Private
172
172
std::unique_ptr<ept::Hierarchy> hierarchy;
173
173
std::queue<ept::TileContents> contents;
174
174
ept::AddonList addons;
175
- std::mutex mutex;
175
+ mutable std::mutex mutex;
176
176
std::condition_variable contentsCv;
177
177
std::vector<PolyXform> polys;
178
178
BoxXform bounds;
179
179
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
+ }
180
190
};
181
191
182
192
EptReader::EptReader () : m_args(new EptReader::Args), m_p(new EptReader::Private),
@@ -289,7 +299,7 @@ void EptReader::initialize()
289
299
// Figure out our max depth.
290
300
const double queryResolution (m_args->m_resolution );
291
301
// reseting depthEnd if initialize() has been called before
292
- m_depthEnd = 0 ;
302
+ m_p-> depthEnd = 0 ;
293
303
if (queryResolution)
294
304
{
295
305
double currentResolution =
@@ -299,17 +309,17 @@ void EptReader::initialize()
299
309
300
310
// To select the current resolution level, we need depthEnd to be one
301
311
// beyond it - this is a non-inclusive parameter.
302
- ++m_depthEnd ;
312
+ ++m_p-> depthEnd ;
303
313
304
314
while (currentResolution > queryResolution)
305
315
{
306
316
currentResolution /= 2 ;
307
- ++m_depthEnd ;
317
+ ++m_p-> depthEnd ;
308
318
}
309
319
310
320
debug << " Query resolution: " << queryResolution << " \n " ;
311
321
debug << " Actual resolution: " << currentResolution << " \n " ;
312
- debug << " Depth end: " << m_depthEnd << " \n " ;
322
+ debug << " Depth end: " << m_p-> depthEnd << " \n " ;
313
323
}
314
324
315
325
debug << " Query bounds: " << m_p->bounds .box << " \n " ;
@@ -461,7 +471,7 @@ QuickInfo EptReader::inspect()
461
471
// If there is a spatial filter from an explicit --bounds, an origin query,
462
472
// or polygons, then we'll limit our number of points to be an upper bound,
463
473
// and clip our bounds to the selected region.
464
- if (hasSpatialFilter ())
474
+ if (m_p-> hasSpatialFilter ())
465
475
{
466
476
log ()->get (LogLevel::Debug) <<
467
477
" Determining overlapping point count" << std::endl;
@@ -643,58 +653,50 @@ void EptReader::overlaps()
643
653
key.b = m_p->info ->bounds ();
644
654
645
655
{
646
- m_nodeId = 1 ;
656
+ m_p-> nodeId = 1 ;
647
657
std::string filename = m_p->info ->hierarchyDir () + key.toString () + " .json" ;
648
658
649
659
// 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);
651
661
}
652
662
m_p->pool ->await ();
653
663
654
664
// Determine the addons that exist to correspond to tiles.
655
665
for (auto & addon : m_p->addons )
656
666
{
657
- m_nodeId = 1 ;
667
+ m_p-> nodeId = 1 ;
658
668
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);
660
670
m_p->pool ->await ();
661
671
}
662
672
}
663
673
664
674
665
- bool EptReader::hasSpatialFilter () const
666
- {
667
- return !m_p->polys .empty () || m_p->bounds .box .valid ();
668
- }
669
-
670
-
671
675
// 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
673
677
{
674
678
auto boxOverlaps = [this , &tileBounds]() -> bool
675
679
{
676
- if (!m_p-> bounds .box .valid ())
680
+ if (!bounds.box .valid ())
677
681
return true ;
678
682
679
- if (m_p-> llToBcbfTransform .valid ())
683
+ if (llToBcbfTransform.valid ())
680
684
{
681
- return reprojectBoundsBcbfToLonLat (m_p->bounds .box , m_p->llToBcbfTransform )
682
- .overlaps (tileBounds);
685
+ return reprojectBoundsBcbfToLonLat (bounds.box , llToBcbfTransform).overlaps (tileBounds);
683
686
}
684
687
685
688
// 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 );
688
690
};
689
691
690
692
// Check the box of the key against our query polygon(s). If it doesn't overlap,
691
693
// we can skip
692
694
auto polysOverlap = [this , &tileBounds]() -> bool
693
695
{
694
- if (m_p-> polys .empty ())
696
+ if (polys.empty ())
695
697
return true ;
696
698
697
- for (auto & ps : m_p-> polys )
699
+ for (auto & ps : polys)
698
700
if (!ps.poly .disjoint (reprojectBoundsViaCorner (tileBounds, ps.xform )))
699
701
return true ;
700
702
return false ;
@@ -707,12 +709,12 @@ bool EptReader::passesSpatialFilter(const BOX3D& tileBounds) const
707
709
// This lock is here because if a bunch of threads are using the transform
708
710
// at the same time, it seems to get corrupted. There may be other instances
709
711
// that need to be locked.
710
- std::lock_guard<std::mutex> lock (m_p-> mutex );
712
+ std::lock_guard<std::mutex> lock (mutex);
711
713
return boxOverlaps () && polysOverlap ();
712
714
}
713
715
714
716
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)
716
718
{
717
719
// If our key isn't in the hierarchy, we've totally traversed this tree
718
720
// branch (there are no lower nodes).
@@ -722,7 +724,7 @@ void EptReader::overlaps(ept::Hierarchy& target, const NL::json& hier, const ept
722
724
723
725
// If our query geometry doesn't overlap the tile or we're past the end of the requested
724
726
// depth, return.
725
- if (!passesSpatialFilter (key.b ) || (m_depthEnd && key.d >= m_depthEnd ))
727
+ if (!passesSpatialFilter (key.b ) || (depthEnd && key.d >= depthEnd ))
726
728
return ;
727
729
728
730
@@ -736,37 +738,37 @@ void EptReader::overlaps(ept::Hierarchy& target, const NL::json& hier, const ept
736
738
737
739
if (numPoints == -1 )
738
740
{
739
- if (!m_hierarchyStep )
740
- m_hierarchyStep = key.d ;
741
+ if (!hierarchyStep )
742
+ hierarchyStep = key.d ;
741
743
742
744
// If the hierarchy points value here is -1, then we need to fetch the
743
745
// hierarchy subtree corresponding to this root.
744
- m_p-> pool ->add ([this , &target, key]()
746
+ pool->add ([this , &target, key]()
745
747
{
746
748
try
747
749
{
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));
750
752
overlaps (target, subRoot, key);
751
753
}
752
754
catch (const arbiter::ArbiterError& err)
753
755
{
754
- throwError (err.what ());
756
+ throw pdal_error (err.what ());
755
757
}
756
758
});
757
759
}
758
760
else if (numPoints < 0 )
759
761
{
760
- throwError (" Invalid point count for key '" + key.toString () + " '." );
762
+ throw pdal_error (" Invalid point count for key '" + key.toString () + " '." );
761
763
}
762
764
else
763
765
{
764
766
// Note that when processing addons, we set node IDs which may
765
767
// not match the base hierarchy, but it doesn't matter since
766
768
// they are never used.
767
769
{
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 ++);
770
772
}
771
773
772
774
for (uint64_t dir (0 ); dir < 8 ; ++dir)
@@ -837,7 +839,7 @@ bool EptReader::processPoint(PointRef& dst, const ept::TileContents& tile)
837
839
double z = p.getFieldAs <double >(Id::Z);
838
840
839
841
// If there is a spatial filter, make sure it passes.
840
- if (hasSpatialFilter ())
842
+ if (m_p-> hasSpatialFilter ())
841
843
if (!passesBoundsFilter (x, y, z) || !passesPolyFilter (x, y, z))
842
844
return false ;
843
845
@@ -916,7 +918,7 @@ point_count_t EptReader::read(PointViewPtr view, point_count_t count)
916
918
{
917
919
ept::ArtifactPtr artifact
918
920
(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 ));
920
922
m_artifactMgr->put (" ept" , artifact);
921
923
}
922
924
0 commit comments