Orfeo Toolbox  3.16
otbImageLayerRenderingModel.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbImageLayerRenderingModel_txx
19 #define __otbImageLayerRenderingModel_txx
20 
22 #include "otbMacro.h"
23 #include "itkTimeProbe.h"
24 
25 namespace otb
26 {
27 
28 template <class TOutputImage, class TLayer>
30 ::ImageLayerRenderingModel() : m_Name("Default"), m_RasterizedQuicklook(),
31  m_HasQuicklook(false), m_RasterizedExtract(), m_HasExtract(false),
32  m_ExtractRegion(), m_RasterizedScaledExtract(), m_HasScaledExtract(false),
33  m_ScaledExtractRegion(), m_Updating(false), m_QuicklookBlendingFilterList(),
34  m_ExtractBlendingFilterList(), m_ScaledExtractBlendingFilterList()
35 
36 {
37  // Initalize the blending filter list
38  m_QuicklookBlendingFilterList = BlendingFilterListType::New();
39  m_ExtractBlendingFilterList = BlendingFilterListType::New();
40  m_ScaledExtractBlendingFilterList = BlendingFilterListType::New();
41 }
42 
43 template <class TOutputImage, class TLayer>
46 {}
47 
48 template <class TOutputImage, class TLayer>
49 void
52 {
53  // Multiple concurrent update guards
54  if (!m_Updating)
55  {
56  m_Updating = true;
57  // Render all visible layers
58  this->RenderVisibleLayers();
59  // Rasterize all visible layers
60  this->RasterizeVisibleLayers();
61  // Notify all listeners
62  this->NotifyAll();
63  m_Updating = false;
64  }
65 }
66 
67 template <class TOutputImage, class TLayer>
68 void
71 {
72  m_QuicklookBlendingFilterList = BlendingFilterListType::New();
73  m_ExtractBlendingFilterList = BlendingFilterListType::New();
74  m_ScaledExtractBlendingFilterList = BlendingFilterListType::New();
75  m_RasterizedQuicklook = OutputImageType::New();
76  m_RasterizedExtract = OutputImageType::New();
77  m_RasterizedScaledExtract = OutputImageType::New();
78 }
79 
80 template <class TOutputImage, class TLayer>
81 void
84 {
85  // Render all visible layers
86  for (LayerIteratorType it = this->GetLayers()->Begin();
87  it != this->GetLayers()->End(); ++it)
88  {
89  // If the layer is visible
90  if (it.Get()->GetVisible())
91  {
92  // Set the extracted region
93  m_ExtractRegion = this->ConstrainRegion(m_ExtractRegion, it.Get()->GetExtent());
94  it.Get()->SetExtractRegion(m_ExtractRegion);
95  // Set the scaled extracted region
96  m_ScaledExtractRegion = this->ConstrainRegion(m_ScaledExtractRegion, m_ExtractRegion);
97  it.Get()->SetScaledExtractRegion(m_ScaledExtractRegion);
98  // Render it
100  << "ImageLayerRenderingModel::RenderVisibleLayers(): Rendering layer " << it.Get()->GetName() <<
101  " with regions (" << m_ExtractRegion.GetIndex() << " " << m_ExtractRegion.GetSize() << ") (" <<
102  m_ScaledExtractRegion.GetIndex() << " " << m_ScaledExtractRegion.GetSize() << ")");
103  it.Get()->Render();
104  }
105  }
106 }
107 
108 template <class TOutputImage, class TLayer>
109 void
112 {
113  // If there are no layer to render
114  if (this->GetNumberOfLayers() == 0)
115  {
116  // Ensure nothing is available
117  m_HasQuicklook = false;
118  m_HasExtract = false;
119  m_HasScaledExtract = false;
120  // and return without doing anything
121  return;
122  }
123 
124  // Get the lowest layer
125  LayerIteratorType it = this->GetLayers()->Begin();
126 
127  bool visible = false;
128 
129  while (!visible && it != this->GetLayers()->End())
130  {
131  visible = it.Get()->GetVisible();
132  ++it;
133  }
134 
135  if (!visible)
136  {
137  // no visible layers, returning
138  return;
139  }
140  --it;
141 
142  // base layer
143  typename LayerType::Pointer baseLayer = it.Get();
144 
145  otbMsgDevMacro(<< "ImageLayerRenderingModel::RasterizeVisibleLayers(): Found base layer named " << it.Get()->GetName());
146 
147  // Configure base layer rasterization
148  if (baseLayer->GetHasQuicklook())
149  {
150  m_HasQuicklook = true;
151  m_RasterizedQuicklook = baseLayer->GetRenderedQuicklook();
152  }
153 
154  if (baseLayer->GetHasExtract())
155  {
156  m_HasExtract = true;
157  m_RasterizedExtract = baseLayer->GetRenderedExtract();
158  }
159 
160  if (baseLayer->GetHasScaledExtract())
161  {
162  m_HasScaledExtract = true;
163  m_RasterizedScaledExtract = baseLayer->GetRenderedScaledExtract();
164  }
165 
166  // Move to the next layer
167  ++it;
168 
169  m_QuicklookBlendingFilterList->Clear();
170  m_ExtractBlendingFilterList->Clear();
171  m_ScaledExtractBlendingFilterList->Clear();
172 
173  unsigned int count = 0;
174  // Walk the remaining layers
175  while (it != this->GetLayers()->End())
176  {
177  // Populate Blending filter list if needed
178 
179  m_QuicklookBlendingFilterList->PushBack(BlendingFilterType::New());
180  m_ExtractBlendingFilterList->PushBack(BlendingFilterType::New());
181  m_ScaledExtractBlendingFilterList->PushBack(BlendingFilterType::New());
182 
183  // If a layer is visible
184  if (it.Get()->GetVisible())
185  {
186  itk::TimeProbe probe;
187  probe.Start();
188  // If quicklook is activated and available for this layer
189  if (m_HasQuicklook && it.Get()->GetHasQuicklook())
190  {
191  // Blend it with the current rasterized quicklook
192  typename BlendingFilterType::Pointer blender = m_QuicklookBlendingFilterList->GetNthElement(count);
193  // Using the blending function of the layer
194  blender->SetBlendingFunction(it.Get()->GetBlendingFunction());
195  blender->SetInput1(m_RasterizedQuicklook);
196  blender->SetInput2(it.Get()->GetRenderedQuicklook());
197  blender->Update();
198  // Store the result as being the current rasterized quicklook
199  m_RasterizedQuicklook = blender->GetOutput();
200  }
201 
202  // If extract is activated and available for this layer
203  if (m_HasExtract && it.Get()->GetHasExtract())
204  {
205  // Blend it with the current rasterized extract
206  typename BlendingFilterType::Pointer blender = m_ExtractBlendingFilterList->GetNthElement(count);
207  // Using the blending function of the layer
208  blender->SetBlendingFunction(it.Get()->GetBlendingFunction());
209  blender->SetInput1(m_RasterizedExtract);
210  blender->SetInput2(it.Get()->GetRenderedExtract());
211  blender->GetOutput()->SetRequestedRegion(m_ExtractRegion);
212  blender->Update();
213  // Store the result as being the current rasterized extract
214  m_RasterizedExtract = blender->GetOutput();
215  }
216 
217  // If scaledExtract is activated and available for this layer
218  if (m_HasScaledExtract && it.Get()->GetHasScaledExtract())
219  {
220  // Blend it with the current rasterized scaledExtract
221  typename BlendingFilterType::Pointer blender = m_ScaledExtractBlendingFilterList->GetNthElement(count);
222  // Using the blending function of the layer
223  blender->SetBlendingFunction(it.Get()->GetBlendingFunction());
224  blender->SetInput1(m_RasterizedScaledExtract);
225  blender->SetInput2(it.Get()->GetRenderedScaledExtract());
226  blender->GetOutput()->SetRequestedRegion(m_ScaledExtractRegion);
227  blender->Update();
228  // Store the result as being the current rasterized scaledExtract
229  m_RasterizedScaledExtract = blender->GetOutput();
230  }
231  probe.Stop();
233  "ImageLayerRenderingModel::RasterizeVisibleLayers(): Previous layer rasterized with layer " <<
234  it.Get()->GetName(
235  ) << " ( " << probe.GetMeanTime() << " s.)");
236  }
237  ++it;
238  ++count;
239  }
240 }
241 
242 template <class TOutputImage, class TLayer>
243 void
246 {
247  // Notify the listener
248  otbMsgDevMacro(<< "ImageLayerRenderingModel::Notify(): Notifying listener");
249  listener->Notify();
250 }
251 
252 template <class TOutputImage, class TLayer>
253 void
256 {
257  // Set the center of the scaled extract region
258  IndexType newIndex = index;
259  newIndex[0] -= m_ScaledExtractRegion.GetSize()[0] / 2;
260  newIndex[1] -= m_ScaledExtractRegion.GetSize()[1] / 2;
261  m_ScaledExtractRegion.SetIndex(newIndex);
262 }
263 
264 template <class TOutputImage, class TLayer>
265 void
268 {
269  // Set the center of the extract region
270  IndexType newIndex = index;
271 
272 // Update Scaled extract center as well
273  this->SetScaledExtractRegionCenter(newIndex);
274 
275  // Update extract region
276  newIndex[0] -= m_ExtractRegion.GetSize()[0] / 2;
277  newIndex[1] -= m_ExtractRegion.GetSize()[1] / 2;
278  m_ExtractRegion.SetIndex(newIndex);
279 }
280 
281 template <class TOutputImage, class TLayer>
282 void
284 ::SetExtractRegionByIndex(const IndexType& startIndex, const IndexType& stopIndex)
285 {
286  RegionType lImageRegion;
287  lImageRegion = this->GetLayer(0)->GetExtent();
288 
289  SizeType lSize;
290  lSize[0] = vcl_abs(stopIndex[0] - startIndex[0]);
291  lSize[1] = vcl_abs(stopIndex[1] - startIndex[1]);
292 
293  IndexType lIndex;
294  lIndex[0] = std::min(startIndex[0], stopIndex[0]);
295  lIndex[1] = std::min(startIndex[1], stopIndex[1]);
296 
297  RegionType lRegion;
298  lRegion.SetIndex(lIndex);
299  lRegion.SetSize(lSize);
300 
301  if (lRegion.Crop(lImageRegion))
302  {
303  m_ExtractRegion = lRegion;
304  }
305 }
306 
307 template <class TOutputImage, class TLayer>
308 unsigned int
311 {
312  if (this->GetNumberOfLayers() < 1)
313  {
314  return 1;
315  }
316  // Get the lowest layer
317  LayerIteratorType it = this->GetLayers()->Begin();
318  // Base layer
319  typename LayerType::Pointer baseLayer = it.Get();
320  return baseLayer->GetQuicklookSubsamplingRate();
321 }
322 
323 template <class TOutputImage, class TLayer>
325 ::RegionType
327 ::ConstrainRegion(const RegionType& region, const RegionType& largest)
328 {
329  RegionType resp = region;
330 
331  // Else we can constrain it
332  IndexType index = resp.GetIndex();
333  typename RegionType::SizeType size = resp.GetSize();
334 
335 // If region is larger than big, then crop
336  if (region.GetSize()[0] > largest.GetSize()[0])
337  {
338  size[0] = largest.GetSize()[0];
339  }
340  if (region.GetSize()[1] > largest.GetSize()[1])
341  {
342  size[1] = largest.GetSize()[1];
343  }
344 
345  // Else we can constrain it
346  // For each dimension
347  for (unsigned int dim = 0; dim < RegionType::ImageDimension; ++dim)
348  {
349  // push left if necessary
350  if (region.GetIndex()[dim] < largest.GetIndex()[dim])
351  {
352  index[dim] = largest.GetIndex()[dim];
353  }
354  // push right if necessary
355  if (index[dim] + size[dim] >= largest.GetIndex()[dim] + largest.GetSize()[dim])
356  {
357  index[dim] = largest.GetIndex()[dim] + largest.GetSize()[dim] - size[dim];
358  }
359  }
360  resp.SetSize(size);
361  resp.SetIndex(index);
362  return resp;
363 }
364 
365 template <class TOutputImage, class TLayer>
366 void
368 ::PrintSelf(std::ostream& os, itk::Indent indent) const
369 {
370  // Call superclass implementation
371  Superclass::PrintSelf(os, indent);
372  os << indent << "Viewer " << m_Name << ": " << std::endl;
373  for (LayerIteratorType it = this->GetLayers()->Begin();
374  it != this->GetLayers()->End(); ++it)
375  {
376  os << indent << it.Get() << std::endl;
377  }
378 }
379 
380 } // end namespace otb
381 
382 #endif

Generated at Sun May 12 2013 00:29:36 for Orfeo Toolbox with doxygen 1.8.3.1