xmsextractor  1.0
XmUGrid2dPolylineDataExtractor.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
6 //------------------------------------------------------------------------------
7 
8 //----- Included files ---------------------------------------------------------
9 
10 // 1. Precompiled header
11 
12 // 2. My own header
14 
15 // 3. Standard library headers
16 #include <sstream>
17 
18 // 4. External library headers
19 
20 // 5. Shared code headers
21 #include <xmscore/misc/XmLog.h>
24 #include <xmsgrid/ugrid/XmUGrid.h>
25 #include <xmsgrid/geometry/GmMultiPolyIntersector.h>
26 #include <xmsgrid/geometry/GmMultiPolyIntersectionSorterTerse.h>
27 
28 // 6. Non-shared code headers
29 
30 //----- Forward declarations ---------------------------------------------------
31 
32 //----- External globals -------------------------------------------------------
33 
34 //----- Namespace declaration --------------------------------------------------
35 
37 namespace xms
38 {
39 //----- Constants / Enumerations -----------------------------------------------
40 
41 //----- Classes / Structs ------------------------------------------------------
42 
43 //----- Internal functions -----------------------------------------------------
44 
45 //----- Class / Function definitions -------------------------------------------
46 
47 namespace
48 {
51 class XmUGrid2dPolylineDataExtractorImpl : public XmUGrid2dPolylineDataExtractor
52 {
53 public:
54  XmUGrid2dPolylineDataExtractorImpl(std::shared_ptr<XmUGrid> a_ugrid,
55  DataLocationEnum a_scalarLocation);
59  virtual BSHP<XmUGrid2dDataExtractor> GetDataExtractor() const override { return m_extractor; }
60  virtual void SetGridScalars(const VecFlt& a_pointScalars,
61  const DynBitset& a_activity,
62  DataLocationEnum a_activityLocation) override;
63 
64  virtual void SetPolyline(const VecPt3d& a_polyline) override;
65  virtual void ExtractData(VecFlt& a_extractedData) override;
66 
67  virtual void ComputeLocationsAndExtractData(const VecPt3d& a_polyline,
68  VecFlt& a_extractedData,
69  VecPt3d& a_extractedLocations) override;
70 
71  virtual void SetUseIdwForPointData(bool a_useIdw) override;
72  virtual void SetNoDataValue(float a_noDataValue) override;
73 
76  virtual const VecFlt& GetScalars() const override { return m_extractor->GetScalars(); }
79  virtual DataLocationEnum GetScalarLocation() const override
80  {
81  return m_extractor->GetScalarLocation();
82  }
83  virtual const VecPt3d& GetExtractLocations() const override;
86  virtual const VecInt& GetCellIndexes() const { return m_extractor->GetCellIndexes(); }
89  virtual bool GetUseIdwForPointData() const override
90  {
91  return m_extractor->GetUseIdwForPointData();
92  }
95  virtual float GetNoDataValue() const override { return m_extractor->GetNoDataValue(); }
96 
97 private:
98  void ComputeExtractLocations(const VecPt3d& a_polyline, VecPt3d& a_locations);
99 
100  BSHP<XmUGrid2dDataExtractor> m_extractor;
101  mutable BSHP<GmMultiPolyIntersector>
103 };
106 
112 //------------------------------------------------------------------------------
116 //------------------------------------------------------------------------------
117 XmUGrid2dPolylineDataExtractorImpl::XmUGrid2dPolylineDataExtractorImpl(
118  std::shared_ptr<XmUGrid> a_ugrid,
119  DataLocationEnum a_scalarLocation)
120 : m_extractor(XmUGrid2dDataExtractor::New(a_ugrid))
121 {
122  if (a_scalarLocation == LOC_UNKNOWN)
123  {
124  XM_LOG(xmlog::error, "Scalar locations are unknown in polyline extractor.");
125  a_scalarLocation = LOC_POINTS;
126  }
127 
128  if (a_scalarLocation == LOC_POINTS)
129  {
130  VecFlt v(a_ugrid->GetPointCount(), 0.0);
131  DynBitset act;
132  m_extractor->SetGridPointScalars(v, act, LOC_POINTS);
133  }
134  else if (a_scalarLocation == LOC_CELLS)
135  {
136  VecFlt v(a_ugrid->GetCellCount(), 0.0);
137  DynBitset act;
138  m_extractor->SetGridCellScalars(v, act, LOC_CELLS);
139  }
140 } // XmUGrid2dPolylineDataExtractorImpl::XmUGrid2dPolylineDataExtractorImpl
141 //------------------------------------------------------------------------------
146 //------------------------------------------------------------------------------
147 void XmUGrid2dPolylineDataExtractorImpl::SetGridScalars(const VecFlt& a_scalars,
148  const DynBitset& a_activity,
149  DataLocationEnum a_activityLocation)
150 {
151  if (m_extractor->GetScalarLocation() == LOC_POINTS)
152  m_extractor->SetGridPointScalars(a_scalars, a_activity, a_activityLocation);
153  else if (m_extractor->GetScalarLocation() == LOC_CELLS)
154  m_extractor->SetGridCellScalars(a_scalars, a_activity, a_activityLocation);
155 } // XmUGrid2dPolylineDataExtractorImpl::SetGridScalars
156 //------------------------------------------------------------------------------
160 //------------------------------------------------------------------------------
161 void XmUGrid2dPolylineDataExtractorImpl::SetPolyline(const VecPt3d& a_polyline)
162 {
163  m_extractor->BuildTriangles(m_extractor->GetScalarLocation());
164  VecPt3d locations;
165  ComputeExtractLocations(a_polyline, locations);
166  m_extractor->SetExtractLocations(locations);
167 } // XmUGrid2dPolylineDataExtractorImpl::SetPolyline
168 //------------------------------------------------------------------------------
172 //------------------------------------------------------------------------------
173 const VecPt3d& XmUGrid2dPolylineDataExtractorImpl::GetExtractLocations() const
174 {
175  return m_extractor->GetExtractLocations();
176 } // XmUGrid2dPolylineDataExtractorImpl::GetExtractLocations
177 //------------------------------------------------------------------------------
182 //------------------------------------------------------------------------------
183 void XmUGrid2dPolylineDataExtractorImpl::ExtractData(VecFlt& a_extractedData)
184 {
185  m_extractor->ExtractData(a_extractedData);
186 } // XmUGrid2dPolylineDataExtractorImpl::ExtractData
187 //------------------------------------------------------------------------------
194 //------------------------------------------------------------------------------
195 void XmUGrid2dPolylineDataExtractorImpl::ComputeLocationsAndExtractData(
196  const VecPt3d& a_polyline,
197  VecFlt& a_extractedData,
198  VecPt3d& a_extractedLocations)
199 {
200  SetPolyline(a_polyline);
201  ExtractData(a_extractedData);
202  a_extractedLocations = GetExtractLocations();
203 } // XmUGrid2dPolylineDataExtractorImpl::ComputeLocationsAndExtractData
204 //------------------------------------------------------------------------------
207 //------------------------------------------------------------------------------
208 void XmUGrid2dPolylineDataExtractorImpl::SetUseIdwForPointData(bool a_useIdw)
209 {
210  m_extractor->SetUseIdwForPointData(a_useIdw);
211 } // XmUGrid2dPolylineDataExtractorImpl::SetUseIdwForPointData
212 //------------------------------------------------------------------------------
216 //------------------------------------------------------------------------------
217 void XmUGrid2dPolylineDataExtractorImpl::SetNoDataValue(float a_value)
218 {
219  m_extractor->SetNoDataValue(a_value);
220 } // XmUGrid2dPolylineDataExtractorImpl::SetNoDataValue
221 //------------------------------------------------------------------------------
225 //------------------------------------------------------------------------------
226 void XmUGrid2dPolylineDataExtractorImpl::ComputeExtractLocations(const VecPt3d& a_polyline,
227  VecPt3d& a_locations)
228 {
229  a_locations.clear();
230  if (a_polyline.empty())
231  {
232  XM_LOG(xmlog::error, "Attempting to extract polyline profile with empty polyline.");
233  return;
234  }
235 
236  if (!m_extractor->GetUGridTriangles())
237  {
238  XM_LOG(xmlog::error, "Attempting to extract polyline profile without setting scalars.");
239  return;
240  }
241 
243  {
244  const VecPt3d& points = m_extractor->GetUGridTriangles()->GetPoints();
245  const VecInt& triangles = m_extractor->GetUGridTriangles()->GetTriangles();
246  VecInt2d polygons;
247  VecInt triangle;
248  for (size_t triangleIdx = 0; triangleIdx < triangles.size(); triangleIdx += 3)
249  {
250  triangle = {triangles[triangleIdx], triangles[triangleIdx + 1], triangles[triangleIdx + 2]};
251  polygons.push_back(triangle);
252  }
253 
254  BSHP<GmMultiPolyIntersectionSorter> sorter(new GmMultiPolyIntersectionSorterTerse());
255  m_multiPolyIntersector = GmMultiPolyIntersector::New(points, polygons, sorter, 0);
256  }
257 
258  // get points crossing cell edges
259  Pt3d lastPoint = a_polyline[0];
260  a_locations.push_back(lastPoint);
261 
262  for (size_t polyIdx = 1; polyIdx < a_polyline.size(); ++polyIdx)
263  {
264  Pt3d pt1 = a_polyline[polyIdx - 1];
265  Pt3d pt2 = a_polyline[polyIdx];
266  VecInt intersectIdxs;
267  VecPt3d intersectPts;
268 
269  m_multiPolyIntersector->TraverseLineSegment(pt1.x, pt1.y, pt2.x, pt2.y, intersectIdxs,
270  intersectPts);
271 
272  if (intersectIdxs.size() != intersectPts.size())
273  {
274  XM_LOG(xmlog::error, "Internal error when extracting polyline profile.");
275  return;
276  }
277 
278  for (size_t i = 0; i < intersectIdxs.size(); ++i)
279  {
280  const Pt3d& currPoint = intersectPts[i];
281  if (lastPoint != currPoint)
282  {
283  if (i != 0 && intersectIdxs[i - 1] == -1)
284  {
285  a_locations.push_back((currPoint + lastPoint) / 2.0);
286  }
287  a_locations.push_back(currPoint);
288  lastPoint = currPoint;
289  }
290  }
291 
292  if (pt2 != a_locations.back())
293  {
294  a_locations.push_back(pt2);
295  lastPoint = pt2;
296  }
297  }
298 } // XmUGrid2dPolylineDataExtractorImpl::ComputeExtractLocations
299 
300 } // namespace
301 
307 //------------------------------------------------------------------------------
312 //------------------------------------------------------------------------------
313 BSHP<XmUGrid2dPolylineDataExtractor> XmUGrid2dPolylineDataExtractor::New(
314  std::shared_ptr<XmUGrid> a_ugrid,
315  DataLocationEnum a_scalarLocation)
316 {
317  BSHP<XmUGrid2dPolylineDataExtractor> extractor(
318  new XmUGrid2dPolylineDataExtractorImpl(a_ugrid, a_scalarLocation));
319  return extractor;
320 } // XmUGrid2dPolylineDataExtractor::New
321 //------------------------------------------------------------------------------
323 //------------------------------------------------------------------------------
325 {
326 } // XmUGrid2dPolylineDataExtractor::XmUGrid2dPolylineDataExtractor
327 //------------------------------------------------------------------------------
329 //------------------------------------------------------------------------------
331 {
332 } // XmUGrid2dPolylineDataExtractor::~XmUGrid2dPolylineDataExtractor
333 
334 } // namespace xms
335 
336 #ifdef CXX_TEST
337 //------------------------------------------------------------------------------
338 // Unit Tests
339 //------------------------------------------------------------------------------
340 using namespace xms;
342 
343 #include <xmscore/misc/xmstype.h>
344 #include <xmscore/testing/TestTools.h>
345 #include <xmsgrid/geometry/geoms.h>
346 
351 //------------------------------------------------------------------------------
353 //------------------------------------------------------------------------------
355 {
356  // clang-format off
357  // 3-------2
358  // | |
359  // 0===============1
360  // | |
361  // 0-------1
362  // clang-format on
363 
364  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
365  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
366  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
367  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
368  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
369 
370  VecFlt pointScalars = {0, 2, 3, 1};
371  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
372 
373  VecFlt extractedData;
374  VecPt3d extractedLocations;
375  VecPt3d polyline = {{-1, 0.5, 0}, {2, 0.5, 0}};
376  extractor->SetPolyline(polyline);
377  extractedLocations = extractor->GetExtractLocations();
378  extractor->ExtractData(extractedData);
379 
380  VecFlt expectedData = {XM_NODATA, 0.5, 1.5, 2.5, XM_NODATA};
381  TS_ASSERT_EQUALS(expectedData, extractedData);
382  VecPt3d expectedLocations = {
383  {-1, 0.5, 0}, {0.0, 0.5, 0.0}, {0.5, 0.5, 0.0}, {1.0, 0.5, 0.0}, {2, 0.5, 0}};
384  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
385 } // XmUGrid2dPolylineDataExtractorUnitTests::testOneCellOneSegment
386 //------------------------------------------------------------------------------
388 //------------------------------------------------------------------------------
390 {
391  // clang-format off
392  // (1) 3--------2 (3)
393  // | |
394  // | 0====1 |
395  // | |
396  // (0) 0--------1 (2)
397  // clang-format on
398 
399  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
400  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
401  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
402  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
403  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
404 
405  VecFlt pointScalars = {0, 2, 3, 1};
406  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
407 
408  VecFlt extractedData;
409  VecPt3d extractedLocations;
410  VecPt3d polyline = {{0.25, 0.50, 0.0}, {0.75, 0.50, 0.0}};
411  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
412 
413  VecFlt expectedData = {1.0, 1.5, 2.0};
414  TS_ASSERT_EQUALS(expectedData, extractedData);
415  VecPt3d expectedLocations = {{0.25, 0.5, 0.0}, {0.5, 0.5, 0.0}, {0.75, 0.5, 0.0}};
416  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
417 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentAllInCell
418 //------------------------------------------------------------------------------
420 //------------------------------------------------------------------------------
422 {
423  // clang-format off
424  // 0===3========2===1
425  // | |
426  // | |
427  // | |
428  // 0--------1
429  // clang-format on
430 
431  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
432  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
433  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
434  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
435  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
436 
437  VecFlt pointScalars = {0, 2, 3, 1};
438  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
439 
440  VecFlt extractedData;
441  VecPt3d extractedLocations;
442  VecPt3d polyline = {{-0.5, 1.0, 0.0}, {1.55, 1.0, 0.0}};
443  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
444 
445  VecFlt expectedData = {XM_NODATA, 1.0, 3.0, XM_NODATA};
446  TS_ASSERT_EQUALS(expectedData, extractedData);
447  VecPt3d expectedLocations = {
448  {-0.5, 1.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}, {1.55, 1.0, 0.0}};
449  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
450 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentAlongEdge
451 //------------------------------------------------------------------------------
453 //------------------------------------------------------------------------------
455 {
456  // clang-format off
457  // 3========2
458  // | |
459  // 0==1 | |
460  // | |
461  // 0--------1
462  // clang-format on
463 
464  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
465  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
466  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
467  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
468  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
469 
470  VecFlt pointScalars = {0, 2, 3, 1};
471  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
472 
473  VecFlt extractedData;
474  VecPt3d extractedLocations;
475  VecPt3d polyline = {{-0.5, 0.5, 0.0}, {-0.25, 0.5, 0.0}};
476  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
477 
478  VecFlt expectedData = {XM_NODATA, XM_NODATA};
479  TS_ASSERT_EQUALS(expectedData, extractedData);
480  VecPt3d expectedLocations = {{-0.5, 0.5, 0.0}, {-0.25, 0.5, 0.0}};
481  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
482 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentAllOutside
483 //------------------------------------------------------------------------------
485 //------------------------------------------------------------------------------
487 {
488  // clang-format off
489  // 3========2
490  // | |
491  // 0====1 |
492  // | |
493  // 0--------1
494  // clang-format on
495 
496  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
497  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
498  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
499  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
500  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
501 
502  VecFlt pointScalars = {0, 2, 3, 1};
503  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
504 
505  VecFlt extractedData;
506  VecPt3d extractedLocations;
507  VecPt3d polyline = {{-0.5, 0.5, 0.0}, {0.0, 0.5, 0.0}};
508  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
509 
510  VecFlt expectedData = {XM_NODATA, 0.5};
511  TS_ASSERT_EQUALS(expectedData, extractedData);
512  VecPt3d expectedLocations = {{-0.5, 0.5, 0.0}, {0.0, 0.5, 0.0}};
513  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
514 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentOutToTouch
515 //------------------------------------------------------------------------------
517 //------------------------------------------------------------------------------
519 {
520  // clang-format off
521  // 3========2
522  // | |
523  // | 0===1
524  // | |
525  // 0--------1
526  // clang-format on
527 
528  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
529  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
530  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
531  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
532  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
533 
534  VecFlt pointScalars = {0, 2, 3, 1};
535  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
536 
537  VecFlt extractedData;
538  VecPt3d extractedLocations;
539  VecPt3d polyline = {{1.0, 0.5, 0.0}, {1.5, 0.5, 0.0}};
540  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
541 
542  VecFlt expectedData = {2.5, XM_NODATA};
543  TS_ASSERT_EQUALS(expectedData, extractedData);
544  VecPt3d expectedLocations = {{1.0, 0.5, 0.0}, {1.5, 0.5, 0.0}};
545  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
546 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentTouchToOut
547 //------------------------------------------------------------------------------
549 //------------------------------------------------------------------------------
551 {
552  // clang-format off
553  // 1
554  // /
555  // 3========2
556  // / | |
557  // 0 | |
558  // | |
559  // 0--------1
560  // clang-format on
561 
562  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
563  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
564  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
565  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
566  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
567 
568  VecFlt pointScalars = {0, 2, 3, 1};
569  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
570 
571  VecFlt extractedData;
572  VecPt3d extractedLocations;
573  VecPt3d polyline = {{-0.5, 0.5, 0.0}, {0.0, 1.0, 0.0}, {0.5, 1.5, 0.0}};
574  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
575 
576  VecFlt expectedData = {XM_NODATA, 1.0, XM_NODATA};
577  TS_ASSERT_EQUALS(expectedData, extractedData);
578  VecPt3d expectedLocations = {{-0.5, 0.5, 0.0}, {0.0, 1.0, 0.0}, {0.5, 1.5, 0.0}};
579  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
580 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentCrossCellPoint
581 //------------------------------------------------------------------------------
583 //------------------------------------------------------------------------------
585 {
586  // clang-format off
587  // 3========2========5
588  // | | |
589  // 0===============1 |
590  // | | |
591  // 0--------1--------4
592  // clang-format on
593 
594  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {2, 0, 0}, {2, 1, 0}};
595  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3, XMU_QUAD, 4, 1, 4, 5, 2};
596  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
597  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
598  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
599 
600  VecFlt pointScalars = {0, 2, 3, 1, 4, 5};
601  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
602 
603  VecFlt extractedData;
604  VecPt3d extractedLocations;
605  VecPt3d polyline = {{-0.5, 0.5, 0.0}, {1.5, 0.5, 0.0}};
606  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
607 
608  VecFlt expectedData = {XM_NODATA, 0.5, 1.5, 2.5, 3.5};
609  TS_ASSERT_EQUALS(expectedData, extractedData);
610  VecPt3d expectedLocations = {
611  {-0.5, 0.5, 0.0}, {0.0, 0.5, 0.0}, {0.5, 0.5, 0.0}, {1.0, 0.5, 0.0}, {1.5, 0.5, 0.0}};
612  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
613 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentAcrossCellIntoSecond
614 //------------------------------------------------------------------------------
616 //------------------------------------------------------------------------------
618 {
619  // clang-format off
620  // 3-------2 7-------6
621  // | | | |
622  // 0========================1 |
623  // | | | |
624  // 0-------1 4-------5
625  // clang-format on
626 
627  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0},
628  {2, 0, 0}, {3, 0, 0}, {3, 1, 0}, {2, 1, 0}};
629  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3, XMU_QUAD, 4, 4, 5, 6, 7};
630  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
631  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
632  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
633 
634  VecFlt pointScalars = {0, 2, 3, 1, 4, 6, 7, 5};
635  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
636 
637  VecFlt extractedData;
638  VecPt3d extractedLocations;
639  VecPt3d polyline = {{-1, 0.5, 0}, {2.5, 0.5, 0}};
640  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
641 
642  VecFlt expectedData = {XM_NODATA, 0.5, 1.5, 2.5, XM_NODATA, 4.5, 5.5};
643  TS_ASSERT_EQUALS(expectedData, extractedData);
644  VecPt3d expectedLocations = {{-1.0, 0.5, 0.0}, {0.0, 0.5, 0.0}, {0.5, 0.5, 0.0}, {1.0, 0.5, 0.0},
645  {1.5, 0.5, 0.0}, {2.0, 0.5, 0.0}, {2.5, 0.5, 0.0}};
646  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
647 } // XmUGrid2dPolylineDataExtractorUnitTests::testSegmentAcrossSplitCells
648 //------------------------------------------------------------------------------
650 //------------------------------------------------------------------------------
652 {
653  // clang-format off
654  // 3--------2
655  // | |
656  // 0=========1=========2
657  // | |
658  // 0--------1
659  // clang-format on
660 
661  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
662  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
663  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
664  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
665  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
666 
667  VecFlt pointScalars = {0, 2, 3, 1};
668  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
669 
670  VecFlt extractedData;
671  VecPt3d extractedLocations;
672  VecPt3d polyline = {{-1, 0.5, 0}, {0.5, 0.5, 0.0}, {2, 0.5, 0}};
673  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
674 
675  VecFlt expectedData = {XM_NODATA, 0.5, 1.5, 2.5, XM_NODATA};
676  TS_ASSERT_EQUALS(expectedData, extractedData);
677  VecPt3d expectedLocations = {
678  {-1.0, 0.5, 0.0}, {0.0, 0.5, 0.0}, {0.5, 0.5, 0.0}, {1.0, 0.5, 0.0}, {2.0, 0.5, 0.0}};
679  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
680 } // XmUGrid2dPolylineDataExtractorUnitTests::testTwoSegmentsAcrossOneCell
681 //------------------------------------------------------------------------------
683 //------------------------------------------------------------------------------
685 {
686  // clang-format off
687  // 3--------2
688  // | |
689  // | | 0====1====2
690  // | |
691  // 0--------1
692  // clang-format on
693 
694  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
695  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
696  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
697  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
698  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
699 
700  VecFlt pointScalars = {0, 2, 3, 1};
701  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
702 
703  VecFlt extractedData;
704  VecPt3d extractedLocations;
705  VecPt3d polyline = {{2.0, 0.5, 0}, {3.0, 0.5, 0.0}, {4.0, 0.5, 0.0}};
706  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
707 
708  VecFlt expectedData = {XM_NODATA, XM_NODATA, XM_NODATA};
709  TS_ASSERT_EQUALS(expectedData, extractedData);
710  VecPt3d expectedLocations = {{2.0, 0.5, 0}, {3.0, 0.5, 0.0}, {4.0, 0.5, 0.0}};
711  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
712 } // XmUGrid2dPolylineDataExtractorUnitTests::testTwoSegmentsAllOutside
713 //------------------------------------------------------------------------------
715 //------------------------------------------------------------------------------
717 {
718  // clang-format off
719  // 3--------2
720  // | |
721  // | 0========1=======2
722  // | |
723  // 0--------1
724  // clang-format on
725 
726  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
727  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
728  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
729  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
730  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
731 
732  VecFlt pointScalars = {0, 2, 3, 1};
733  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
734 
735  VecFlt extractedData;
736  VecPt3d extractedLocations;
737  VecPt3d polyline = {{0.5, 0.5, 0}, {3.0, 0.5, 0.0}, {4.0, 0.5, 0.0}};
738  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
739 
740  VecFlt expectedData = {1.5, 2.5, XM_NODATA, XM_NODATA};
741  TS_ASSERT_EQUALS(expectedData, extractedData);
742  VecPt3d expectedLocations = {{0.5, 0.5, 0}, {1.0, 0.5, 0}, {3.0, 0.5, 0.0}, {4.0, 0.5, 0.0}};
743  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
744 } // XmUGrid2dPolylineDataExtractorUnitTests::testTwoSegmentsFirstExiting
745 //------------------------------------------------------------------------------
747 //------------------------------------------------------------------------------
749 {
750  // clang-format off
751  // 3========2========5
752  // | | |
753  // | 0========1=========2
754  // | | |
755  // 0--------1--------4
756  // clang-format on
757 
758  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {2, 0, 0}, {2, 1, 0}};
759  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3, XMU_QUAD, 4, 1, 4, 5, 2};
760  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
761  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
762  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
763 
764  VecFlt pointScalars = {0, 2, 3, 1, 4, 5};
765  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
766 
767  VecFlt extractedData;
768  VecPt3d extractedLocations;
769  VecPt3d polyline = {{0.5, 0.5, 0.0}, {1.5, 0.5, 0.0}, {2.5, 0.5, 0.0}};
770  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
771 
772  VecFlt expectedData = {1.5, 2.5, 3.5, 4.5, XM_NODATA};
773  TS_ASSERT_EQUALS(expectedData, extractedData);
774  VecPt3d expectedLocations = {
775  {0.5, 0.5, 0.0}, {1.0, 0.5, 0.0}, {1.5, 0.5, 0.0}, {2.0, 0.5, 0.0}, {2.5, 0.5, 0.0}};
776  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
777 } // XmUGrid2dPolylineDataExtractorUnitTests::testTwoSegmentsJoinInCell
778 //------------------------------------------------------------------------------
780 //------------------------------------------------------------------------------
782 {
783  // clang-format off
784  // 3========2========5
785  // | | |
786  // | 0====1=============2
787  // | | |
788  // 0--------1--------4
789  // clang-format on
790 
791  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {2, 0, 0}, {2, 1, 0}};
792  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3, XMU_QUAD, 4, 1, 4, 5, 2};
793  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
794  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
795  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
796 
797  VecFlt pointScalars = {0, 2, 3, 1, 4, 5};
798  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
799 
800  VecFlt extractedData;
801  VecPt3d extractedLocations;
802  VecPt3d polyline = {{0.5, 0.5, 0.0}, {1.0, 0.5, 0.0}, {2.5, 0.5, 0.0}};
803  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
804 
805  VecFlt expectedData = {1.5, 2.5, 3.5, 4.5, XM_NODATA};
806  TS_ASSERT_EQUALS(expectedData, extractedData);
807  VecPt3d expectedLocations = {
808  {0.5, 0.5, 0.0}, {1.0, 0.5, 0.0}, {1.5, 0.5, 0.0}, {2.0, 0.5, 0.0}, {2.5, 0.5, 0.0}};
809  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
810 } // XmUGrid2dPolylineDataExtractorUnitTests::testTwoSegmentsJoinOnBoundary
811 //------------------------------------------------------------------------------
813 //------------------------------------------------------------------------------
815 {
816  // clang-format off
817  // 3----3---2
818  // | \ |
819  // | 0========1
820  // | | \ |
821  // 0--------1 2
822  // clang-format on
823 
824  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}};
825  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3};
826  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
827  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
828  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
829 
830  VecFlt pointScalars = {0, 2, 3, 1};
831  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_POINTS);
832 
833  VecFlt extractedData;
834  VecPt3d extractedLocations;
835  VecPt3d polyline = {{0.5, 0.5, 0}, {1.5, 0.5, 0.0}, {1.5, 0.0, 0.0}, {0.5, 1.0, 0.0}};
836  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
837 
838  VecFlt expectedData = {1.5, 2.5, XM_NODATA, XM_NODATA, 2.5, 2.25, 2.0};
839  TS_ASSERT_EQUALS(expectedData, extractedData);
840  VecPt3d expectedLocations = {{0.5, 0.5, 0}, {1.0, 0.5, 0}, {1.5, 0.5, 0.0}, {1.5, 0.0, 0.0},
841  {1.0, 0.5, 0}, {0.75, 0.75, 0.0}, {0.5, 1.0, 0.0}};
842  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
843 } // XmUGrid2dPolylineDataExtractorUnitTests::testTwoSegmentsJoinOnBoundary
844 //------------------------------------------------------------------------------
846 //------------------------------------------------------------------------------
848 {
849  // clang-format off
850  // 3========2========5
851  // | | |
852  // 0===============1 |
853  // | | |
854  // 0--------1--------4
855  // clang-format on
856 
857  VecPt3d points = {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {2, 0, 0}, {2, 1, 0}};
858  VecInt cells = {XMU_QUAD, 4, 0, 1, 2, 3, XMU_QUAD, 4, 1, 4, 5, 2};
859  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
860  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
861  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_CELLS);
862 
863  VecFlt cellScalars = {1, 2};
864  extractor->SetGridScalars(cellScalars, DynBitset(), LOC_CELLS);
865 
866  VecFlt extractedData;
867  VecPt3d extractedLocations;
868  VecPt3d polyline = {{-0.5, 0.75, 0.0}, {1.5, 0.75, 0.0}};
869  extractor->ComputeLocationsAndExtractData(polyline, extractedData, extractedLocations);
870 
871  VecFlt expectedData = {XM_NODATA, 1.0, 1.0, 1.25, 1.5, 1.75, 1.875};
872  TS_ASSERT_EQUALS(expectedData, extractedData);
873  VecPt3d expectedLocations = {{-0.5, 0.75, 0.0}, {0.0, 0.75, 0.0}, {0.25, 0.75, 0.0},
874  {0.75, 0.75, 0.0}, {1., 0.75, 0.0}, {1.25, 0.75, 0.0},
875  {1.5, 0.75, 0.0}};
876  TS_ASSERT_EQUALS(expectedLocations, extractedLocations);
877 } // XmUGrid2dPolylineDataExtractorUnitTests::testCellScalars
878 //------------------------------------------------------------------------------
880 //------------------------------------------------------------------------------
883 {
884  // build 2x3 grid
885  VecPt3d points = {{288050, 3907770, 0}, {294050, 3907770, 0}, {300050, 3907770, 0},
886  {306050, 3907770, 0}, {288050, 3901770, 0}, {294050, 3901770, 0},
887  {300050, 3901770, 0}, {306050, 3901770, 0}, {288050, 3895770, 0},
888  {294050, 3895770, 0}, {300050, 3895770, 0}, {306050, 3895770, 0}};
889  VecInt cells = {XMU_QUAD, 4, 0, 4, 5, 1, XMU_QUAD, 4, 1, 5, 6, 2, XMU_QUAD, 4, 2, 6, 7, 3,
890  XMU_QUAD, 4, 4, 8, 9, 5, XMU_QUAD, 4, 5, 9, 10, 6, XMU_QUAD, 4, 6, 10, 11, 7};
891  std::shared_ptr<XmUGrid> ugrid = XmUGrid::New(points, cells);
892  // Step 1. Create an extractor for an XmUGrid giving the mapped location of the scalar values
893  BSHP<XmUGrid2dPolylineDataExtractor> extractor =
894  XmUGrid2dPolylineDataExtractor::New(ugrid, LOC_POINTS);
895 
896  // Step 2. Optionally set the "no data" value.
897  extractor->SetNoDataValue(-999.0);
898 
899  // Step 3. Set the polyline to be extracted along.
900  VecPt3d extractedLocations;
901  VecPt3d polyline = {
902  {290764, 3895106, 0}, {291122, 3909108, 0}, {302772, 3909130, 0}, {302794, 3895775, 0}};
903  extractor->SetPolyline(polyline);
904 
905  // Step 4. Optionally get the locations used for extraction along the polyline.
906  extractedLocations = extractor->GetExtractLocations();
907  VecPt3d expectedLocations = {
908  {290764.0, 3895106.0, 0.0}, {290780.9, 3895770.0, 0.0}, {290862.4, 3898957.5, 0.0},
909  {290934.3, 3901770.0, 0.0}, {291012.0, 3904807.9, 0.0}, {291087.7, 3907770.0, 0.0},
910  {291122.0, 3909108.0, 0.0}, {302772.0, 3909130.0, 0.0}, {302774.2, 3907770.0, 0.0},
911  {302778.7, 3905041.2, 0.0}, {302784.1, 3901770.0, 0.0}, {302788.6, 3899031.3, 0.0},
912  {302794.0, 3895775.0, 0.0},
913  };
914  TS_ASSERT_DELTA_VECPT3D(expectedLocations, extractedLocations, 0.15);
915 
916  VecFlt extractedData;
917 
918  // time step 1
919  // Step 5. Set the point scalars for the first time step.
920  VecFlt pointScalars = {730.787f, 1214.54f, 1057.145f, 629.2069f, 351.1153f, 631.6649f,
921  1244.366f, 449.9133f, 64.04247f, 240.9716f, 680.0491f, 294.9547f};
922  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_CELLS);
923  // Step 6. Extract the data.
924  extractor->ExtractData(extractedData);
925  VecFlt expectedData = {-999.0f, 144.5f, 299.4f, 485.9f, 681.8f, 975.7f, -999.0f,
926  -999.0f, 862.8f, 780.9f, 882.3f, 811.0f, 504.4f};
927  TS_ASSERT_DELTA_VEC(expectedData, extractedData, 0.2);
928 
929  // time step 2
930  // Step 7. Continue using steps 5 and 6 for remaining time steps.
931  pointScalars = {-999.0f, 1220.5f, 1057.1f, 613.2f, 380.1f, 625.6f,
932  722.2f, 449.9f, 51.0f, 240.9f, 609.0f, 294.9f};
933  extractor->SetGridScalars(pointScalars, DynBitset(), LOC_CELLS);
934  extractor->ExtractData(extractedData);
935  expectedData = {-999.0f, 137.4f, 314.8f, 498.1f, -196.9f, 124.7f, -999.0f,
936  -999.0f, 855.5f, 780.9f, 598.1f, 527.1f, 465.4f};
937  TS_ASSERT_DELTA_VEC(expectedData, extractedData, 0.2);
938 } // XmUGrid2dPolylineDataExtractorUnitTests::testTransientTutorial
940 
941 #endif
void testCellScalars()
Test extractor with cell scalars.
void testOneCellOneSegment()
Test extractor with point scalars only.
void testSegmentAcrossCellIntoSecond()
Test extractor with single segment crossing first cell into second.
BSHP< GmMultiPolyIntersector > m_multiPolyIntersector
BSHP< XmUGrid2dDataExtractor > m_extractor
The data extractor.
void testTwoSegmentsAcrossOneCell()
Test extractor with two segments going across a single cell.
void testTwoSegmentsJoinOnBoundary()
Test extractor with two segments joining on two cell boundary.
void testSegmentAllInCell()
Test extractor with single segment all inside of cell.
void testSegmentAlongEdge()
Test extractor with single segment along an edge.
void testTransientTutorial()
Test XmUGrid2dPolylineDataExtractor for tutorial with transient data.
void testSegmentAllOutside()
Test extractor with single segment all outside of cell.
DataLocationEnum
The location at which the data will be stored.
void testTwoSegmentsFirstExiting()
Test extractor with two segments: first in to outside, second outside.
void testSegmentAcrossSplitCells()
Test extractor with single segment going across unconnected cells.
Contains the XmUGrid2dDataExtractor Class and supporting data types.
void testTwoSegmentsAllOutside()
Test extractor with two segments all outside of cell.
void testSegmentTouchToOut()
Test extractor with single segment with first point touching edge.
XMS Namespace.
void testTwoSegmentsJoinInCell()
Test extractor with two segments joining in a cell.
void testThreeSegmentsCrossOnBoundary()
Test extractor with three segments two crossing at boundary.
Contains the XmUGrid Class and supporting data types.
void testSegmentCrossCellPoint()
Test extractor with single segment touching cell point.
Contains the XmUGrid2dPolylineDataExtractor Class and supporting data types.
static BSHP< XmUGrid2dPolylineDataExtractor > New(std::shared_ptr< XmUGrid > a_ugrid, DataLocationEnum a_scalarLocation)
Create a new XmUGrid2dPolylineDataExtractor.
Provides ability to interpolate and extract the scalar values points and along arcs for an unstructur...
Provides ability to interpolate and extract the scalar values along a polyline for an unstructured gr...
void testSegmentOutToTouch()
Test extractor with single segment with endpoint touching cell.