OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimElevationMosaic.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author:
6 //
7 // Description: implementation for image mosaic
8 //
9 //*************************************************************************
10 // $Id: ossimElevationMosaic.cpp 15766 2009-10-20 12:37:09Z gpotts $
11 
15 #include <ossim/base/ossimTrace.h>
16 static const ossimTrace traceDebug("ossimElevationMosaic:debug");
17 static const ossim_float32 MIN_ELEVATION = -500.0;
18 static const ossim_float32 MAX_ELEVATION = 32000.0;
19 
20 using namespace std;
21 
22 RTTI_DEF1(ossimElevationMosaic, "ossimElevationMosaic", ossimImageCombiner)
25  theTile(NULL)
26 {
27 
28 }
29 
31  : ossimImageCombiner(inputSources),
32  theTile(NULL)
33 {
34 }
35 
36 
38 {
39 }
40 
42  const ossimIrect& tileRect,
43  ossim_uint32 resLevel)
44 {
45  long size = getNumberOfInputs();
46  ossim_uint32 layerIdx = 0;
47  // If there is only one in the mosaic then just return it.
48  if(size == 1)
49  {
50  return getNextTile(layerIdx, 0, tileRect, resLevel);
51  }
52 
53  ossimIpt origin = tileRect.ul();
54  ossim_uint32 w = tileRect.width();
55  ossim_uint32 h = tileRect.height();
56 
57  if(!theTile.valid())
58  {
59  // try to initialize
60  allocate();
61 
62  // if we still don't have a buffer
63  // then we will leave
64  if(!theTile.valid())
65  {
67  }
68  }
69 
70  ossim_uint32 tileW = theTile->getWidth();
71  ossim_uint32 tileH = theTile->getHeight();
72  if((w != tileW)||
73  (h != tileH))
74  {
75  theTile->setWidth(w);
76  theTile->setHeight(h);
77  if((w*h)!=(tileW*tileH))
78  {
80  }
81  }
82  theTile->setOrigin(origin);
83 
84  //---
85  // General Note:
86  //
87  // Note: I will not check for disabled or enabled since we have
88  // no clear way to handle this within a mosaic. The default will be
89  // to do a simple a A over B type mosaic. Derived classes should
90  // check for the enabled and disabled and always
91  // use this default implementation if they are disabled.
92  //---
93 
94  theTile->setOrigin(origin);
95  theTile->makeBlank();
96  switch(theTile->getScalarType())
97  {
98  case OSSIM_UCHAR:
99  {
100  if(!hasDifferentInputs())
101  {
102  return combine(static_cast<ossim_uint8>(0),
103  tileRect,
104  resLevel);
105  }
106  else
107  {
108  return combineNorm(static_cast<ossim_uint8>(0),
109  tileRect,
110  resLevel);
111  }
112  }
113  case OSSIM_SINT8:
114  {
115  if(!hasDifferentInputs())
116  {
117  return combine(static_cast<ossim_sint8>(0),
118  tileRect,
119  resLevel);
120  }
121  else
122  {
123  return combineNorm(static_cast<ossim_sint8>(0),
124  tileRect,
125  resLevel);
126  }
127  }
128  case OSSIM_FLOAT:
130  {
131  if(!hasDifferentInputs())
132  {
133  return combine(static_cast<float>(0),
134  tileRect,
135  resLevel);
136  }
137  else
138  {
139  return combineNorm(static_cast<float>(0),
140  tileRect,
141  resLevel);
142  }
143  }
144  case OSSIM_USHORT16:
145  case OSSIM_USHORT11:
146  case OSSIM_USHORT12:
147  case OSSIM_USHORT13:
148  case OSSIM_USHORT14:
149  case OSSIM_USHORT15:
150  {
151  if(!hasDifferentInputs())
152  {
153  return combine(static_cast<ossim_uint16>(0),
154  tileRect,
155  resLevel);
156  }
157  else
158  {
159  return combineNorm(static_cast<ossim_uint16>(0),
160  tileRect,
161  resLevel);
162  }
163  }
164  case OSSIM_SSHORT16:
165  {
166  if(!hasDifferentInputs())
167  {
168  return combine(static_cast<ossim_sint16>(0),
169  tileRect,
170  resLevel);
171  }
172  else
173  {
174  return combineNorm(static_cast<ossim_sint16>(0),
175  tileRect,
176  resLevel);
177  }
178  }
179  case OSSIM_SINT32:
180  {
181  if(!hasDifferentInputs())
182  {
183  return combine(static_cast<ossim_sint32>(0),
184  tileRect,
185  resLevel);
186  }
187  else
188  {
189  return combineNorm(static_cast<ossim_sint32>(0),
190  tileRect,
191  resLevel);
192  }
193  }
194  case OSSIM_UINT32:
195  {
196  if(!hasDifferentInputs())
197  {
198  return combine(static_cast<ossim_uint32>(0),
199  tileRect,
200  resLevel);
201  }
202  else
203  {
204  return combineNorm(static_cast<ossim_uint32>(0),
205  tileRect,
206  resLevel);
207  }
208  }
209  case OSSIM_DOUBLE:
211  {
212  if(!hasDifferentInputs())
213  {
214  return combine(static_cast<double>(0),
215  tileRect,
216  resLevel);
217  }
218  else
219  {
220  return combineNorm(static_cast<double>(0),
221  tileRect,
222  resLevel);
223  }
224  }
226  default:
227  {
229  << "Scalar type = " << theTile->getScalarType()
230  << " Not supported by ossimElevationMosaic" << endl;
231  }
232  }
233 
235 }
236 
238 {
240  theTile = NULL;
241 }
242 
244 {
245  theTile = NULL;
246 
247  if( (getNumberOfInputs() > 0) && getInput(0) )
248  {
250  theTile->initialize();
251  }
252 }
253 
255  const char* prefix)const
256 {
257  return ossimImageCombiner::saveState(kwl, prefix);
258 }
259 
261  const char* prefix)
262 {
263  return ossimImageCombiner::loadState(kwl, prefix);
264 }
265 
267  T,// dummy template variable
268  const ossimIrect& tileRect,
269  ossim_uint32 resLevel)
270 {
271  ossim_uint32 layerIdx = 0;
272  //---
273  // Get the first tile from the input sources. If this(index 0) is blank
274  // that means there are no layers so go no further.
275  //---
276  ossimRefPtr<ossimImageData> currentImageData =
277  getNextNormTile(layerIdx, 0, tileRect, resLevel);
278  if(!currentImageData)
279  {
280  return theTile;
281  }
282 
283  ossimRefPtr<ossimImageData> destination = theTile;
284  ossimDataObjectStatus destinationStatus = theTile->getDataObjectStatus();
285 
286 
287  float** srcBands = new float*[theLargestNumberOfInputBands];
288  float* srcBandsNullPix = new float[theLargestNumberOfInputBands];
289  T** destBands = new T*[theLargestNumberOfInputBands];
290  T* destBandsNullPix = new T[theLargestNumberOfInputBands];
291  T* destBandsMinPix = new T[theLargestNumberOfInputBands];
292  T* destBandsMaxPix = new T[theLargestNumberOfInputBands];
293 
294  ossim_uint32 band;
295  ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
296  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
297  for(band = 0; band < minNumberOfBands; ++band)
298  {
299  srcBands[band] = static_cast<float*>(currentImageData->getBuf(band));
300  srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(band));
301 
302  destBands[band] = static_cast<T*>(theTile->getBuf(band));
303  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
304  destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
305  destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
306  }
307 
308  // if the src is smaller than the destination in number
309  // of bands we will just duplicate the last band.
310  for(;band < theLargestNumberOfInputBands; ++band)
311  {
312  srcBands[band] = static_cast<float*>(srcBands[minNumberOfBands - 1]);
313  srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(minNumberOfBands - 1));
314 
315  destBands[band] = static_cast<T*>(theTile->getBuf(band));
316  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
317  destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
318  destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
319  }
320 
321  // Loop to copy from layers to output tile.
322  while(currentImageData.valid())
323  {
324  //---
325  // Check the status of the source tile. If empty get the next source
326  // tile and loop back.
327  //---
328  ossimDataObjectStatus currentStatus =
329  currentImageData->getDataObjectStatus();
330  if ( (currentStatus == OSSIM_EMPTY) || (currentStatus == OSSIM_NULL) )
331  {
332  currentImageData = getNextNormTile(layerIdx, tileRect, resLevel);
333  continue;
334  }
335 
336  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
337 
338  for(band = 0; band < minNumberOfBands; ++band)
339  {
340  srcBands[band] = static_cast<float*>(currentImageData->getBuf(band));
341  srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(band));
342  }
343  // if the src is smaller than the destination in number
344  // of bands we will just duplicate the last band.
345  for(;band < theLargestNumberOfInputBands; ++band)
346  {
347  srcBands[band] = srcBands[minNumberOfBands - 1];
348  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
349  }
350 
351  if ( (currentStatus == OSSIM_FULL) &&
352  (destinationStatus == OSSIM_EMPTY) )
353  {
354  // Copy full tile to empty tile.
355  for(band=0; band < theLargestNumberOfInputBands; ++band)
356  {
357  float delta = destBandsMaxPix[band] - destBandsMinPix[band];
358  float minP = destBandsMinPix[band];
359 
360  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
361  {
362  destBands[band][offset] =
363  (T)( minP + delta*srcBands[band][offset]);
364  }
365  }
366  }
367  else // Copy tile checking all the pixels...
368  {
369  for(band = 0; band < theLargestNumberOfInputBands; ++band)
370  {
371  float delta = destBandsMaxPix[band] - destBandsMinPix[band];
372  float minP = destBandsMinPix[band];
373 
374  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
375  {
376  if (destBands[band][offset] < MIN_ELEVATION || destBands[band][offset] > MAX_ELEVATION) //== destBandsNullPix[band])
377  {
378  if (srcBands[band][offset] > MIN_ELEVATION && srcBands[band][offset] < MAX_ELEVATION)
379  {
380  destBands[band][offset] =
381  (T)(minP + delta*srcBands[band][offset]);
382  }
383  }
384  }
385  }
386  }
387 
388  // Validate output tile and return if full.
389  destinationStatus = destination->validate();
390  if (destinationStatus == OSSIM_FULL)
391  {
392 
393  break;//return destination;
394  }
395 
396  // If we get here we're are still not full. Get a tile from next layer.
397  currentImageData = getNextNormTile(layerIdx, tileRect, resLevel);
398  }
399 
400  // Cleanup...
401  delete [] srcBands;
402  delete [] destBands;
403  delete [] srcBandsNullPix;
404  delete [] destBandsNullPix;
405  delete [] destBandsMinPix;
406  delete [] destBandsMaxPix;
407 
408  return destination;
409 }
410 
412  T,// dummy template variable
413  const ossimIrect& tileRect,
414  ossim_uint32 resLevel)
415 {
416  ossim_uint32 layerIdx = 0;
417  bool hasInvalidElevations = false;
418  //---
419  // Get the first tile from the input sources. If this(index 0) is blank
420  // that means there are no layers so go no further.
421  //---
422  ossimRefPtr<ossimImageData> currentImageData =
423  getNextTile(layerIdx, 0, tileRect, resLevel);
424  if (!currentImageData)
425  {
426  return theTile;
427  }
428 
429  ossimRefPtr<ossimImageData> destination = theTile;
430  ossimDataObjectStatus destinationStatus = theTile->getDataObjectStatus();
431 
432  T** srcBands = new T*[theLargestNumberOfInputBands];
433  T* srcBandsNullPix = new T[theLargestNumberOfInputBands];
434  T** destBands = new T*[theLargestNumberOfInputBands];
435  T* destBandsNullPix = new T[theLargestNumberOfInputBands];
436 
437  ossim_uint32 band;
438  ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
439  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
440  for(band = 0; band < minNumberOfBands; ++band)
441  {
442  srcBands[band] = static_cast<T*>(currentImageData->getBuf(band));
443  destBands[band] = static_cast<T*>(theTile->getBuf(band));
444  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(band));
445  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
446  }
447  // if the src is smaller than the destination in number
448  // of bands we will just duplicate the last band.
449  for(;band < theLargestNumberOfInputBands; ++band)
450  {
451  srcBands[band] = static_cast<T*>(srcBands[minNumberOfBands - 1]);
452  destBands[band] = static_cast<T*>(theTile->getBuf(band));
453  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
454  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
455  }
456 
457  // Loop to copy from layers to output tile.
458  while(currentImageData.valid())
459  {
460  //---
461  // Check the status of the source tile. If empty get the next source
462  // tile and loop back.
463  //---
464  ossimDataObjectStatus currentStatus =
465  currentImageData->getDataObjectStatus();
466  if ( (currentStatus == OSSIM_EMPTY) || (currentStatus == OSSIM_NULL) )
467  {
468  currentImageData = getNextNormTile(layerIdx, tileRect, resLevel);
469  continue;
470  }
471 
472  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
473 
474  for(band = 0; band < minNumberOfBands; ++band)
475  {
476  srcBands[band] = static_cast<T*>(currentImageData->getBuf(band));
477  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(band));
478  }
479  // if the src is smaller than the destination in number
480  // of bands we will just duplicate the last band.
481  for(;band < theLargestNumberOfInputBands; ++band)
482  {
483  srcBands[band] = srcBands[minNumberOfBands - 1];
484  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
485  }
486 
487  if ( (currentStatus == OSSIM_FULL) &&
488  (destinationStatus == OSSIM_EMPTY) )
489  {
490  // Copy full tile to empty tile.
491  for(ossim_uint32 band=0; band < theLargestNumberOfInputBands; ++band)
492  {
493  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
494  {
495  destBands[band][offset] = srcBands[band][offset];
496  if(destBands[band][offset] < MIN_ELEVATION || destBands[band][offset] > MAX_ELEVATION)
497  {
498  hasInvalidElevations = true;
499  }
500  }
501  }
502  }
503  else // Copy tile checking all the pixels...
504  {
505  for(band = 0; band < theLargestNumberOfInputBands; ++band)
506  {
507 
508  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
509  {
510  if(destBands[band][offset] < MIN_ELEVATION || destBands[band][offset] > MAX_ELEVATION) //== destBandsNullPix[band])
511  {
512  hasInvalidElevations = true;
513  destBands[band][offset] = srcBands[band][offset];
514  }
515  }
516  }
517  }
518 
519  // Validate output tile and return if full.
520  destinationStatus = destination->validate();
521  if (!hasInvalidElevations)
522  {
523  break;
524  }
525  //if (destinationStatus == OSSIM_FULL)
526  //{
527  // break;//return destination;
528  //}
529 
530  // If we get here we're are still not full. Get a tile from next layer.
531  currentImageData = getNextTile(layerIdx, tileRect, resLevel);
532  }
533 
534  // Cleanup...
535  delete [] srcBands;
536  delete [] destBands;
537  delete [] srcBandsNullPix;
538  delete [] destBandsNullPix;
539 
540  return destination;
541 }
16 bit unsigned integer (15 bits used)
8 bit signed integer
virtual ossim_uint32 getWidth() const
virtual const ossim_float64 * getMaxPix() const
virtual ossim_uint32 getNumberOfBands() const
This will be a base for all combiners.
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
float ossim_float32
virtual ossimRefPtr< ossimImageData > getNextNormTile(ossim_uint32 &returnedIdx, const ossim_uint32 index, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
ossim_uint32 height() const
Definition: ossimIrect.h:487
ossimRefPtr< ossimImageData > combine(T, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &origin, ossim_uint32 resLevel=0)
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
16 bit unsigned integer (14 bits used)
16 bit unsigned integer (13 bits used)
32 bit unsigned integer
virtual void initialize()
Initialize the data buffer.
ossimConnectableObject * getInput(ossim_uint32 index=0)
returns the object at the specified index.
virtual void setHeight(ossim_uint32 height)
virtual ossimRefPtr< ossimImageData > getNextTile(ossim_uint32 &returnedIdx, const ossim_uint32 startIdx, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
std::vector< ossimRefPtr< ossimConnectableObject > > ConnectableObjectList
static ossimImageDataFactory * instance()
ossimRefPtr< ossimImageData > theTile
ossim_uint32 theLargestNumberOfInputBands
yy_size_t size
virtual ossimDataObjectStatus validate() const
32 bit signed integer
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
virtual void setWidth(ossim_uint32 width)
ossimRefPtr< ossimImageData > combineNorm(T, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
virtual bool hasDifferentInputs() const
virtual void setOrigin(const ossimIpt &origin)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
virtual const ossim_float64 * getMinPix() const
virtual ossimScalarType getScalarType() const
virtual void makeBlank()
Initializes data to null pixel values.
64 bit normalized floating point
16 bit unsigned integer (11 bits used)
virtual const void * getBuf() const
virtual ossim_uint32 getNumberOfInputs() const
Returns the number of input objects.
void allocate()
Called on first getTile, will initialize all data needed.
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=NULL)
Method to the load (recreate) the state of an object from a keyword list.
ossimDataObjectStatus
Definitions for data object status.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=NULL) const
Method to save the state of an object to a keyword list.
An image mosaic is a simple combiner that will just do a simple mosaic.
32 bit floating point
16 bit unsigned iteger
64 bit floating point
16 bit signed integer
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
8 bit unsigned iteger
16 bit unsigned integer (12 bits used)