Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

gdal_misc.cpp

00001 /******************************************************************************
00002  * $Id: gdal_misc_cpp-source.html,v 1.10 2002/04/16 13:11:48 warmerda Exp $
00003  *
00004  * Project:  GDAL Core
00005  * Purpose:  Free standing functions for GDAL.
00006  * Author:   Frank Warmerdam, warmerda@home.com
00007  *
00008  ******************************************************************************
00009  * Copyright (c) 1999, Frank Warmerdam
00010  *
00011  * Permission is hereby granted, free of charge, to any person obtaining a
00012  * copy of this software and associated documentation files (the "Software"),
00013  * to deal in the Software without restriction, including without limitation
00014  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00015  * and/or sell copies of the Software, and to permit persons to whom the
00016  * Software is furnished to do so, subject to the following conditions:
00017  *
00018  * The above copyright notice and this permission notice shall be included
00019  * in all copies or substantial portions of the Software.
00020  *
00021  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00022  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00023  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00024  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00025  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00026  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00027  * DEALINGS IN THE SOFTWARE.
00028  ******************************************************************************
00029  *
00030  * $Log: gdal_misc_cpp-source.html,v $
00030  * Revision 1.10  2002/04/16 13:11:48  warmerda
00030  * updated
00030  *
00031  * Revision 1.29  2001/12/07 20:04:21  warmerda
00032  * fixed serious bug in random sampler
00033  *
00034  * Revision 1.28  2001/11/30 03:41:26  warmerda
00035  * Fixed bug with the block sampling rate being too low to satisfy large
00036  * sample count values.  Fixed bug with tiled images including some uninitialized
00037  * or zero data in the sample set on partial edge tiles.
00038  *
00039  * Revision 1.27  2001/11/26 20:14:01  warmerda
00040  * added GDALProjDef stubs for old 'bridges'
00041  *
00042  * Revision 1.26  2001/11/19 16:03:16  warmerda
00043  * moved GDALDectoDMS here
00044  *
00045  * Revision 1.25  2001/08/15 15:05:44  warmerda
00046  * return magnitude for complex samples in random sampler
00047  *
00048  * Revision 1.24  2001/07/18 04:04:30  warmerda
00049  * added CPL_CVSID
00050  *
00051  * Revision 1.23  2001/05/01 18:09:25  warmerda
00052  * added GDALReadWorldFile()
00053  *
00054  * Revision 1.22  2000/12/04 20:45:14  warmerda
00055  * removed unused variable.
00056  *
00057  * Revision 1.21  2000/10/06 15:22:49  warmerda
00058  * added GDALDataTypeUnion
00059  *
00060  * Revision 1.20  2000/08/18 15:24:48  warmerda
00061  * added GDALTermProgress
00062  *
00063  * Revision 1.19  2000/08/09 16:25:42  warmerda
00064  * don't crash if block is null
00065  *
00066  * Revision 1.18  2000/07/11 14:35:43  warmerda
00067  * added documentation
00068  *
00069  * Revision 1.17  2000/07/05 17:53:33  warmerda
00070  * Removed unused code related to nXCheck.
00071  *
00072  * Revision 1.16  2000/06/27 17:21:26  warmerda
00073  * added GDALGetRasterSampleOverview
00074  *
00075  * Revision 1.15  2000/06/26 22:17:49  warmerda
00076  * added scaled progress support
00077  *
00078  * Revision 1.14  2000/06/05 17:24:05  warmerda
00079  * added real complex support
00080  *
00081  * Revision 1.13  2000/04/21 21:55:32  warmerda
00082  * made more robust if block read fails
00083  *
00084  * Revision 1.12  2000/04/17 20:59:40  warmerda
00085  * Removed printf.
00086  *
00087  * Revision 1.11  2000/04/17 20:59:14  warmerda
00088  * fixed sampling bug
00089  *
00090  * Revision 1.10  2000/03/31 13:41:45  warmerda
00091  * added gcp support functions
00092  *
00093  * Revision 1.9  2000/03/24 00:09:19  warmerda
00094  * added sort-of random sampling
00095  *
00096  * Revision 1.8  2000/03/23 16:53:21  warmerda
00097  * use overviews for approximate min/max
00098  *
00099  * Revision 1.7  2000/03/09 23:21:44  warmerda
00100  * added GDALDummyProgress
00101  *
00102  * Revision 1.6  2000/03/06 21:59:44  warmerda
00103  * added min/max calculate
00104  *
00105  * Revision 1.5  2000/03/06 02:20:15  warmerda
00106  * added getname functions for colour interpretations
00107  *
00108  * Revision 1.4  1999/07/23 19:35:47  warmerda
00109  * added GDALGetDataTypeName
00110  *
00111  * Revision 1.3  1999/05/17 02:00:45  vgough
00112  * made pure_virtual C linkage
00113  *
00114  * Revision 1.2  1999/05/16 19:32:13  warmerda
00115  * Added __pure_virtual.
00116  *
00117  * Revision 1.1  1998/12/06 02:50:16  warmerda
00118  * New
00119  *
00120  */
00121 
00122 #include "gdal_priv.h"
00123 #include "cpl_string.h"
00124 
00125 CPL_CVSID("$Id: gdal_misc_cpp-source.html,v 1.10 2002/04/16 13:11:48 warmerda Exp $");
00126 
00127 /************************************************************************/
00128 /*                           __pure_virtual()                           */
00129 /*                                                                      */
00130 /*      The following is a gross hack to remove the last remaining      */
00131 /*      dependency on the GNU C++ standard library.                     */
00132 /************************************************************************/
00133 
00134 #ifdef __GNUC__
00135 
00136 extern "C"
00137 void __pure_virtual()
00138 
00139 {
00140 }
00141 
00142 #endif
00143 
00144 /************************************************************************/
00145 /*                         GDALDataTypeUnion()                          */
00146 /************************************************************************/
00147 
00158 GDALDataType GDALDataTypeUnion( GDALDataType eType1, GDALDataType eType2 )
00159 
00160 {
00161     int         bFloating, bComplex, nBits, bSigned;
00162 
00163     bComplex = GDALDataTypeIsComplex(eType1) | GDALDataTypeIsComplex(eType2);
00164     
00165     switch( eType1 )
00166     {
00167       case GDT_Byte:
00168         nBits = 8;
00169         bSigned = FALSE;
00170         bFloating = FALSE;
00171         break;
00172         
00173       case GDT_Int16:
00174       case GDT_CInt16:
00175         nBits = 16;
00176         bSigned = TRUE;
00177         bFloating = FALSE;
00178         break;
00179         
00180       case GDT_UInt16:
00181         nBits = 16;
00182         bSigned = FALSE;
00183         bFloating = FALSE;
00184         break;
00185         
00186       case GDT_Int32:
00187       case GDT_CInt32:
00188         nBits = 32;
00189         bSigned = TRUE;
00190         bFloating = FALSE;
00191         break;
00192         
00193       case GDT_UInt32:
00194         nBits = 32;
00195         bSigned = FALSE;
00196         bFloating = FALSE;
00197         break;
00198 
00199       case GDT_Float32:
00200       case GDT_CFloat32:
00201         nBits = 32;
00202         bSigned = TRUE;
00203         bFloating = TRUE;
00204         break;
00205 
00206       case GDT_Float64:
00207       case GDT_CFloat64:
00208         nBits = 64;
00209         bSigned = TRUE;
00210         bFloating = TRUE;
00211         break;
00212 
00213       default:
00214         CPLAssert( FALSE );
00215         return GDT_Unknown;
00216     }
00217 
00218     switch( eType2 )
00219     {
00220       case GDT_Byte:
00221         break;
00222         
00223       case GDT_Int16:
00224         nBits = MAX(nBits,16);
00225         bSigned = TRUE;
00226         break;
00227         
00228       case GDT_UInt16:
00229         nBits = MAX(nBits,16);
00230         break;
00231         
00232       case GDT_Int32:
00233       case GDT_CInt32:
00234         nBits = MAX(nBits,32);
00235         bSigned = TRUE;
00236         break;
00237         
00238       case GDT_UInt32:
00239         nBits = MAX(nBits,32);
00240         break;
00241 
00242       case GDT_Float32:
00243       case GDT_CFloat32:
00244         nBits = MAX(nBits,32);
00245         bSigned = TRUE;
00246         bFloating = TRUE;
00247         break;
00248 
00249       case GDT_Float64:
00250       case GDT_CFloat64:
00251         nBits = MAX(nBits,64);
00252         bSigned = TRUE;
00253         bFloating = TRUE;
00254         break;
00255 
00256       default:
00257         CPLAssert( FALSE );
00258         return GDT_Unknown;
00259     }
00260 
00261     if( nBits == 8 )
00262         return GDT_Byte;
00263     else if( nBits == 16 && bComplex )
00264         return GDT_CInt16;
00265     else if( nBits == 16 && bSigned )
00266         return GDT_Int16;
00267     else if( nBits == 16 && !bSigned )
00268         return GDT_UInt16;
00269     else if( nBits == 32 && bFloating && bComplex )
00270         return GDT_CFloat32;
00271     else if( nBits == 32 && bFloating )
00272         return GDT_Float32;
00273     else if( nBits == 32 && bComplex )
00274         return GDT_CInt32;
00275     else if( nBits == 32 && bSigned )
00276         return GDT_Int32;
00277     else if( nBits == 32 && !bSigned )
00278         return GDT_UInt32;
00279     else if( nBits == 64 && bComplex )
00280         return GDT_CFloat64;
00281     else
00282         return GDT_Float64;
00283 }
00284 
00285 
00286 /************************************************************************/
00287 /*                        GDALGetDataTypeSize()                         */
00288 /************************************************************************/
00289 int GDALGetDataTypeSize( GDALDataType eDataType )
00290 
00291 {
00292     switch( eDataType )
00293     {
00294       case GDT_Byte:
00295         return 8;
00296 
00297       case GDT_UInt16:
00298       case GDT_Int16:
00299         return 16;
00300 
00301       case GDT_UInt32:
00302       case GDT_Int32:
00303       case GDT_Float32:
00304       case GDT_CInt16:
00305         return 32;
00306 
00307       case GDT_Float64:
00308       case GDT_CInt32:
00309       case GDT_CFloat32:
00310         return 64;
00311 
00312       case GDT_CFloat64:
00313         return 128;
00314 
00315       default:
00316         CPLAssert( FALSE );
00317         return 0;
00318     }
00319 }
00320 
00321 /************************************************************************/
00322 /*                       GDALDataTypeIsComplex()                        */
00323 /************************************************************************/
00324 
00325 int GDALDataTypeIsComplex( GDALDataType eDataType )
00326 
00327 {
00328     switch( eDataType )
00329     {
00330       case GDT_CInt16:
00331       case GDT_CInt32:
00332       case GDT_CFloat32:
00333       case GDT_CFloat64:
00334         return TRUE;
00335 
00336       default:
00337         return FALSE;
00338     }
00339 }
00340 
00341 /************************************************************************/
00342 /*                        GDALGetDataTypeName()                         */
00343 /************************************************************************/
00344 
00345 const char *GDALGetDataTypeName( GDALDataType eDataType )
00346 
00347 {
00348     switch( eDataType )
00349     {
00350       case GDT_Byte:
00351         return "Byte";
00352 
00353       case GDT_UInt16:
00354         return "UInt16";
00355 
00356       case GDT_Int16:
00357         return "Int16";
00358 
00359       case GDT_UInt32:
00360         return "UInt32";
00361         
00362       case GDT_Int32:
00363         return "Int32";
00364         
00365       case GDT_Float32:
00366         return "Float32";
00367 
00368       case GDT_Float64:
00369         return "Float64";
00370 
00371       case GDT_CInt16:
00372         return "CInt16";
00373 
00374       case GDT_CInt32:
00375         return "CInt32";
00376 
00377       case GDT_CFloat32:
00378         return "CFloat32";
00379 
00380       case GDT_CFloat64:
00381         return "CFloat64";
00382 
00383       default:
00384         return NULL;
00385     }
00386 }
00387 
00388 /************************************************************************/
00389 /*                  GDALGetPaletteInterpretationName()                  */
00390 /************************************************************************/
00391 
00392 const char *GDALGetPaletteInterpretationName( GDALPaletteInterp eInterp )
00393 
00394 {
00395     switch( eInterp )
00396     {
00397       case GPI_Gray:
00398         return "Gray";
00399 
00400       case GPI_RGB:
00401         return "RGB";
00402         
00403       case GPI_CMYK:
00404         return "CMYK";
00405 
00406       case GPI_HLS:
00407         return "HLS";
00408         
00409       default:
00410         return "Unknown";
00411     }
00412 }
00413 
00414 /************************************************************************/
00415 /*                   GDALGetColorInterpretationName()                   */
00416 /************************************************************************/
00417 
00418 const char *GDALGetColorInterpretationName( GDALColorInterp eInterp )
00419 
00420 {
00421     switch( eInterp )
00422     {
00423       case GCI_Undefined:
00424         return "Undefined";
00425 
00426       case GCI_GrayIndex:
00427         return "Gray";
00428 
00429       case GCI_PaletteIndex:
00430         return "Palette";
00431 
00432       case GCI_RedBand:
00433         return "Red";
00434 
00435       case GCI_GreenBand:
00436         return "Green";
00437 
00438       case GCI_BlueBand:
00439         return "Blue";
00440 
00441       case GCI_AlphaBand:
00442         return "Alpha";
00443 
00444       case GCI_HueBand:
00445         return "Hue";
00446 
00447       case GCI_SaturationBand:
00448         return "Saturation";
00449 
00450       case GCI_LightnessBand:
00451         return "Lightness";
00452 
00453       case GCI_CyanBand:
00454         return "Cyan";
00455 
00456       case GCI_MagentaBand:
00457         return "Magenta";
00458 
00459       case GCI_YellowBand:
00460         return "Yellow";
00461 
00462       case GCI_BlackBand:
00463         return "Black";
00464         
00465       default:
00466         return "Unknown";
00467     }
00468 }
00469 
00470 /************************************************************************/
00471 /*                      GDALComputeRasterMinMax()                       */
00472 /************************************************************************/
00473 
00492 void GDALComputeRasterMinMax( GDALRasterBandH hBand, int bApproxOK, 
00493                               double adfMinMax[2] )
00494 
00495 {
00496     double       dfMin=0.0, dfMax=0.0;
00497     GDALRasterBand *poBand;
00498 
00499 /* -------------------------------------------------------------------- */
00500 /*      Does the driver already know the min/max?                       */
00501 /* -------------------------------------------------------------------- */
00502     if( bApproxOK )
00503     {
00504         int          bSuccessMin, bSuccessMax;
00505 
00506         dfMin = GDALGetRasterMinimum( hBand, &bSuccessMin );
00507         dfMax = GDALGetRasterMaximum( hBand, &bSuccessMax );
00508 
00509         if( bSuccessMin && bSuccessMax )
00510         {
00511             adfMinMax[0] = dfMin;
00512             adfMinMax[1] = dfMax;
00513             return;
00514         }
00515     }
00516     
00517 /* -------------------------------------------------------------------- */
00518 /*      If we have overview bands, use them for min/max.                */
00519 /* -------------------------------------------------------------------- */
00520     if( bApproxOK )
00521         poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, 2500 );
00522     else 
00523         poBand = (GDALRasterBand *) hBand;
00524     
00525 /* -------------------------------------------------------------------- */
00526 /*      Figure out the ratio of blocks we will read to get an           */
00527 /*      approximate value.                                              */
00528 /* -------------------------------------------------------------------- */
00529     int         nBlockXSize, nBlockYSize;
00530     int         nBlocksPerRow, nBlocksPerColumn;
00531     int         nSampleRate;
00532     int         bGotNoDataValue, bFirstValue = TRUE;
00533     double      dfNoDataValue;
00534 
00535     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
00536 
00537     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
00538     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
00539     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
00540 
00541     if( bApproxOK )
00542         nSampleRate = 
00543             (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
00544     else
00545         nSampleRate = 1;
00546     
00547     for( int iSampleBlock = 0; 
00548          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
00549          iSampleBlock += nSampleRate )
00550     {
00551         double dfValue = 0.0;
00552         int  iXBlock, iYBlock, nXCheck, nYCheck;
00553         GDALRasterBlock *poBlock;
00554 
00555         iYBlock = iSampleBlock / nBlocksPerRow;
00556         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
00557         
00558         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
00559         if( poBlock == NULL )
00560             continue;
00561         
00562         if( (iXBlock+1) * nBlockXSize > poBand->GetXSize() )
00563             nXCheck = poBand->GetXSize() - iXBlock * nBlockXSize;
00564         else
00565             nXCheck = nBlockXSize;
00566 
00567         if( (iYBlock+1) * nBlockYSize > poBand->GetYSize() )
00568             nYCheck = poBand->GetYSize() - iYBlock * nBlockYSize;
00569         else
00570             nYCheck = nBlockYSize;
00571 
00572         /* this isn't the fastest way to do this, but is easier for now */
00573         for( int iY = 0; iY < nYCheck; iY++ )
00574         {
00575             for( int iX = 0; iX < nXCheck; iX++ )
00576             {
00577                 int    iOffset = iX + iY * nBlockXSize;
00578 
00579                 switch( poBlock->GetDataType() )
00580                 {
00581                   case GDT_Byte:
00582                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
00583                     break;
00584                   case GDT_UInt16:
00585                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
00586                     break;
00587                   case GDT_Int16:
00588                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
00589                     break;
00590                   case GDT_UInt32:
00591                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
00592                     break;
00593                   case GDT_Int32:
00594                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
00595                     break;
00596                   case GDT_Float32:
00597                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
00598                     break;
00599                   case GDT_Float64:
00600                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
00601                     break;
00602                   case GDT_CInt16:
00603                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
00604                     break;
00605                   case GDT_CInt32:
00606                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
00607                     break;
00608                   case GDT_CFloat32:
00609                     dfValue = ((float *) poBlock->GetDataRef())[iOffset*2];
00610                     break;
00611                   case GDT_CFloat64:
00612                     dfValue = ((double *) poBlock->GetDataRef())[iOffset*2];
00613                     break;
00614                   default:
00615                     CPLAssert( FALSE );
00616                 }
00617                 
00618                 if( bGotNoDataValue && dfValue == dfNoDataValue )
00619                     continue;
00620 
00621                 if( bFirstValue )
00622                 {
00623                     dfMin = dfMax = dfValue;
00624                     bFirstValue = FALSE;
00625                 }
00626                 else
00627                 {
00628                     dfMin = MIN(dfMin,dfValue);
00629                     dfMax = MAX(dfMax,dfValue);
00630                 }
00631             }
00632         }
00633     }
00634 
00635     adfMinMax[0] = dfMin;
00636     adfMinMax[1] = dfMax;
00637 }
00638 
00639 /************************************************************************/
00640 /*                         GDALDummyProgress()                          */
00641 /************************************************************************/
00642 
00707 int GDALDummyProgress( double, const char *, void * )
00708 
00709 {
00710     return TRUE;
00711 }
00712 
00713 /************************************************************************/
00714 /*                         GDALScaledProgress()                         */
00715 /************************************************************************/
00716 typedef struct { 
00717     GDALProgressFunc pfnProgress;
00718     void *pData;
00719     double dfMin;
00720     double dfMax;
00721 } GDALScaledProgressInfo;
00722 
00723 int GDALScaledProgress( double dfComplete, const char *pszMessage, 
00724                         void *pData )
00725 
00726 {
00727     GDALScaledProgressInfo *psInfo = (GDALScaledProgressInfo *) pData;
00728 
00729     return psInfo->pfnProgress( dfComplete * (psInfo->dfMax - psInfo->dfMin)
00730                                 + psInfo->dfMin,
00731                                 pszMessage, psInfo->pData );
00732 }
00733 
00734 /************************************************************************/
00735 /*                      GDALCreateScaledProgress()                      */
00736 /************************************************************************/
00737 
00738 void *GDALCreateScaledProgress( double dfMin, double dfMax, 
00739                                 GDALProgressFunc pfnProgress, 
00740                                 void * pData )
00741 
00742 {
00743     GDALScaledProgressInfo *psInfo;
00744 
00745     psInfo = (GDALScaledProgressInfo *) 
00746         CPLCalloc(sizeof(GDALScaledProgressInfo),1);
00747 
00748     if( ABS(dfMin-dfMax) < 0.0000001 )
00749         dfMax = dfMin + 0.01;
00750 
00751     psInfo->pData = pData;
00752     psInfo->pfnProgress = pfnProgress;
00753     psInfo->dfMin = dfMin;
00754     psInfo->dfMax = dfMax;
00755 
00756     return (void *) psInfo;
00757 }
00758 
00759 /************************************************************************/
00760 /*                     GDALDestroyScaledProgress()                      */
00761 /************************************************************************/
00762 
00763 void GDALDestroyScaledProgress( void * pData )
00764 
00765 {
00766     CPLFree( pData );
00767 }
00768 
00769 /************************************************************************/
00770 /*                          GDALTermProgress()                          */
00771 /************************************************************************/
00772 
00773 int GDALTermProgress( double dfComplete, const char *pszMessage, void * )
00774 
00775 {
00776     static double dfLastComplete = -1.0;
00777 
00778     if( dfLastComplete > dfComplete )
00779     {
00780         if( dfLastComplete > 1.0 )
00781             dfLastComplete = -1.0;
00782         else
00783             dfLastComplete = dfComplete;
00784     }
00785 
00786     if( floor(dfLastComplete*10) != floor(dfComplete*10) )
00787     {
00788         int    nPercent = (int) floor(dfComplete*100);
00789 
00790         if( nPercent == 0 && pszMessage != NULL )
00791             fprintf( stdout, "%s:", pszMessage );
00792 
00793         if( nPercent == 100 )
00794             fprintf( stdout, "%d - done.\n", (int) floor(dfComplete*100) );
00795         else
00796         {
00797             fprintf( stdout, "%d.", (int) floor(dfComplete*100) );
00798             fflush( stdout );
00799         }
00800     }
00801     else if( floor(dfLastComplete*30) != floor(dfComplete*30) )
00802     {
00803         fprintf( stdout, "." );
00804         fflush( stdout );
00805     }
00806 
00807     dfLastComplete = dfComplete;
00808 
00809     return TRUE;
00810 }
00811 
00812 /************************************************************************/
00813 /*                    GDALGetRasterSampleOverview()                     */
00814 /************************************************************************/
00815 
00831 GDALRasterBandH GDALGetRasterSampleOverview( GDALRasterBandH hBand, 
00832                                              int nDesiredSamples )
00833 
00834 {
00835     int     nBestSamples; 
00836     GDALRasterBandH hBestBand = hBand;
00837 
00838     nBestSamples = GDALGetRasterBandXSize(hBand) 
00839         * GDALGetRasterBandYSize(hBand);
00840 
00841     for( int iOverview = 0; 
00842          iOverview < GDALGetOverviewCount( hBand );
00843          iOverview++ )
00844     {
00845         GDALRasterBandH hOBand = GDALGetOverview( hBand, iOverview );
00846         int    nOSamples;
00847 
00848         nOSamples = GDALGetRasterBandXSize(hOBand) 
00849             * GDALGetRasterBandYSize(hOBand);
00850 
00851         if( nOSamples < nBestSamples && nOSamples > nDesiredSamples )
00852         {
00853             nBestSamples = nOSamples;
00854             hBestBand = hOBand;
00855         }
00856     }
00857 
00858     return hBestBand;
00859 }
00860 
00861 /************************************************************************/
00862 /*                     GDALGetRandomRasterSample()                      */
00863 /************************************************************************/
00864 
00865 int GDALGetRandomRasterSample( GDALRasterBandH hBand, int nSamples, 
00866                                float *pafSampleBuf )
00867 
00868 {
00869     GDALRasterBand *poBand;
00870 
00871     poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, nSamples );
00872 
00873 /* -------------------------------------------------------------------- */
00874 /*      Figure out the ratio of blocks we will read to get an           */
00875 /*      approximate value.                                              */
00876 /* -------------------------------------------------------------------- */
00877     int         nBlockXSize, nBlockYSize;
00878     int         nBlocksPerRow, nBlocksPerColumn;
00879     int         nSampleRate;
00880     int         bGotNoDataValue;
00881     double      dfNoDataValue;
00882     int         nActualSamples = 0;
00883     int         nBlockSampleRate;
00884     int         nBlockPixels, nBlockCount;
00885 
00886     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
00887 
00888     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
00889 
00890     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
00891     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
00892 
00893     nBlockPixels = nBlockXSize * nBlockYSize;
00894     nBlockCount = nBlocksPerRow * nBlocksPerColumn;
00895 
00896     nSampleRate = (int) MAX(1,sqrt((double) nBlockCount)-2.0);
00897 
00898     if( nSampleRate == nBlocksPerRow && nSampleRate > 1 )
00899         nSampleRate--;
00900 
00901     while( nSampleRate > 1 
00902            && ((nBlockCount-1) / nSampleRate + 1) * nBlockPixels < nSamples )
00903         nSampleRate--;
00904 
00905     nBlockSampleRate = 
00906         MAX(1,nBlockPixels / (nSamples / ((nBlockCount-1) / nSampleRate + 1)));
00907     
00908     for( int iSampleBlock = 0; 
00909          iSampleBlock < nBlockCount;
00910          iSampleBlock += nSampleRate )
00911     {
00912         double dfValue = 0.0, dfReal, dfImag;
00913         int  iXBlock, iYBlock, iX, iY, iXValid, iYValid, iRemainder = 0;
00914         GDALRasterBlock *poBlock;
00915 
00916         iYBlock = iSampleBlock / nBlocksPerRow;
00917         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
00918 
00919         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
00920         if( poBlock == NULL )
00921             continue;
00922 
00923         if( iXBlock * nBlockXSize > poBand->GetXSize() )
00924             iXValid = poBand->GetXSize() - iXBlock * nBlockXSize;
00925         else
00926             iXValid = nBlockXSize;
00927 
00928         if( iYBlock * nBlockYSize > poBand->GetYSize() )
00929             iYValid = poBand->GetYSize() - iYBlock * nBlockYSize;
00930         else
00931             iYValid = nBlockYSize;
00932 
00933         for( iY = 0; iY < iYValid; iY++ )
00934         {
00935             for( iX = iRemainder; iX < iXValid; iX += nBlockSampleRate )
00936             {
00937                 int     iOffset;
00938 
00939                 iOffset = iX + iY * nBlockXSize; 
00940                 switch( poBlock->GetDataType() )
00941                 {
00942                   case GDT_Byte:
00943                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
00944                     break;
00945                   case GDT_UInt16:
00946                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
00947                     break;
00948                   case GDT_Int16:
00949                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
00950                     break;
00951                   case GDT_UInt32:
00952                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
00953                     break;
00954                   case GDT_Int32:
00955                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
00956                     break;
00957                   case GDT_Float32:
00958                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
00959                     break;
00960                   case GDT_Float64:
00961                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
00962                     break;
00963                   case GDT_CInt16:
00964                     dfReal = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
00965                     dfImag = ((GInt16 *) poBlock->GetDataRef())[iOffset*2+1];
00966                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
00967                     break;
00968                   case GDT_CInt32:
00969                     dfReal = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
00970                     dfImag = ((GInt32 *) poBlock->GetDataRef())[iOffset*2+1];
00971                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
00972                     break;
00973                   case GDT_CFloat32:
00974                     dfReal = ((float *) poBlock->GetDataRef())[iOffset*2];
00975                     dfImag = ((float *) poBlock->GetDataRef())[iOffset*2+1];
00976                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
00977                     break;
00978                   case GDT_CFloat64:
00979                     dfReal = ((double *) poBlock->GetDataRef())[iOffset*2];
00980                     dfImag = ((double *) poBlock->GetDataRef())[iOffset*2+1];
00981                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
00982                     break;
00983                   default:
00984                     CPLAssert( FALSE );
00985                 }
00986             
00987                 if( bGotNoDataValue && dfValue == dfNoDataValue )
00988                     continue;
00989 
00990                 if( nActualSamples < nSamples )
00991                     pafSampleBuf[nActualSamples++] = dfValue;
00992             }
00993 
00994             iRemainder = iX - iXValid;
00995         }
00996     }
00997 
00998     return nActualSamples;
00999 }
01000 
01001 /************************************************************************/
01002 /*                            GDALInitGCPs()                            */
01003 /************************************************************************/
01004 
01005 void GDALInitGCPs( int nCount, GDAL_GCP * psGCP )
01006 
01007 {
01008     for( int iGCP = 0; iGCP < nCount; iGCP++ )
01009     {
01010         memset( psGCP, 0, sizeof(GDAL_GCP) );
01011         psGCP->pszId = CPLStrdup("");
01012         psGCP->pszInfo = CPLStrdup("");
01013         psGCP++;
01014     }
01015 }
01016 
01017 /************************************************************************/
01018 /*                           GDALDeinitGCPs()                           */
01019 /************************************************************************/
01020 
01021 void GDALDeinitGCPs( int nCount, GDAL_GCP * psGCP )
01022 
01023 {
01024     for( int iGCP = 0; iGCP < nCount; iGCP++ )
01025     {
01026         CPLFree( psGCP->pszId );
01027         CPLFree( psGCP->pszInfo );
01028         psGCP++;
01029     }
01030 }
01031 
01032 /************************************************************************/
01033 /*                         GDALDuplicateGCPs()                          */
01034 /************************************************************************/
01035 
01036 GDAL_GCP *GDALDuplicateGCPs( int nCount, const GDAL_GCP *pasGCPList )
01037 
01038 {
01039     GDAL_GCP    *pasReturn;
01040 
01041     pasReturn = (GDAL_GCP *) CPLMalloc(sizeof(GDAL_GCP) * nCount);
01042     GDALInitGCPs( nCount, pasReturn );
01043 
01044     for( int iGCP = 0; iGCP < nCount; iGCP++ )
01045     {
01046         CPLFree( pasReturn[iGCP].pszId );
01047         pasReturn[iGCP].pszId = CPLStrdup( pasGCPList[iGCP].pszId );
01048 
01049         CPLFree( pasReturn[iGCP].pszInfo );
01050         pasReturn[iGCP].pszInfo = CPLStrdup( pasGCPList[iGCP].pszInfo );
01051 
01052         pasReturn[iGCP].dfGCPPixel = pasGCPList[iGCP].dfGCPPixel;
01053         pasReturn[iGCP].dfGCPLine = pasGCPList[iGCP].dfGCPLine;
01054         pasReturn[iGCP].dfGCPX = pasGCPList[iGCP].dfGCPX;
01055         pasReturn[iGCP].dfGCPY = pasGCPList[iGCP].dfGCPY;
01056         pasReturn[iGCP].dfGCPZ = pasGCPList[iGCP].dfGCPZ;
01057     }
01058 
01059     return pasReturn;
01060 }
01061                              
01062 /************************************************************************/
01063 /*                         GDALReadWorldFile()                          */
01064 /*                                                                      */
01065 /*      Helper function for translator implementators wanting           */
01066 /*      support for ESRI world files.                                   */
01067 /************************************************************************/
01068 
01069 int GDALReadWorldFile( const char * pszBaseFilename, const char *pszExtension,
01070                        double *padfGeoTransform )
01071 
01072 {
01073     const char  *pszTFW;
01074     char        szExtUpper[32], szExtLower[32];
01075     int         i;
01076     FILE        *fpTFW;
01077     char        **papszLines;
01078 
01079     if( *pszExtension == '.' )
01080         pszExtension++;
01081 
01082 /* -------------------------------------------------------------------- */
01083 /*      Generate upper and lower case versions of the extension.        */
01084 /* -------------------------------------------------------------------- */
01085     strcpy( szExtUpper, pszExtension );
01086     strcpy( szExtLower, pszExtension );
01087 
01088     for( i = 0; szExtUpper[i] != '\0'; i++ )
01089     {
01090         if( szExtUpper[i] >= 'a' && szExtUpper[i] <= 'z' )
01091             szExtUpper[i] = szExtUpper[i] - 'a' + 'A';
01092         if( szExtLower[i] >= 'A' && szExtLower[i] <= 'Z' )
01093             szExtLower[i] = szExtLower[i] - 'A' + 'a';
01094     }
01095 
01096 /* -------------------------------------------------------------------- */
01097 /*      Try lower case, then upper case.                                */
01098 /* -------------------------------------------------------------------- */
01099     pszTFW = CPLResetExtension( pszBaseFilename, szExtLower );
01100 
01101     fpTFW = VSIFOpen( pszTFW, "rt" );
01102 
01103 #ifndef WIN32
01104     if( fpTFW == NULL )
01105     {
01106         pszTFW = CPLResetExtension( pszBaseFilename, szExtUpper );
01107         fpTFW = VSIFOpen( pszTFW, "rt" );
01108     }
01109 #endif
01110     
01111     if( fpTFW == NULL )
01112         return FALSE;
01113 
01114     VSIFClose( fpTFW );
01115 
01116 /* -------------------------------------------------------------------- */
01117 /*      We found the file, now load and parse it.                       */
01118 /* -------------------------------------------------------------------- */
01119     papszLines = CSLLoad( pszTFW );
01120     if( CSLCount(papszLines) >= 6 
01121         && atof(papszLines[0]) != 0.0
01122         && atof(papszLines[3]) != 0.0 )
01123     {
01124         padfGeoTransform[0] = atof(papszLines[4]);
01125         padfGeoTransform[1] = atof(papszLines[0]);
01126         padfGeoTransform[2] = atof(papszLines[2]);
01127         padfGeoTransform[3] = atof(papszLines[5]);
01128         padfGeoTransform[4] = atof(papszLines[1]);
01129         padfGeoTransform[5] = atof(papszLines[3]);
01130 
01131         // correct for center of pixel vs. top left of pixel
01132         padfGeoTransform[0] -= 0.5 * padfGeoTransform[1];
01133         padfGeoTransform[0] -= 0.5 * padfGeoTransform[2];
01134         padfGeoTransform[3] -= 0.5 * padfGeoTransform[4];
01135         padfGeoTransform[3] -= 0.5 * padfGeoTransform[5];
01136 
01137         CSLDestroy(papszLines);
01138 
01139         return TRUE;
01140     }
01141     else
01142     {
01143         CPLDebug( "GDAL", 
01144                   "GDALReadWorldFile(%s) found file, but it was corrupt.",
01145                   pszTFW );
01146         CSLDestroy(papszLines);
01147         return FALSE;
01148     }
01149 }
01150 
01151 /************************************************************************/
01152 /*                            GDALDecToDMS()                            */
01153 /*                                                                      */
01154 /*      Translate a decimal degrees value to a DMS string with          */
01155 /*      hemisphere.                                                     */
01156 /************************************************************************/
01157 
01158 const char *GDALDecToDMS( double dfAngle, const char * pszAxis,
01159                           int nPrecision )
01160 
01161 {
01162     int         nDegrees, nMinutes;
01163     double      dfSeconds;
01164     char        szFormat[30];
01165     static char szBuffer[50];
01166     const char  *pszHemisphere;
01167     
01168 
01169     nDegrees = (int) ABS(dfAngle);
01170     nMinutes = (int) ((ABS(dfAngle) - nDegrees) * 60);
01171     dfSeconds = (ABS(dfAngle) * 3600 - nDegrees*3600 - nMinutes*60);
01172 
01173     if( EQUAL(pszAxis,"Long") && dfAngle < 0.0 )
01174         pszHemisphere = "W";
01175     else if( EQUAL(pszAxis,"Long") )
01176         pszHemisphere = "E";
01177     else if( dfAngle < 0.0 )
01178         pszHemisphere = "S";
01179     else
01180         pszHemisphere = "N";
01181 
01182     sprintf( szFormat, "%%3dd%%2d\'%%.%df\"%s", nPrecision, pszHemisphere );
01183     sprintf( szBuffer, szFormat, nDegrees, nMinutes, dfSeconds );
01184 
01185     return( szBuffer );
01186 }
01187 
01188 /************************************************************************/
01189 /* -------------------------------------------------------------------- */
01190 /*      The following stubs are present to ensure that older GDAL       */
01191 /*      bridges don't fail with newer libraries.                        */
01192 /* -------------------------------------------------------------------- */
01193 /************************************************************************/
01194 
01195 CPL_C_START
01196 
01197 void *GDALCreateProjDef( const char * pszDef )
01198 {
01199     CPLDebug( "GDAL", "GDALCreateProjDef no longer supported." );
01200     return NULL;
01201 }
01202 
01203 CPLErr GDALReprojectToLongLat( void *pDef, double *, double * )
01204 {
01205     CPLDebug( "GDAL", "GDALReprojectToLatLong no longer supported." );
01206     return CE_Failure;
01207 }
01208 
01209 CPLErr GDALReprojectFromLongLat( void *pDef, double *, double * )
01210 {
01211     CPLDebug( "GDAL", "GDALReprojectFromLatLong no longer supported." );
01212     return CE_Failure;
01213 }
01214 
01215 void GDALDestroyProjDef( void *pDef )
01216 
01217 {
01218     CPLDebug( "GDAL", "GDALDestroyProjDef no longer supported." );
01219 }
01220 
01221 CPL_C_END

Generated at Thu Mar 28 09:47:29 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000