QGIS API Documentation  master-59fd5e0
src/core/raster/qgsrasterpipe.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsrasterpipe.cpp - Internal raster processing modules interface
00003      --------------------------------------
00004     Date                 : Jun 21, 2012
00005     Copyright            : (C) 2012 by Radim Blazek
00006     email                : radim dot blazek at gmail dot com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <typeinfo>
00019 
00020 #include <QByteArray>
00021 
00022 #include "qgslogger.h"
00023 #include "qgsrasterpipe.h"
00024 
00025 QgsRasterPipe::QgsRasterPipe()
00026 {
00027 }
00028 
00029 QgsRasterPipe::QgsRasterPipe( const QgsRasterPipe& thePipe )
00030 {
00031   for ( int i = 0; i < thePipe.size(); i++ )
00032   {
00033     QgsRasterInterface* interface = thePipe.at( i );
00034     QgsRasterInterface* clone = interface->clone();
00035 
00036     Role role = interfaceRole( clone );
00037     QgsDebugMsg( QString( "cloned inerface with role %1" ).arg( role ) );
00038     if ( i > 0 )
00039     {
00040       clone->setInput( mInterfaces.at( i - 1 ) );
00041     }
00042     mInterfaces.append( clone );
00043     if ( role != UnknownRole )
00044     {
00045       mRoleMap.insert( role, i );
00046     }
00047   }
00048 }
00049 
00050 QgsRasterPipe::~QgsRasterPipe()
00051 {
00052   foreach ( QgsRasterInterface* interface, mInterfaces )
00053   {
00054     delete interface;
00055   }
00056 }
00057 
00058 bool QgsRasterPipe::connect( QVector<QgsRasterInterface*> theInterfaces )
00059 {
00060   QgsDebugMsg( "Entered" );
00061   for ( int i = 1; i < theInterfaces.size(); i++ )
00062   {
00063     if ( ! theInterfaces[i]->setInput( theInterfaces[i-1] ) )
00064     {
00065       QgsDebugMsg( QString( "cannot connect %1 to %2" ).arg( typeid( *( theInterfaces[i] ) ).name() ).arg( typeid( *( theInterfaces[i-1] ) ).name() ) );
00066       return false;
00067     }
00068   }
00069   return true;
00070 }
00071 
00072 bool QgsRasterPipe::insert( int idx, QgsRasterInterface* theInterface )
00073 {
00074   QgsDebugMsg( QString( "insert %1 at %2" ).arg( typeid( *theInterface ).name() ).arg( idx ) );
00075   if ( idx > mInterfaces.size() )
00076   {
00077     idx = mInterfaces.size();
00078   }
00079   // make a copy of pipe to test connection, we test the connections
00080   // of the whole pipe, because the types and band numbers may change
00081   QVector<QgsRasterInterface*> interfaces = mInterfaces;
00082 
00083   interfaces.insert( idx, theInterface );
00084   bool success = false;
00085   if ( connect( interfaces ) )
00086   {
00087     success = true;
00088     mInterfaces.insert( idx, theInterface );
00089     setRole( theInterface, idx );
00090     QgsDebugMsg( "inserted ok" );
00091   }
00092 
00093   // Connect or reconnect (after the test) interfaces
00094   connect( mInterfaces );
00095   return success;
00096 }
00097 
00098 bool QgsRasterPipe::replace( int idx, QgsRasterInterface* theInterface )
00099 {
00100   QgsDebugMsg( QString( "replace by %1 at %2" ).arg( typeid( *theInterface ).name() ).arg( idx ) );
00101   if ( !checkBounds( idx ) ) return false;
00102   if ( !theInterface ) return false;
00103 
00104   // make a copy of pipe to test connection, we test the connections
00105   // of the whole pipe, because the types and band numbers may change
00106   QVector<QgsRasterInterface*> interfaces = mInterfaces;
00107 
00108   interfaces[idx] = theInterface;
00109   bool success = false;
00110   if ( connect( interfaces ) )
00111   {
00112     success = true;
00113     delete mInterfaces[idx];
00114     mInterfaces[idx] = theInterface;
00115     setRole( theInterface, idx );
00116     QgsDebugMsg( "replaced ok" );
00117   }
00118 
00119   // Connect or reconnect (after the test) interfaces
00120   connect( mInterfaces );
00121   return success;
00122 }
00123 
00124 QgsRasterPipe::Role QgsRasterPipe::interfaceRole( QgsRasterInterface * interface ) const
00125 {
00126   Role role = UnknownRole;
00127   if ( dynamic_cast<QgsRasterDataProvider *>( interface ) ) role = ProviderRole;
00128   else if ( dynamic_cast<QgsRasterRenderer *>( interface ) ) role = RendererRole;
00129   else if ( dynamic_cast<QgsRasterResampleFilter *>( interface ) ) role = ResamplerRole;
00130   else if ( dynamic_cast<QgsBrightnessContrastFilter *>( interface ) ) role = BrightnessRole;
00131   else if ( dynamic_cast<QgsHueSaturationFilter *>( interface ) ) role = HueSaturationRole;
00132   else if ( dynamic_cast<QgsRasterProjector *>( interface ) ) role = ProjectorRole;
00133   else if ( dynamic_cast<QgsRasterNuller *>( interface ) ) role = NullerRole;
00134 
00135   QgsDebugMsg( QString( "%1 role = %2" ).arg( typeid( *interface ).name() ).arg( role ) );
00136   return role;
00137 }
00138 
00139 void QgsRasterPipe::setRole( QgsRasterInterface * theInterface, int idx )
00140 {
00141   Role role = interfaceRole( theInterface );
00142   if ( role == UnknownRole ) return;
00143   mRoleMap.insert( role, idx );
00144 }
00145 
00146 void QgsRasterPipe::unsetRole( QgsRasterInterface * theInterface )
00147 {
00148   Role role = interfaceRole( theInterface );
00149   if ( role == UnknownRole ) return;
00150   mRoleMap.remove( role );
00151 }
00152 
00153 bool QgsRasterPipe::set( QgsRasterInterface* theInterface )
00154 {
00155   QgsDebugMsg( QString( "%1" ).arg( typeid( *theInterface ).name() ) );
00156 
00157   if ( !theInterface ) return false;
00158 
00159   Role role = interfaceRole( theInterface );
00160 
00161   // We don't know where to place unknown interface
00162   if ( role == UnknownRole ) return false;
00163 
00164   //if ( mInterfacesMap.value ( role ) )
00165   if ( mRoleMap.contains( role ) )
00166   {
00167     // An old interface of the same role exists -> replace
00168     // replace may still fail and return false
00169     return replace( mRoleMap.value( role ), theInterface );
00170   }
00171 
00172   int idx = 0;
00173 
00174   // Not found, find the best default position for this kind of interface
00175   //   QgsRasterDataProvider  - ProviderRole
00176   //   QgsRasterRenderer      - RendererRole
00177   //   QgsRasterResampler     - ResamplerRole
00178   //   QgsRasterProjector     - ProjectorRole
00179 
00180   int providerIdx = mRoleMap.value( ProviderRole, -1 );
00181   int rendererIdx = mRoleMap.value( RendererRole, -1 );
00182   int resamplerIdx = mRoleMap.value( ResamplerRole, -1 );
00183   int brightnessIdx = mRoleMap.value( BrightnessRole, -1 );
00184   int hueSaturationIdx = mRoleMap.value( HueSaturationRole, -1 );
00185 
00186   if ( role == ProviderRole )
00187   {
00188     idx = 0;
00189   }
00190   else if ( role == RendererRole )
00191   {
00192     idx =  providerIdx + 1;
00193   }
00194   else if ( role == BrightnessRole )
00195   {
00196     idx =  qMax( providerIdx, rendererIdx ) + 1;
00197   }
00198   else if ( role == HueSaturationRole )
00199   {
00200     idx =  qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ) + 1;
00201   }
00202   else if ( role == ResamplerRole )
00203   {
00204     idx = qMax( qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ) + 1;
00205   }
00206   else if ( role == ProjectorRole )
00207   {
00208     idx = qMax( qMax( qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ), resamplerIdx )  + 1;
00209   }
00210 
00211   return insert( idx, theInterface );  // insert may still fail and return false
00212 }
00213 
00214 QgsRasterInterface * QgsRasterPipe::interface( Role role ) const
00215   {
00216     QgsDebugMsg( QString( "role = %1" ).arg( role ) );
00217     if ( mRoleMap.contains( role ) )
00218     {
00219       return mInterfaces.value( mRoleMap.value( role ) );
00220     }
00221     return 0;
00222   }
00223 
00224 QgsRasterDataProvider * QgsRasterPipe::provider() const
00225 {
00226   return dynamic_cast<QgsRasterDataProvider *>( interface( ProviderRole ) );
00227 }
00228 
00229 QgsRasterRenderer * QgsRasterPipe::renderer() const
00230 {
00231   return dynamic_cast<QgsRasterRenderer *>( interface( RendererRole ) );
00232 }
00233 
00234 QgsRasterResampleFilter * QgsRasterPipe::resampleFilter() const
00235 {
00236   return dynamic_cast<QgsRasterResampleFilter *>( interface( ResamplerRole ) );
00237 }
00238 
00239 QgsBrightnessContrastFilter * QgsRasterPipe::brightnessFilter() const
00240 {
00241   return dynamic_cast<QgsBrightnessContrastFilter *>( interface( BrightnessRole ) );
00242 }
00243 
00244 QgsHueSaturationFilter * QgsRasterPipe::hueSaturationFilter() const
00245 {
00246   return dynamic_cast<QgsHueSaturationFilter *>( interface( HueSaturationRole ) );
00247 }
00248 
00249 QgsRasterProjector * QgsRasterPipe::projector() const
00250 {
00251   return dynamic_cast<QgsRasterProjector*>( interface( ProjectorRole ) );
00252 }
00253 
00254 QgsRasterNuller * QgsRasterPipe::nuller() const
00255 {
00256   return dynamic_cast<QgsRasterNuller*>( interface( NullerRole ) );
00257 }
00258 
00259 bool QgsRasterPipe::remove( int idx )
00260 {
00261   QgsDebugMsg( QString( "remove at %1" ).arg( idx ) );
00262 
00263   if ( !checkBounds( idx ) ) return false;
00264 
00265   // make a copy of pipe to test connection, we test the connections
00266   // of the whole pipe, because the types and band numbers may change
00267   QVector<QgsRasterInterface*> interfaces = mInterfaces;
00268 
00269   interfaces.remove( idx );
00270   bool success = false;
00271   if ( connect( interfaces ) )
00272   {
00273     success = true;
00274     unsetRole( mInterfaces[idx] );
00275     delete mInterfaces[idx];
00276     mInterfaces.remove( idx );
00277     QgsDebugMsg( "removed ok" );
00278   }
00279 
00280   // Connect or reconnect (after the test) interfaces
00281   connect( mInterfaces );
00282   return success;
00283 }
00284 
00285 bool QgsRasterPipe::remove( QgsRasterInterface * theInterface )
00286 {
00287   if ( !theInterface ) return false;
00288 
00289   return remove( mInterfaces.indexOf( theInterface ) );
00290 }
00291 
00292 bool QgsRasterPipe::canSetOn( int idx, bool on )
00293 {
00294   QgsDebugMsg( QString( "idx = %1 on = %2" ).arg( idx ).arg( on ) );
00295   if ( !checkBounds( idx ) ) return false;
00296 
00297   // Because setting interface on/off may change its output we must check if
00298   // connection is OK after such switch
00299   bool onOrig =  mInterfaces[idx]->on();
00300 
00301   if ( onOrig == on ) return true;
00302 
00303   mInterfaces[idx]->setOn( on );
00304 
00305   bool success = connect( mInterfaces );
00306 
00307   mInterfaces[idx]->setOn( onOrig );
00308   connect( mInterfaces );
00309   return success;
00310 }
00311 
00312 bool QgsRasterPipe::setOn( int idx, bool on )
00313 {
00314   QgsDebugMsg( QString( "idx = %1 on = %2" ).arg( idx ).arg( on ) );
00315   if ( !checkBounds( idx ) ) return false;
00316 
00317   bool onOrig =  mInterfaces[idx]->on();
00318 
00319   if ( onOrig == on ) return true;
00320 
00321   mInterfaces[idx]->setOn( on );
00322 
00323   if ( connect( mInterfaces ) ) return true;
00324 
00325   mInterfaces[idx]->setOn( onOrig );
00326   connect( mInterfaces );
00327 
00328   return false;
00329 }
00330 
00331 bool QgsRasterPipe::checkBounds( int idx ) const
00332 {
00333   if ( idx < 0 || idx >= mInterfaces.size() ) return false;
00334   return true;
00335 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines