21 #include <xmscore/misc/XmError.h> 22 #include <xmscore/misc/XmLog.h> 23 #include <xmscore/misc/xmstype.h> 25 #include <xmsgrid/ugrid/XmUGrid.h> 26 #include <xmsgrid/geometry/geoms.h> 27 #include <xmsgrid/geometry/GmTriSearch.h> 28 #include <xmsinterp/interpolate/InterpUtil.h> 59 const DynBitset& a_activity,
62 const DynBitset& a_activity,
66 virtual void ExtractData(VecFlt& a_outData)
override;
97 DynBitset& a_cellActivity);
103 const VecFlt& a_cellScalars,
104 const DynBitset& a_cellActivity);
106 const VecInt& a_cellIdxs,
107 const VecFlt& a_cellScalars,
108 const DynBitset& a_cellActivity);
112 BSHP<XmUGridTriangles2d>
132 , m_triangleType(LOC_UNKNOWN)
134 , m_extractLocations()
137 , m_useIdwForPointData(false)
138 , m_noDataValue(XM_NODATA)
148 : m_ugrid(a_extractor->m_ugrid)
149 , m_triangleType(a_extractor->m_triangleType)
151 , m_extractLocations()
154 , m_useIdwForPointData(a_extractor->m_useIdwForPointData)
155 , m_noDataValue(a_extractor->m_noDataValue)
166 const DynBitset& a_activity,
169 if (a_pointScalars.size() !=
m_ugrid->GetPointCount())
171 XM_LOG(xmlog::debug,
"Invalid point scalar size in 2D data extractor.");
176 DynBitset cellActivity;
190 const DynBitset& a_activity,
193 if ((
int)a_cellScalars.size() !=
m_ugrid->GetCellCount())
195 XM_LOG(xmlog::debug,
"Invalid cell scalar size in 2D data extractor.");
200 DynBitset cellActivity;
225 VecDbl interpWeights;
228 int cellIdx =
m_triangles->GetIntersectedCell(pt, interpIdxs, interpWeights);
233 double interpValue = 0.0;
234 for (
size_t i = 0; i < interpIdxs.size(); ++i)
236 int ptIdx = interpIdxs[i];
237 double weight = interpWeights[i];
239 interpValue += scalar * weight;
241 a_outData.push_back(static_cast<float>(interpValue));
256 VecPt3d locations(1, a_location);
287 DynBitset& a_cellActivity)
289 if (a_activity.empty())
292 a_cellActivity = a_activity;
297 if (a_location == LOC_POINTS)
301 else if (a_location == LOC_CELLS)
304 a_cellActivity = a_activity;
315 DynBitset& a_cellActivity)
317 if (a_pointActivity.size() !=
m_ugrid->GetPointCount() && !a_pointActivity.empty())
319 XM_LOG(xmlog::debug,
"Invalid point activity size in 2D data extractor.");
322 if (a_pointActivity.empty())
324 a_cellActivity = a_pointActivity;
329 a_cellActivity.reset();
330 a_cellActivity.resize(
m_ugrid->GetCellCount(),
true);
331 VecInt attachedCells;
332 int numPoints =
m_ugrid->GetPointCount();
333 for (
int pointIdx = 0; pointIdx < numPoints; ++pointIdx)
335 if (pointIdx < a_pointActivity.size() && !a_pointActivity[pointIdx])
337 m_ugrid->GetPointAdjacentCells(pointIdx, attachedCells);
338 for (
auto cellIdx : attachedCells)
340 a_cellActivity[cellIdx] =
false;
352 if (a_cellActivity.size() !=
m_ugrid->GetCellCount() && !a_cellActivity.empty())
354 XM_LOG(xmlog::debug,
"Invalid cell activity size in 2D data extractor.");
368 int numCells =
m_ugrid->GetCellCount();
369 for (
int cellIdx = 0; cellIdx < numCells; ++cellIdx)
371 if (a_cellActivity.empty() || a_cellActivity[cellIdx])
373 int centroidIdx =
m_triangles->GetCellCentroid(cellIdx);
374 if (centroidIdx >= 0)
376 m_ugrid->GetCellPoints(cellIdx, cellPoints);
378 for (
auto ptIdx : cellPoints)
380 double average = sum / cellPoints.size();
393 const DynBitset& a_cellActivity)
397 int numPoints =
m_ugrid->GetPointCount();
398 for (
int pointIdx = 0; pointIdx < numPoints; ++pointIdx)
400 m_ugrid->GetPointAdjacentCells(pointIdx, cellIdxs);
412 int numCells =
m_ugrid->GetCellCount();
413 for (
int cellIdx = 0; cellIdx < numCells; ++cellIdx)
415 int pointIdx =
m_triangles->GetCellCentroid(cellIdx);
417 m_pointScalars[pointIdx] = cellIdx >= a_cellScalars.size() ? 0.0f : a_cellScalars[cellIdx];
428 const VecFlt& a_cellScalars,
429 const DynBitset& a_cellActivity)
433 for (
auto cellIdx : a_cellIdxs)
435 if (cellIdx >= a_cellActivity.size() || a_cellActivity[cellIdx])
437 sum += cellIdx >= a_cellScalars.size() ? 0.0 : a_cellScalars[cellIdx];
443 average = sum / sumCount;
446 return static_cast<float>(average);
457 const VecInt& a_cellIdxs,
458 const VecFlt& a_cellScalars,
459 const DynBitset& a_cellActivity)
461 Pt3d pt =
m_ugrid->GetPointLocation(a_pointIdx);
462 VecInt cellCentroids;
463 for (
auto cellIdx : a_cellIdxs)
465 int centroidIdx =
m_triangles->GetCellCentroid(cellIdx);
466 if (0 <= centroidIdx && a_cellActivity[cellIdx])
468 cellCentroids.push_back(centroidIdx);
471 if (!cellCentroids.empty())
475 inDistanceSquared(pt, cellCentroids,
m_triangles->GetPoints(),
true, d2);
476 inIdwWeights(d2, 2,
false, weights);
478 double interpValue = 0.0;
479 for (
size_t cellIdx = 0; cellIdx < cellCentroids.size(); ++cellIdx)
481 int ptIdx = cellCentroids[cellIdx];
482 double weight = weights[cellIdx];
483 interpValue += a_cellScalars[cellIdx] * weight;
485 return static_cast<float>(interpValue);
500 bool triangleCentroids = a_location == LOC_CELLS;
537 BSHP<XmUGrid2dDataExtractorImpl> copied = BDPC<XmUGrid2dDataExtractorImpl>(a_extractor);
569 #include <xmscore/testing/TestTools.h> 586 VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
587 VecInt cells = {XMU_TRIANGLE, 3, 0, 1, 2, XMU_TRIANGLE, 3, 2, 3, 0};
588 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
590 TS_ASSERT(extractor);
591 extractor->SetNoDataValue(-999.0);
593 VecFlt pointScalars = {1, 2, 3, 2};
594 extractor->SetGridPointScalars(pointScalars, DynBitset(), LOC_POINTS);
595 VecPt3d extractLocations = {
596 {0.0, 0.0, 0.0}, {0.25, 0.75, 100.0}, {0.5, 0.5, 0.0}, {0.75, 0.25, -100.0}, {-1.0, -1.0, 0.0}};
597 extractor->SetExtractLocations(extractLocations);
600 extractor->ExtractData(interpValues);
601 VecFlt expected = {1.0, 2.0, 2.0, 2.0, -999.0};
602 TS_ASSERT_EQUALS(expected, interpValues);
615 VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
616 VecInt cells = {XMU_TRIANGLE, 3, 0, 1, 2, XMU_TRIANGLE, 3, 2, 3, 0};
617 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
619 TS_ASSERT(extractor);
621 VecFlt pointScalars = {1, 2, 3, 2};
622 DynBitset cellActivity;
623 cellActivity.push_back(
true);
624 cellActivity.push_back(
false);
625 extractor->SetGridPointScalars(pointScalars, cellActivity, LOC_CELLS);
626 extractor->SetExtractLocations({{0.25, 0.75, 100.0}, {0.75, 0.25, -100.0}, {-1.0, -1.0, 0.0}});
629 extractor->ExtractData(interpValues);
630 VecFlt expected = {XM_NODATA, 2.0, XM_NODATA};
631 TS_ASSERT_EQUALS(expected, interpValues);
652 {0, 0, 0}, {1, 0, 0}, {3, 0, 0},
653 {0, 1, 0}, {2, 1, 0}, {3, 1, 0},
654 {0, 2, 0}, {1, 2, 0}, {3, 2, 0}};
656 XMU_TRIANGLE, 3, 0, 1, 3,
657 XMU_TRIANGLE, 3, 1, 4, 3,
658 XMU_TRIANGLE, 3, 1, 2, 4,
659 XMU_TRIANGLE, 3, 2, 5, 4,
661 XMU_TRIANGLE, 3, 3, 7, 6,
662 XMU_TRIANGLE, 3, 3, 4, 7,
663 XMU_TRIANGLE, 3, 4, 8, 7,
664 XMU_TRIANGLE, 3, 4, 5, 8};
666 VecFlt pointScalars = {
672 VecPt3d extractLocations = {
684 VecFlt expectedPerCell = {
685 0.25, XM_NODATA, XM_NODATA, XM_NODATA,
686 1.75, XM_NODATA, XM_NODATA, XM_NODATA };
689 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
691 TS_ASSERT(extractor);
695 DynBitset pointActivity;
696 pointActivity.resize(9,
true);
697 pointActivity[4] =
false;
698 extractor->SetGridPointScalars(pointScalars, pointActivity, LOC_POINTS);
701 extractor->SetExtractLocations(extractLocations);
704 extractor->ExtractData(interpValues);
705 TS_ASSERT_EQUALS(expectedPerCell, interpValues);
718 VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
719 VecInt cells = {XMU_TRIANGLE, 3, 0, 1, 2, XMU_TRIANGLE, 3, 2, 3, 0};
720 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
722 TS_ASSERT(extractor);
724 VecFlt pointScalars = {1, 2, 3};
726 activity.push_back(
true);
727 activity.push_back(
false);
728 extractor->SetGridPointScalars(pointScalars, activity, LOC_POINTS);
730 VecPt3d extractLocations = {{0.25, 0.75, 100.0}, {0.75, 0.25, 0.0}};
731 extractor->SetExtractLocations(extractLocations);
734 extractor->ExtractData(interpValues);
735 VecFlt expected = {1.0, XM_NODATA};
736 TS_ASSERT_EQUALS(expected, interpValues);
752 VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
753 VecInt cells = {XMU_TRIANGLE, 3, 0, 1, 2, XMU_TRIANGLE, 3, 2, 3, 0};
754 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
758 TS_ASSERT(extractor);
762 VecFlt cellScalars = {1, 2};
763 extractor->SetGridCellScalars(cellScalars, DynBitset(), LOC_CELLS);
766 extractor->SetExtractLocations({{0.0, 0.0, 0.0},
769 {0.75, 0.25, -100.0},
774 extractor->ExtractData(interpValues);
775 VecFlt expected = {1.5, 2.0, 1.5, 1.0, XM_NODATA};
776 TS_ASSERT_EQUALS(expected, interpValues);
798 {0, 0, 0}, {1, 0, 0}, {3, 0, 0},
799 {0, 1, 0}, {2, 1, 0}, {3, 1, 0},
800 {0, 2, 0}, {1, 2, 0}, {3, 2, 0}};
802 XMU_TRIANGLE, 3, 0, 1, 3,
803 XMU_TRIANGLE, 3, 1, 4, 3,
804 XMU_TRIANGLE, 3, 1, 2, 4,
805 XMU_TRIANGLE, 3, 2, 5, 4,
807 XMU_TRIANGLE, 3, 3, 7, 6,
808 XMU_TRIANGLE, 3, 3, 4, 7,
809 XMU_TRIANGLE, 3, 4, 8, 7,
810 XMU_TRIANGLE, 3, 4, 5, 8};
812 VecFlt cellScalars = {
818 VecPt3d extractLocations = {
830 VecFlt expectedPerCell = {
831 XM_NODATA, 4.0000, XM_NODATA, 8.2500,
832 XM_NODATA, 6.0000, XM_NODATA, 9.750
836 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
838 TS_ASSERT(extractor);
842 DynBitset cellActivity;
843 cellActivity.resize(8,
true);
844 cellActivity[0] =
false;
845 cellActivity[2] =
false;
846 cellActivity[4] =
false;
847 cellActivity[6] =
false;
848 extractor->SetGridCellScalars(cellScalars, cellActivity, LOC_CELLS);
851 extractor->SetExtractLocations(extractLocations);
854 extractor->ExtractData(interpValues);
855 TS_ASSERT_EQUALS(expectedPerCell, interpValues);
876 {0, 0, 0}, {1, 0, 0}, {3, 0, 0},
877 {0, 1, 0}, {2, 1, 0}, {3, 1, 0},
878 {0, 2, 0}, {1, 2, 0}, {3, 2, 0}};
880 XMU_TRIANGLE, 3, 0, 1, 3,
881 XMU_TRIANGLE, 3, 1, 4, 3,
882 XMU_TRIANGLE, 3, 1, 2, 4,
883 XMU_TRIANGLE, 3, 2, 5, 4,
885 XMU_TRIANGLE, 3, 3, 7, 6,
886 XMU_TRIANGLE, 3, 3, 4, 7,
887 XMU_TRIANGLE, 3, 4, 8, 7,
888 XMU_TRIANGLE, 3, 4, 5, 8};
890 VecFlt cellScalars = {
896 VecPt3d extractLocations = {
908 VecFlt expectedPerCell = {
909 2.0f, 3.4444f, XM_NODATA, 6.75f,
910 3.5f, 5.7303f, 5.4652f, 8.25f
914 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
916 TS_ASSERT(extractor);
917 extractor->SetUseIdwForPointData(
true);
921 DynBitset cellActivity;
922 cellActivity.resize(8,
true);
923 cellActivity[2] =
false;
924 extractor->SetGridCellScalars(cellScalars, cellActivity, LOC_CELLS);
927 extractor->SetExtractLocations(extractLocations);
930 extractor->ExtractData(interpValues);
931 TS_ASSERT_DELTA_VEC(expectedPerCell, interpValues, 0.001);
944 VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
945 VecInt cells = {XMU_TRIANGLE, 3, 0, 1, 2, XMU_TRIANGLE, 3, 2, 3, 0};
946 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
948 TS_ASSERT(extractor);
950 DynBitset pointActivity;
951 pointActivity.resize(4,
true);
952 pointActivity[1] =
false;
953 VecFlt cellScalars = {1, 2};
954 extractor->SetGridCellScalars(cellScalars, pointActivity, LOC_POINTS);
955 extractor->SetExtractLocations({{0.0, 0.0, 0.0},
958 {0.75, 0.25, -100.0},
962 extractor->ExtractData(interpValues);
963 VecFlt expected = {2.0, 2.0, 2.0, XM_NODATA, XM_NODATA};
964 TS_ASSERT_EQUALS(expected, interpValues);
977 VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
978 VecInt cells = {XMU_TRIANGLE, 3, 0, 1, 2, XMU_TRIANGLE, 3, 2, 3, 0};
979 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
981 TS_ASSERT(extractor);
983 VecFlt cellScalars = {1};
985 activity.push_back(
false);
986 extractor->SetGridCellScalars(cellScalars, activity, LOC_CELLS);
987 VecPt3d extractLocations = {{0.25, 0.75, 100.0}, {0.75, 0.25, 0.0}};
988 extractor->SetExtractLocations(extractLocations);
991 extractor->ExtractData(interpValues);
992 VecFlt expected = {0.0, XM_NODATA};
993 TS_ASSERT_EQUALS(expected, interpValues);
1001 VecPt3d points = {{0, 1, 0}, {1, 1, 0}, {2, 1, 0}, {3, 1, 0},
1002 {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}};
1004 XMU_QUAD, 4, 0, 4, 5, 1,
1005 XMU_QUAD, 4, 1, 5, 6, 2,
1006 XMU_QUAD, 4, 2, 6, 7, 3
1009 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
1011 TS_ASSERT(extractor);
1015 VecPt3d extractLocations = {
1022 scalars = {1, 2, 3};
1024 extractor->SetGridCellScalars(scalars, activity, LOC_CELLS);
1025 extractor->SetExtractLocations(extractLocations);
1027 VecFlt extractedValues;
1028 extractor->ExtractData(extractedValues);
1029 VecFlt expectedValues = {1.25, 2.0, 2.75};
1030 TS_ASSERT_EQUALS(expectedValues, extractedValues);
1033 scalars = {2, 3, 4};
1034 activity.resize(3,
true);
1035 activity[1] =
false;
1036 extractor->SetGridCellScalars(scalars, activity, LOC_CELLS);
1037 extractor->SetExtractLocations(extractLocations);
1039 extractor->ExtractData(extractedValues);
1040 expectedValues = {2, XM_NODATA, 4};
1041 TS_ASSERT_EQUALS(expectedValues, extractedValues);
1044 scalars = {3, 4, 5};
1046 extractor->SetGridCellScalars(scalars, activity, LOC_CELLS);
1047 extractor->SetExtractLocations(extractLocations);
1049 extractor->ExtractData(extractedValues);
1050 expectedValues = {3.25, 4.0, 4.75};
1051 TS_ASSERT_EQUALS(expectedValues, extractedValues);
1055 scalars = {1, 2, 3, 4, 2, 3, 4, 5};
1057 extractor->SetGridPointScalars(scalars, activity, LOC_POINTS);
1058 extractor->SetExtractLocations(extractLocations);
1060 extractor->ExtractData(extractedValues);
1061 expectedValues = {2.5, 3.0, 3.5};
1062 TS_ASSERT_EQUALS(expectedValues, extractedValues);
1065 scalars = {2, 3, 4, 5, 3, 4, 5, 6};
1066 activity.resize(8,
true);
1067 activity[0] =
false;
1068 extractor->SetGridPointScalars(scalars, activity, LOC_POINTS);
1069 extractor->SetExtractLocations(extractLocations);
1071 extractor->ExtractData(extractedValues);
1072 expectedValues = {XM_NODATA, 4.0, 4.5};
1073 TS_ASSERT_EQUALS(expectedValues, extractedValues);
1076 scalars = {3, 4, 5, 6, 4, 5, 6, 7};
1077 activity.resize(8,
true);
1078 activity[1] =
false;
1079 extractor->SetGridPointScalars(scalars, activity, LOC_POINTS);
1080 extractor->SetExtractLocations(extractLocations);
1082 extractor->ExtractData(extractedValues);
1083 expectedValues = {XM_NODATA, XM_NODATA, 5.5};
1084 TS_ASSERT_EQUALS(expectedValues, extractedValues);
1088 extractor->SetGridPointScalars(scalars, activity, LOC_POINTS);
1089 extractor->SetExtractLocations(extractLocations);
1091 extractor->ExtractData(extractedValues);
1092 expectedValues = {4.5, 5, 5.5};
1093 TS_ASSERT_EQUALS(expectedValues, extractedValues);
1106 VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
1107 VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
1108 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
1110 TS_ASSERT(extractor);
1112 VecFlt pointScalars = {1, 2, 3, 4};
1113 extractor->SetGridPointScalars(pointScalars, DynBitset(), LOC_POINTS);
1114 extractor->SetExtractLocations({{0.5, 0.5, 0.0}});
1115 VecFlt interpValues;
1116 extractor->ExtractData(interpValues);
1117 VecFlt expected = {2.0};
1118 TS_ASSERT_EQUALS(expected, interpValues);
1121 extractor2->SetGridPointScalars(pointScalars, DynBitset(), LOC_POINTS);
1122 extractor2->SetExtractLocations({{0.5, 0.5, 0.0}});
1123 extractor2->ExtractData(interpValues);
1124 TS_ASSERT_EQUALS(expected, interpValues);
1133 VecPt3d points = {{288050, 3907770, 0}, {294050, 3907770, 0}, {300050, 3907770, 0},
1134 {306050, 3907770, 0}, {288050, 3901770, 0}, {294050, 3901770, 0},
1135 {300050, 3901770, 0}, {306050, 3901770, 0}, {288050, 3895770, 0},
1136 {294050, 3895770, 0}, {300050, 3895770, 0}, {306050, 3895770, 0}};
1137 VecInt cells = {XMU_QUAD, 4, 0, 4, 5, 1, XMU_QUAD, 4, 1, 5, 6, 2, XMU_QUAD, 4, 2, 6, 7, 3,
1138 XMU_QUAD, 4, 4, 8, 9, 5, XMU_QUAD, 4, 5, 9, 10, 6, XMU_QUAD, 4, 6, 10, 11, 7};
1139 std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
1144 VecPt3d extractLocations = {{289780, 3906220, 0}, {293780, 3899460, 0}, {298900, 3900780, 0},
1145 {301170, 3904960, 0}, {296330, 3906180, 0}, {307395, 3901463, 0}};
1146 extractor->SetExtractLocations(extractLocations);
1147 VecFlt extractedData;
1148 VecPt3d retrievedLocations = extractor->GetExtractLocations();
1149 TS_ASSERT_EQUALS(extractLocations, retrievedLocations);
1153 extractor->SetNoDataValue(-999.0);
1158 VecFlt pointScalars = {730.787f, 1214.54f, 1057.145f, 629.2069f, 351.1153f, 631.6649f,
1159 1244.366f, 449.9133f, 64.04247f, 240.9716f, 680.0491f, 294.9547f};
1160 extractor->SetGridPointScalars(pointScalars, DynBitset(), LOC_CELLS);
1162 extractor->ExtractData(extractedData);
1164 VecFlt expectedData = {719.6f, 468.6f, 1033.8f, 996.5f, 1204.3f, -999.0f};
1165 TS_ASSERT_DELTA_VEC(expectedData, extractedData, 0.2);
1169 pointScalars = {-999.0f, 1220.5f, 1057.1f, 613.2f, 380.1f, 625.6f,
1170 722.2f, 449.9f, 51.0f, 240.9f, 609.0f, 294.9f};
1171 DynBitset cellActivity;
1172 cellActivity.resize(ugrid->GetCellCount(),
true);
1173 cellActivity[0] =
false;
1174 extractor->SetGridPointScalars(pointScalars, cellActivity, LOC_CELLS);
1176 extractor->ExtractData(extractedData);
1178 expectedData = {-999.0f, 466.4f, 685.0f, 849.4f, 1069.6f, -999.0f};
1179 TS_ASSERT_DELTA_VEC(expectedData, extractedData, 0.2);
Class to store XmUGrid triangles. Tracks where midpoints and triangles came from. ...
BSHP< VecInt > m_triangles
Triangles for the UGrid.
DataLocationEnum
The location at which the data will be stored.
Contains the XmUGrid Class and supporting data types.