11 #include <boost/thread.hpp> 23 #include <xmsgrid/geometry/GmPtSearch.h> 27 #include <xmsgrid/geometry/geoms.h> 74 BSHP<ThreadLoop> q = BDPC<ThreadLoop>(r);
90 virtual void SetPtsTris(BSHP<VecPt3d> a_pts, BSHP<VecInt> a_tris)
override;
91 void SetScalars(
const float* a_scalar,
size_t a_n)
override;
92 void SetScalars(BSHP<VecFlt> a_scalar)
override;
93 virtual void SetPts(BSHP<VecPt3d> a_pts,
bool a_2d)
override;
100 virtual const BSHP<VecPt3d>
GetPts()
const override;
101 virtual const BSHP<VecInt>
GetTris()
const override;
102 virtual const BSHP<VecFlt>
GetScalars()
const override;
105 virtual void SetTrunc(
double a_sMax,
double a_sMin)
override;
130 return InterpIdw::CLASSIC;
131 return InterpIdw::MODIFIED;
138 return InterpIdw::CONSTANT;
164 VecDbl& a_wt)
const override;
171 virtual std::string
ToString()
const override;
173 void SetPower(
double a_power)
override;
175 void SetSearchOpts(
int a_nNearestPoints,
bool a_quad_oct_Search)
override;
186 const Pt3d& a_pt)
const;
191 BSHP<Observer> a_p)
override;
248 static void iSaveWeight(
int a_ptIdx,
int a_pt,
double a_val)
251 iPtIdx()[a_ptIdx].push_back(a_pt);
252 iWeights()[a_ptIdx].push_back(a_val);
259 static void iCallSignals(
VecInt2d& a_ptIdx,
262 for (
size_t i = 0; i < a_ptIdx.size(); ++i)
265 for (
size_t j = 0; j < a_ptIdx[i].size(); ++j)
312 , m_quadOctSearch(false)
313 , m_modifiedShepardWeights(true)
319 , m_scalarFrom(new
VecFlt())
322 , m_saveWeights(false)
326 , m_multiThread(true)
332 InterpIdwImpl::~InterpIdwImpl()
363 s.push_back((
float)p.z);
447 if (1 == nPts.size())
449 rval = (*m_scalarFrom)[nPts[0]];
451 iSaveWeight(a_idx, nPts[0], 1.0);
474 a_scalars.assign(a_pts.size(), 0);
477 iPtIdx().assign(a_scalars.size(),
VecInt());
478 iWeights().assign(a_scalars.size(),
VecDbl());
483 for (
size_t i = 0; i < a_pts.size(); ++i)
491 threadMgr->SetThreadLoopClass(
InterpThread(*
this, a_scalars, a_pts).CreateForNewThread());
492 threadMgr->SetObserver(
m_prog);
493 if (a_pts.size() < 10000)
494 threadMgr->ExplicitlySetNumThreads(2);
495 threadMgr->RunThreads((
int)a_scalars.size());
499 iCallSignals(iPtIdx(), iWeights());
577 m_ptSearch->NearestPtsToPt(a_pt, 1,
false, a_nPts);
589 a_nPts.assign(
m_pts->size(), 0);
590 for (
size_t i = 0; i <
m_pts->size(); ++i)
607 std::stringstream ss;
628 for (
size_t i = 0; i <
m_ptIdx.size(); ++i)
633 for (
size_t i = 0; i <
m_weights.size(); ++i)
656 const Pt3d& a_pt)
const 660 for (
size_t i = 0; i < a_w.size(); ++i)
666 iSaveWeight(a_ptIdx, j, a_w[i]);
678 if (a_ == InterpIdw::CLASSIC)
680 else if (a_ == InterpIdw::MODIFIED)
738 rval =
m_nodalFunc->ScalarFromPtIdx(a_ptIdx, a_loc);
765 a_pts = {{-75.0, -16.0, 0.0}, {-60.0, 32.0, 0.0}, {-34.0, 50.0, 0.0}, {-34.0, 27.0, 0.0},
766 {-8.0, 40.0, 0.0}, {16.0, 38.0, 0.0}, {-25.0, 14.0, 43.64}, {10.0, 18.0, 44.16},
767 {27.0, 26.0, 0.0}, {63.0, 35.0, 0.0}, {-32.0, 0.0, 59.04}, {-7.0, 7.0, 90.2},
768 {26.0, 6.0, 67.2}, {75.0, 7.0, 0.0}, {-37.0, -15.0, 9.24}, {-7.0, -13.0, 71.0},
769 {2.0, -3.0, 98.4}, {31.0, -15.0, 25.56}, {60.0, -13.0, 0.0}, {-50.0, -30.0, 0.0},
770 {-30.0, -28.0, 0.0}, {43.0, -22.0, 0.0}, {-32.0, -50.0, 0.0}, {27.0, -37.0, 0.0},
772 a_scalar.resize(a_pts.size());
773 for (
size_t i = 0; i < a_pts.size(); ++i)
774 a_scalar[i] = (
float)a_pts[i].z;
776 a_iPts = {{-90, 60, 0}, {90, 60, 0}, {-90, -60, 0}, {90, -60, 0}, {60, -33, 0}};
797 BSHP<VecPt3d> pts(
new VecPt3d());
798 pts->push_back(
Pt3d());
800 idw->SetPts(pts,
true);
801 idw->SetScalars(&scalar[0], scalar.size());
804 pts->push_back(
Pt3d(1, 1, 1));
806 idw->SetMultiThreading(
false);
807 idw->InterpToPts(*pts, scalar);
808 TS_ASSERT_EQUALS(2.0f, scalar[0]);
815 BSHP<VecPt3d> pts(
new VecPt3d());
817 BSHP<VecFlt> scalar(
new VecFlt());
822 idw->SetPts(pts,
true);
823 idw->SetScalars(scalar);
824 idw->SetMultiThreading(
false);
825 idw->InterpToPts(ipts, s);
826 vBase = {4.5606198f, 2.9842966f, 4.8022637f, 2.8352659f, 0.0f};
834 BSHP<VecPt3d> pts(
new VecPt3d());
836 VecFlt scalar, s(5), vBase;
839 idw->SetPts(pts,
true);
840 idw->SetScalars(&scalar[0], scalar.size());
841 idw->SetSearchOpts(-1,
false);
842 for (
int i = 0; i < 5; ++i)
843 s[i] = idw->InterpToPt(ipts[i]);
844 vBase = {10.172515f, 7.9736009f, 9.5391436f, 7.2670202f, 0.0f};
852 BSHP<VecPt3d> pts(
new VecPt3d());
857 idw->SetPts(pts,
true);
858 idw->SetScalars(&scalar[0], scalar.size());
859 idw->SetSearchOpts(5,
false);
863 idw->InterpWeights(myPt, idx, wt);
864 wtBase = {0.0019633969662346436, 0.064476394365326525, 0.0, 0.014616102731534851,
865 0.91894410593690401};
873 BSHP<VecPt3d> pts(
new VecPt3d());
875 VecFlt scalar, s(5), vBase;
878 idw->SetPts(pts,
true);
879 idw->SetScalars(&scalar[0], scalar.size());
880 idw->SetSearchOpts(6,
true);
882 idw->SetNodalFunction(InterpIdw::GRAD_PLANE, 6,
true, NULL);
883 for (
int i = 0; i < 5; ++i)
884 s[i] = idw->InterpToPt(ipts[i]);
885 vBase = {6.1976342f, 0.60451090f, -0.80145311f, 13.252287f, 0.0f};
893 BSHP<VecPt3d> pts(
new VecPt3d());
895 VecFlt scalar, s(5), vBase;
898 idw->SetPts(pts,
true);
899 idw->SetScalars(&scalar[0], scalar.size());
900 idw->SetWeightCalcMethod(InterpIdw::CLASSIC);
901 for (
int i = 0; i < 5; ++i)
902 s[i] = idw->InterpToPt(ipts[i]);
903 vBase = {16.884138f, 15.516511f, 16.895596f, 14.160349f, 0.0f};
906 for (
int i = 0; i < 5; ++i)
907 s[i] = idw->InterpToPt(ipts[i]);
908 vBase = {21.907907f, 21.933628f, 22.670679f, 19.839111f, 0.0f};
916 BSHP<VecPt3d> pts(
new VecPt3d());
918 VecFlt scalar, s(5), vBase;
921 idw->SetPts(pts,
true);
922 idw->SetScalars(&scalar[0], scalar.size());
923 idw->SetNodalFunction(InterpIdw::QUADRATIC,
XM_NONE,
true, NULL);
924 for (
int i = 0; i < 5; ++i)
925 s[i] = idw->InterpToPt(ipts[i]);
926 vBase = {-46.129936f, -65.856499f, -71.997749f, -47.643417f, 0.0f};
934 BSHP<VecPt3d> pts(
new VecPt3d());
936 VecFlt scalar, s(5), vBase;
939 idw->SetPts(pts,
false);
940 idw->SetScalars(&scalar[0], scalar.size());
941 idw->SetNodalFunction(InterpIdw::GRAD_PLANE,
XM_NONE,
true, NULL);
942 for (
int i = 0; i < 5; ++i)
943 s[i] = idw->InterpToPt(ipts[i]);
944 vBase = {1.5025957e-008f, -7.7562149e-008f, 1.4442284e-007f, -6.1540938e-008f, 0.0f};
946 idw->SetNodalFunction(InterpIdw::QUADRATIC,
XM_NONE,
true, NULL);
947 for (
int i = 0; i < 5; ++i)
948 s[i] = idw->InterpToPt(ipts[i]);
949 vBase = {5.2535050e-008f, -1.2138121e-007f, 4.1972626e-007f, -1.1271275e-007f, 0.0f};
958 BSHP<VecPt3d> pts(
new VecPt3d());
960 VecFlt scalar, s(5), vBase;
961 *pts = {{0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}};
962 scalar.assign(pts->size(), 0);
963 ipts.assign(5,
Pt3d(-1, 0, 0));
981 BSHP<VecPt3d> pts(
new VecPt3d());
983 VecFlt scalar, s(5), vBase;
984 *pts = {{0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}};
985 scalar.assign(pts->size(), 0);
986 ipts.assign(5,
Pt3d(-1, 0, 0));
996 for (
int i = 0; i < 5; ++i)
virtual bool GetSearchOptsUseQuadrantSearch() const override
get the search options option to do a quadrant or octant search
BSHP< VecFlt > m_scalarFrom
Scalars at the points used to interpolate.
BSHP< VecPt3d > m_pts
Points used to interpolate.
virtual float InterpToPt(const Pt3d &a_pt) override
Interpolates to the location specified by a_pt and returns the value.
void testInterp2d_b()
tests 2d interpolation using all idw points
std::vector< int > VecInt
double m_truncMin
Minimum truncation value. All interpolated values will be >=.
Threading class to compute idw interpolation in parallel.
double ScalarFromNodalFunc(int a_ptIdx, const Pt3d &a_loc) const
Returns a scalar value based on the nodal function. When nodal functions are used then the scalar val...
void testInterp2d_e()
tests 2d interpolation using classic weighting, exponent set to 1
virtual const BSHP< VecInt > GetTris() const override
Returns shared pointer to triangles vector.
InterpIdwImpl & m_interp
Idw interpolation class.
BSHP< GmPtSearch > m_ptSearch
Class used to find nearest points.
#define XM_ENSURE_FALSE(...)
Signals that can be called when performing idw or kriging interpolation. Used by GMS with Pilot Point...
void testInterp3d()
test 3d interpolation
std::vector< double > VecDbl
virtual void SetTrunc(double a_sMax, double a_sMin) override
Set the truncation values for the interpolation and turn on truncation.
virtual int GetSearchOptsNumNearestPts() const override
get the search options number of nearest points
virtual DynBitset GetTriActivity() const override
Returns empty bitset. No triangles used for idw.
std::vector< float > VecFlt
static BSHP< NodalFunc > New(int a_type, bool a_2d, boost::shared_ptr< GmPtSearch > a_ptSearch, const std::vector< Pt3d > &a_pts, const std::vector< float > &a_scalar, int a_nNearest, bool a_quad_oct, double a_power, bool a_modifiedShepardWeights, boost::shared_ptr< Observer > a_p, InterpNatNeigh *a_natNeigh)
Creates a NodalFunc class.
void SetWeightCalcMethod(InterpIdw::WeightEnum a_) override
Sets the method for calculating the weights. The classic just uses 1/distance^exponent. The modified method uses another formulation based on the distance of the furtherest location from the interpolation pt.
virtual bool GetTruncateInterpolatedValues() const override
get the option to truncate interpolated values
bool m_trunc
flag to indicate if truncation is on
int CurrIdx()
Returns the current index of the thread.
static BSHP< InterpIdw > New()
Creates an InterpIdw class.
bool m_saveWeights
flag for saving the interpolation weights
void testInterp2d_a()
tests 2d interpolation
void testInterp2d_f()
test 2d interpolation with a quadratic nodal function
Class that performs inverse distance weighted interpolation.
void testCreateClass()
Creates a class.
void SetNodalFunction(NodalFuncEnum a_, int a_nNearest, bool a_quad_oct, BSHP< Observer > a_p) override
Sets the type of nodal function as well as options for computing nodal functions. ...
BSHP< NodalFunc > m_nodalFunc
Nodal function (constant, gradient plane, quadratic)
void VecToStream(std::stringstream &a_ss, const T &a_v, std::string a_label)
virtual ~InterpIdw()
Destructor.
virtual void SetPts(BSHP< VecPt3d > a_pts, bool a_2d) override
Sets the points that will be used to do the interpolation.
InterpIdwImpl()
Creates an InterpIdw class.
void testErrors()
test error reporting. Errors can be generated by the nodal function setup process.
virtual const BSHP< VecPt3d > GetPts() const override
Returns shared pointer to points vector.
void SetObserver(BSHP< Observer > a_prog) override
Set the observer class so that feedback on the interpolation process can be received.
virtual void SetPtsTris(BSHP< VecPt3d > a_pts, BSHP< VecInt > a_tris) override
Sets the points that will be used to do the interpolation.
virtual void SetSaveWeights(bool a_) override
sets a flag to save the weights computed by the interpolation
boost::dynamic_bitset< size_t > DynBitset
std::vector< VecInt > VecInt2d
const VecPt3d & m_pts
Pts being interpolated to.
void testErrors2()
test error reporting.
void RecalcNodalFunc()
Recalculates the nodal function. This happens when the scalars change.
virtual double GetTruncMax() const override
get the maximum truncation value
VecDbl2d m_weights
calculated weights for saving weights
virtual void InterpWeights(const Pt3d &a_pt, VecInt &a_idx, VecDbl &a_wt) const override
Given a location and an array of points the weights associated with array of points are calculated...
void SetSearchOpts(int a_nNearestPoints, bool a_quad_oct_Search) override
Sets the search options for how to find the nearest points to the interpolation point. The number of nearest points can be specified as well as whether to find the nearest points in each quadrant or octant.
void SetPower(double a_power) override
Sets the exponent for the interpolation. By default the class does inverse distance squared weighting...
std::string GetAndClearStackStr()
#define XM_ENSURE_TRUE(...)
virtual WeightEnum GetWeightCalcMethod() const override
get the weight calculation method
void Worker() override
Actually does the interpolation in a thread.
void inSetDataIndex(int val)
Calls the SetDataIndex signal.
static BSHP< ThreadMgr > New()
Creates a ThreadMgr.
void ValFromWeights(VecDbl &a_w, VecInt &a_nPts, float &a_val, int a_ptIdx, const Pt3d &a_pt) const
Given a vector of weights, the interpolated value a_val is computed at the point a_pt.
virtual void SetTriActivity(DynBitset &) override
Sets triangle activity. Ignored by IDW.
#define XM_ENSURE_TRUE_VOID_NO_ASSERT(...)
VecFlt & m_scalarTo
Scalars filled by this class.
Implementation of InterpIdw class.
virtual void SetMultiThreading(bool a_) override
sets a flag to use (or not) multi-threading when interpolating
void testInterp2d_c()
tests 2d interpolation using nearest 5 points
virtual void SetPtActivity(DynBitset &a_activity) override
Sets the activity on the point being used to interpolate.
void CreateNodalFunctionPtr(NodalFuncEnum a_, int a_nNearest, bool a_quad_oct, BSHP< Observer > a_p)
Creates the Nodal function class.
virtual const BSHP< VecFlt > GetScalars() const override
Returns shared pointer to scalars vector.
WeightEnum
Weight calculation method enumeration.
void testInterp2d_d()
tests 2d interpolation changing the exponent to 3 and nearest 6 pts
virtual int GetNodalFunctionNumNearestPts() const override
get the nodal function number of nearest points
Utility functions called by interpolation code.
bool m_multiThread
flag to indicate if multithreading should be used when interpolating
void inDistanceSquared(const Pt3d &a_pt, const std::vector< int > &a_ptIdxs, const std::vector< Pt3d > &a_ptLoc, bool a_2d, std::vector< double > &a_d2)
Computes the distance squared between the point "a_pt" and the other points. The other points are def...
BSHP< ThreadLoop > CreateForNewThread() override
creates an instance of this class for a new thread
virtual NodalFuncEnum GetNodalFunctionType() const override
get the type of nodal function (constant, gradient plane, quadratic)
InterpThread(InterpIdwImpl &a_, VecFlt &a_s, const VecPt3d &a_p)
constructor
NodalFuncEnum
Nodal fuction type enumeration.
std::string m_idString
identification for comparison with other Interp classes
virtual double GetTruncMin() const override
get minimum truncation value
BSHP< Observer > m_prog
Observer that reports status of interpolation process.
std::vector< VecDbl > VecDbl2d
void testInterpToPts()
tests interpolating to 1 location from 1 location
BSHP< VecInt > m_tris
triangles ignored by idw
virtual bool GetNodalFunctionUseQuadrantSearch() const override
get the nodal function option to use a quadrant search
virtual std::string ToString() const override
Write the internals to a string.
VecInt2d m_ptIdx
pt indexes for saving weights
static XmLog & Instance(bool a_delete=false, XmLog *a_new=NULL)
virtual void InterpToPts(const VecPt3d &a_pts, VecFlt &a_scalars) override
Interpolates to an array of points and fills in an array of scalars. This method will run in parallel...
void SetScalars(const float *a_scalar, size_t a_n) override
Sets the scalar values that will be used to do the interpolation.
void inIdwWeights(const std::vector< double > &a_distSquare, double a_power, bool a_modifiedShepardWeights, std::vector< double > &a_w)
Computes the idw weights that would be assigned to points associated with the distance squared that i...
static void iGetPoints(VecPt3d &a_pts, VecFlt &a_scalar, VecPt3d &a_iPts)
Get points for testing.
double m_truncMax
Maximum truncation value. All interpolated values will be <=.
virtual double GetPower() const override
get the idw power (1/d or 1/d^2 or 1/d^3)
bool m_modifiedShepardWeights
flag for calculating weights using a the modified shepard's approach
bool m_quadOctSearch
flag for performing quadrant(2d) or octant (3d) searching for nearest ps
void inFillWtArray(int id, double wt)
calls the FillWtArray signal
virtual DynBitset GetPtActivity() const override
Returns bitset of point activity.
bool inAllScalarsEqual(const std::vector< float > &a_scalars, const DynBitset &a_act)
Check to see if the all of the values in the scalars array are the same. It will also take into accou...
std::vector< Pt3d > VecPt3d