OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimChipProcTool.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 
16 #include <ossim/base/ossimNotify.h>
22 #include <ossim/base/ossimTrace.h>
33 #include <ossim/init/ossimInit.h>
41 #include <cmath>
42 #include <sstream>
43 #include <string>
44 
45 static const std::string AOI_GEO_RECT_KW = "aoi_geo_rect";
46 static const std::string AOI_MAP_RECT_KW = "aoi_map_rect";
47 static const std::string AOI_GEO_CENTER_KW = "aoi_geo_center";
48 static const std::string AOI_SIZE_METERS_KW = "aoi_size_meters";
49 static const std::string AOI_SIZE_PIXELS_KW = "aoi_size_pixels";
50 static const std::string CLIP_POLY_LAT_LON_KW = "clip_poly_lat_lon";
51 static const std::string LUT_FILE_KW = "lut_file";
52 static const std::string GSD_KW = "gsd";
53 static const std::string OUTPUT_RADIOMETRY_KW = "output_radiometry";
54 static const std::string READER_PROPERTY_KW = "reader_property";
55 static const std::string SNAP_TIE_TO_ORIGIN_KW = "snap_tie_to_origin";
56 static const std::string SRS_KW = "srs";
57 static const std::string TILE_SIZE_KW = "tile_size"; // pixels
58 static const std::string TRUE_KW = "true";
59 static const std::string WRITER_KW = "writer";
60 static const std::string WRITER_PROPERTY_KW = "writer_property";
61 
63 : m_projIsIdentity(false),
64  m_geoScaled (false),
65  m_productScalarType(OSSIM_SCALAR_UNKNOWN),
66  m_needCutRect(false)
67 {}
68 
70 : m_projIsIdentity(false),
71  m_geoScaled(false),
72  m_productScalarType(OSSIM_SCALAR_UNKNOWN),
73  m_needCutRect(false)
74 {
76  m_gsd.makeNan();
79 }
80 
82 {
83  clear();
84 }
85 
87 {
88  m_gsd.makeNan();
89 
90  m_procChain = 0;
91  m_imgLayers.clear();
92  m_writer = 0;
93  m_geom = 0;
94  m_needCutRect = false;
95 }
96 
98 {
99  if (!ossimTool::initialize(ap))
100  return false;
101  if (m_helpRequested)
102  return true;
103 
104  std::string tempString1;
105  ossimArgumentParser::ossimParameter stringParam1(tempString1);
106  std::string tempString2;
107  ossimArgumentParser::ossimParameter stringParam2(tempString2);
108  std::string tempString3;
109  ossimArgumentParser::ossimParameter stringParam3(tempString3);
110  std::string tempString4;
111  ossimArgumentParser::ossimParameter stringParam4(tempString4);
112  double tempDouble1;
113  ossimArgumentParser::ossimParameter doubleParam1(tempDouble1);
114  double tempDouble2;
115  ossimArgumentParser::ossimParameter doubleParam2(tempDouble2);
116  vector<ossimString> paramList;
117 
118  ossim_uint32 readerPropIdx = 0;
119  ossim_uint32 writerPropIdx = 0;
120  ostringstream keys;
121 
122  if ( ap.read("--load-options", stringParam1))
123  {
124  if (!m_kwl.addFile(tempString1.c_str()))
125  {
127  throw ossimException("Must supply an output file.");
128  }
129  }
130 
131  if ( ap.read("--aoi-geo-bbox", stringParam1, stringParam2, stringParam3, stringParam4))
132  {
133  ostringstream ostr;
134  ostr<<tempString1<<" "<<tempString2<<" "<<tempString3<<" "<<tempString4<<ends;
135  m_kwl.addPair( AOI_GEO_RECT_KW, ostr.str() );
136  }
137 
138  if ( ap.read("--aoi-geo-center", stringParam1, stringParam2))
139  {
140  ostringstream ostr;
141  ostr<<tempString1<<" "<<tempString2<<ends;
142  m_kwl.addPair( AOI_GEO_CENTER_KW, ostr.str() );
143  }
144 
145  if ( ap.read("--aoi-map-bbox", stringParam1, stringParam2, stringParam3, stringParam4))
146  {
147  ostringstream ostr;
148  ostr<<tempString1<<" "<<tempString2<<" "<<tempString3<<" "<<tempString4<<ends;
149  m_kwl.addPair( AOI_MAP_RECT_KW, ostr.str() );
150  }
151 
152  if ( ap.read("--aoi-size-meters", stringParam1, stringParam2))
153  {
154  ostringstream ostr;
155  ostr<<tempString1<<" "<<tempString2<<ends;
156  m_kwl.addPair( AOI_SIZE_METERS_KW, ostr.str() );
157  }
158 
159  if ( ap.read("--aoi-size-pixels", stringParam1, stringParam2))
160  {
161  ostringstream ostr;
162  ostr<<tempString1<<" "<<tempString2<<ends;
163  m_kwl.addPair( AOI_SIZE_PIXELS_KW, ostr.str() );
164  }
165 
166  if (ap.read("-b", stringParam1) || ap.read("--bands", stringParam1))
167  m_kwl.addPair( std::string(ossimKeywordNames::BANDS_KW), tempString1 );
168 
169  if( ap.read("--central-meridian", stringParam1) )
170  m_kwl.addPair( std::string(ossimKeywordNames::CENTRAL_MERIDIAN_KW), tempString1 );
171 
172  if( ap.read("--color-table", stringParam1) || ap.read("--lut", stringParam1) )
173  m_kwl.addPair( LUT_FILE_KW, tempString1 );
174 
175  if ( ap.read("-e", stringParam1) || ap.read("--entry", stringParam1) )
176  m_kwl.addPair( std::string(ossimKeywordNames::ENTRY_KW), tempString1 );
177 
178  if (ap.read("--dem", paramList))
179  {
180  ostringstream value;
181  for(ossim_uint32 idx=0; idx<paramList.size(); ++idx)
182  {
183  ostringstream key;
185  m_kwl.addPair(key.str(), paramList[idx] );
186  }
187  }
188 
189  if( ap.read("--gsd", stringParam1) )
190  m_kwl.addPair( GSD_KW, tempString1 );
191 
192  if ( ap.read("--hemisphere", stringParam1) )
193  m_kwl.addPair( std::string(ossimKeywordNames::HEMISPHERE_KW), tempString1 );
194 
195  vector<ossimString> imageFnames;
196  if (ap.read("--image", imageFnames) || ap.read("-i", imageFnames))
197  {
198  if (imageFnames.size() == 1)
199  m_kwl.add(ossimKeywordNames::IMAGE_FILE_KW, imageFnames[0].chars() );
200  else for(ossim_uint32 idx=0; idx<imageFnames.size(); ++idx)
201  {
202  ostringstream key;
204  m_kwl.addPair(key.str(), imageFnames[idx] );
205  }
206  }
207 
208  if( ap.read("--origin-latitude", stringParam1) )
209  m_kwl.addPair( std::string(ossimKeywordNames::ORIGIN_LATITUDE_KW), tempString1 );
210 
211  if(ap.read("--output-file", stringParam1) || ap.read("-o", stringParam1))
213 
214  if(ap.read("--output-radiometry", stringParam1))
215  m_kwl.addPair( OUTPUT_RADIOMETRY_KW, tempString1 );
216 
217  if( ap.read("--projection", stringParam1) )
218  m_kwl.addPair( std::string(ossimKeywordNames::PROJECTION_KW), tempString1 );
219 
220  while (ap.read("--reader-prop", stringParam1))
221  {
222  ostringstream key;
223  key << READER_PROPERTY_KW << readerPropIdx;
224  m_kwl.addPair(key.str(), tempString1 );
225  ++readerPropIdx;
226  }
227 
228  if ( ap.read("--snap-tie-to-origin") )
229  m_kwl.addPair( SNAP_TIE_TO_ORIGIN_KW, TRUE_KW);
230 
231  if( ap.read("--srs", stringParam1) )
232  {
233  ossimString os = tempString1;
234  if ( os.contains("EPSG:") )
235  os.gsub( ossimString("EPSG:"), ossimString("") );
236  m_kwl.addPair( SRS_KW, os.string() );
237  }
238 
239  if( ap.read("--tile-size", stringParam1) )
240  m_kwl.addPair( TILE_SIZE_KW, tempString1 );
241 
242  if( ap.read("-w", stringParam1) || ap.read("--writer", stringParam1) )
243  m_kwl.addPair( WRITER_KW, tempString1);
244 
245  while (ap.read("--writer-prop", stringParam1))
246  {
247  ostringstream key;
248  key << WRITER_PROPERTY_KW << writerPropIdx;
249  m_kwl.addPair(key.str(), tempString1 );
250  ++writerPropIdx;
251  }
252 
253  if( ap.read("--zone", stringParam1) )
254  m_kwl.addPair( std::string(ossimKeywordNames::ZONE_KW), tempString1);
255 
256  return true;
257 }
258 
260 {
261  // ossim_uint32 inputIdx = 0;
262 
263  bool dumpKwl = false;
264  if ( ap.read("--dump-options") )
265  dumpKwl = true;
266 
267  if ( ap.argc() >= 2 )
268  {
269  // Output file is last arg:
271  }
272  else
273  {
275  {
277  throw ossimException("Must supply an output file.");
278  }
279  }
280 
281  if ( ap.argc() > 2 ) // User passed inputs in front of output file.
282  {
283  int pos = 1; // ap.argv[0] is application name.
284  int idx = 0;
285  while ( pos < (ap.argc()-1) )
286  {
287  ostringstream key;
289  m_kwl.add( key.str().c_str(), ap[pos] );
290 
291  ++pos; // Go to next arg...
292 
293  } // End: while ( pos < (ap.argc()-1) )
294 
295  } // End: if ( ap.argc() > 2 )
296 
297  // End of arg parsing.
299  if ( ap.errors() )
300  {
302  throw ossimException("Unknown option...");
303  }
304 
305  if (dumpKwl)
306  {
308  f.setExtension("kwl");
309  if (!m_kwl.write(f.chars()))
310  {
311  ostringstream xmsg;
312  xmsg<<"ossimChipProcUtil:"<<__LINE__<<" Error encountered writing options file to <"<<f<<">";
313  throw ossimException(xmsg.str());
314  }
315  ossimNotify(ossimNotifyLevel_NOTICE)<<"\nWrote options file to <"<<f<<">"<<endl;
316  }
317 
318  initialize(m_kwl);
319 }
320 
322 {
323  m_helpRequested = false;
324 
325  // Don't copy KWL if member KWL passed in:
326  if (&kwl != &m_kwl)
327  {
328  // Start with clean options keyword list.
329  m_kwl.clear();
330  m_kwl.addList( kwl, true );
331  }
332 
333  // Assign some members from KWL:
335  getScalarTypeFromString( m_kwl.findKey( OUTPUT_RADIOMETRY_KW ) );
336 
338 
339  // Create chains for input sources.
340  loadImageFiles();
341 
342  // Load any specified DEMs:
343  loadDemFiles();
344 
345  // Initialize projection and propagate to chains.
347 
348  // Pass control to derived class so it can add its specific processing to the chain(s). This
349  // should return an initialized m_procChain.
351  finalizeChain();
352 }
353 
355 {
356  ostringstream errMsg;
357 
358  // See if an LUT is requested:
359  ossimFilename lutFile = m_kwl.findKey( LUT_FILE_KW );
360  if (!lutFile.empty())
361  {
362  if ( !lutFile.exists() )
363  {
364  errMsg<<"ERROR ossimChipProcUtil ["<<__LINE__<<"] Color table <"<<lutFile
365  <<"> does not exists: "<<ends;
366  throw ossimException(errMsg.str());
367  }
369  lut->setLut(lutFile);
370  m_procChain->add(lut.get());
371  }
372 
373  if (m_needCutRect)
374  {
375  // Add a cut filter. This will:
376  // 1) Null out/clip any data pulled in.
377  // 2) Speed up by not propagating get tile request outside the cut or "aoi"
378  // to the left hand side(input).
383  }
384 
385  // Set the image size here. Note must be set after combineLayers. This is needed for
386  // the ossimImageGeometry::worldToLocal call for a geographic projection to handle wrapping
387  // accross the date line.
389 
390  // Reset the source bounding rect if it changed.
392 }
393 
395 {
396  if (m_helpRequested)
397  return true;
398 
399  ostringstream xmsg;
400 
401  if ( !m_procChain.valid() )
402  {
403  xmsg << "ossimChipProcUtil:"<<__LINE__<<"Null pointer encountered for m_procChain!";
404  throw ossimException(xmsg.str());
405  }
406 
407  if (m_geom->getImageSize().hasNans())
408  {
409  xmsg << "ossimChipProcUtil:"<<__LINE__<<"Image size is NaN!";
410  throw ossimException(xmsg.str());
411  }
412 
413  // Set up the writer.
414  m_writer = newWriter();
415 
416  // Connect the writer to the processing chain.
418 
419  // Set the area of interest. NOTE: This must be called after the writer->connectMyInputTo as
420  // ossimImageFileWriter::initialize incorrectly resets AOI back to the bounding rect.
422 
424  throw ossimException( "Unable to initialize writer for execution" );
425 
426  // Add a listener to get percent complete.
427  ossimStdOutProgress prog(0, true);
428  m_writer->addListener(&prog);
429 
430  // Write the file:
431  m_writer->execute();
432  m_writer->removeListener(&prog);
433  if(m_writer->isAborted())
434  {
435  xmsg << "ossimChipProcUtil:"<<__LINE__<<"Writer Process aborted!";
436  throw ossimException(xmsg.str());
437  }
438 
439  ossimNotify(ossimNotifyLevel_INFO)<<"Wrote product image to <"<<m_productFilename<<">"<<endl;
440 
441  return true;
442 }
443 
445 {
446  if(m_writer.valid())
447  {
448  m_writer->abort();
449  }
450 }
451 
453  const ossimDpt& gsd)
454 {
455  ostringstream xmsg;
456  if (!m_geom.valid())
457  return 0;
458 
460  if (proj == 0)
461  return 0;
462 
463  proj->setMetersPerPixel(gsd);
464  ossimGpt ulGpt = proj->inverse(map_bounding_rect.ul());
465  ossimGpt lrGpt = proj->inverse(map_bounding_rect.lr());
466  m_aoiGroundRect = ossimGrect(ulGpt, lrGpt);
467  ossimDrect view_rect;
468  m_geom->worldToLocal(m_aoiGroundRect, view_rect);
469  m_aoiViewRect = view_rect;
471 
472  return getChip(m_aoiViewRect);
473 }
474 
476 {
478  if (!m_geom.valid())
479  return chip;
480 
481  // Set the new cut rectangle. Note that a NaN rect passed in implies the full AOI:
482  if (!geo_bounding_grect.hasNans())
483  {
484  ossimNotify(ossimNotifyLevel_INFO) <<"\nossimChipProcUtil::getChip(grect) -- NaN rect "
485  "provided. Using full AOI."<<endl;
486  m_aoiGroundRect = geo_bounding_grect;
488  }
489 
490  return getChip(m_aoiViewRect);
491 }
492 
494 {
496  if(!m_procChain.valid())
497  return chip;
498 
499  m_aoiViewRect = bounding_irect;
501 
502  // There should not be a chipper filter in the chain for getImage() calls since the chipping
503  // is implied by the requested rect to getTile(), but if present, make sure it covers
504  // the requested AOI to avoid masking out the tile.
505  if (!m_cutRectFilter.valid())
506  {
510  }
512  return m_procChain->getTile( m_aoiViewRect, 0 );
513 }
514 
516 {
518  if(m_procChain.valid())
519  {
520  chip = m_procChain->getTile( m_aoiViewRect, 0 );
521  }
522  return chip;
523 }
524 
526 {
527  return this;
528 };
529 
531 {
532  return this;
533 }
534 
536 {
537  return this;
538 }
539 
541 {
543  ossim_uint32 count = numImages;
544  ossim_uint32 entryIndex = 0;
545 
546  // Returns 0 if no entry found. This is default anyway.
547  ossim_uint32 globalEntryValue = ossimString(m_kwl.find(ossimKeywordNames::ENTRY_KW)).toUInt32();
548 
549  for (ossim_uint32 i=0; count > 0; ++i)
550  {
551  ossimFilename f;
552  if (numImages == 1)
553  {
554  ostringstream key;
555  key << ossimKeywordNames::IMAGE_FILE_KW; // Try non-indexed first
556  f = m_kwl.findKey( key.str() );
557  }
558  if (f.empty())
559  {
560  ostringstream key;
562  f = m_kwl.findKey( key.str() );
563  }
564  if ( f.empty() )
565  continue;
566 
567  // Look for the entry key, e.g. image_source0.entry: 10
568  ostringstream entryKey;
570  ossimString os = m_kwl.findKey(entryKey.str());
571  if (!os.empty())
572  entryIndex = os.toUInt32();
573  else
574  entryIndex = globalEntryValue;
575 
576  // Add it:
578  if (!ic.valid())
579  {
580  ostringstream errMsg;
581  errMsg<<"ERROR: ossimChipProcUtil ["<<__LINE__<<"] Could not open <"<<f<<">"<<ends;
582  throw ossimException(errMsg.str());
583  }
584 
585  // Need a band selector?
586  std::vector<ossim_uint32> bandList(0);
587  getBandList(i, bandList );
588  if ( bandList.size() )
589  ic->setBandSelection( bandList );
590 
591  m_imgLayers.push_back(ic);
592  --count;
593  }
594 }
595 
598 {
599  // Init chain with handler:
601  if (!chain->open(fname))
602  {
603  ostringstream errMsg;
604  errMsg<<"ERROR: ossimChipProcUtil ["<<__LINE__<<"] Could not open <"<<fname<<">"<<ends;
605  throw ossimException(errMsg.str());
606  }
607 
608  // Set any reader props:
609  ossimImageHandler* handler = chain->getImageHandler().get();
610  setReaderProps( handler );
611  if (!handler->setCurrentEntry( entry_index ))
612  {
613  std::ostringstream errMsg;
614  errMsg << " ERROR: ossimChipProcUtil ["<<__LINE__<<"] Entry " << entry_index << " out of range!" << std::endl;
615  throw ossimException( errMsg.str() );
616  }
617 
618  // Set up the remapper:
621  {
624  chain->add(remapper.get());
625  }
626 
627  // Set up the renderer with cache:
628  chain->addResampler();
629  chain->addCache();
630 
631  // Add geo polygon cutter if specifried:
632  ossimString param = m_kwl.findKey(CLIP_POLY_LAT_LON_KW);
633  if (!param.empty())
634  {
635  std::vector<ossimGpt> points;
636  ossim::toVector(points, param);
637  if(points.size() >= 3)
638  {
639  ossimGeoPolygon polygon(points);
640  chain->addGeoPolyCutterPolygon(polygon);
641  }
642  }
643 
644  chain->initialize();
645  return chain;
646 }
647 
649 {
651  if (numDems == 0)
652  return;
653 
654  cout<<m_kwl<<endl;//TODO:REMOVE
655  ossim_uint32 count = numDems;
656  for (ossim_uint32 i=0; count > 0; ++i)
657  {
658  ossimFilename f;
659  if (numDems == 1)
660  {
661  ostringstream key;
662  key << ossimKeywordNames::ELEVATION_SOURCE_KW; // Try non-indexed first
663  f = m_kwl.findKey( key.str() );
664  }
665  if (f.empty())
666  {
667  ostringstream key;
669  cout<<key.str()<<endl;//TODO:REMOVE
670  f = m_kwl.findKey( key.str() );
671  }
672  if ( f.empty() )
673  continue;
674 
675  if (!f.isReadable())
676  {
677  ostringstream errMsg;
678  errMsg << "ossimChipProcUtil ["<<__LINE__<<"] Could not open DEM file: <" << f << ">";
679  throw ossimException(errMsg.str());
680  }
681 
682  m_demSources.push_back(f);
684  --count;
685  }
686 }
687 
689 {
690  static const char* MODULE = "ossimChipProcUtil::createOutputProjection()";
691 
693  ossimString srs = m_kwl.findKey( SRS_KW );
694  if ( op.size() && srs.size() )
695  {
697  << MODULE << " WARNING:"
698  << "\nBoth " << SRS_KW << " and " << ossimKeywordNames::PROJECTION_KW
699  << " keywords are set!"
700  << "\nsrs: " << srs
701  << "\noutput_projection: " << op
702  << "\nTaking " << srs << " over " << op << "\n";
703  }
704 
706  m_geoScaled = false;
707  op.downcase();
708 
709  if (op.contains("epsg"))
710  srs = op;
711 
712  if ( (op == "geo") || (srs.contains("4326")))
713  proj = new ossimEquDistCylProjection();
714 
715  else if (srs.size())
716  {
718  ossimProjectionFactoryRegistry::instance()->createProjection(srs));
719  if (!proj.valid())
720  throw ossimException("ossimChipProcUtil::createOutputProjection() -- Bad EPSG code passed.");
721  }
722  else if (op == "geo-scaled")
723  {
724  m_geoScaled = true; // used later when reference latitude is known
725  proj = new ossimEquDistCylProjection();
726  }
727  else if ( ( op == "input" ) || (op == "identity") || (op == "none") )
728  proj = newIdentityProjection();
729 
730  else if ( (op == "utm") || (op == "ossimutmprojection") )
731  proj = newUtmProjection();
732 
733  else
734  {
735  m_geoScaled = true; // used later when reference latitude is known
736  proj = new ossimEquDistCylProjection();
737  }
738 
739  // Create our ossimImageGeometry with projection (no transform).
740  proj->setElevationLookupFlag(true);
741  m_geom->setProjection(proj.get());
742 
743  // Set the scale and AOI.
745  initializeAOI(); // also sets the tie point to AOI UL and geoscaling to origin.
746 
747  // Setup the view in all the chains.
749 }
750 
752 {
754  ossimProjection* input_proj = 0;
755  ossimRefPtr<ossimMapProjection> output_proj = 0;
756  ossimRefPtr<ossimImageRenderer> resampler = 0;
757 
758  if ( m_imgLayers.size() )
759  {
760  sic = m_imgLayers[0];
761  if (sic.valid())
762  {
764  if (ih.valid())
765  {
767  if (geom.valid())
768  {
769  input_proj = geom->getProjection();
770 
771  // Check if input is UTM, need to copy zone and hemisphere if so:
772  ossimUtmProjection* input_utm = dynamic_cast<ossimUtmProjection*>(input_proj);
773  if ( input_utm )
774  {
776  output_utm->setZone(input_utm->getZone());
777  output_utm->setHemisphere(input_utm->getHemisphere());
778  output_proj = output_utm.get();
779  }
780  else
781  {
782  input_proj = dynamic_cast<ossimMapProjection*>( geom->getProjection() );
783  if (input_proj)
784  {
785  output_proj = (ossimMapProjection*) input_proj->dup();
786  m_projIsIdentity = true;
787  }
788  }
789  }
790  }
791  }
792  }
793 
794  // try input dem "image" if specified:
795  if (!output_proj.valid() && (m_demSources.size()))
796  {
797  ossimImageGeometry geom;
798  if (geom.open(m_demSources[0]))
799  {
800  input_proj = dynamic_cast<ossimMapProjection*>(geom.getProjection());
801  if (input_proj)
802  {
803  output_proj = (ossimMapProjection*) input_proj->dup();
804  m_projIsIdentity = true;
805  }
806  }
807  }
808 
809  return output_proj;
810 }
811 
813 {
814  // Make projection:
816 
817  // Set the zone from keyword option:
818  bool setZone = false;
819  ossim_int32 zone = 0;
820  std::string value = m_kwl.findKey( std::string( ossimKeywordNames::ZONE_KW ) );
821  if ( value.size() )
822  zone = ossimString(value).toUInt32();
823  if ( (zone > 0 ) && ( zone < 61 ) )
824  {
825  utm->setZone( zone );
826  setZone = true;
827  }
828 
829  // Set the hemisphere from keyword option:
830  bool setHemisphere = false;
832  if ( h.size() )
833  {
834  h.upcase();
835  if ( ( h == "N" ) || ( h == "NORTH" ) || ( h == "S" ) || ( h == "SOUTH" ) )
836  {
837  utm->setHemisphere( h.string()[0] );
838  setHemisphere = true;
839  }
840  }
841 
842  if ( !setZone || !setHemisphere )
843  {
844  // Check for user set "central_meridian" and "origin_latitude":
845  ossimGpt origin;
846  getProjectionOrigin(origin);
847  if ( !setZone )
848  utm->setZone(origin);
849  if ( !setHemisphere )
850  utm->setHemisphere(origin);
851  }
852 
853  return ossimRefPtr<ossimMapProjection>(utm.get());
854 }
855 
857 {
858  // The GSD computation may be a chicken-and-egg problem. Need to try different methods depending
859  // on information available in KWL including specified input images and DEMs.
860 
862  dynamic_cast<ossimMapProjection*>(m_geom->getProjection());
863 
864  ossimString lookup = m_kwl.findKey( GSD_KW );
865  if ( lookup.size() )
866  m_gsd.y = m_gsd.x = lookup.toFloat64();
867 
868  if (m_gsd.hasNans() && m_projIsIdentity && m_geom.valid())
870 
871  if (m_gsd.hasNans())
872  {
873  // No GSD specified, use minimum among all input images:
874  ossimGpt chainTiePoint;
875  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx = m_imgLayers.begin();
876  while ( chainIdx != m_imgLayers.end() )
877  {
878  ossimRefPtr<ossimImageGeometry> geom = (*chainIdx)->getImageGeometry();
879  if (geom.valid())
880  {
881  ossimDpt gsd;
882  geom->getMetersPerPixel(gsd);
883  gsd.y = gsd.x = gsd.mean();
884  if (m_gsd.hasNans() || ( m_gsd.x > gsd.x))
885  m_gsd = gsd;
886  }
887  ++chainIdx;
888  }
889  }
890 
891  if (m_gsd.hasNans())
892  {
893  // Still no GSD established, try using minimum among all input DEMs (the operation possibly
894  // involves DEMs as inputs):
895  std::vector<ossimFilename>::iterator demFile = m_demSources.begin();
896  while ( demFile != m_demSources.end() )
897  {
898  ossimImageGeometry geom;
899  if (geom.open(*demFile))
900  {
901  ossimDpt gsd;
902  geom.getMetersPerPixel(gsd);
903  gsd.y = gsd.x = gsd.mean();
904  if (m_gsd.hasNans() || ( m_gsd.x > gsd.x))
905  m_gsd = gsd;
906  }
907  ++demFile;
908  }
909  }
910 
911  if (m_gsd.hasNans())
912  {
913  // Still no GSD specified. As a last resort, use the elevation database nominal GSD at center
914  // as output GSD. This is valid since most operations without input images depend on DEM data.
915  // Requires that the center point be given in input spec:
916  ossimGpt centerGpt;
917  findCenterGpt(centerGpt);
918  if (!centerGpt.hasNans())
919  {
922  if (m_gsd.x == 0) // getMeanSpacing unfortunately return 0 for unknown GSD
923  m_gsd.makeNan();
924  }
925  }
926 
927  if (!m_gsd.hasNans())
928  mapProj->setMetersPerPixel(m_gsd);
929 }
930 
932 {
933  // Nan rect for starters.
936  ossimString lookup;
937 
938  // Image size:
939  ossimIpt imageSize(0,0);
940  if (m_kwl.hasKey(AOI_SIZE_PIXELS_KW))
941  {
942  lookup = m_kwl.findKey( AOI_SIZE_PIXELS_KW );
943  lookup.trim();
944  imageSize.x = lookup.before(" ").toUInt32();
945  imageSize.y = lookup.after(" ").toUInt32();
946  }
947 
948  // The AOI rect can be specified in different ways:
949  if ( m_kwl.hasKey( AOI_GEO_CENTER_KW.c_str() ) )
950  {
951  // A center point was given:
952  ossimGpt centerGpt;
953  findCenterGpt(centerGpt);
954 
955  // A center point spec can be accompanied by a width/height (in meters or pixels):
956  ossimDpt sizeMeters;
957  sizeMeters.makeNan();
958  if (m_kwl.hasKey(AOI_SIZE_METERS_KW))
959  {
960  lookup = m_kwl.findKey( AOI_SIZE_METERS_KW );
961  lookup.trim();
962  sizeMeters.x = lookup.before(" ").toDouble();
963  sizeMeters.y = lookup.after(" ").toDouble();
964  }
965  else if (m_kwl.hasKey(AOI_SIZE_PIXELS_KW))
966  {
967  if ( (imageSize.x > 0)&& (imageSize.y > 0 ) )
968  {
969  sizeMeters.x = imageSize.x*m_gsd.x;
970  sizeMeters.y = imageSize.y*m_gsd.y;
971  }
972  }
973  if (!sizeMeters.hasNans())
974  {
975  ossimDpt metersPerDegree (centerGpt.metersPerDegree());
976  double dlat = sizeMeters.y/metersPerDegree.y/2.0;
977  double dlon = sizeMeters.x/metersPerDegree.x/2.0;
978  ossimGpt ulgpt (centerGpt.lat + dlat, centerGpt.lon - dlon);
979  ossimGpt lrgpt (centerGpt.lat - dlat, centerGpt.lon + dlon);
980  m_aoiGroundRect = ossimGrect(ulgpt, lrgpt);
981  sizeMeters.x = imageSize.x*m_gsd.x;
982  sizeMeters.y = imageSize.y*m_gsd.y;
983  }
984  if (!sizeMeters.hasNans())
985  {
986  ossimDpt metersPerDegree (centerGpt.metersPerDegree());
987  double dlat = sizeMeters.y/metersPerDegree.y/2.0;
988  double dlon = sizeMeters.x/metersPerDegree.x/2.0;
989  ossimGpt ulgpt (centerGpt.lat + dlat, centerGpt.lon - dlon);
990  ossimGpt lrgpt (centerGpt.lat - dlat, centerGpt.lon + dlon);
991  m_aoiGroundRect = ossimGrect(ulgpt, lrgpt);
992  m_needCutRect = true;
993  }
994  }
995 
996  else if ( m_kwl.hasKey( AOI_GEO_RECT_KW ) )
997  {
998  ossimString lookup = m_kwl.findKey(AOI_GEO_RECT_KW);
999  lookup.trim();
1000  vector<ossimString> substrings = lookup.split(" ");
1001  if (substrings.size() != 4)
1002  {
1003  ostringstream errMsg;
1004  errMsg << "ossimChipProcUtil ["<<__LINE__<<"] Incorrect number of values specified for "
1005  "aoi_geo_rect!";
1006  throw( ossimException(errMsg.str()) );
1007  }
1008  ossim_float64 minLatF = substrings[0].toFloat64();
1009  ossim_float64 minLonF = substrings[1].toFloat64();
1010  ossim_float64 maxLatF = substrings[2].toFloat64();
1011  ossim_float64 maxLonF = substrings[3].toFloat64();
1012 
1013  // Check for swap so we don't get a negative height.
1014  // Note no swap check for longitude as box could cross date line.
1015  if ( minLatF > maxLatF )
1016  {
1017  ossim_float64 tmpF = minLatF;
1018  minLatF = maxLatF;
1019  maxLatF = tmpF;
1020  }
1021 
1022  // Assume cut box is edge to edge or "Pixel Is Area". Our
1023  // AOI(area of interest) uses center of pixel or "Pixel Is Point"
1024  // so get the degrees per pixel and shift AOI to center.
1025  ossimGpt ulgpt (maxLatF, minLonF);
1026  ossimGpt lrgpt (minLatF , maxLonF);
1027  m_aoiGroundRect = ossimGrect(ulgpt, lrgpt);
1028  m_needCutRect = true;
1029 
1030  if ( (imageSize.x > 0) && (imageSize.y > 0) )
1031  {
1033  dynamic_cast<ossimMapProjection*>(m_geom->getProjection());
1034  if (mapProj.valid())
1035  {
1036  ossimDpt gsd;
1037  gsd.x = std::fabs( maxLonF - minLonF ) / imageSize.x;
1038  gsd.y = std::fabs( maxLatF - minLatF ) / imageSize.y;
1039  mapProj->setDecimalDegreesPerPixel(gsd);
1040  }
1041  }
1042  }
1043 
1044  else if ( m_kwl.hasKey( AOI_MAP_RECT_KW ) )
1045  {
1047  dynamic_cast<ossimMapProjection*>(m_geom->getProjection());
1048  if (mapProj.valid())
1049  {
1050  ossimString lookup = m_kwl.findKey(AOI_MAP_RECT_KW);
1051  lookup.trim();
1052  vector<ossimString> substrings = lookup.split(", ", true);
1053  if (substrings.size() != 4)
1054  {
1055  ostringstream errMsg;
1056  errMsg << "ossimChipProcUtil ["<<__LINE__<<"] Incorrect number of values specified for "
1057  "aoi_geo_rect!";
1058  throw( ossimException(errMsg.str()) );
1059  }
1060  ossim_float64 minX = substrings[0].toFloat64();
1061  ossim_float64 minY = substrings[1].toFloat64();
1062  ossim_float64 maxX = substrings[2].toFloat64();
1063  ossim_float64 maxY = substrings[3].toFloat64();
1064 
1065  // Check for swap so we don't get a negative height.
1066  // Note no swap check for longitude as box could cross date line.
1067  if ( minX > maxX )
1068  {
1069  ossim_float64 tmpF = minX;
1070  minX = maxX;
1071  maxX = tmpF;
1072  }
1073  if ( minY > maxY )
1074  {
1075  ossim_float64 tmpF = minY;
1076  minY = maxY;
1077  maxY = tmpF;
1078  }
1079 
1080  ossimDpt ulMap (minX, maxY);
1081  ossimDpt lrMap (maxX , minY);
1082  ossimGpt ulGeo = mapProj->inverse(ulMap);
1083  ossimGpt lrGeo = mapProj->inverse(lrMap);
1084  m_aoiGroundRect = ossimGrect(ulGeo, lrGeo);
1085  m_needCutRect = true;
1086 
1087  if ( (imageSize.x > 0) && (imageSize.y > 0) )
1088  {
1090  dynamic_cast<ossimMapProjection*>(m_geom->getProjection());
1091  if (mapProj.valid())
1092  {
1093  ossimDpt gsd;
1094  gsd.x = std::fabs( maxX - minX ) / imageSize.x;
1095  gsd.y = std::fabs( maxY - minY ) / imageSize.y;
1096  mapProj->setMetersPerPixel(gsd);
1097  }
1098  }
1099  }
1100  }
1101 
1102  // If no user defined rect set to scene bounding rect.
1103  if ( m_aoiGroundRect.hasNans() )
1104  setAoiToInputs();
1105 
1106  // If AOI established, we can set projection TP and origin if applicable:
1108  dynamic_cast<ossimMapProjection*>(m_geom->getProjection());
1109  if (!m_aoiGroundRect.hasNans() && mapProj.valid())
1110  {
1111  // Geo-scaled projection needs to know the reference latitude:
1112  if (m_geoScaled)
1113  {
1114  // The origin may have ben explicitely specified,or just use midpoint of AOI:
1115  ossimGpt origin;
1116  if (!getProjectionOrigin(origin))
1117  origin = m_aoiGroundRect.midPoint();
1118  mapProj->setOrigin(origin);
1120  }
1121 
1122  // Set the tie-point of the projection to the AOI's UL.
1123  // Adjust it to be on an even pixel distance from projection origin if desired:
1124  mapProj->setUlTiePoints(m_aoiGroundRect.ul());
1125  bool snapToTP = false;
1126  m_kwl.getBoolKeywordValue(snapToTP, SNAP_TIE_TO_ORIGIN_KW.c_str());
1127  if ( snapToTP )
1128  mapProj->snapTiePointToOrigin();
1129 
1130  // Re-establish the AOI view rect based on updated projection:
1132  }
1133 }
1134 
1136 {
1137  gpt = ossimGpt(0,0,0);
1138  bool found_spec = false;
1140  if ( lookup.size() )
1141  {
1142  gpt.lat = lookup.toFloat64();
1143  if ( (gpt.lat < -90) || (gpt.lat > 90.0) )
1144  {
1145  std::string errMsg = "origin latitude range error! Valid range: -90 to 90";
1146  throw ossimException(errMsg);
1147  }
1148  m_geoScaled = true;
1149  found_spec = true;
1150  }
1151 
1153  if ( lookup.size() )
1154  {
1155  gpt.lon = lookup.toFloat64();
1156  if ( (gpt.lon < -180.0) || (gpt.lon > 180.0) )
1157  {
1158  std::string errMsg = "central meridian range error! Valid range: -180 to 180";
1159  throw ossimException(errMsg);
1160  }
1161  found_spec = true;
1162  }
1163  return found_spec;
1164 }
1165 
1167 {
1168  gpt.hgt = 0.0;
1169  ossimString lookup = m_kwl.findKey( AOI_GEO_CENTER_KW );
1170  if (lookup.size())
1171  {
1172  lookup.trim();
1173  vector<ossimString> substrings = lookup.split(", ");
1174  if (substrings.size() != 2)
1175  {
1176  ostringstream errMsg;
1177  errMsg << "ossimChipProcUtil ["<<__LINE__<<"] Incorrect number of values specified for "
1178  "aoi_geo_center!";
1179  throw( ossimException(errMsg.str()) );
1180  }
1181  gpt.lat = substrings[0].toDouble();
1182  gpt.lon = substrings[1].toDouble();
1183  return;
1184  }
1185 
1186  lookup = m_kwl.findKey(AOI_GEO_RECT_KW);
1187  if (lookup.size())
1188  {
1189  lookup.trim();
1190  vector<ossimString> substrings = lookup.split(", ");
1191  if (substrings.size() != 4)
1192  {
1193  ostringstream errMsg;
1194  errMsg << "ossimChipProcUtil ["<<__LINE__<<"] Incorrect number of values specified for "
1195  "aoi_geo_rect!";
1196  throw( ossimException(errMsg.str()) );
1197  }
1198  ossim_float64 minLatF = substrings[0].toDouble();
1199  ossim_float64 minLonF = substrings[1].toDouble();
1200  ossim_float64 maxLatF = substrings[2].toDouble();
1201  ossim_float64 maxLonF = substrings[3].toDouble();
1202  gpt.lat = 0.5*(minLatF + maxLatF);
1203  gpt.lon = 0.5*(minLonF + maxLonF);
1204  return;
1205  }
1206  gpt.makeNan();
1207 }
1208 
1210 {
1212  ossimGrect bbox_i;
1214 
1215  // Assign the AOI to be the bounding rect of the union of all inputs. Start with image inputs:
1216  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chain = m_imgLayers.begin();
1217  while (chain != m_imgLayers.end())
1218  {
1219  geom = (*chain)->getImageGeometry();
1220  if (geom.valid())
1221  {
1222  geom->getBoundingGroundRect(bbox_i);
1223  if (!bbox_i.hasNans())
1224  {
1225  if (m_aoiGroundRect.hasNans())
1226  m_aoiGroundRect = bbox_i;
1227  else
1229  }
1230  }
1231  ++chain;
1232  }
1233 
1234  // Now determine DEM inputs coverage:
1235  ossimGrect bbox_dems;
1236  bbox_dems.makeNan();
1237  std::vector<ossimFilename>::iterator dem_file = m_demSources.begin();
1238  while (dem_file != m_demSources.end())
1239  {
1241  if (!geom->open(*dem_file))
1242  {
1244  << "ossimHLZUtil::initialize ERR: Cannot open DEM file <" << *dem_file << "> "
1245  "as image handler. Ignoring entry for bounding box computation.\n" << std::endl;
1246  }
1247  geom->getBoundingGroundRect(bbox_i);
1248  if (!bbox_i.hasNans())
1249  {
1250  if (bbox_dems.hasNans())
1251  bbox_dems = bbox_i;
1252  else
1253  bbox_dems.expandToInclude(bbox_i);
1254  }
1255  ++dem_file;
1256  }
1257 
1258  // Finally compute the AOI as the intersection of the image and DEM inputs:
1259  if (m_aoiGroundRect.hasNans())
1260  m_aoiGroundRect = bbox_dems;
1261  else if (!bbox_dems.hasNans())
1263 }
1264 
1266 {
1267  // Nan rect for starters.
1269  if (m_aoiGroundRect.hasNans())
1270  return;
1271 
1272  // Assume cut box is edge to edge or "Pixel Is Area". Our
1273  // AOI(area of interest) uses center of pixel or "Pixel Is Point"
1274  // so get the degrees per pixel and shift AOI to center.
1275  ossimDpt halfDpp;
1276  m_geom->getDegreesPerPixel( halfDpp );
1277  halfDpp = halfDpp/2.0;
1278 
1279  ossimGpt gpt(0.0, 0.0, 0.0);
1280  ossimDpt ulPt;
1281  ossimDpt lrPt;
1282 
1283  // Upper left:
1284  gpt.lat = m_aoiGroundRect.ul().lat - halfDpp.y;
1285  gpt.lon = m_aoiGroundRect.ul().lon + halfDpp.x;
1286  m_geom->worldToLocal(gpt, ulPt);
1287 
1288  // Lower right:
1289  gpt.lat = m_aoiGroundRect.lr().lat + halfDpp.y;
1290  gpt.lon = m_aoiGroundRect.lr().lon - halfDpp.x;
1291  m_geom->worldToLocal(gpt, lrPt);
1292 
1293  m_aoiViewRect = ossimIrect( ossimIpt(ulPt), ossimIpt(lrPt) );
1294 
1295  // If no user defined rect set to scene bounding rect.
1296  if ( m_aoiViewRect.hasNans() )
1298 }
1299 
1301 {
1302  // we need to make sure the outputs are refreshed so they can reset themselves
1303  // Needed when we are doing interactive update to the GSD and clip window
1305  ossimEventVisitor eventVisitor(refreshEvent.get());
1306  ossimViewInterfaceVisitor viewVisitor(m_geom.get());
1307 
1308  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx = m_imgLayers.begin();
1309  while ( chainIdx != m_imgLayers.end() )
1310  {
1311  viewVisitor.reset();
1312  eventVisitor.reset();
1313  (*chainIdx)->accept(viewVisitor);
1314  (*chainIdx)->accept(eventVisitor);
1315  ossimRefPtr<ossimImageRenderer> resampler = (*chainIdx)->getImageRenderer();
1316  if (resampler.valid())
1317  {
1318  resampler->setView( m_geom.get() );
1319  resampler->propagateEventToOutputs(*refreshEvent);
1320  }
1321  ++chainIdx;
1322  }
1323 }
1324 
1326 {
1327  if ( ih )
1328  {
1329  ossim_uint32 count = m_kwl.numberOf( READER_PROPERTY_KW.c_str() );
1330  for (ossim_uint32 i = 0; i < count; ++i)
1331  {
1332  ossimString key = READER_PROPERTY_KW;
1333  key += ossimString::toString(i);
1334  ossimString value = m_kwl.findKey( key.string() );
1335  if ( value.size() )
1336  {
1337  std::vector<ossimString> splitArray;
1338  value.split(splitArray, "=");
1339  if(splitArray.size() == 2)
1340  {
1342  new ossimStringProperty(splitArray[0], splitArray[1]);
1343 
1344  ih->setProperty( prop );
1345  }
1346  }
1347  }
1348  }
1349 }
1350 
1352  std::vector<ossim_uint32>& bandList ) const
1353 {
1354  bandList.clear();
1355  ostringstream key;
1356  key << ossimKeywordNames::IMAGE_FILE_KW << image_idx << "." << ossimKeywordNames::BANDS_KW;
1357  ossimString os = m_kwl.findKey(key.str());
1358  if (os.empty())
1359  {
1360  // Look for possible global bands selection:
1362  }
1363 
1364  if ( os.size() )
1365  {
1366  std::vector<ossimString> band_list(0);
1367  os.split( band_list, ossimString(", "), false );
1368  if ( band_list.size() )
1369  {
1370  std::vector<ossimString>::const_iterator i = band_list.begin();
1371  while ( i != band_list.end() )
1372  {
1373  ossim_uint32 band = (*i).toUInt32();
1374  if ( band ) // One based so we need to subtract.
1375  {
1376  bandList.push_back( band - 1 );
1377  }
1378  ++i;
1379  }
1380  }
1381  }
1382 } // End: ossimChipProcUtil::getBandList
1383 
1385 {
1386  ostringstream xmsg;
1387  ossimRefPtr<ossimImageSource> demMosaic = 0;
1388 
1389  if (m_demSources.empty())
1390  {
1391  // Establish connection to DEM posts directly as raster "images" versus using the OSSIM elev
1392  // manager that performs interpolation of DEM posts for arbitrary locations. These elev images
1393  // feed into a combiner in order to have a common tap for elev pixels:
1396  }
1397 
1398  // Open a raster image for each elevation source being considered:
1400  vector<ossimFilename>::iterator fname_iter = m_demSources.begin();
1401  while (fname_iter != m_demSources.end())
1402  {
1404  if (!chain.valid() || !chain->getImageRenderer().valid() )
1405  {
1406  xmsg<<"ossimChipProcUtil:"<<__LINE__<<" Cannot open DEM file at <"<<*fname_iter<<">";
1407  throw(xmsg.str());
1408  }
1409 
1410  // Set up the input chain with proper renderer IVT:
1412  (chain->getImageHandler()->getImageGeometry().get(), m_geom.get());
1413  chain->getImageRenderer()->setImageViewTransform(ivt.get());
1414  ossimRefPtr<ossimConnectableObject> connectable = chain.get();
1415  elevChains.push_back(connectable);
1416  ++fname_iter;
1417  }
1418 
1419  if (elevChains.size() == 1)
1420  demMosaic = (ossimImageSource*) elevChains[0].get();
1421  else
1422  demMosaic = new ossimImageMosaic(elevChains);
1423 
1424  return demMosaic;
1425 }
1426 
1427 
1430 {
1431  ossimRefPtr<ossimImageSource> combiner = 0;
1432  ossim_uint32 layerCount = (ossim_uint32) layers.size();
1433  if ( layerCount == 1 )
1434  {
1435  combiner = layers[0].get();
1436  }
1437  else if (layerCount > 1)
1438  {
1439  combiner = new ossimImageMosaic;
1440  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx = layers.begin();
1441  while ( chainIdx != layers.end() )
1442  {
1443  combiner->connectMyInputTo( (*chainIdx).get() );
1444  ++chainIdx;
1445  }
1446  }
1447  return combiner;
1448 }
1449 
1451 {
1453 
1454  ossimString lookup = m_kwl.findKey( WRITER_KW );
1455  if ( lookup.size() )
1456  {
1458  if ( !writer.valid() )
1459  {
1460  ostringstream errMsg;
1461  errMsg << "ossimChipProcUtil ["<<__LINE__<<"] ERROR creating writer for <"<<lookup<<">"
1462  <<ends;
1463  throw ossimException(errMsg.str());
1464  }
1465  }
1466  else // Create from output file extension.
1467  {
1469  createWriterFromExtension( m_productFilename.ext() );
1470 
1471  if ( !writer.valid() )
1472  {
1473  ostringstream errMsg;
1474  errMsg << "ossimChipProcUtil ["<<__LINE__<<"] ERROR creating writer from extension <"
1475  <<m_productFilename.ext()<<">"<<ends;
1476  throw ossimException(errMsg.str());
1477  }
1478  }
1479 
1480  // Set the output name.
1481  writer->setFilename( m_productFilename );
1482 
1483  // Add any writer props.
1484  ossim_uint32 count = m_kwl.numberOf( WRITER_PROPERTY_KW.c_str() );
1485  for (ossim_uint32 i = 0; i < count; ++i)
1486  {
1487  ossimString key = WRITER_PROPERTY_KW;
1488  key += ossimString::toString(i);
1489  lookup = m_kwl.findKey( key.string() );
1490  if ( lookup.size() )
1491  {
1492  std::vector<ossimString> splitArray;
1493  lookup.split(splitArray, "=");
1494  if(splitArray.size() == 2)
1495  {
1497  new ossimStringProperty(splitArray[0], splitArray[1]);
1498 
1499  writer->setProperty( prop );
1500  }
1501  }
1502  }
1503 
1504  // Output tile size:
1505  lookup = m_kwl.findKey( TILE_SIZE_KW );
1506  if ( lookup.size() )
1507  {
1508  ossimIpt tileSize;
1509  tileSize.x = lookup.toInt32();
1510  if ( (tileSize.x % 16) == 0 )
1511  {
1512  tileSize.y = tileSize.x;
1513  writer->setTileSize( tileSize );
1514  }
1515  }
1516 
1517  return writer;
1518 }
1519 
1521 {
1522  // Add global usage options.
1524 
1525  // Set app name.
1526  std::string appName = ap.getApplicationName();
1528 
1529  // Base class has some:
1530  ossimTool::setUsage(ap);
1531 
1532  // Add options.
1533  au->addCommandLineOption("--aoi-geo-bbox", "<min-lat> <min-lon> <max-lat> <max-lon>\nSpecify a comma-separated list for the lower-left and upper-right corners of the scene rect in decimal degrees.");
1534  au->addCommandLineOption("--aoi-geo-center", "<lat> <lon>\nCenter of AOI in decimal degrees.");
1535  au->addCommandLineOption("--aoi-map-bbox", "<min-x> <min-y> <max-x> <max-y>\nSpecify a space-separated list for the upper-left and lower-right corners of the scene rect in decimal degrees.");
1536  au->addCommandLineOption("--aoi-map-center", "<x> <y>\nCenter of AOI in map coordinates.");
1537  au->addCommandLineOption("--aoi-size-pixels", "<dx> <dy>,\nSize of AOI in output product pixels.");
1538  au->addCommandLineOption("--aoi-size-meters", "<dx> <dy>,\nSize of AOI in meters.");
1539  au->addCommandLineOption( "-b or --bands <n,n...>", "Use the specified bands in given order: e.g. \"3,2,1\" will select bands 3, 2 and 1 of the input image.\nNote: it is 1 based" );
1540  au->addCommandLineOption("--central-meridian","<lon>\nNote if set this will be used for the central meridian of the projection. This can be used to lock the utm zone.");
1541  au->addCommandLineOption("--color-table | --lut","<color-table.kwl>\nKeyword list containing color table for color-relief option.");
1542  au->addCommandLineOption("--deg-per-pixel","<dpp_xy> | <dpp_x> <dpp_y>\nSpecifies an override for degrees per pixel. Takes either a single value applied equally to x and y directions, or two values applied correspondingly to x then y. This option takes precedence over the \"--meters\" option.");
1543  au->addCommandLineOption("--dem", "<file1>[,<file2>...]\n Input DEM file(s) (comma-separated) to process.");
1544  au->addCommandLineOption("--dump-options","The current state of the utility (after the entire command line is parsed) is written to the file $PWD/<utility>.kwl, where <utility> is the name of the operation being performed. See \"--load-options\".");
1545  au->addCommandLineOption("-e or --entry", "<entry> For multi image handlers which entry do you wish to extract. For list of entries use: \"ossim-info -i <your_image>\" ");
1546  au->addCommandLineOption("--gsd", "<meters>\nSpecifies an override for the meters per pixel");
1547  au->addCommandLineOption("-h or --help", "Display this help and exit.");
1548  au->addCommandLineOption("--hemisphere", "<hemisphere>\nSpecify a projection hemisphere if supported. E.g. UTM projection. This will lock the hemisphere even if input scene center is the other hemisphere. Valid values for UTM are \"N\" and \"S\"");
1549  au->addCommandLineOption("--image | -i", "<file1>[, <file2>...] Input image file(s) (comma-separated) to process.");
1550  au->addCommandLineOption("--load-options","[<filename>]\nThe contents of <filename> (keyword-value pairs) are loaded as command options. The command-line options take precedence. See \"--load-options\" and \"--write-template\" options.");
1551  au->addCommandLineOption("--output-file | -o","<filename>\nThe product output file name. The format is dictated by the extension.");
1552  au->addCommandLineOption("--origin-latitude","<latidude_in_decimal_degrees>\nNote if set this will be used for the origin latitude of the projection. Setting this to something other than 0.0 with a geographic projection creates a scaled geographic projection.");
1553  au->addCommandLineOption("--output-radiometry", "<R>\nSpecifies the desired product's pixel radiometry type. Possible values for <R> are: U8, U11, U16, S16, F32. Note this overrides the deprecated option \"scale-to-8-bit\".");
1554  au->addCommandLineOption("--projection", "<output_projection> Valid projections: geo, geo-scaled, input or utm\ngeo = Equidistant Cylindrical, origin latitude = 0.0\ngeo-scaled = Equidistant Cylindrical, origin latitude = image center\ninput Use first images projection. Must be a map projecion.\nutm = Universal Tranverse Mercator\nIf input and multiple sources the projection of the first image will be used.\nIf utm the zone will be set from the scene center of first image.\nNOTE: --srs takes precedence over this option.");
1555  au->addCommandLineOption("--reader-prop", "<string>Adds a property to send to the reader. format is name=value");
1556  au->addCommandLineOption("--scale-to-8-bit", "Scales the output to unsigned eight bits per band. This option has been deprecated by the newer \"--output-radiometry\" option.");
1557  au->addCommandLineOption("--snap-tie-to-origin", "Snaps tie point to projection origin so that (tie-origin)/gsd come out on an even integer boundary.");
1558  au->addCommandLineOption("--srs","<src_code>\nSpecify a spatial reference system(srs) code for the output projection. Example: --srs EPSG:4326");
1559  au->addCommandLineOption("-t or --thumbnail", "<max_dimension>\nSpecify a thumbnail resolution.\nScale will be adjusted so the maximum dimension = argument given.");
1560  au->addCommandLineOption("--tile-size", "<size_in_pixels>\nSets the output tile size if supported by writer. Notes: This sets both dimensions. Must be a multiple of 16, e.g. 1024.");
1561  au->addCommandLineOption("-w or --writer","<writer>\nSpecifies the output writer. Default uses output file extension to determine writer. For valid output writer types use: \"ossim-info --writers\"\n");
1562  au->addCommandLineOption("--writer-prop", "<writer-property>\nPasses a name=value pair to the writer for setting it's property. Any number of these can appear on the line.");
1563  au->addCommandLineOption("--write-template", "<filename>\nWrites a keywrd list template to the filename specified.");
1564  au->addCommandLineOption("--zone", "<zone>\nSpecify a projection zone if supported. E.g. UTM projection. This will lock the zone even if input scene center is in another zone. Valid values for UTM are \"1\" to \"60\"");
1565 }
1566 
void getBoundingGroundRect(ossimGrect &bounding_grect) const
void setRectangle(const ossimIrect &rect)
virtual ~ossimChipProcTool()
virtual destructor
virtual double getMeanSpacingMeters() const
Returns the mean post spacing (in meters) for the highest resolution DEM in the list or NaN if no DEM...
virtual bool initialize(ossimArgumentParser &ap)
Initial method to be ran prior to execute.
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.
virtual ossimObject * dup() const =0
void getBandList(ossim_uint32 image_idx, std::vector< ossim_uint32 > &bandList) const
Gets the band list if BANDS keyword is set.
ossimString before(const ossimString &str, std::string::size_type pos=0) const
METHOD: before(str, pos) Returns string beginning at pos and ending one before the token str If strin...
void computeAdjustedViewFromGrect()
Initializes m_aoiViewRect given m_aoiGroundRect.
double mean() const
Returns the average of x and y.
Definition: ossimDpt.h:159
static const char * PROJECTION_KW
void setProjection(ossimProjection *projection)
Sets the projection to be used for local-to-world coordinate transformation.
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
Within the image chain will pass the head of the list.
void setReaderProps(ossimImageHandler *ih) const
Passes reader properties to single image handler if any.
virtual void initProcessingChain()=0
Derived classes initialize their custom chains here.
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
ossimChipProcTool()
default constructor
ossimRefPtr< ossimImageGeometry > m_geom
ossim_uint32 numberOf(const char *str) const
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
virtual void loadDemFiles()
Loads all DEM files specified in master KWL into the elev manager&#39;s database.
static const char * OUTPUT_FILE_KW
const ossimIpt & getImageSize() const
ossimGrect m_aoiGroundRect
static const char * CENTRAL_MERIDIAN_KW
Represents serializable keyword/value map.
bool addFile(const char *file)
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
bool m_helpRequested
Definition: ossimTool.h:150
ossimRefPtr< const ossimImageHandler > getImageHandler() const
static const ossimErrorCode OSSIM_OK
void addResampler()
Adds a resampler (a.k.a.
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
virtual bool addListener(ossimListener *listener)
Overrides base "addListener" this will capture the pointer and then call the base class "addListener"...
void makeNan()
Definition: ossimGrect.h:284
void addOptions(ossimArgumentParser &parser)
Definition: ossimInit.cpp:100
const ossimMapProjection * getAsMapProjection() const
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...
const ossimDpt & ul() const
Definition: ossimDrect.h:339
double y
Definition: ossimDpt.h:165
virtual void setOrigin(const ossimGpt &origin)
Sets theOrigin to origin.
bool contains(char aChar) const
Definition: ossimString.h:58
bool hasKey(const std::string &key) const
Checks for key in map.
virtual void initialize()
virtual ossimString getClassName() const
Definition: ossimTool.cpp:36
virtual void propagateEventToOutputs(ossimEvent &event)
static ossimImageWriterFactoryRegistry * instance()
void addList(const ossimKeywordlist &src, bool overwrite=true)
Visitor to update view and then propagate property event to outputs.
Definition: ossimVisitor.h:179
void makeNan()
Definition: ossimGpt.h:130
static ossimString toString(bool aValue)
Numeric to string methods.
virtual ossimListenerManager * getManager()
virtual void setTileSize(const ossimIpt &tileSize)
Sets the output image tiling size if supported by the writer.
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...
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.
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
virtual void setDecimalDegreesPerPixel(const ossimDpt &gsd)
ossim_uint32 toUInt32() const
static ossimElevManager * instance()
METHOD: instance() Implements singelton pattern.
virtual void initializeProjectionGsd()
Initializes the projection gsd.
ossimDpt getDegreesPerPixel() const
Returns the resolution of this image in degrees/pixel.
ossimApplicationUsage * getApplicationUsage()
virtual void setProperty(ossimRefPtr< ossimProperty > property)
void setImageSize(const ossimIpt &size)
An image mosaic is a simple combiner that will just do a simple mosaic.
virtual bool write(const char *file, const char *comment=0) const
Methods to dump the ossimKeywordlist to a file on disk.
ossimIpt size() const
Definition: ossimIrect.h:510
virtual ossimGpt inverse(const ossimDpt &projectedPoint) const =0
Will take a point in meters and convert it to ground.
void getCellsForBounds(const std::string &connectionString, const ossim_float64 &minLat, const ossim_float64 &minLon, const ossim_float64 &maxLat, const ossim_float64 &maxLon, std::vector< ossimFilename > &cells, ossim_uint32 maxNumberOfCells=0)
Gets a list of elevation cells needed to cover bounding box.
bool hasNans() const
Definition: ossimGrect.h:298
void setBandSelection(const std::vector< ossim_uint32 > &bandList)
method to set band selector.
Single image chain class.
virtual void setMetersPerPixel(const ossimDpt &gsd)
ossimRefPtr< ossimImageChain > m_procChain
void expandToInclude(const ossimGpt &gpt)
Expands existing rect to accommodate argument point.
Definition: ossimGrect.cpp:299
virtual ossimScalarType getOutputScalarType() const
This call is passed to the head of the list.
ossim_int32 toInt32() const
void reportRemainingOptionsAsUnrecognized(ossimErrorSeverity severity=OSSIM_BENIGN)
for each remaining option report it as an unrecongnized.
bool open(const ossimFilename &image)
Shortcut way of getting to an image&#39;s geometry when access to pixels is not needed.
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
std::vector< ossimFilename > m_demSources
void setCutType(ossimRectangleCutType cutType)
virtual void setUsage(ossimArgumentParser &ap)
Initializes the aurgument parser with expected parameters and options.
static const char * ZONE_KW
ossimRefPtr< ossimMapProjection > newUtmProjection()
Convenience method to get a utm projection.
static ossimScalarTypeLut * instance()
Returns the static instance of an ossimScalarTypeLut object.
std::vector< ossimRefPtr< ossimConnectableObject > > ConnectableObjectList
bool errors(ossimErrorSeverity severity=OSSIM_BENIGN) const
virtual void setOutputScalarType(ossimScalarType scalarType)
Sets the output scalar type.
OSSIM_DLL void toVector(std::vector< ossimDpt > &result, const ossimString &stringOfPoints)
Will take a string list separated by spaces and convert to a vector of ossimDpts. ...
virtual void clear()
Disconnects and clears the dem and image layers.
bool exists() const
ossimFilename m_productFilename
virtual void setUsage(ossimArgumentParser &ap)
Initializes the aurgument parser with expected parameters and options.
Definition: ossimTool.cpp:41
ossim_float64 lon
Definition: ossimGpt.h:266
virtual void finalizeChain()
Called after initProcessingChain() to append common items to the processing chain.
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if non defined...
std::string::size_type size() const
Definition: ossimString.h:405
virtual double getHeightAboveEllipsoid(const ossimGpt &gpt)
ossimGrect clipToRect(const ossimGrect &rect) const
Definition: ossimGrect.h:190
void setLut(const ossimFilename &file)
Set lookup table(lut) method.
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
ossimDpt getMetersPerPixel() const
Returns the GSD associated with this image in the active projection.
ossimRefPtr< ossimImageSource > mosaicDemSources()
Some utilities need to work on DEMs as images.
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
void createOutputProjection()
Creates the output or view projection.
double toDouble() const
ossim_float64 toFloat64() const
std::vector< ossimRefPtr< ossimSingleImageChain > > m_imgLayers
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
const ossimGpt & ul() const
Definition: ossimGrect.h:252
ossimRefPtr< ossimImageFileWriter > m_writer
bool loadElevationPath(const ossimFilename &path, bool set_as_first=false)
Adds a new elevation file (or multiple files if path is a directory) to the collection.
virtual bool initialize(ossimArgumentParser &ap)
Initializes from command line arguments.
Definition: ossimTool.cpp:58
virtual bool add(ossimConnectableObject *source)
Will return true or false if an image source was added to the chain.
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
virtual ossim_int32 connectMyInputTo(ossimConnectableObject *inputObject, bool makeOutputConnection=true, bool createEventFlag=true)
Will try to connect this objects input to the passed in object.
bool getBoolKeywordValue(bool &rtn_val, const char *keyword, const char *prefix=0) const
[OLK, Aug/2008] Sets the boolean <rtn_val> depending on value associated with keyword for values = (y...
static const char * BANDS_KW
bool hasNans() const
Definition: ossimDpt.h:67
ossimRefPtr< ossimCacheTileSource > addCache()
Adds a new cache to the current end of the chain.
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
ossimGpt midPoint() const
Definition: ossimGrect.h:178
bool isReadable() const
void setZone(const ossimGpt &ground)
bool getProjectionOrigin(ossimGpt &gpt)
Reads the KWL for origin latitude and central meridian.
static ossimProjectionFactoryRegistry * instance()
static const char * ORIGIN_LATITUDE_KW
static const char * ENTRY_KW
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
Will pass this call to the head of the list.
virtual void setFilename(const ossimFilename &file)
const ossimProjection * getProjection() const
Access methods for projection (may be NULL pointer).
ossimRefPtr< ossimImageFileWriter > newWriter()
Creates a new writer.
virtual void initializeAOI()
Initializes m_aoiViewRect with the output area of interest as specified in master KWL...
virtual ossimObject * getObject()
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual ossimErrorCode getErrorStatus() const
ossimScalarType m_productScalarType
bool hasNans() const
Definition: ossimGpt.h:135
ossim_int32 y
Definition: ossimIpt.h:142
void findCenterGpt(ossimGpt &gpt)
Tries to determine the AOI center point based on KWL entries, else returns NaNs in gpt...
void makeNan()
Definition: ossimIrect.h:329
virtual void setAreaOfInterest(const ossimIrect &inputRect)
static const char * HEMISPHERE_KW
double x
Definition: ossimDpt.h:164
virtual void loadImageFiles()
Creates chains for image entries associated with specified keyword.
bool open(const ossimFilename &file, bool openOverview=true)
open method that takes an image file.
bool empty() const
Definition: ossimString.h:411
ossimRefPtr< ossimMapProjection > newIdentityProjection()
Sets the single image chain for identity operations view to a ossimImageViewAffineTransform.
ossim_int32 getZone() const
static ossimInit * instance()
Definition: ossimInit.cpp:89
bool hasNans() const
Definition: ossimIrect.h:337
ossimImageFileWriter * createWriter(const ossimFilename &filename) const
virtual void setUlTiePoints(const ossimGpt &gpt)
ossimString ext() const
bool worldToLocal(const ossimGpt &world_pt, ossimDpt &local_pt) const
Exposes the 3D world-to-local image coordinate reverse projection.
ossimDpt metersPerDegree() const
Definition: ossimGpt.cpp:498
ossim_int32 x
Definition: ossimIpt.h:141
ossim_float64 lat
Definition: ossimGpt.h:265
ossimRefPtr< const ossimImageRenderer > getImageRenderer() const
ossimString & gsub(const ossimString &searchKey, const ossimString &replacementValue, bool replaceAll=false)
Substitutes searchKey string with replacementValue and returns a reference to *this.
bool hasNans() const
Definition: ossimIpt.h:58
static const char * IMAGE_FILE_KW
ossimFilename & setExtension(const ossimString &e)
Sets the extension of a file name.
ossimString after(const ossimString &str, std::string::size_type pos=0) const
METHOD: after(str, pos) Returns string immediately after the token str.
virtual bool removeListener(ossimListener *listener)
Overrides base "removeListener".
virtual bool setCurrentEntry(ossim_uint32 entryIdx)
void setElevationLookupFlag(bool flag)
static const char * ELEVATION_SOURCE_KW
const ossimDpt & lr() const
Definition: ossimDrect.h:341
const ossimGpt & lr() const
Definition: ossimGrect.h:269
int & argc()
return the argument count.
void setHemisphere(const ossimGpt &ground)
void setExpandEnvVarsFlag(bool flag)
virtual bool execute()
Performs the actual product write.
void setAoiToInputs()
Assigns the AOI to be the bounding rect of the union of all inputs.
virtual bool setView(ossimObject *baseObject)
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)
void makeNan()
Definition: ossimDpt.h:65
ossimRefPtr< ossimRectangleCutFilter > m_cutRectFilter
virtual bool execute()
Calls: writeFile() writeMetaDataFiles()
void propagateGeometryToChains()
Loops through all chains and sets the output projection.
void addGeoPolyCutterPolygon(const vector< ossimGpt > &polygon)
int ossim_int32
void writeErrorMessages(std::ostream &output, ossimErrorSeverity sevrity=OSSIM_BENIGN)
write out error messages at an above specified .
const std::string & string() const
Definition: ossimString.h:414