QGIS API Documentation  2.14.0-Essen
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  QgsDebugMsgLevel( QString( "cloned interface with role %1" ).arg( role ), 4 );
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  Q_FOREACH ( QgsRasterInterface* interface, mInterfaces )
53  {
54  delete interface;
55  }
56 }
57 
58 bool QgsRasterPipe::connect( QVector<QgsRasterInterface*> theInterfaces )
59 {
60  QgsDebugMsgLevel( "Entered", 4 );
61  for ( int i = 1; i < theInterfaces.size(); i++ )
62  {
63  if ( ! theInterfaces[i]->setInput( theInterfaces[i-1] ) )
64  {
65 #ifdef QGISDEBUG
66  const QgsRasterInterface &a = *theInterfaces[i];
67  const QgsRasterInterface &b = *theInterfaces[i-1];
68  QgsDebugMsg( QString( "cannot connect %1 to %2" ).arg( typeid( a ).name(), typeid( b ).name() ) );
69 #endif
70  return false;
71  }
72  }
73  return true;
74 }
75 
76 bool QgsRasterPipe::insert( int idx, QgsRasterInterface* theInterface )
77 {
78  QgsDebugMsgLevel( QString( "insert %1 at %2" ).arg( typeid( *theInterface ).name() ).arg( idx ), 4 );
79  if ( idx > mInterfaces.size() )
80  {
81  idx = mInterfaces.size();
82  }
83  // make a copy of pipe to test connection, we test the connections
84  // of the whole pipe, because the types and band numbers may change
85  QVector<QgsRasterInterface*> interfaces = mInterfaces;
86 
87  interfaces.insert( idx, theInterface );
88  bool success = false;
89  if ( connect( interfaces ) )
90  {
91  success = true;
92  mInterfaces.insert( idx, theInterface );
93  setRole( theInterface, idx );
94  QgsDebugMsgLevel( "inserted ok", 4 );
95  }
96 
97  // Connect or reconnect (after the test) interfaces
98  connect( mInterfaces );
99  return success;
100 }
101 
102 bool QgsRasterPipe::replace( int idx, QgsRasterInterface* theInterface )
103 {
104  if ( !theInterface ) return false;
105 
106  QgsDebugMsgLevel( QString( "replace by %1 at %2" ).arg( typeid( *theInterface ).name() ).arg( idx ), 4 );
107  if ( !checkBounds( idx ) ) return false;
108 
109  // make a copy of pipe to test connection, we test the connections
110  // of the whole pipe, because the types and band numbers may change
111  QVector<QgsRasterInterface*> interfaces = mInterfaces;
112 
113  interfaces[idx] = theInterface;
114  bool success = false;
115  if ( connect( interfaces ) )
116  {
117  success = true;
118  delete mInterfaces.at( idx );
119  mInterfaces[idx] = theInterface;
120  setRole( theInterface, idx );
121  QgsDebugMsgLevel( "replaced ok", 4 );
122  }
123 
124  // Connect or reconnect (after the test) interfaces
125  connect( mInterfaces );
126  return success;
127 }
128 
129 QgsRasterPipe::Role QgsRasterPipe::interfaceRole( QgsRasterInterface * interface ) const
130 {
131  Role role = UnknownRole;
132  if ( dynamic_cast<QgsRasterDataProvider *>( interface ) ) role = ProviderRole;
133  else if ( dynamic_cast<QgsRasterRenderer *>( interface ) ) role = RendererRole;
134  else if ( dynamic_cast<QgsRasterResampleFilter *>( interface ) ) role = ResamplerRole;
135  else if ( dynamic_cast<QgsBrightnessContrastFilter *>( interface ) ) role = BrightnessRole;
136  else if ( dynamic_cast<QgsHueSaturationFilter *>( interface ) ) role = HueSaturationRole;
137  else if ( dynamic_cast<QgsRasterProjector *>( interface ) ) role = ProjectorRole;
138  else if ( dynamic_cast<QgsRasterNuller *>( interface ) ) role = NullerRole;
139 
140  QgsDebugMsgLevel( QString( "%1 role = %2" ).arg( typeid( *interface ).name() ).arg( role ), 4 );
141  return role;
142 }
143 
144 void QgsRasterPipe::setRole( QgsRasterInterface * theInterface, int idx )
145 {
146  Role role = interfaceRole( theInterface );
147  if ( role == UnknownRole ) return;
148  mRoleMap.insert( role, idx );
149 }
150 
151 void QgsRasterPipe::unsetRole( QgsRasterInterface * theInterface )
152 {
153  Role role = interfaceRole( theInterface );
154  if ( role == UnknownRole ) return;
155  mRoleMap.remove( role );
156 }
157 
159 {
160  if ( !theInterface ) return false;
161 
162  QgsDebugMsgLevel( QString( "%1" ).arg( typeid( *theInterface ).name() ), 4 );
163  Role role = interfaceRole( theInterface );
164 
165  // We don't know where to place unknown interface
166  if ( role == UnknownRole ) return false;
167 
168  //if ( mInterfacesMap.value ( role ) )
169  if ( mRoleMap.contains( role ) )
170  {
171  // An old interface of the same role exists -> replace
172  // replace may still fail and return false
173  return replace( mRoleMap.value( role ), theInterface );
174  }
175 
176  int idx = 0;
177 
178  // Not found, find the best default position for this kind of interface
179  // QgsRasterDataProvider - ProviderRole
180  // QgsRasterRenderer - RendererRole
181  // QgsRasterResampler - ResamplerRole
182  // QgsRasterProjector - ProjectorRole
183 
184  int providerIdx = mRoleMap.value( ProviderRole, -1 );
185  int rendererIdx = mRoleMap.value( RendererRole, -1 );
186  int resamplerIdx = mRoleMap.value( ResamplerRole, -1 );
187  int brightnessIdx = mRoleMap.value( BrightnessRole, -1 );
188  int hueSaturationIdx = mRoleMap.value( HueSaturationRole, -1 );
189 
190  if ( role == ProviderRole )
191  {
192  idx = 0;
193  }
194  else if ( role == RendererRole )
195  {
196  idx = providerIdx + 1;
197  }
198  else if ( role == BrightnessRole )
199  {
200  idx = qMax( providerIdx, rendererIdx ) + 1;
201  }
202  else if ( role == HueSaturationRole )
203  {
204  idx = qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ) + 1;
205  }
206  else if ( role == ResamplerRole )
207  {
208  idx = qMax( qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ) + 1;
209  }
210  else if ( role == ProjectorRole )
211  {
212  idx = qMax( qMax( qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ), resamplerIdx ) + 1;
213  }
214 
215  return insert( idx, theInterface ); // insert may still fail and return false
216 }
217 
218 QgsRasterInterface * QgsRasterPipe::interface( Role role ) const
219  {
220  QgsDebugMsgLevel( QString( "role = %1" ).arg( role ), 4 );
221  if ( mRoleMap.contains( role ) )
222  {
223  return mInterfaces.value( mRoleMap.value( role ) );
224  }
225  return nullptr;
226  }
227 
229 {
230  return dynamic_cast<QgsRasterDataProvider *>( interface( ProviderRole ) );
231 }
232 
234 {
235  return dynamic_cast<QgsRasterRenderer *>( interface( RendererRole ) );
236 }
237 
239 {
240  return dynamic_cast<QgsRasterResampleFilter *>( interface( ResamplerRole ) );
241 }
242 
244 {
245  return dynamic_cast<QgsBrightnessContrastFilter *>( interface( BrightnessRole ) );
246 }
247 
249 {
250  return dynamic_cast<QgsHueSaturationFilter *>( interface( HueSaturationRole ) );
251 }
252 
254 {
255  return dynamic_cast<QgsRasterProjector*>( interface( ProjectorRole ) );
256 }
257 
259 {
260  return dynamic_cast<QgsRasterNuller*>( interface( NullerRole ) );
261 }
262 
263 bool QgsRasterPipe::remove( int idx )
264 {
265  QgsDebugMsgLevel( QString( "remove at %1" ).arg( idx ), 4 );
266 
267  if ( !checkBounds( idx ) ) return false;
268 
269  // make a copy of pipe to test connection, we test the connections
270  // of the whole pipe, because the types and band numbers may change
271  QVector<QgsRasterInterface*> interfaces = mInterfaces;
272 
273  interfaces.remove( idx );
274  bool success = false;
275  if ( connect( interfaces ) )
276  {
277  success = true;
278  unsetRole( mInterfaces.at( idx ) );
279  delete mInterfaces.at( idx );
280  mInterfaces.remove( idx );
281  QgsDebugMsgLevel( "removed ok", 4 );
282  }
283 
284  // Connect or reconnect (after the test) interfaces
285  connect( mInterfaces );
286  return success;
287 }
288 
290 {
291  if ( !theInterface ) return false;
292 
293  return remove( mInterfaces.indexOf( theInterface ) );
294 }
295 
296 bool QgsRasterPipe::canSetOn( int idx, bool on )
297 {
298  QgsDebugMsgLevel( QString( "idx = %1 on = %2" ).arg( idx ).arg( on ), 4 );
299  if ( !checkBounds( idx ) ) return false;
300 
301  // Because setting interface on/off may change its output we must check if
302  // connection is OK after such switch
303  bool onOrig = mInterfaces.at( idx )->on();
304 
305  if ( onOrig == on ) return true;
306 
307  mInterfaces.at( idx )->setOn( on );
308 
309  bool success = connect( mInterfaces );
310 
311  mInterfaces.at( idx )->setOn( onOrig );
312  connect( mInterfaces );
313  return success;
314 }
315 
316 bool QgsRasterPipe::setOn( int idx, bool on )
317 {
318  QgsDebugMsgLevel( QString( "idx = %1 on = %2" ).arg( idx ).arg( on ), 4 );
319  if ( !checkBounds( idx ) ) return false;
320 
321  bool onOrig = mInterfaces.at( idx )->on();
322 
323  if ( onOrig == on ) return true;
324 
325  mInterfaces.at( idx )->setOn( on );
326 
327  if ( connect( mInterfaces ) ) return true;
328 
329  mInterfaces.at( idx )->setOn( onOrig );
330  connect( mInterfaces );
331 
332  return false;
333 }
334 
335 bool QgsRasterPipe::checkBounds( int idx ) const
336 {
337  if ( idx < 0 || idx >= mInterfaces.size() ) return false;
338  return true;
339 }
Base class for processing modules.
Definition: qgsrasterpipe.h:41
QgsRasterNuller * nuller() const
bool contains(const Key &key) const
void append(const T &value)
QgsBrightnessContrastFilter * brightnessFilter() const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
int indexOf(const T &value, int from) const
Raster pipe that deals with null values.
void insert(int i, const T &value)
Resample filter pipe for rasters.
int size() const
Definition: qgsrasterpipe.h:84
T value(int i) const
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
void remove(int i)
QgsRasterDataProvider * provider() const
QgsRasterProjector * projector() const
Base class for processing filters like renderers, reprojector, resampler etc.
bool canSetOn(int idx, bool on)
Test if interface at index may be swithed on/off.
const T & at(int i) const
bool remove(int idx)
Remove and delete interface at given index if possible.
bool setOn(int idx, bool on)
Set interface at index on/off Returns true on success.
virtual QgsRasterInterface * clone() const =0
Clone itself, create deep copy.
Brightness/contrast filter pipe for rasters.
Color and saturation filter pipe for rasters.
bool insert(int idx, QgsRasterInterface *theInterface)
Try to insert interface at specified index and connect if connection would fail, the interface is not...
iterator insert(const Key &key, const T &value)
QgsHueSaturationFilter * hueSaturationFilter() const
bool replace(int idx, QgsRasterInterface *theInterface)
Try to replace interface at specified index and connect if connection would fail, the interface is no...
int size() const
QgsRasterRenderer * renderer() const
bool set(QgsRasterInterface *theInterface)
Insert a new known interface in default place or replace interface of the same role if it already exi...
QgsRasterResampleFilter * resampleFilter() const
Raster renderer pipe that applies colors to a raster.
const T value(const Key &key) const
Base class for raster data providers.
int remove(const Key &key)