CPLErr 
VRTSourcedRasterBand::ComputeStatistics( int bApproxOK,
                                   double *pdfMin, double *pdfMax, 
                                   double *pdfMean, double *pdfStdDev,
                                   GDALProgressFunc pfnProgress, 
                                   void *pProgressData )

{
    if( nSources != 1 )
        return GDALRasterBand::ComputeStatistics(  bApproxOK,  
                                              pdfMin, pdfMax, 
                                              pdfMean, pdfStdDev,
                                              pfnProgress, pProgressData );

    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

/* -------------------------------------------------------------------- */
/*      If we have overview bands, use them for statistics.             */
/* -------------------------------------------------------------------- */
    if( bApproxOK && GetOverviewCount() > 0 && !HasArbitraryOverviews() )
    {
        GDALRasterBand *poBand;

        poBand = GetRasterSampleOverview( GDALSTAT_APPROX_NUMSAMPLES );

        if( poBand != this )
            return poBand->ComputeStatistics( FALSE,  
                                              pdfMin, pdfMax, 
                                              pdfMean, pdfStdDev,
                                              pfnProgress, pProgressData );
    }

/* -------------------------------------------------------------------- */
/*      Try with source bands.                                          */
/* -------------------------------------------------------------------- */
    if ( bAntiRecursionFlag )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "VRTSourcedRasterBand::ComputeStatistics() called recursively on the same band. "
                  "It looks like the VRT is referencing itself." );
        return CE_Failure;
    }
    bAntiRecursionFlag = TRUE;
    
    double dfMin = 0.0, dfMax = 0.0, dfMean = 0.0, dfStdDev = 0.0;

    CPLErr eErr = papoSources[0]->ComputeStatistics(GetXSize(), GetYSize(), bApproxOK,  
                                                    &dfMin, &dfMax, 
                                                    &dfMean, &dfStdDev,
                                                    pfnProgress, pProgressData);
    if (eErr != CE_None)
    {
        eErr = GDALRasterBand::ComputeStatistics(bApproxOK,  
                                                 pdfMin, pdfMax, 
                                                 pdfMean, pdfStdDev,
                                                 pfnProgress, pProgressData);
        bAntiRecursionFlag = FALSE;
        return eErr;
    }

    bAntiRecursionFlag = FALSE;

    SetStatistics( dfMin, dfMax, dfMean, dfStdDev );

/* -------------------------------------------------------------------- */
/*      Record results.                                                 */
/* -------------------------------------------------------------------- */
    if( pdfMin != NULL )
        *pdfMin = dfMin;
    if( pdfMax != NULL )
        *pdfMax = dfMax;

    if( pdfMean != NULL )
        *pdfMean = dfMean;

    if( pdfStdDev != NULL )
        *pdfStdDev = dfStdDev;

    return CE_None;
}
bool wxGISGPCompStatTool::Execute(ITrackCancel* pTrackCancel)
{
    if(!Validate())
    {
        //add messages to pTrackCancel
        if(pTrackCancel)
            pTrackCancel->PutMessage(_("Unexpected error occurred"), -1, enumGISMessageErr);
        return false;
    }

    IGxObjectContainer* pGxObjectContainer = dynamic_cast<IGxObjectContainer*>(m_pCatalog);
    if(!pGxObjectContainer)
    {
        //add messages to pTrackCancel
        if(pTrackCancel)
            pTrackCancel->PutMessage(_("Error getting catalog object"), -1, enumGISMessageErr);
        return false;
    }

    wxString sSrcPath = m_paParam[0]->GetValue();
    IGxObject* pGxObject = pGxObjectContainer->SearchChild(sSrcPath);
    if(!pGxObject)
    {
        //add messages to pTrackCancel
        if(pTrackCancel)
            pTrackCancel->PutMessage(_("Error getting source object"), -1, enumGISMessageErr);
        return false;
    }
    IGxDataset* pGxDataset = dynamic_cast<IGxDataset*>(pGxObject);
    if(!pGxDataset)
    {
        //add messages to pTrackCancel
        if(pTrackCancel)
            pTrackCancel->PutMessage(_("Source object is of incompatible type"), -1, enumGISMessageErr);
        return false;
    }
    wxGISRasterDatasetSPtr pSrcDataSet = boost::dynamic_pointer_cast<wxGISRasterDataset>(pGxDataset->GetDataset());

    if(!pSrcDataSet)
    {
        //add messages to pTrackCancel
        if(pTrackCancel)
            pTrackCancel->PutMessage(_("Source dataset is of incompatible type"), -1, enumGISMessageErr);
        return false;
    }

	if(!pSrcDataSet->Open(false))
		return false;

    GDALDataset* poGDALDataset = pSrcDataSet->GetRaster();
    if(!poGDALDataset)
    {
        //add messages to pTrackCancel
        if(pTrackCancel)
            pTrackCancel->PutMessage(_("Error getting raster"), -1, enumGISMessageErr);
        return false;
    }

    bool bApproxOK = m_paParam[1]->GetValue();

    for(int nBand = 0; nBand < poGDALDataset->GetRasterCount(); nBand++ )
    {
        double      dfMin(0), dfMax(255), dfMean(127), dfStdDev(2);
        CPLErr      eErr;

        if(pTrackCancel)
            pTrackCancel->PutMessage(wxString::Format(_("Proceed band %d"), nBand + 1), -1, enumGISMessageInfo);
        GDALRasterBand* pBand = poGDALDataset->GetRasterBand(nBand + 1);
        eErr = pBand->ComputeStatistics(bApproxOK, &dfMin, &dfMax, &dfMean, &dfStdDev, ExecToolProgress, (void*)pTrackCancel);   
	    if(eErr != CE_None)
	    {
            if(pTrackCancel)
            {
                const char* pszErr = CPLGetLastErrorMsg();
				pTrackCancel->PutMessage(wxString::Format(_("ComputeStatistics failed! GDAL error: %s"), wxString(pszErr, wxConvUTF8).c_str()), -1, enumGISMessageErr);
            }
            return false;
        }
        pTrackCancel->PutMessage(wxString::Format(_("Band %d: min - %.2f, max - %.2f, mean - %.2f, StdDev - %.2f"), nBand + 1, dfMin, dfMax, dfMean, dfStdDev), -1, enumGISMessageNorm);
     //   eErr = pBand->SetStatistics(dfMin, dfMax, dfMean, dfStdDev);   
	    //if(eErr != CE_None)
	    //{
     //       if(pTrackCancel)
     //       {
     //           const char* pszErr = CPLGetLastErrorMsg();
     //           pTrackCancel->PutMessage(wxString::Format(_("ComputeStatistics failed! GDAL error: %s"), wgMB2WX(pszErr)), -1, enumGISMessageErr);
     //       }
     //       return false;
     //   }
    }
    //poGDALDataset->FlushCache();

    pSrcDataSet->SetHasStatistics(true);

    return true;
}