QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsrasterpipe.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterpipe.cpp - Internal raster processing modules interface
3  --------------------------------------
4  Date : Jun 21, 2012
5  Copyright : (C) 2012 by Radim Blazek
6  email : radim dot blazek at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <typeinfo>
19 
20 #include <QByteArray>
21 
22 #include "qgslogger.h"
23 #include "qgsrasterpipe.h"
24 
26 {
27 }
28 
30 {
31  for ( int i = 0; i < thePipe.size(); i++ )
32  {
33  QgsRasterInterface* interface = thePipe.at( i );
34  QgsRasterInterface* clone = interface->clone();
35 
36  Role role = interfaceRole( clone );
37  QgsDebugMsg( QString( "cloned inerface with role %1" ).arg( role ) );
38  if ( i > 0 )
39  {
40  clone->setInput( mInterfaces.at( i - 1 ) );
41  }
42  mInterfaces.append( clone );
43  if ( role != UnknownRole )
44  {
45  mRoleMap.insert( role, i );
46  }
47  }
48 }
49 
51 {
52  foreach ( QgsRasterInterface* interface, mInterfaces )
53  {
54  delete interface;
55  }
56 }
57 
58 bool QgsRasterPipe::connect( QVector<QgsRasterInterface*> theInterfaces )
59 {
60  QgsDebugMsg( "Entered" );
61  for ( int i = 1; i < theInterfaces.size(); i++ )
62  {
63  if ( ! theInterfaces[i]->setInput( theInterfaces[i-1] ) )
64  {
65  QgsDebugMsg( QString( "cannot connect %1 to %2" ).arg( typeid( *( theInterfaces[i] ) ).name() ).arg( typeid( *( theInterfaces[i-1] ) ).name() ) );
66  return false;
67  }
68  }
69  return true;
70 }
71 
72 bool QgsRasterPipe::insert( int idx, QgsRasterInterface* theInterface )
73 {
74  QgsDebugMsg( QString( "insert %1 at %2" ).arg( typeid( *theInterface ).name() ).arg( idx ) );
75  if ( idx > mInterfaces.size() )
76  {
77  idx = mInterfaces.size();
78  }
79  // make a copy of pipe to test connection, we test the connections
80  // of the whole pipe, because the types and band numbers may change
81  QVector<QgsRasterInterface*> interfaces = mInterfaces;
82 
83  interfaces.insert( idx, theInterface );
84  bool success = false;
85  if ( connect( interfaces ) )
86  {
87  success = true;
88  mInterfaces.insert( idx, theInterface );
89  setRole( theInterface, idx );
90  QgsDebugMsg( "inserted ok" );
91  }
92 
93  // Connect or reconnect (after the test) interfaces
94  connect( mInterfaces );
95  return success;
96 }
97 
98 bool QgsRasterPipe::replace( int idx, QgsRasterInterface* theInterface )
99 {
100  if ( !theInterface ) return false;
101 
102  QgsDebugMsg( QString( "replace by %1 at %2" ).arg( typeid( *theInterface ).name() ).arg( idx ) );
103  if ( !checkBounds( idx ) ) return false;
104 
105  // make a copy of pipe to test connection, we test the connections
106  // of the whole pipe, because the types and band numbers may change
107  QVector<QgsRasterInterface*> interfaces = mInterfaces;
108 
109  interfaces[idx] = theInterface;
110  bool success = false;
111  if ( connect( interfaces ) )
112  {
113  success = true;
114  delete mInterfaces[idx];
115  mInterfaces[idx] = theInterface;
116  setRole( theInterface, idx );
117  QgsDebugMsg( "replaced ok" );
118  }
119 
120  // Connect or reconnect (after the test) interfaces
121  connect( mInterfaces );
122  return success;
123 }
124 
125 QgsRasterPipe::Role QgsRasterPipe::interfaceRole( QgsRasterInterface * interface ) const
126 {
127  Role role = UnknownRole;
128  if ( dynamic_cast<QgsRasterDataProvider *>( interface ) ) role = ProviderRole;
129  else if ( dynamic_cast<QgsRasterRenderer *>( interface ) ) role = RendererRole;
130  else if ( dynamic_cast<QgsRasterResampleFilter *>( interface ) ) role = ResamplerRole;
131  else if ( dynamic_cast<QgsBrightnessContrastFilter *>( interface ) ) role = BrightnessRole;
132  else if ( dynamic_cast<QgsHueSaturationFilter *>( interface ) ) role = HueSaturationRole;
133  else if ( dynamic_cast<QgsRasterProjector *>( interface ) ) role = ProjectorRole;
134  else if ( dynamic_cast<QgsRasterNuller *>( interface ) ) role = NullerRole;
135 
136  QgsDebugMsg( QString( "%1 role = %2" ).arg( typeid( *interface ).name() ).arg( role ) );
137  return role;
138 }
139 
140 void QgsRasterPipe::setRole( QgsRasterInterface * theInterface, int idx )
141 {
142  Role role = interfaceRole( theInterface );
143  if ( role == UnknownRole ) return;
144  mRoleMap.insert( role, idx );
145 }
146 
147 void QgsRasterPipe::unsetRole( QgsRasterInterface * theInterface )
148 {
149  Role role = interfaceRole( theInterface );
150  if ( role == UnknownRole ) return;
151  mRoleMap.remove( role );
152 }
153 
155 {
156  if ( !theInterface ) return false;
157 
158  QgsDebugMsg( QString( "%1" ).arg( typeid( *theInterface ).name() ) );
159  Role role = interfaceRole( theInterface );
160 
161  // We don't know where to place unknown interface
162  if ( role == UnknownRole ) return false;
163 
164  //if ( mInterfacesMap.value ( role ) )
165  if ( mRoleMap.contains( role ) )
166  {
167  // An old interface of the same role exists -> replace
168  // replace may still fail and return false
169  return replace( mRoleMap.value( role ), theInterface );
170  }
171 
172  int idx = 0;
173 
174  // Not found, find the best default position for this kind of interface
175  // QgsRasterDataProvider - ProviderRole
176  // QgsRasterRenderer - RendererRole
177  // QgsRasterResampler - ResamplerRole
178  // QgsRasterProjector - ProjectorRole
179 
180  int providerIdx = mRoleMap.value( ProviderRole, -1 );
181  int rendererIdx = mRoleMap.value( RendererRole, -1 );
182  int resamplerIdx = mRoleMap.value( ResamplerRole, -1 );
183  int brightnessIdx = mRoleMap.value( BrightnessRole, -1 );
184  int hueSaturationIdx = mRoleMap.value( HueSaturationRole, -1 );
185 
186  if ( role == ProviderRole )
187  {
188  idx = 0;
189  }
190  else if ( role == RendererRole )
191  {
192  idx = providerIdx + 1;
193  }
194  else if ( role == BrightnessRole )
195  {
196  idx = qMax( providerIdx, rendererIdx ) + 1;
197  }
198  else if ( role == HueSaturationRole )
199  {
200  idx = qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ) + 1;
201  }
202  else if ( role == ResamplerRole )
203  {
204  idx = qMax( qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ) + 1;
205  }
206  else if ( role == ProjectorRole )
207  {
208  idx = qMax( qMax( qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ), resamplerIdx ) + 1;
209  }
210 
211  return insert( idx, theInterface ); // insert may still fail and return false
212 }
213 
214 QgsRasterInterface * QgsRasterPipe::interface( Role role ) const
215  {
216  QgsDebugMsg( QString( "role = %1" ).arg( role ) );
217  if ( mRoleMap.contains( role ) )
218  {
219  return mInterfaces.value( mRoleMap.value( role ) );
220  }
221  return 0;
222  }
223 
225 {
226  return dynamic_cast<QgsRasterDataProvider *>( interface( ProviderRole ) );
227 }
228 
230 {
231  return dynamic_cast<QgsRasterRenderer *>( interface( RendererRole ) );
232 }
233 
235 {
236  return dynamic_cast<QgsRasterResampleFilter *>( interface( ResamplerRole ) );
237 }
238 
240 {
241  return dynamic_cast<QgsBrightnessContrastFilter *>( interface( BrightnessRole ) );
242 }
243 
245 {
246  return dynamic_cast<QgsHueSaturationFilter *>( interface( HueSaturationRole ) );
247 }
248 
250 {
251  return dynamic_cast<QgsRasterProjector*>( interface( ProjectorRole ) );
252 }
253 
255 {
256  return dynamic_cast<QgsRasterNuller*>( interface( NullerRole ) );
257 }
258 
259 bool QgsRasterPipe::remove( int idx )
260 {
261  QgsDebugMsg( QString( "remove at %1" ).arg( idx ) );
262 
263  if ( !checkBounds( idx ) ) return false;
264 
265  // make a copy of pipe to test connection, we test the connections
266  // of the whole pipe, because the types and band numbers may change
267  QVector<QgsRasterInterface*> interfaces = mInterfaces;
268 
269  interfaces.remove( idx );
270  bool success = false;
271  if ( connect( interfaces ) )
272  {
273  success = true;
274  unsetRole( mInterfaces[idx] );
275  delete mInterfaces[idx];
276  mInterfaces.remove( idx );
277  QgsDebugMsg( "removed ok" );
278  }
279 
280  // Connect or reconnect (after the test) interfaces
281  connect( mInterfaces );
282  return success;
283 }
284 
286 {
287  if ( !theInterface ) return false;
288 
289  return remove( mInterfaces.indexOf( theInterface ) );
290 }
291 
292 bool QgsRasterPipe::canSetOn( int idx, bool on )
293 {
294  QgsDebugMsg( QString( "idx = %1 on = %2" ).arg( idx ).arg( on ) );
295  if ( !checkBounds( idx ) ) return false;
296 
297  // Because setting interface on/off may change its output we must check if
298  // connection is OK after such switch
299  bool onOrig = mInterfaces[idx]->on();
300 
301  if ( onOrig == on ) return true;
302 
303  mInterfaces[idx]->setOn( on );
304 
305  bool success = connect( mInterfaces );
306 
307  mInterfaces[idx]->setOn( onOrig );
308  connect( mInterfaces );
309  return success;
310 }
311 
312 bool QgsRasterPipe::setOn( int idx, bool on )
313 {
314  QgsDebugMsg( QString( "idx = %1 on = %2" ).arg( idx ).arg( on ) );
315  if ( !checkBounds( idx ) ) return false;
316 
317  bool onOrig = mInterfaces[idx]->on();
318 
319  if ( onOrig == on ) return true;
320 
321  mInterfaces[idx]->setOn( on );
322 
323  if ( connect( mInterfaces ) ) return true;
324 
325  mInterfaces[idx]->setOn( onOrig );
326  connect( mInterfaces );
327 
328  return false;
329 }
330 
331 bool QgsRasterPipe::checkBounds( int idx ) const
332 {
333  if ( idx < 0 || idx >= mInterfaces.size() ) return false;
334  return true;
335 }