OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGdalOverviewBuilder.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: David Burken
6 //
7 // Description: OSSIM wrapper for building gdal overviews (tiff or hfa) from
8 // an ossim image handler using the GDAL library.
9 //
10 //----------------------------------------------------------------------------
11 // $Id: ossimGdalOverviewBuilder.cpp 15766 2009-10-20 12:37:09Z gpotts $
12 
13 #include <cmath>
14 #include <gdal_priv.h>
15 
17 #include <ossimGdalTiledDataset.h>
18 #include <ossimGdalDataset.h>
20 #include <ossim/base/ossimTrace.h>
24 
26  "ossimGdalOverviewBuilder",
28 
29 static const char* OVR_TYPE[] = { "unknown",
30  "gdal_tiff_nearest",
31  "gdal_tiff_average",
32  "gdal_hfa_nearest",
33  "gdal_hfa_average" };
34 
35 static const ossimTrace traceDebug(
36  ossimString("ossimGdalOverviewBuilder:debug"));
37 
39  :
40  theDataset(0),
41  theOutputFile(),
42  theOverviewType(ossimGdalOverviewTiffAverage),
43  theLevels(0),
44  theGenerateHfaStatsFlag(false)
45 {
46 }
47 
49 {
50  if ( theDataset )
51  {
52  delete theDataset;
53  theDataset = 0;
54  }
55 }
56 
58 {
59  theOutputFile = file;
60 }
61 
63 {
65  {
66  if (theDataset)
67  {
69  {
70  ossimFilename outputFile =
72 
73  switch (theOverviewType)
74  {
77  outputFile.setExtension(getExtensionFromType());
78  break;
79  default:
80  outputFile += ".ovr";
81  break;
82  }
83  return outputFile;
84  }
85  }
86  }
87 
88  return theOutputFile;
89 }
90 
92 {
93  if (theDataset)
94  {
95  delete theDataset;
96  }
98  return theDataset->open(file);
99 }
100 
102 {
103  if ( !imageSource )
104  {
105  return false;
106  }
107 
108  if (theDataset)
109  {
110  delete theDataset;
111  }
112 
114  theDataset->setImageHandler(imageSource);
115  return true;
116 }
117 
119 {
120  if(type == OVR_TYPE[ossimGdalOverviewTiffNearest])
121  {
123  }
124  else if(type == OVR_TYPE[ossimGdalOverviewTiffAverage])
125  {
127  }
128  else if(type == OVR_TYPE[ossimGdalOverviewHfaNearest])
129  {
131  }
132  else if(type == OVR_TYPE[ossimGdalOverviewHfaAverage])
133  {
135  }
136  else
137  {
138  return false;
139  }
140  return true;
141 }
142 
144 {
145  return ossimString(OVR_TYPE[theOverviewType]);
146 }
147 
149  std::vector<ossimString>& typeList)const
150 {
151  typeList.push_back(
153  typeList.push_back(
155  typeList.push_back(
157  typeList.push_back(
159 }
160 
162 {
163  if (traceDebug())
164  {
166  << "ossimGdalOverviewBuilder::execute entered..."
167  << endl;
168  }
169 
170  bool result = false;
171 
173  {
174  return result;
175  }
176 
177  // Get the output file.
178  ossimFilename overviewFile = getOutputFile();
179 
180  // Check the file. Disallow same file overview building.
181  if (theDataset->getImageHandler()->getFilename() == overviewFile)
182  {
184  << "Source image file and overview file cannot be the same!"
185  << std::endl;
186  return result;
187  }
188 
190  {
191  theDataset->setGdalAcces(GA_Update);
193  if (generateHfaStats() == false)
194  {
195  cerr << " generateHfaStats failed..." << endl;
196  }
197  else
198  {
199  // delete theDataset;
200  // return true;
201  }
202  }
203 
204  // theDataset->setGdalAcces(GA_Update);
205 
207 
208  // Get the number of bands.
209  // ossim_uint32 bands = theDataset->getImageHandler()->
210  // getNumberOfOutputBands();
211 
212  // Get the resampling string.
213  ossimString pszResampling = getGdalResamplingType();
214 
215  // Compute the number of levels.
217  ossim_uint32 minBound = ossim::min( bounds.width(), bounds.height() );
218 
219  //---
220  // Set the decimation levels. If set through the property interface use
221  // that; else compute.
222  //---
223  ossim_int32 numberOfLevels = 0;
224 
225  if (theLevels.size())
226  {
227  numberOfLevels = theLevels.size();
228  }
229  else
230  {
232  while (minBound > stopDim)
233  {
234  minBound = minBound / 2;
235  ++numberOfLevels;
236  }
237 
238  if (numberOfLevels == 0)
239  {
240  return result; // nothing to do.
241  }
242  }
243 
244  ossim_int32* levelDecimationFactor = new ossim_int32[numberOfLevels];
245 
246  ossim_uint32 idx;
247 
248  if (theLevels.size())
249  {
250  for (idx = 0; idx < theLevels.size(); ++idx)
251  {
252  levelDecimationFactor[idx] = theLevels[idx];
253  }
254  }
255  else
256  {
257  levelDecimationFactor[0] = 2;
258  for(idx = 1; idx < static_cast<ossim_uint32>(numberOfLevels); ++idx)
259  {
260  levelDecimationFactor[idx] = levelDecimationFactor[idx-1]*2;
261  }
262  }
263 
264  if (traceDebug())
265  {
267  << "ossimGdalOverviewBuilder::execute DEBUG:"
268  << "\noverviewFilename: " << overviewFile
269  << "\npszResampling: " << pszResampling
270  << "\nnumberOfLevels: " << numberOfLevels
271  << endl;
272  for(idx = 0; idx < static_cast<ossim_uint32>(numberOfLevels); ++idx)
273  {
275  << "levelDecimationFactor["
276  << idx << "]: " << levelDecimationFactor[idx]
277  << endl;
278  }
279  }
280 
281  CPLErr eErr = CE_None;
282 
285  {
286  CPLSetConfigOption("USE_RRD", "YES");
287  }
288 
289  if( theDataset->BuildOverviews( pszResampling.c_str(),
290  numberOfLevels,
291  levelDecimationFactor,
292  0,
293  0,
294  GDALTermProgress,
295  0 ) != CE_None )
296  {
298  << "Overview building failed." << std::endl;
299  }
300 
301  if ( levelDecimationFactor )
302  {
303  delete [] levelDecimationFactor;
304  levelDecimationFactor = 0;
305  }
306 
307  if (eErr == CE_None )
308  {
309  result = true;
310  }
311 
312  if (result == true)
313  {
315  << "Wrote file: " << overviewFile << std::endl;
316  }
317 
318  return result;
319 }
320 
322 {
323  if (property.valid() == false)
324  {
325  return;
326  }
327 
328  ossimString s = property->getName();
329  s.downcase();
330  if ( s == "levels" )
331  {
332  ossimString value;
333  property->valueToString(value);
334 
335  if (traceDebug())
336  {
338  << "ossimGdalOverviewBuilder::setProperty DEBUG:"
339  << std::endl;
340  }
341  theLevels.clear();
342  std::vector<ossimString> v1 = value.split(",");
343  for (ossim_uint32 i = 0; i < v1.size(); ++i)
344  {
345  ossim_int32 level = v1[i].toInt32();
346  theLevels.push_back(level);
347  if (traceDebug())
348  {
350  << "level[" << i << "]: " << level << std::endl;
351  }
352  }
353  }
354  else if ( s == "generate-hfa-stats" )
355  {
357  }
358 }
359 
361  std::vector<ossimString>& propertyNames)const
362 {
363  propertyNames.push_back(ossimString("levels"));
364  propertyNames.push_back(ossimString("generate-hfa-stats"));
365 }
366 
368 {
369  out << "ossimGdalOverviewBuilder::print"
370  << "\nfilename: " << theOutputFile.c_str()
371  << "\noverview_type: "
372  << OVR_TYPE[theOverviewType]
373  << "\nresampling type: " << getGdalResamplingType()
374  << std::endl;
375  return out;
376 }
377 
379 {
380  // GDALAllRegister();
381 
382  //---
383  // Equivalent:
384  // gdal_translate -of HFA -co AUX=YES -co STATISTICS=YES
385  // -co DEPENDENT_FILE=utm.tif utm.tif utm.aux
386  //---
387  bool result = false;
388 
389  if (!theDataset)
390  {
391  return result;
392  }
393  if (!theDataset->getImageHandler())
394  {
395  return result;
396  }
397 
398  ossimFilename sourceImageFile =
400  if (sourceImageFile.empty())
401  {
402  return result;
403  }
404 
405  // This is the output driver.
406  GDALDriverH hDriver = GDALGetDriverByName( "HFA" );
407  if (!hDriver)
408  {
409  return false;
410  }
411 
412  // This is the source data set.
413  GDALDatasetH hDataset = theDataset;
414 
415  GDALDatasetH hOutDS = 0;
416  int bStrict = true;
417 
418  char** papszCreateOptions = 0;
419  GDALProgressFunc pfnProgress = GDALTermProgress;
420 
421  ossimString s = "DEPENDENT_FILE=";
422  s += sourceImageFile.file(); // Must not have absolute path...
423 
424  papszCreateOptions = CSLAddString( papszCreateOptions, "AUX=YES");
425  papszCreateOptions = CSLAddString( papszCreateOptions, "STATISTICS=YES");
426  papszCreateOptions = CSLAddString( papszCreateOptions, s.c_str() );
427 
428  hOutDS = GDALCreateCopy( hDriver,
429  getOutputFile().c_str(),
430  hDataset,
431  bStrict,
432  papszCreateOptions,
433  pfnProgress,
434  0 );
435 
436  CSLDestroy( papszCreateOptions );
437  if( hOutDS != 0 )
438  {
439  GDALClose( hOutDS );
440  }
441 
442  return true;
443 }
444 
446 {
447  ossimString result;
448  switch (theOverviewType)
449  {
452  result = "nearest";
453  break;
456  result = "average";
457  break;
459  result = "unknown";
460  break;
461  }
462  return result;
463 }
464 
466 {
467  ossimString result;
468  switch (theOverviewType)
469  {
472  result = "aux";
473  break;
474 
475  default:
476  result = "ovr";
477  break;
478  }
479  return result;
480 }
481 
482 
483 
485 {
486  return this;
487 }
488 
490 {
491  return this;
492 }
493 
495  ossim_int32 index,
496  const ossimConnectableObject* obj) const
497 {
498  if ( (index == 0) &&
500  {
501  return true;
502  }
503 
504  return false;
505 }
void initGdalOverviewManager()
Calls gdal&#39;s oOvManager.Initialize.
bool open(const ossimFilename &file)
Open that takes a file name.
virtual bool setOverviewType(const ossimString &type)
Sets the overview output type.
static const ossimFilename NIL
This was taken from Wx widgets for performing touch and access date stamps.
Definition: ossimFilename.h:40
ossimString getExtensionFromType() const
bool valid() const
Definition: ossimRefPtr.h:75
ossimGdalOverviewType theOverviewType
std::vector< ossim_int32 > theLevels
virtual bool execute()
Builds the overviews.
void setImageHandler(ossimImageHandler *ih)
Sets theImageHandler.
ossim_uint32 height() const
Definition: ossimIrect.h:487
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 setProperty(ossimRefPtr< ossimProperty > property)
Method to set properties.
virtual bool setInputSource(ossimImageHandler *imageSource)
Sets the input to the builder.
const ossimImageHandler * getImageHandler() const
ossimGdalOverviewBuilder Class to build overviews from the GDAL library.
virtual ~ossimGdalOverviewBuilder()
virtual destructor
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
Method to populate the list of property names.
virtual std::ostream & print(std::ostream &out) const
print method.
virtual ossim_uint32 getOverviewStopDimension() const
Get the overview stop dimension.
void setGdalAcces(GDALAccess access)
Set the access data member.
ossimGdalOverviewBuilder()
default constructor
virtual const ossimFilename & getFilename() const
Returns the filename.
ossimString getGdalResamplingType() const
unsigned int ossim_uint32
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
virtual bool canConnectMyInputTo(ossim_int32 index, const ossimConnectableObject *obj) const
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
ossimGdalDataset This is a gdal data set that wraps an ossim image handler.
T min(T a, T b)
Definition: ossimCommon.h:203
ossim_uint32 width() const
Definition: ossimIrect.h:500
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual void setOutputFile(const ossimFilename &file)
Sets the output filename.
virtual void getTypeNameList(std::vector< ossimString > &typeList) const
Method to populate class supported types.
virtual ossimObject * getObject()
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool empty() const
Definition: ossimString.h:411
virtual ossimFilename getOutputFile() const
Returns the output.
ossimFilename file() const
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
Returns zero-based bounding rectangle of the image.
bool open(const ossimFilename &file)
open method.
virtual ossimString getOverviewType() const
Gets the overview type.
ossimFilename & setExtension(const ossimString &e)
Sets the extension of a file name.
RTTI_DEF1(ossimGdalOverviewBuilder, "ossimGdalOverviewBuilder", ossimOverviewBuilderBase)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32