OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimHlzTool.cpp
Go to the documentation of this file.
1 //**************************************************************************************************
2 //
3 // OSSIM Open Source Geospatial Data Processing Library
4 // See top level LICENSE.txt file for license information
5 //
6 //**************************************************************************************************
7 
10 #include <ossim/base/ossimRtti.h>
11 #include <ossim/base/ossimGrect.h>
13 #include <ossim/init/ossimInit.h>
31 #include <ossim/base/Thread.h>
32 #include <fstream>
33 #include <cstddef>
34 
35 static const string MASK_EXCLUDE_KW = "exclude_regions";
36 static const string MASK_INCLUDE_KW = "include_regions";
37 static const string SLOPE_OUTPUT_FILE_KW = "slope_output_file";
38 static const string POINT_CLOUD_FILE_KW = "point_clouds";
39 static const string HLZ_CODING_KW = "hlz_coding";
40 static const string LZ_MIN_RADIUS_KW = "min_lz_radius";
41 static const string ROUGHNESS_THRESHOLD_KW = "max_roughness";
42 static const string SLOPE_THRESHOLD_KW = "max_slope";
43 
44 const char* ossimHlzTool::DESCRIPTION =
45  "Computes bitmap of helicopter landing zones given ROI and DEM.";
46 
47 using namespace std;
48 
50 : m_slopeThreshold(7.0),
51  m_roughnessThreshold(0.5),
52  m_hlzMinRadius(25.0),
53  m_outBuffer(NULL),
54  m_badLzValue(255),
55  m_marginalLzValue(128),
56  m_goodLzValue(64),
57  m_useLsFitMethod(true),
58  m_numThreads(1),
59  d_accumT(0)
60 {
61 }
62 
64 {
65 }
66 
68 {
69  // Add global usage options.
71 
72  // Set the general usage:
74  ossimString usageString = ap.getApplicationName();
75  usageString += " hlz [options] <output-image>";
76  au->setCommandLineUsage(usageString);
77 
78  // Set the command line options:
79  au->addCommandLineOption("--exclude-regions <file1>[, <file2>...]",
80  "List of raster image(s) representing mask files that defines regions to be excluded from "
81  "HLZ solutions. Any non-zero pixel is excluded Multiple filenames must be comma-separated.");
82  au->addCommandLineOption("--hlz-coding <bad> <marginal> <good>",
83  "Specifies the pixel values (0-255) for the output product corresponding to bad, marginal, "
84  "and good landing zones, respectively. Defaults to bad=255 (null), marginal=128, and "
85  "good=64.");
86  au->addCommandLineOption("--include-regions <file1>[, <file2>...]",
87  "List of raster image(s) representing mask files that defines regions where the HLZs ."
88  "identified must overlap. Any non-zero pixel represents an inclusion zone. Multiple "
89  "filenames must be comma-separated.");
90  au->addCommandLineOption("--output-slope <filename.tif>",
91  "Generates a slope byproduct image (floating point degrees) to the specified filename. "
92  "Only valid if normal-vector method used (i.e., --ls-fit option NOT specified)");
93  au->addCommandLineOption("--point-clouds <file1>[, <file2>...]",
94  "Specifies ancillary point-cloud data file(s) for level-2 search for obstructions. "
95  "Must be comma-separated file names.");
96  au->addCommandLineOption("--min-lz-radius <meters>",
97  "Specifies minimum radius of landing zone. Defaults to 25 m. ");
98  au->addCommandLineOption("--max-roughness <meters>",
99  "Specifies the terrain roughness threshold (meters). This is the maximum deviation from a "
100  "flat plane permitted. Defaults to 0.5 m. Valid only with --ls-fit specified.");
101  au->addCommandLineOption("--max-slope <degrees>",
102  "Threshold for acceptable landing zone terrain slope. Defaults to 7 deg.");
103  au->addCommandLineOption("--threads <n>",
104  "Number of threads. Defaults to use single core. For engineering/debug purposes.");
105  au->addCommandLineOption("--use-slope",
106  "Slope is computed from the normal vector using neighboring posts instead of "
107  "least-squares fit to a plane (prefered). For engineering/debug purposes.");
108 }
109 
111 {
113  return false;
114  if (m_helpRequested)
115  return true;
116 
117  string ts1;
119  string ts2;
121  string ts3;
123  ossimString key ;
124 
125  vector<ossimString> maskFnames;
126  ap.read("--exclude-regions", maskFnames);
127  for(ossim_uint32 idx=0; idx<maskFnames.size(); ++idx)
128  {
129  key = MASK_EXCLUDE_KW;
130  key += ossimString::toString(idx++);
131  m_kwl.addPair(key.string(), maskFnames[idx] );
132  }
133 
134  if (ap.read("--hlz-coding", sp1, sp2, sp3) || ap.read("--values", sp1, sp2, sp3))
135  {
136  ostringstream value;
137  value<<ts1<<" "<<ts2<<" "<<ts3;
138  m_kwl.addPair( HLZ_CODING_KW, value.str() );
139  }
140 
141  maskFnames.clear();
142  ap.read("--include-regions", maskFnames);
143  for(ossim_uint32 idx=0; idx<maskFnames.size(); ++idx)
144  {
145  key = MASK_INCLUDE_KW;
146  key += ossimString::toString(idx++);
147  m_kwl.addPair(key.string(), maskFnames[idx] );
148  }
149 
150  if ( ap.read("--output-slope", sp1))
151  m_kwl.addPair(SLOPE_OUTPUT_FILE_KW, ts1);
152 
153  vector<ossimString> pcFnames;
154  ap.read("--point-clouds", pcFnames);
155  for(ossim_uint32 idx=0; idx<pcFnames.size(); ++idx)
156  {
157  key = POINT_CLOUD_FILE_KW;
158  key += ossimString::toString(idx++);
159  m_kwl.addPair(key.string(), pcFnames[idx] );
160  }
161 
162  if (ap.read("--min-lz-radius", sp1) || ap.read("--rlz", sp1))
163  m_kwl.addPair(LZ_MIN_RADIUS_KW, ts1);
164 
165  if (ap.read("--max-roughness", sp1) || ap.read("--roughness", sp1))
166  m_kwl.addPair(ROUGHNESS_THRESHOLD_KW, ts1);
167 
168  if (ap.read("--max-slope", sp1) || ap.read("--slope", sp1))
169  m_kwl.addPair(SLOPE_THRESHOLD_KW, ts1);
170 
171  if (ap.read("--threads", sp1))
172  {
173  // Command line mode only
175  }
176 
177  if (ap.read("--use_slope"))
178  {
179  // Command line mode only
180  m_useLsFitMethod = false;
181  }
182 
184  return true;
185 }
186 
188 {
189  ossimString value;
190  ostringstream xmsg;
191 
192  // Don't copy KWL if member KWL passed in:
193  if (&kwl != &m_kwl)
194  {
195  // Start with clean options keyword list.
196  m_kwl.clear();
197  m_kwl.addList( kwl, true );
198  }
199 
200  value = m_kwl.findKey(LZ_MIN_RADIUS_KW);
201  if (!value.empty())
202  m_hlzMinRadius = value.toDouble();
203  if (m_hlzMinRadius < 1.0)
204  {
205  xmsg<<"ossimHlzUtil:"<<__LINE__<<" The HLZ minimum radius is too small.";
206  throw(xmsg.str());
207  }
208 
209  value = m_kwl.findKey(ROUGHNESS_THRESHOLD_KW);
210  if (!value.empty())
211  m_roughnessThreshold = value.toDouble();
212 
213  value = m_kwl.findKey(SLOPE_THRESHOLD_KW);
214  if (!value.empty())
215  m_slopeThreshold = value.toDouble();
216 
217  value = m_kwl.findKey(HLZ_CODING_KW);
218  if (!value.empty())
219  {
220  vector<ossimString> values = value.split(" ");
221  if (values.size() == 3)
222  {
223  m_badLzValue = values[0].toUInt8();
224  m_marginalLzValue = values[1].toUInt8();
225  m_goodLzValue = values[2].toUInt8();
226  }
227  else
228  {
229  xmsg<<"ossimHlzUtil:"<<__LINE__<<" Unexpected number of values encountered for keyword <"
230  <<HLZ_CODING_KW<<">.";
231  throw(xmsg.str());
232  }
233  }
234 
236 }
237 
239 {
240  ostringstream xmsg;
241 
243  {
244  xmsg<<"ossimHlzUtil:"<<__LINE__<<" Encountered NaNs in AOI."<<ends;
245  throw ossimException(xmsg.str());
246  }
247 
248 
249  // If PC provided as file on command line, Load it. This uses the output ground rect so needs to
250  // be after the initialization of m_geom:
251  loadPcFiles();
252 
253  // If threat-domes spec (or any mask) provided as file on command line, Load it:
254  loadMaskFiles();
255 
256  // In order to use the slope filter to establish terrain quality, the elevation data needs to
257  // be loaded as images, not elevation cells. Need to transfer relevant cells to image chains:
259 
260  // The "chain" for this utility is just the memory source containing the output buffer:
263  if (!m_outBuffer.valid())
264  {
265  xmsg<<"ossimHlzUtil:"<<__LINE__<<" Error encountered allocating output image buffer.";
266  throw(xmsg.str());
267  }
271 
272  // If input image(s) provided, need to combine them with the product:
273  if (m_imgLayers.empty())
274  {
276  }
277  else
278  {
280  combiner->connectMyInputTo(m_memSource.get());
281  m_procChain->add(combiner.get());
282  }
283 
284  if (!m_useLsFitMethod)
285  {
286  // Add the slope computation engine on the elevation source.
287  // Set up processing chain with plane to normal filter, equation combiner, and band selector.
289  slope_filter->connectMyInputTo(m_combinedElevSource.get());
291  m_combinedElevSource = slope_filter.get();
293 
294  m_slopeFile = m_kwl.findKey(SLOPE_OUTPUT_FILE_KW);
295  if (!m_slopeFile.empty())
296  writeSlopeImage();
297  }
298  // Determine number of posts (in one dimension) needed to cover the specified LZ radius:
299  if ((m_gsd.x == 0) || (m_gsd.y == 0) || m_gsd.hasNans())
300  {
301  ostringstream xmsg;
302  xmsg<<"ossimHlzUtil:"<<__LINE__<<" Invalid GSD: "<<m_gsd;
303  throw(xmsg.str());
304  }
305 
306  m_demFilterSize.x = (int) ceil(m_hlzMinRadius/m_gsd.x);
307  m_demFilterSize.y = (int) ceil(m_hlzMinRadius/m_gsd.y);
308  if ((m_demFilterSize.x < 2) || (m_demFilterSize.y < 2))
309  {
310  xmsg<<"ossimHlzUtil:"<<__LINE__<<" The DEM provided does not have sufficient"
311  " resolution to determine HLZs.";
312  throw ossimException(xmsg.str());
313  }
314 }
315 
317 {
318  ostringstream xmsg;
319 
320  ossimString key;
321  ossimFilename pc_file;
323  ossimGrect pc_bbox;
324 
325  for(ossim_uint32 idx=0; true; ++idx)
326  {
327  key = POINT_CLOUD_FILE_KW;
328  key += ossimString::toString(idx++);
329  pc_file = m_kwl.find(key.chars());
330  if (pc_file.empty())
331  break;
332 
333  ossimRefPtr<ossimPointCloudHandler> pc_handler = registry->open(pc_file);
334  if (!pc_handler.valid())
335  {
336  xmsg<<"ossimHlzUtil:"<<__LINE__<<" Error loading point cloud file <"<<pc_file<<">.";
337  throw(xmsg.str());
338  }
339 
340  // Verify that PC bounding rect overlaps the output bounding rect:
341  pc_handler->getBounds(pc_bbox);
342  if (m_aoiGroundRect.intersects(pc_bbox))
343  {
344  m_pcSources.push_back(pc_handler);
345  }
346  else
347  {
349  << "ossimHLZUtil::loadPcFile() WARNING: point-cloud file <" << pc_file << "> "
350  << "does not overlap the output ROI." << endl;
351  }
352  }
353 }
354 
356 {
357  ostringstream xmsg;
358 
359  ossimString key;
360  ossimFilename mask_file;
361 
362  // Exclusion masks:
363  for(ossim_uint32 idx=0; true; ++idx)
364  {
365  key = MASK_EXCLUDE_KW;
366  key += ossimString::toString(idx++);
367  mask_file = m_kwl.find(key.chars());
368  if (mask_file.empty())
369  break;
370 
371  MaskSource mask_image (this, mask_file, true);
372  if (mask_image.image.valid())
373  m_maskSources.push_back(mask_image);
374  }
375 
376  // Inclusion masks:
377  for(ossim_uint32 idx=0; true; ++idx)
378  {
379  key = MASK_INCLUDE_KW;
380  key += ossimString::toString(idx++);
381  mask_file = m_kwl.find(key.chars());
382  if (mask_file.empty())
383  break;
384 
385  // First check if the filename specified is an image file:
386  MaskSource mask_image (this, mask_file, false);
387  if (mask_image.image.valid())
388  m_maskSources.push_back(mask_image);
389  }
390 }
391 
393 {
394  ostringstream xmsg;
395  if (!m_geom.valid())
396  return 0;
397 
398  m_aoiViewRect = bounding_irect;
401 
402  if (computeHLZ())
403  {
404  // The memory source has been populated, now do the getTile on the full chain to pick up
405  // other filters inserted after the memsource:
406  return m_procChain->getTile( m_aoiViewRect, 0 );
407  }
408  // else:
409  return 0;
410 }
411 
413 {
414  if (m_helpRequested)
415  return true;
416 
419 }
420 
422 {
423 
424  // To help with multithreading, just load entire AOI of DEM into memory:
426  if (!m_demBuffer.valid())
427  return false;
428 
429  // Allocate the output image buffer:
432  ostringstream xmsg;
433  if (!m_outBuffer.valid() || !m_memSource.valid())
434  {
435  xmsg<<"ossimHlzUtil:"<<__LINE__<<" Error encountered allocating output image buffer.";
436  throw(xmsg.str());
437  }
438 
439  // Initialize the image with all points hidden:
442  m_outBuffer->fill(0);
444 
445  d_accumT = 0;
446 
447  // Establish loop limits in input DEM raster coordinate space:
448  ossim_int32 min_x = m_aoiViewRect.ul().x;
449  ossim_int32 min_y = m_aoiViewRect.ul().y;
452  ossimIpt chip_origin;
453  ossim_uint32 numPatches = (max_x-min_x)*(max_y-min_y);
454 
455  // Determine the DEM step size as a fraction of the LZ radius:
456  const double CHIP_STEP_FACTOR = 0.25; // chip position increment as fraction of chip width
457  ossim_int32 dem_step =
458  (ossim_int32) floor(4*CHIP_STEP_FACTOR*m_hlzMinRadius/(m_gsd.x+m_gsd.y));
459  if (dem_step <= 0)
460  dem_step = 1;
461 
462  // Hack: degrading to single thread when slope-image scheme is used. Runs extremely slow in
463  // multithread mode, but much faster as single thread than multithreaded ls-fit
464  if ((m_numThreads == 1) || !m_useLsFitMethod)
465  {
466  // Not threaded (or slope-image scheme):
468  ossim_uint32 chipId = 0;
469  for (chip_origin.y = min_y; chip_origin.y <= max_y; chip_origin.y += dem_step)
470  {
471  for (chip_origin.x = min_x; chip_origin.x <= max_x; chip_origin.x += dem_step)
472  {
473  std::shared_ptr<ossimHlzTool::PatchProcessorJob> job = 0;
474  if (m_useLsFitMethod)
475  job = std::make_shared<ossimHlzTool::LsFitPatchProcessorJob>(this, chip_origin, chipId++);
476  else
477  job = std::make_shared<ossimHlzTool::NormPatchProcessorJob>(this, chip_origin, chipId++);
478  job->start();
479  }
480  setPercentComplete(100*chipId/numPatches);
481  }
482  }
483  else
484  {
485  if (m_numThreads == 0)
487 
488  // Loop over input DEM, creating a thread job for each filter window:
489  std::shared_ptr<ossimJobMultiThreadQueue> jobMtQueue =
490  std::make_shared<ossimJobMultiThreadQueue>(nullptr, m_numThreads);
491  std::shared_ptr<ossimJobQueue> jobQueue = jobMtQueue->getJobQueue();
492 
493  ossimNotify(ossimNotifyLevel_INFO) << "\nPreparing " << numPatches << " jobs..." << endl; // TODO: DEBUG
495  ossim_int32 qsize = 0;
496  ossimIpt chip_origin;
497  ossim_uint32 chipId = 0;
498  for (chip_origin.y = min_y; chip_origin.y <= max_y; ++chip_origin.y)
499  {
500  for (chip_origin.x = min_x; chip_origin.x <= max_x; ++chip_origin.x)
501  {
502  //ossimNotify(ossimNotifyLevel_INFO) << "Submitting " << chipId << endl;
503  std::shared_ptr<ossimHlzTool::PatchProcessorJob> job = 0;
504  if (m_useLsFitMethod)
505  job = std::make_shared<ossimHlzTool::LsFitPatchProcessorJob>(this, chip_origin, chipId++);
506  else
507  job = std::make_shared<ossimHlzTool::NormPatchProcessorJob>(this, chip_origin, chipId++);
508  jobQueue->add(job, false);
509  }
510  qsize = jobQueue->size();
511  setPercentComplete(100*(chipId-qsize)/numPatches);
512  }
513 
514  // Wait until all chips have been processed before proceeding:
515  ossimNotify(ossimNotifyLevel_INFO) << "All jobs queued. Waiting for job threads to finish..." << endl;
516  while (jobMtQueue->hasJobsToProcess() || jobMtQueue->numberOfBusyThreads())
517  {
518  qsize = jobMtQueue->getJobQueue()->size();
519  setPercentComplete(100*(numPatches-qsize)/numPatches);
521  }
522  jobMtQueue = 0;
523  }
524 
525  ossimNotify(ossimNotifyLevel_INFO) << "Finished processing chips." << endl;
526  return true;
527 }
528 
530 {
531  // Set up the writer:
533  ossimTiffWriter* tif_writer = new ossimTiffWriter();
534  tif_writer->setGeotiffFlag(true);
535  tif_writer->setFilename(m_slopeFile);
536  writer = tif_writer;
539  if (writer->execute())
540  ossimNotify(ossimNotifyLevel_INFO)<<"Wrote slope image to <"<<m_slopeFile<<">."<<endl;
541  else
542  {
543  ossimNotify(ossimNotifyLevel_WARN)<<"ossimHLZUtil::writeSlopeImage() Error encountered "
544  "writing slope image to <"<<m_slopeFile<<">."<<endl;
545  }
546 }
547 
549 
551  ossim_uint32 /*chip_id*/)
552 : m_hlzUtil (hlzUtil),
553  m_demPatchUL (origin),
554  m_status (0),
555  m_nullValue (hlzUtil->m_demBuffer->getNullPix(0))
556 {
559 }
560 
562 {
563  bool passed = level1Test() && level2Test() && maskTest();
564  ossimIpt p;
565 
566  std::lock_guard<std::mutex> lock (m_bufMutex);
567  for (p.y = m_demPatchUL.y; p.y < m_demPatchLR.y; ++p.y)
568  {
569  for (p.x = m_demPatchUL.x; p.x < m_demPatchLR.x; ++p.x)
570  {
571  if (passed && (m_status == 2))
572  m_hlzUtil->m_outBuffer->setValue(p.x, p.y, m_hlzUtil->m_goodLzValue);
573  else if (passed && (m_status == 1))
574  m_hlzUtil->m_outBuffer->setValue(p.x, p.y, m_hlzUtil->m_marginalLzValue);
575  else
576  m_hlzUtil->m_outBuffer->setValue(p.x, p.y, m_hlzUtil->m_badLzValue);
577  }
578  }
579 }
580 
582 {
583  // Start with computing best-fit plane:
584  ossimIpt p;
585  double z;
586  double y_meters;
587  for (p.y = m_demPatchUL.y; p.y < m_demPatchLR.y; ++p.y)
588  {
589  y_meters = p.y*m_hlzUtil->m_gsd.y;
590  for (p.x = m_demPatchUL.x; p.x < m_demPatchLR.x; ++p.x)
591  {
592  z = m_hlzUtil->m_demBuffer->getPix(p, 0);
593  if ((z == m_nullValue) || ossim::isnan(z))
594  return false;
595  m_plane->addSample(p.x*m_hlzUtil->m_gsd.x, y_meters, z);
596  }
597  }
598  if (!m_plane->solveLS())
599  return false;
600 
601  // The slope is derived from the normal unit vector. Extract that from the solution and test
602  // against threshold:
603  double a, b, c;
604  m_plane->getLSParms(a, b, c);
605  double z_proj = 1.0 / sqrt(a*a + b*b + 1.0);
606  double theta = fabs(ossim::acosd(z_proj));
607  if (theta > m_hlzUtil->m_slopeThreshold)
608  return false;
609 
610  // Passed the slope test. Now measure the roughness as peak deviation from the plane:
611  double distance;
612  for (p.y = m_demPatchUL.y; (p.y < m_demPatchLR.y); ++p.y)
613  {
614  for (p.x = m_demPatchUL.x; (p.x < m_demPatchLR.x); ++p.x)
615  {
616  z = m_hlzUtil->m_demBuffer->getPix(p, 0);
617  distance = fabs(z_proj * (a*p.x + b*p.y + c - z));
618  if (distance > m_hlzUtil->m_roughnessThreshold)
619  return false;
620  }
621  }
622 
623  m_status = 1; // indicates passed level 1
624  return true;
625 }
626 
628 {
629  // The processing chain is outputing slope values in degrees from vertical.
630  // Scan the data tile for slopes outside the threshold:
631  ossimIpt p;
632  float theta;
633  for (p.y = m_demPatchUL.y; p.y < m_demPatchLR.y; ++p.y)
634  {
635  for (p.x = m_demPatchUL.x; p.x < m_demPatchLR.x; ++p.x)
636  {
637  theta = m_hlzUtil->m_demBuffer->getPix(p, 0);
638  if ((theta == m_nullValue) || ossim::isnan(theta) || (theta > m_hlzUtil->m_slopeThreshold))
639  return false;
640  }
641  }
642 
643  m_status = 1; // indicates passed level 1
644  return true;
645 }
646 
648 {
649  // Level 2 only valid if a point cloud dataset is available:
650  if (m_hlzUtil->m_pcSources.empty())
651  {
652  ++m_status; // assumes level2 passes
653  return true;
654  }
655 
656  // Need to convert DEM file coordinate bounds to geographic.
657  ossimGpt chipUlGpt, chipLrGpt;
658  m_hlzUtil->m_geom->localToWorld(ossimDpt(m_demPatchUL), chipUlGpt);
659  m_hlzUtil->m_geom->localToWorld(ossimDpt(m_demPatchLR), chipLrGpt);
660  chipUlGpt.hgt = ossim::nan();
661  chipLrGpt.hgt = ossim::nan();
662  ossimGrect grect (chipUlGpt, chipLrGpt);
663 
664  // TODO: LIMITATION: Only a single point cloud source is considered. Need to expand to handle
665  // a list:
666  const ossimPointCloudHandler* pc_src = m_hlzUtil->m_pcSources[0].get();
667 
668  // First check if there is even any coverage:
669  m_status = 0; // reset assumes no coverage
670  ossimGrect bb;
671  pc_src->getBounds(bb);
672  if (!bb.intersects(grect))
673  return false;
674 
676  pc_src->getBlock(grect, pc_block);
677  if (pc_block.empty())
678  return false;
679 
680  bool found_obstruction = false;
681 
682  // Scan the block for obstructions:
683  ossimGpt point_plh;
684  ossimDpt point_xy;
685  ossim_uint32 numPoints = pc_block.size();
686  for (ossim_uint32 i=0; (i<numPoints) && !found_obstruction; ++i)
687  {
688  //If this is not the only return, implies clutter along the ray:
689  int num_returns = (int) pc_block[i]->getField(ossimPointRecord::NumberOfReturns);
690  if (num_returns > 1)
691  {
692  found_obstruction = true;
693  break;
694  }
695  }
696 
697  if (!found_obstruction)
698  m_status = 2;
699 
700  return true;
701 }
702 
704 {
705  // Threat dome only valid if a mask source is available:
706  if (m_hlzUtil->m_maskSources.empty())
707  return true;
708 
709  ossimIrect chipRect (m_demPatchUL, m_demPatchLR);
710  vector<MaskSource>::iterator mask_source = m_hlzUtil->m_maskSources.begin();
711  bool test_passed = true;
712  ossimIpt p;
713  ossim_uint8 mask_value;
714 
715  while ((mask_source != m_hlzUtil->m_maskSources.end()) && test_passed)
716  {
717  ossimRefPtr<ossimImageData> mask_data = mask_source->image->getTile(chipRect);
718  for (p.y = m_demPatchUL.y; (p.y < m_demPatchLR.y) && test_passed; ++p.y)
719  {
720  for (p.x = m_demPatchUL.x; (p.x < m_demPatchLR.x) && test_passed; ++p.x)
721  {
722  mask_value = mask_data->getPix(p);
723  if (( mask_value && mask_source->exclude) || (!mask_value && !mask_source->exclude))
724  test_passed = false;
725  }
726  }
727  ++mask_source;
728  }
729 
730  return test_passed;
731 }
732 
734  const ossimFilename& mask_image,
735  bool exclusion)
736 : exclude (exclusion)
737 {
738  image = hlzUtil->createInputChain(mask_image);
739 }
virtual void initProcessingChain()
Derived classes initialize their custom chains here.
double m_slopeThreshold
Definition: ossimHlzTool.h:78
virtual bool initialize(ossimArgumentParser &ap)
Initial method to be ran prior to execute.
void fill(ossim_uint32 band, ossim_float64 value)
will fill the entire band with the value.
std::string getApplicationName() const
return the application name, as specified by argv[0]
void addCommandLineOption(const ossimString &option, const ossimString &explanation)
ossimRefPtr< ossimImageData > getChip()
Get chip method that assumes pre-initialized state.
void writeSlopeImage()
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
Within the image chain will pass the head of the list.
ossimRefPtr< ossimImageGeometry > m_geom
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
virtual void setImageRectangle(const ossimIrect &rect)
Filter class for computing the slope image of the input image connection.
ossimGrect m_aoiGroundRect
std::vector< ossimRefPtr< ossimPointCloudHandler > > m_pcSources
Definition: ossimHlzTool.h:91
ossim_uint8 m_goodLzValue
Definition: ossimHlzTool.h:88
Represents serializable keyword/value map.
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
bool m_helpRequested
Definition: ossimTool.h:150
double m_roughnessThreshold
Definition: ossimHlzTool.h:79
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
virtual void run()
Abstract method and must be overriden by the base class.
bool read(const std::string &str)
search for an occurance of a string in the argument list, on sucess remove that occurance from the li...
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
double y
Definition: ossimDpt.h:165
ossim_uint32 height() const
Definition: ossimIrect.h:487
void addList(const ossimKeywordlist &src, bool overwrite=true)
static ossimString toString(bool aValue)
Numeric to string methods.
bool m_useLsFitMethod
Definition: ossimHlzTool.h:89
void setImage(ossimRefPtr< ossimImageData > image)
ossim_uint8 m_badLzValue
Definition: ossimHlzTool.h:86
virtual void setPercentComplete(double percentComplete)
ossimKeywordlist m_kwl
Definition: ossimTool.h:148
ossimRefPtr< ossimImageSource > combineLayers(std::vector< ossimRefPtr< ossimSingleImageChain > > &layers) const
When multiple input sources are present, this method instantiates a combiner and adds inputs...
const ossimIpt & ul() const
Definition: ossimIrect.h:274
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
virtual void getBounds(ossimGrect &bounds) const
double acosd(double x)
Definition: ossimCommon.h:264
void addPair(const std::string &key, const std::string &value, bool overwrite=true)
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
ossim_uint32 toUInt32() const
ossimRefPtr< ossimMemoryImageSource > m_memSource
Definition: ossimHlzTool.h:85
void setCommandLineUsage(const ossimString &explanation)
virtual ossim_float64 getPix(const ossimIpt &position, ossim_uint32 band=0) const
Will return the pixel at location position.
MaskSource(ossimHlzTool *hlzUtil, const ossimFilename &mask_image, bool exclude)
ossimApplicationUsage * getApplicationUsage()
double d_accumT
Definition: ossimHlzTool.h:96
void setImageSize(const ossimIpt &size)
static void sleepInMicroSeconds(ossim_uint64 micros)
Utility method to allow one to sleep in microseconds.
Definition: Thread.cpp:83
ossimIpt size() const
Definition: ossimIrect.h:510
virtual void initialize()
Initialize the data buffer.
bool hasNans() const
Definition: ossimGrect.h:298
ossimRefPtr< ossimImageChain > m_procChain
OSSIM_DLL ossim_uint32 getNumberOfThreads()
Get the number threads to use from ossimPreferences or ossim::Thread.
virtual ossimPointCloudHandler * open(const ossimFilename &fileName) const
static const char * DESCRIPTION
Used by ossimUtilityFactory.
Definition: ossimHlzTool.h:50
ossim_uint32 m_numThreads
Definition: ossimHlzTool.h:95
ossimIpt m_demFilterSize
Definition: ossimHlzTool.h:82
virtual bool initialize(ossimArgumentParser &ap)
Initial method to be ran prior to execute.
virtual void setUsage(ossimArgumentParser &ap)
Initializes the aurgument parser with expected parameters and options.
virtual bool execute()
Performs the actual product write.
PatchProcessorJob(ossimHlzTool *hlzUtil, const ossimIpt &origin, ossim_uint32 chip_id=0)
static ossimImageDataFactory * instance()
ossimRefPtr< ossimImageData > m_demBuffer
Definition: ossimHlzTool.h:83
virtual void setGeotiffFlag(bool flag)
bool localToWorld(const ossimDpt &local_pt, ossimGpt &world_pt) const
Exposes the 3D projection from image to world coordinates.
void loadMaskFiles()
ossimRefPtr< ossimImageSource > m_combinedElevSource
Definition: ossimHlzTool.h:90
unsigned int ossim_uint32
void processRemainingArgs(ossimArgumentParser &ap)
Intended to be called after derived class has picked off its own options from the parser...
const char * chars() const
For backward compatibility.
Definition: ossimString.h:77
ossimRefPtr< ossimImageSource > mosaicDemSources()
Some utilities need to work on DEMs as images.
bool empty() const
double toDouble() const
std::vector< ossimRefPtr< ossimSingleImageChain > > m_imgLayers
virtual void setImageGeometry(ossimImageGeometry *geom)
Default implementation sets geometry of the first input to the geometry specified.
const ossimIpt & lr() const
Definition: ossimIrect.h:276
virtual bool add(ossimConnectableObject *source)
Will return true or false if an image source was added to the chain.
virtual ossim_int32 connectMyInputTo(ossimConnectableObject *inputObject, bool makeOutputConnection=true, bool createEventFlag=true)
Will try to connect this objects input to the passed in object.
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
bool hasNans() const
Definition: ossimDpt.h:67
virtual ossim_uint32 size() const
Returns allocated size.
void setSlopeType(SlopeType t)
static ossimPointCloudHandlerRegistry * instance()
virtual void setUsage(ossimArgumentParser &ap)
Initializes the aurgument parser with expected parameters and options.
ossimRefPtr< ossimImageData > m_outBuffer
Definition: ossimHlzTool.h:84
virtual void setFilename(const ossimFilename &file)
virtual void getBlock(const ossimGrect &bounds, ossimPointBlock &block) const
Fetches the block of points inside the block bounds.
ossim_uint8 m_marginalLzValue
Definition: ossimHlzTool.h:87
double m_hlzMinRadius
Definition: ossimHlzTool.h:80
void loadPcFiles()
ossim_int32 y
Definition: ossimIpt.h:142
virtual void setAreaOfInterest(const ossimIrect &inputRect)
double x
Definition: ossimDpt.h:164
bool empty() const
Definition: ossimString.h:411
ossimFilename m_slopeFile
Definition: ossimHlzTool.h:81
bool hasNans() const
Definition: ossimIrect.h:337
ossim_int32 x
Definition: ossimIpt.h:141
virtual void initialize()=0
8 bit unsigned integer
ossimRefPtr< ossimSingleImageChain > image
Definition: ossimHlzTool.h:57
std::vector< MaskSource > m_maskSources
Definition: ossimHlzTool.h:92
Base class for all point-cloud file readers.
float distance(double lat1, double lon1, double lat2, double lon2, int units)
bool intersects(const ossimGrect &rect) const
Definition: ossimGrect.cpp:266
virtual bool execute()
Performs the actual product write.
unsigned char ossim_uint8
ossimRefPtr< ossimSingleImageChain > createInputChain(const ossimFilename &image_file, ossim_uint32 entry_index=0)
Creates the ossimSingleImageChain from image filename and populates the chain with resampler and prod...
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual bool execute()
Calls: writeFile() writeMetaDataFiles()
int ossim_int32
const std::string & string() const
Definition: ossimString.h:414
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91