LCOV - code coverage report
Current view: directory - apps - gdal_grid.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 422 224 53.1 %
Date: 2013-03-30 Functions: 6 4 66.7 %

       1                 : /* ****************************************************************************
       2                 :  * $Id: gdal_grid.cpp 25582 2013-01-29 21:13:43Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Utilities
       5                 :  * Purpose:  GDAL scattered data gridding (interpolation) tool
       6                 :  * Author:   Andrey Kiselev, dron@ak4719.spb.edu
       7                 :  *
       8                 :  * ****************************************************************************
       9                 :  * Copyright (c) 2007, Andrey Kiselev <dron@ak4719.spb.edu>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include <cstdlib>
      31                 : #include <vector>
      32                 : #include <algorithm>
      33                 : 
      34                 : #include "cpl_string.h"
      35                 : #include "gdal.h"
      36                 : #include "gdal_alg.h"
      37                 : #include "ogr_spatialref.h"
      38                 : #include "ogr_api.h"
      39                 : #include "ogrsf_frmts.h"
      40                 : #include "gdalgrid.h"
      41                 : #include "commonutils.h"
      42                 : 
      43                 : CPL_CVSID("$Id: gdal_grid.cpp 25582 2013-01-29 21:13:43Z rouault $");
      44                 : 
      45                 : /************************************************************************/
      46                 : /*                               Usage()                                */
      47                 : /************************************************************************/
      48                 : 
      49               0 : static void Usage(const char* pszErrorMsg = NULL)
      50                 : 
      51                 : {
      52                 :     printf( 
      53                 :         "Usage: gdal_grid [--help-general] [--formats]\n"
      54                 :         "    [-ot {Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/\n"
      55                 :         "          CInt16/CInt32/CFloat32/CFloat64}]\n"
      56                 :         "    [-of format] [-co \"NAME=VALUE\"]\n"
      57                 :         "    [-zfield field_name]\n"
      58                 :         "    [-a_srs srs_def] [-spat xmin ymin xmax ymax]\n"
      59                 :         "    [-clipsrc <xmin ymin xmax ymax>|WKT|datasource|spat_extent]\n"
      60                 :         "    [-clipsrcsql sql_statement] [-clipsrclayer layer]\n"
      61                 :         "    [-clipsrcwhere expression]\n"
      62                 :         "    [-l layername]* [-where expression] [-sql select_statement]\n"
      63                 :         "    [-txe xmin xmax] [-tye ymin ymax] [-outsize xsize ysize]\n"
      64                 :         "    [-a algorithm[:parameter1=value1]*]"
      65                 :         "    [-q]\n"
      66                 :         "    <src_datasource> <dst_filename>\n"
      67                 :         "\n"
      68                 :         "Available algorithms and parameters with their's defaults:\n"
      69                 :         "    Inverse distance to a power (default)\n"
      70                 :         "        invdist:power=2.0:smoothing=0.0:radius1=0.0:radius2=0.0:angle=0.0:max_points=0:min_points=0:nodata=0.0\n"
      71                 :         "    Moving average\n"
      72                 :         "        average:radius1=0.0:radius2=0.0:angle=0.0:min_points=0:nodata=0.0\n"
      73                 :         "    Nearest neighbor\n"
      74                 :         "        nearest:radius1=0.0:radius2=0.0:angle=0.0:nodata=0.0\n"
      75                 :         "    Various data metrics\n"
      76                 :         "        <metric name>:radius1=0.0:radius2=0.0:angle=0.0:min_points=0:nodata=0.0\n"
      77                 :         "        possible metrics are:\n"
      78                 :         "            minimum\n"
      79                 :         "            maximum\n"
      80                 :         "            range\n"
      81                 :         "            count\n"
      82                 :         "            average_distance\n"
      83                 :         "            average_distance_pts\n"
      84               0 :         "\n");
      85                 : 
      86               0 :     if( pszErrorMsg != NULL )
      87               0 :         fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
      88                 : 
      89               0 :     GDALDestroyDriverManager();
      90               0 :     exit( 1 );
      91                 : }
      92                 : 
      93                 : /************************************************************************/
      94                 : /*                          GetAlgorithmName()                          */
      95                 : /*                                                                      */
      96                 : /*      Translates algortihm code into mnemonic name.                   */
      97                 : /************************************************************************/
      98                 : 
      99              27 : static void PrintAlgorithmAndOptions( GDALGridAlgorithm eAlgorithm,
     100                 :                                       void *pOptions )
     101                 : {
     102              27 :     switch ( eAlgorithm )
     103                 :     {
     104                 :         case GGA_InverseDistanceToAPower:
     105               5 :             printf( "Algorithm name: \"%s\".\n", szAlgNameInvDist );
     106                 :             printf( "Options are "
     107                 :                     "\"power=%f:smoothing=%f:radius1=%f:radius2=%f:angle=%f"
     108                 :                     ":max_points=%lu:min_points=%lu:nodata=%f\"\n",
     109                 :                 ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfPower,
     110                 :                 ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfSmoothing,
     111                 :                 ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfRadius1,
     112                 :                 ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfRadius2,
     113                 :                 ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfAngle,
     114                 :                 (unsigned long)((GDALGridInverseDistanceToAPowerOptions *)pOptions)->nMaxPoints,
     115                 :                 (unsigned long)((GDALGridInverseDistanceToAPowerOptions *)pOptions)->nMinPoints,
     116               5 :                 ((GDALGridInverseDistanceToAPowerOptions *)pOptions)->dfNoDataValue);
     117               5 :             break;
     118                 :         case GGA_MovingAverage:
     119               4 :             printf( "Algorithm name: \"%s\".\n", szAlgNameAverage );
     120                 :             printf( "Options are "
     121                 :                     "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
     122                 :                     ":nodata=%f\"\n",
     123                 :                 ((GDALGridMovingAverageOptions *)pOptions)->dfRadius1,
     124                 :                 ((GDALGridMovingAverageOptions *)pOptions)->dfRadius2,
     125                 :                 ((GDALGridMovingAverageOptions *)pOptions)->dfAngle,
     126                 :                 (unsigned long)((GDALGridMovingAverageOptions *)pOptions)->nMinPoints,
     127               4 :                 ((GDALGridMovingAverageOptions *)pOptions)->dfNoDataValue);
     128               4 :             break;
     129                 :         case GGA_NearestNeighbor:
     130               7 :             printf( "Algorithm name: \"%s\".\n", szAlgNameNearest );
     131                 :             printf( "Options are "
     132                 :                     "\"radius1=%f:radius2=%f:angle=%f:nodata=%f\"\n",
     133                 :                 ((GDALGridNearestNeighborOptions *)pOptions)->dfRadius1,
     134                 :                 ((GDALGridNearestNeighborOptions *)pOptions)->dfRadius2,
     135                 :                 ((GDALGridNearestNeighborOptions *)pOptions)->dfAngle,
     136               7 :                 ((GDALGridNearestNeighborOptions *)pOptions)->dfNoDataValue);
     137               7 :             break;
     138                 :         case GGA_MetricMinimum:
     139               2 :             printf( "Algorithm name: \"%s\".\n", szAlgNameMinimum );
     140                 :             printf( "Options are "
     141                 :                     "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
     142                 :                     ":nodata=%f\"\n",
     143                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
     144                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
     145                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
     146                 :                 (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
     147               2 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
     148               2 :             break;
     149                 :         case GGA_MetricMaximum:
     150               2 :             printf( "Algorithm name: \"%s\".\n", szAlgNameMaximum );
     151                 :             printf( "Options are "
     152                 :                     "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
     153                 :                     ":nodata=%f\"\n",
     154                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
     155                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
     156                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
     157                 :                 (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
     158               2 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
     159               2 :             break;
     160                 :         case GGA_MetricRange:
     161               2 :             printf( "Algorithm name: \"%s\".\n", szAlgNameRange );
     162                 :             printf( "Options are "
     163                 :                     "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
     164                 :                     ":nodata=%f\"\n",
     165                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
     166                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
     167                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
     168                 :                 (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
     169               2 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
     170               2 :             break;
     171                 :         case GGA_MetricCount:
     172               2 :             printf( "Algorithm name: \"%s\".\n", szAlgNameCount );
     173                 :             printf( "Options are "
     174                 :                     "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
     175                 :                     ":nodata=%f\"\n",
     176                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
     177                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
     178                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
     179                 :                 (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
     180               2 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
     181               2 :             break;
     182                 :         case GGA_MetricAverageDistance:
     183               2 :             printf( "Algorithm name: \"%s\".\n", szAlgNameAverageDistance );
     184                 :             printf( "Options are "
     185                 :                     "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
     186                 :                     ":nodata=%f\"\n",
     187                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
     188                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
     189                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
     190                 :                 (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
     191               2 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
     192               2 :             break;
     193                 :         case GGA_MetricAverageDistancePts:
     194               1 :             printf( "Algorithm name: \"%s\".\n", szAlgNameAverageDistancePts );
     195                 :             printf( "Options are "
     196                 :                     "\"radius1=%f:radius2=%f:angle=%f:min_points=%lu"
     197                 :                     ":nodata=%f\"\n",
     198                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius1,
     199                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfRadius2,
     200                 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfAngle,
     201                 :                 (unsigned long)((GDALGridDataMetricsOptions *)pOptions)->nMinPoints,
     202               1 :                 ((GDALGridDataMetricsOptions *)pOptions)->dfNoDataValue);
     203               1 :             break;
     204                 :         default:
     205               0 :             printf( "Algorithm is unknown.\n" );
     206                 :             break;
     207                 :     }
     208              27 : }
     209                 : 
     210                 : /************************************************************************/
     211                 : /*                          ProcessGeometry()                           */
     212                 : /*                                                                      */
     213                 : /*  Extract point coordinates from the geometry reference and set the   */
     214                 : /*  Z value as requested. Test whther we are in the clipped region      */
     215                 : /*  before processing.                                                  */
     216                 : /************************************************************************/
     217                 : 
     218           25041 : static void ProcessGeometry( OGRPoint *poGeom, OGRGeometry *poClipSrc,
     219                 :                              int iBurnField, double dfBurnValue,
     220                 :                              std::vector<double> &adfX,
     221                 :                              std::vector<double> &adfY,
     222                 :                              std::vector<double> &adfZ )
     223                 : 
     224                 : {
     225           25041 :     if ( poClipSrc && !poGeom->Within(poClipSrc) )
     226               0 :         return;
     227                 : 
     228           25041 :     adfX.push_back( poGeom->getX() );
     229           25041 :     adfY.push_back( poGeom->getY() );
     230           25041 :     if ( iBurnField < 0 )
     231           25041 :         adfZ.push_back( poGeom->getZ() );
     232                 :     else
     233               0 :         adfZ.push_back( dfBurnValue );
     234                 : }
     235                 : 
     236                 : /************************************************************************/
     237                 : /*                            ProcessLayer()                            */
     238                 : /*                                                                      */
     239                 : /*      Process all the features in a layer selection, collecting       */
     240                 : /*      geometries and burn values.                                     */
     241                 : /************************************************************************/
     242                 : 
     243              27 : static CPLErr ProcessLayer( OGRLayerH hSrcLayer, GDALDatasetH hDstDS,
     244                 :                           OGRGeometry *poClipSrc,
     245                 :                           GUInt32 nXSize, GUInt32 nYSize, int nBand,
     246                 :                           int& bIsXExtentSet, int& bIsYExtentSet,
     247                 :                           double& dfXMin, double& dfXMax,
     248                 :                           double& dfYMin, double& dfYMax,
     249                 :                           const char *pszBurnAttribute,
     250                 :                           GDALDataType eType,
     251                 :                           GDALGridAlgorithm eAlgorithm, void *pOptions,
     252                 :                           int bQuiet, GDALProgressFunc pfnProgress )
     253                 : 
     254                 : {
     255                 : /* -------------------------------------------------------------------- */
     256                 : /*      Get field index, and check.                                     */
     257                 : /* -------------------------------------------------------------------- */
     258              27 :     int iBurnField = -1;
     259                 : 
     260              27 :     if ( pszBurnAttribute )
     261                 :     {
     262                 :         iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ),
     263               0 :                                            pszBurnAttribute );
     264               0 :         if( iBurnField == -1 )
     265                 :         {
     266                 :             printf( "Failed to find field %s on layer %s, skipping.\n",
     267                 :                     pszBurnAttribute, 
     268               0 :                     OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) );
     269               0 :             return CE_Failure;
     270                 :         }
     271                 :     }
     272                 : 
     273                 : /* -------------------------------------------------------------------- */
     274                 : /*      Collect the geometries from this layer, and build list of       */
     275                 : /*      values to be interpolated.                                      */
     276                 : /* -------------------------------------------------------------------- */
     277                 :     OGRFeature *poFeat;
     278              27 :     std::vector<double> adfX, adfY, adfZ;
     279                 : 
     280              27 :     OGR_L_ResetReading( hSrcLayer );
     281                 : 
     282           25095 :     while( (poFeat = (OGRFeature *)OGR_L_GetNextFeature( hSrcLayer )) != NULL )
     283                 :     {
     284           25041 :         OGRGeometry *poGeom = poFeat->GetGeometryRef();
     285                 : 
     286           25041 :         if ( poGeom != NULL )
     287                 :         {
     288           25041 :             OGRwkbGeometryType eType = wkbFlatten( poGeom->getGeometryType() );
     289           25041 :             double  dfBurnValue = 0.0;
     290                 : 
     291           25041 :             if ( iBurnField >= 0 )
     292               0 :                 dfBurnValue = poFeat->GetFieldAsDouble( iBurnField );
     293                 : 
     294           25041 :             if ( eType == wkbMultiPoint )
     295                 :             {
     296                 :                 int iGeom;
     297               0 :                 int nGeomCount = ((OGRMultiPoint *)poGeom)->getNumGeometries();
     298                 : 
     299               0 :                 for ( iGeom = 0; iGeom < nGeomCount; iGeom++ )
     300                 :                 {
     301                 :                     ProcessGeometry( (OGRPoint *)((OGRMultiPoint *)poGeom)->getGeometryRef(iGeom),
     302                 :                                      poClipSrc, iBurnField, dfBurnValue,
     303               0 :                                      adfX, adfY, adfZ);
     304                 :                 }
     305                 :             }
     306           25041 :             else if ( eType == wkbPoint )
     307                 :             {
     308                 :                 ProcessGeometry( (OGRPoint *)poGeom, poClipSrc,
     309           25041 :                                  iBurnField, dfBurnValue, adfX, adfY, adfZ);
     310                 :             }
     311                 :         }
     312                 : 
     313           25041 :         OGRFeature::DestroyFeature( poFeat );
     314                 :     }
     315                 : 
     316              27 :     if ( adfX.size() == 0 )
     317                 :     {
     318                 :         printf( "No point geometry found on layer %s, skipping.\n",
     319               0 :                 OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) );
     320               0 :         return CE_None;
     321                 :     }
     322                 : 
     323                 : /* -------------------------------------------------------------------- */
     324                 : /*      Compute grid geometry.                                          */
     325                 : /* -------------------------------------------------------------------- */
     326              27 :     if ( !bIsXExtentSet || !bIsYExtentSet )
     327                 :     {
     328               0 :         OGREnvelope sEnvelope;
     329               0 :         OGR_L_GetExtent( hSrcLayer, &sEnvelope, TRUE );
     330                 : 
     331               0 :         if ( !bIsXExtentSet )
     332                 :         {
     333               0 :             dfXMin = sEnvelope.MinX;
     334               0 :             dfXMax = sEnvelope.MaxX;
     335               0 :             bIsXExtentSet = TRUE;
     336                 :         }
     337                 : 
     338               0 :         if ( !bIsYExtentSet )
     339                 :         {
     340               0 :             dfYMin = sEnvelope.MinY;
     341               0 :             dfYMax = sEnvelope.MaxY;
     342               0 :             bIsYExtentSet = TRUE;
     343                 :         }
     344                 :     }
     345                 : 
     346                 : /* -------------------------------------------------------------------- */
     347                 : /*      Perform gridding.                                               */
     348                 : /* -------------------------------------------------------------------- */
     349                 : 
     350              27 :     const double    dfDeltaX = ( dfXMax - dfXMin ) / nXSize;
     351              27 :     const double    dfDeltaY = ( dfYMax - dfYMin ) / nYSize;
     352                 : 
     353              27 :     if ( !bQuiet )
     354                 :     {
     355              27 :         printf( "Grid data type is \"%s\"\n", GDALGetDataTypeName(eType) );
     356                 :         printf( "Grid size = (%lu %lu).\n",
     357              27 :                 (unsigned long)nXSize, (unsigned long)nYSize );
     358                 :         printf( "Corner coordinates = (%f %f)-(%f %f).\n",
     359                 :                 dfXMin - dfDeltaX / 2, dfYMax + dfDeltaY / 2,
     360              27 :                 dfXMax + dfDeltaX / 2, dfYMin - dfDeltaY / 2 );
     361              27 :         printf( "Grid cell size = (%f %f).\n", dfDeltaX, dfDeltaY );
     362              27 :         printf( "Source point count = %lu.\n", (unsigned long)adfX.size() );
     363              27 :         PrintAlgorithmAndOptions( eAlgorithm, pOptions );
     364              27 :         printf("\n");
     365                 :     }
     366                 : 
     367              27 :     GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, nBand );
     368                 : 
     369              27 :     if (adfX.size() == 0)
     370                 :     {
     371                 :         // FIXME: Shoulda' set to nodata value instead
     372               0 :         GDALFillRaster( hBand, 0.0 , 0.0 );
     373               0 :         return CE_None;
     374                 :     }
     375                 : 
     376                 :     GUInt32 nXOffset, nYOffset;
     377                 :     int     nBlockXSize, nBlockYSize;
     378              27 :     int     nDataTypeSize = GDALGetDataTypeSize(eType) / 8;
     379                 : 
     380                 :     // Try to grow the work buffer up to 16 MB if it is smaller
     381              27 :     GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
     382              27 :     const GUInt32 nDesiredBufferSize = 16*1024*1024;
     383              27 :     if( (GUInt32)nBlockXSize < nXSize && (GUInt32)nBlockYSize < nYSize &&
     384                 :         (GUInt32)nBlockXSize < nDesiredBufferSize / (nBlockYSize * nDataTypeSize) )
     385                 :     {
     386               0 :         int nNewBlockXSize  = nDesiredBufferSize / (nBlockYSize * nDataTypeSize);
     387               0 :         nBlockXSize = (nNewBlockXSize / nBlockXSize) * nBlockXSize;
     388               0 :         if( (GUInt32)nBlockXSize > nXSize )
     389               0 :             nBlockXSize = nXSize;
     390                 :     }
     391              27 :     else if( (GUInt32)nBlockXSize == nXSize && (GUInt32)nBlockYSize < nYSize &&
     392                 :              (GUInt32)nBlockYSize < nDesiredBufferSize / (nXSize * nDataTypeSize) )
     393                 :     {
     394               0 :         int nNewBlockYSize = nDesiredBufferSize / (nXSize * nDataTypeSize);
     395               0 :         nBlockYSize = (nNewBlockYSize / nBlockYSize) * nBlockYSize;
     396               0 :         if( (GUInt32)nBlockYSize > nYSize )
     397               0 :             nBlockYSize = nYSize;
     398                 :     }
     399              27 :     CPLDebug("GDAL_GRID", "Work buffer: %d * %d", nBlockXSize, nBlockYSize);
     400                 : 
     401                 :     void    *pData =
     402              27 :         VSIMalloc3( nBlockXSize, nBlockYSize, nDataTypeSize );
     403              27 :     if( pData == NULL )
     404                 :     {
     405               0 :         CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate work buffer");
     406               0 :         return CE_Failure;
     407                 :     }
     408                 : 
     409              27 :     GUInt32 nBlock = 0;
     410                 :     GUInt32 nBlockCount = ((nXSize + nBlockXSize - 1) / nBlockXSize)
     411              27 :         * ((nYSize + nBlockYSize - 1) / nBlockYSize);
     412                 : 
     413              27 :     CPLErr eErr = CE_None;
     414              54 :     for ( nYOffset = 0; nYOffset < nYSize && eErr == CE_None; nYOffset += nBlockYSize )
     415                 :     {
     416              54 :         for ( nXOffset = 0; nXOffset < nXSize && eErr == CE_None; nXOffset += nBlockXSize )
     417                 :         {
     418                 :             void *pScaledProgress;
     419                 :             pScaledProgress =
     420                 :                 GDALCreateScaledProgress( (double)nBlock / nBlockCount,
     421                 :                                           (double)(nBlock + 1) / nBlockCount,
     422              27 :                                           pfnProgress, NULL );
     423              27 :             nBlock ++;
     424                 : 
     425              27 :             int nXRequest = nBlockXSize;
     426              27 :             if (nXOffset + nXRequest > nXSize)
     427               1 :                 nXRequest = nXSize - nXOffset;
     428                 : 
     429              27 :             int nYRequest = nBlockYSize;
     430              27 :             if (nYOffset + nYRequest > nYSize)
     431               1 :                 nYRequest = nYSize - nYOffset;
     432                 : 
     433                 :             eErr = GDALGridCreate( eAlgorithm, pOptions,
     434                 :                             adfX.size(), &(adfX[0]), &(adfY[0]), &(adfZ[0]),
     435                 :                             dfXMin + dfDeltaX * nXOffset,
     436                 :                             dfXMin + dfDeltaX * (nXOffset + nXRequest),
     437                 :                             dfYMin + dfDeltaY * nYOffset,
     438                 :                             dfYMin + dfDeltaY * (nYOffset + nYRequest),
     439                 :                             nXRequest, nYRequest, eType, pData,
     440              27 :                             GDALScaledProgress, pScaledProgress );
     441                 : 
     442              27 :             if( eErr == CE_None )
     443                 :                 eErr = GDALRasterIO( hBand, GF_Write, nXOffset, nYOffset,
     444                 :                           nXRequest, nYRequest, pData,
     445              27 :                           nXRequest, nYRequest, eType, 0, 0 );
     446                 : 
     447              27 :             GDALDestroyScaledProgress( pScaledProgress );
     448                 :         }
     449                 :     }
     450                 : 
     451              27 :     CPLFree( pData );
     452              27 :     return eErr;
     453                 : }
     454                 : 
     455                 : /************************************************************************/
     456                 : /*                            LoadGeometry()                            */
     457                 : /*                                                                      */
     458                 : /*  Read geometries from the given dataset using specified filters and  */
     459                 : /*  returns a collection of read geometries.                            */
     460                 : /************************************************************************/
     461                 : 
     462               0 : static OGRGeometryCollection* LoadGeometry( const char* pszDS,
     463                 :                                             const char* pszSQL,
     464                 :                                             const char* pszLyr,
     465                 :                                             const char* pszWhere )
     466                 : {
     467                 :     OGRDataSource       *poDS;
     468                 :     OGRLayer            *poLyr;
     469                 :     OGRFeature          *poFeat;
     470               0 :     OGRGeometryCollection *poGeom = NULL;
     471                 :         
     472               0 :     poDS = OGRSFDriverRegistrar::Open( pszDS, FALSE );
     473               0 :     if ( poDS == NULL )
     474               0 :         return NULL;
     475                 : 
     476               0 :     if ( pszSQL != NULL )
     477               0 :         poLyr = poDS->ExecuteSQL( pszSQL, NULL, NULL ); 
     478               0 :     else if ( pszLyr != NULL )
     479               0 :         poLyr = poDS->GetLayerByName( pszLyr );
     480                 :     else
     481               0 :         poLyr = poDS->GetLayer(0);
     482                 :         
     483               0 :     if ( poLyr == NULL )
     484                 :     {
     485                 :         fprintf( stderr,
     486               0 :             "FAILURE: Failed to identify source layer from datasource.\n" );
     487               0 :         OGRDataSource::DestroyDataSource( poDS );
     488               0 :         return NULL;
     489                 :     }
     490                 :     
     491               0 :     if ( pszWhere )
     492               0 :         poLyr->SetAttributeFilter( pszWhere );
     493                 :         
     494               0 :     while ( (poFeat = poLyr->GetNextFeature()) != NULL )
     495                 :     {
     496               0 :         OGRGeometry* poSrcGeom = poFeat->GetGeometryRef();
     497               0 :         if ( poSrcGeom )
     498                 :         {
     499                 :             OGRwkbGeometryType eType =
     500               0 :                 wkbFlatten( poSrcGeom->getGeometryType() );
     501                 :             
     502               0 :             if ( poGeom == NULL )
     503               0 :                 poGeom = new OGRMultiPolygon();
     504                 : 
     505               0 :             if ( eType == wkbPolygon )
     506               0 :                 poGeom->addGeometry( poSrcGeom );
     507               0 :             else if ( eType == wkbMultiPolygon )
     508                 :             {
     509                 :                 int iGeom;
     510                 :                 int nGeomCount =
     511               0 :                     ((OGRMultiPolygon *)poSrcGeom)->getNumGeometries();
     512                 : 
     513               0 :                 for ( iGeom = 0; iGeom < nGeomCount; iGeom++ )
     514                 :                 {
     515                 :                     poGeom->addGeometry(
     516               0 :                         ((OGRMultiPolygon *)poSrcGeom)->getGeometryRef(iGeom) );
     517                 :                 }
     518                 :             }
     519                 :             else
     520                 :             {
     521               0 :                 fprintf( stderr, "FAILURE: Geometry not of polygon type.\n" );
     522               0 :                 OGRGeometryFactory::destroyGeometry( poGeom );
     523               0 :                 OGRFeature::DestroyFeature( poFeat );
     524               0 :                 if ( pszSQL != NULL )
     525               0 :                     poDS->ReleaseResultSet( poLyr );
     526               0 :                 OGRDataSource::DestroyDataSource( poDS );
     527               0 :                 return NULL;
     528                 :             }
     529                 :         }
     530                 :     
     531               0 :         OGRFeature::DestroyFeature( poFeat );
     532                 :     }
     533                 :     
     534               0 :     if( pszSQL != NULL )
     535               0 :         poDS->ReleaseResultSet( poLyr );
     536               0 :     OGRDataSource::DestroyDataSource( poDS );
     537                 :     
     538               0 :     return poGeom;
     539                 : }
     540                 : 
     541                 : /************************************************************************/
     542                 : /*                                main()                                */
     543                 : /************************************************************************/
     544                 : 
     545                 : #define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
     546                 :     do { if (i + nExtraArg >= argc) \
     547                 :         Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
     548                 : 
     549              28 : int main( int argc, char ** argv )
     550                 : {
     551                 :     GDALDriverH     hDriver;
     552              28 :     const char      *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
     553              28 :     int             bFormatExplicitelySet = FALSE;
     554              28 :     char            **papszLayers = NULL;
     555              28 :     const char      *pszBurnAttribute = NULL;
     556              28 :     const char      *pszWHERE = NULL, *pszSQL = NULL;
     557              28 :     GDALDataType    eOutputType = GDT_Float64;
     558              28 :     char            **papszCreateOptions = NULL;
     559              28 :     GUInt32         nXSize = 0, nYSize = 0;
     560              28 :     double          dfXMin = 0.0, dfXMax = 0.0, dfYMin = 0.0, dfYMax = 0.0;
     561              28 :     int             bIsXExtentSet = FALSE, bIsYExtentSet = FALSE;
     562              28 :     GDALGridAlgorithm eAlgorithm = GGA_InverseDistanceToAPower;
     563              28 :     void            *pOptions = NULL;
     564              28 :     char            *pszOutputSRS = NULL;
     565              28 :     int             bQuiet = FALSE;
     566              28 :     GDALProgressFunc pfnProgress = GDALTermProgress;
     567                 :     int             i;
     568              28 :     OGRGeometry     *poSpatialFilter = NULL;
     569              28 :     int             bClipSrc = FALSE;
     570              28 :     OGRGeometry     *poClipSrc = NULL;
     571              28 :     const char      *pszClipSrcDS = NULL;
     572              28 :     const char      *pszClipSrcSQL = NULL;
     573              28 :     const char      *pszClipSrcLayer = NULL;
     574              28 :     const char      *pszClipSrcWhere = NULL;
     575                 : 
     576                 :     /* Check strict compilation and runtime library version as we use C++ API */
     577              28 :     if (! GDAL_CHECK_VERSION(argv[0]))
     578               0 :         exit(1);
     579                 : 
     580              28 :     GDALAllRegister();
     581              28 :     OGRRegisterAll();
     582                 : 
     583              28 :     argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
     584              28 :     if( argc < 1 )
     585               0 :         exit( -argc );
     586                 : 
     587                 : /* -------------------------------------------------------------------- */
     588                 : /*      Parse arguments.                                                */
     589                 : /* -------------------------------------------------------------------- */
     590             247 :     for( i = 1; i < argc; i++ )
     591                 :     {
     592             220 :         if( EQUAL(argv[i], "--utility_version") )
     593                 :         {
     594                 :             printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
     595               1 :                    argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
     596               1 :             return 0;
     597                 :         }
     598             219 :         else if( EQUAL(argv[i],"--help") )
     599               0 :             Usage();
     600             219 :         else if( EQUAL(argv[i],"-of") )
     601                 :         {
     602               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     603               0 :             pszFormat = argv[++i];
     604               0 :             bFormatExplicitelySet = TRUE;
     605                 :         }
     606                 : 
     607             219 :         else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") )
     608                 :         {
     609               0 :             bQuiet = TRUE;
     610               0 :             pfnProgress = GDALDummyProgress;
     611                 :         }
     612                 : 
     613             219 :         else if( EQUAL(argv[i],"-ot") )
     614                 :         {
     615              27 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     616                 :             int iType;
     617                 :             
     618             324 :             for( iType = 1; iType < GDT_TypeCount; iType++ )
     619                 :             {
     620             594 :                 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
     621             297 :                     && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
     622                 :                              argv[i+1]) )
     623                 :                 {
     624              27 :                     eOutputType = (GDALDataType) iType;
     625                 :                 }
     626                 :             }
     627                 : 
     628              27 :             if( eOutputType == GDT_Unknown )
     629                 :             {
     630                 :                 Usage(CPLSPrintf("Unknown output pixel type: %s.",
     631               0 :                                  argv[i + 1] ));
     632                 :             }
     633              27 :             i++;
     634                 :         }
     635                 : 
     636             192 :         else if( EQUAL(argv[i],"-txe") )
     637                 :         {
     638              27 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
     639              27 :             dfXMin = atof(argv[++i]);
     640              27 :             dfXMax = atof(argv[++i]);
     641              27 :             bIsXExtentSet = TRUE;
     642                 :         }   
     643                 : 
     644             165 :         else if( EQUAL(argv[i],"-tye") )
     645                 :         {
     646              27 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
     647              27 :             dfYMin = atof(argv[++i]);
     648              27 :             dfYMax = atof(argv[++i]);
     649              27 :             bIsYExtentSet = TRUE;
     650                 :         }   
     651                 : 
     652             138 :         else if( EQUAL(argv[i],"-outsize") )
     653                 :         {
     654              27 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
     655              27 :             nXSize = atoi(argv[++i]);
     656              27 :             nYSize = atoi(argv[++i]);
     657                 :         }   
     658                 : 
     659             111 :         else if( EQUAL(argv[i],"-co") )
     660                 :         {
     661               3 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     662               3 :             papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
     663                 :         }   
     664                 : 
     665             108 :         else if( EQUAL(argv[i],"-zfield") )
     666                 :         {
     667               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     668               0 :             pszBurnAttribute = argv[++i];
     669                 :         }
     670                 : 
     671             108 :         else if( EQUAL(argv[i],"-where") )
     672                 :         {
     673               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     674               0 :             pszWHERE = argv[++i];
     675                 :         }
     676                 : 
     677             108 :         else if( EQUAL(argv[i],"-l") )
     678                 :         {
     679              27 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     680              27 :             papszLayers = CSLAddString( papszLayers, argv[++i] );
     681                 :         }
     682                 : 
     683              81 :         else if( EQUAL(argv[i],"-sql") )
     684                 :         {
     685               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     686               0 :             pszSQL = argv[++i];
     687                 :         }
     688                 : 
     689              81 :         else if( EQUAL(argv[i],"-spat") )
     690                 :         {
     691               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4);
     692               0 :             OGRLinearRing  oRing;
     693                 : 
     694               0 :             oRing.addPoint( atof(argv[i+1]), atof(argv[i+2]) );
     695               0 :             oRing.addPoint( atof(argv[i+1]), atof(argv[i+4]) );
     696               0 :             oRing.addPoint( atof(argv[i+3]), atof(argv[i+4]) );
     697               0 :             oRing.addPoint( atof(argv[i+3]), atof(argv[i+2]) );
     698               0 :             oRing.addPoint( atof(argv[i+1]), atof(argv[i+2]) );
     699                 : 
     700               0 :             poSpatialFilter = new OGRPolygon();
     701               0 :             ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
     702               0 :             i += 4;
     703                 :         }
     704                 : 
     705              81 :         else if ( EQUAL(argv[i],"-clipsrc") )
     706                 :         {
     707               0 :             if (i + 1 >= argc)
     708               0 :                 Usage(CPLSPrintf("%s option requires 1 or 4 arguments", argv[i]));
     709                 : 
     710               0 :             bClipSrc = TRUE;
     711               0 :             errno = 0;
     712               0 :             const double unused = strtod( argv[i + 1], NULL );    // XXX: is it a number or not?
     713               0 :             if ( errno != 0
     714               0 :                  && argv[i + 2] != NULL
     715               0 :                  && argv[i + 3] != NULL
     716               0 :                  && argv[i + 4] != NULL)
     717                 :             {
     718               0 :                 OGRLinearRing  oRing;
     719                 : 
     720               0 :                 oRing.addPoint( atof(argv[i + 1]), atof(argv[i + 2]) );
     721               0 :                 oRing.addPoint( atof(argv[i + 1]), atof(argv[i + 4]) );
     722               0 :                 oRing.addPoint( atof(argv[i + 3]), atof(argv[i + 4]) );
     723               0 :                 oRing.addPoint( atof(argv[i + 3]), atof(argv[i + 2]) );
     724               0 :                 oRing.addPoint( atof(argv[i + 1]), atof(argv[i + 2]) );
     725                 : 
     726               0 :                 poClipSrc = new OGRPolygon();
     727               0 :                 ((OGRPolygon *) poClipSrc)->addRing( &oRing );
     728               0 :                 i += 4;
     729                 : 
     730               0 :                 (void)unused;
     731                 :             }
     732               0 :             else if (EQUALN(argv[i + 1], "POLYGON", 7)
     733               0 :                      || EQUALN(argv[i + 1], "MULTIPOLYGON", 12))
     734                 :             {
     735               0 :                 OGRGeometryFactory::createFromWkt(&argv[i + 1], NULL, &poClipSrc);
     736               0 :                 if ( poClipSrc == NULL )
     737                 :                 {
     738                 :                     Usage("Invalid geometry. "
     739               0 :                              "Must be a valid POLYGON or MULTIPOLYGON WKT.");
     740                 :                 }
     741               0 :                 i++;
     742                 :             }
     743               0 :             else if (EQUAL(argv[i + 1], "spat_extent") )
     744                 :             {
     745               0 :                 i++;
     746                 :             }
     747                 :             else
     748                 :             {
     749               0 :                 pszClipSrcDS = argv[i + 1];
     750               0 :                 i++;
     751                 :             }
     752                 :         }
     753                 : 
     754              81 :         else if ( EQUAL(argv[i], "-clipsrcsql") )
     755                 :         {
     756               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     757               0 :             pszClipSrcSQL = argv[i + 1];
     758               0 :             i++;
     759                 :         }
     760                 : 
     761              81 :         else if ( EQUAL(argv[i], "-clipsrclayer") )
     762                 :         {
     763               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     764               0 :             pszClipSrcLayer = argv[i + 1];
     765               0 :             i++;
     766                 :         }
     767                 : 
     768              81 :         else if ( EQUAL(argv[i], "-clipsrcwhere") )
     769                 :         {
     770               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     771               0 :             pszClipSrcWhere = argv[i + 1];
     772               0 :             i++;
     773                 :         }
     774                 : 
     775              81 :         else if( EQUAL(argv[i],"-a_srs") )
     776                 :         {
     777               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     778               0 :             OGRSpatialReference oOutputSRS;
     779                 : 
     780               0 :             if( oOutputSRS.SetFromUserInput( argv[i+1] ) != OGRERR_NONE )
     781                 :             {
     782                 :                 fprintf( stderr, "Failed to process SRS definition: %s\n", 
     783               0 :                          argv[i+1] );
     784               0 :                 GDALDestroyDriverManager();
     785               0 :                 exit( 1 );
     786                 :             }
     787                 : 
     788               0 :             oOutputSRS.exportToWkt( &pszOutputSRS );
     789               0 :             i++;
     790                 :         }   
     791                 : 
     792              81 :         else if( EQUAL(argv[i],"-a") )
     793                 :         {
     794              27 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     795              27 :             if ( ParseAlgorithmAndOptions( argv[++i], &eAlgorithm, &pOptions )
     796                 :                  != CE_None )
     797                 :             {
     798                 :                 fprintf( stderr,
     799               0 :                          "Failed to process algorithm name and parameters.\n" );
     800               0 :                 exit( 1 );
     801                 :             }
     802                 :         }
     803                 : 
     804              54 :         else if( argv[i][0] == '-' )
     805                 :         {
     806               0 :             Usage(CPLSPrintf("Unkown option name '%s'", argv[i]));
     807                 :         }
     808                 : 
     809              54 :         else if( pszSource == NULL )
     810                 :         {
     811              27 :             pszSource = argv[i];
     812                 :         }
     813                 : 
     814              27 :         else if( pszDest == NULL )
     815                 :         {
     816              27 :             pszDest = argv[i];
     817                 :         }
     818                 : 
     819                 :         else
     820                 :         {
     821               0 :             Usage("Too many command options.");
     822                 :         }
     823                 :     }
     824                 : 
     825              27 :     if( pszSource == NULL )
     826                 :     {
     827               0 :         Usage("Source datasource is not specified.");
     828                 :     }
     829              27 :     if( pszDest == NULL )
     830                 :     {
     831               0 :         Usage("Target dataset is not specified.");
     832                 :     }
     833              27 :     if( pszSQL == NULL && papszLayers == NULL )
     834                 :     {
     835               0 :         Usage("Neither -sql nor -l are specified.");
     836                 :     }
     837                 :     
     838              27 :     if ( bClipSrc && pszClipSrcDS != NULL )
     839                 :     {
     840                 :         poClipSrc = LoadGeometry( pszClipSrcDS, pszClipSrcSQL,
     841               0 :                                   pszClipSrcLayer, pszClipSrcWhere );
     842               0 :         if ( poClipSrc == NULL )
     843                 :         {
     844               0 :             Usage("Cannot load source clip geometry.");
     845                 :         }
     846                 :     }
     847              27 :     else if ( bClipSrc && poClipSrc == NULL && !poSpatialFilter )
     848                 :     {
     849                 :         Usage("-clipsrc must be used with -spat option or \n"
     850                 :                  "a bounding box, WKT string or datasource must be "
     851               0 :                  "specified.");
     852                 :     }
     853                 : 
     854              27 :     if ( poSpatialFilter )
     855                 :     {
     856               0 :         if ( poClipSrc )
     857                 :         {
     858               0 :             OGRGeometry *poTemp = poSpatialFilter->Intersection( poClipSrc );
     859                 : 
     860               0 :             if ( poTemp )
     861                 :             {
     862               0 :                 OGRGeometryFactory::destroyGeometry( poSpatialFilter );
     863               0 :                 poSpatialFilter = poTemp;
     864                 :             }
     865                 : 
     866               0 :             OGRGeometryFactory::destroyGeometry( poClipSrc );
     867               0 :             poClipSrc = NULL;
     868                 :         }
     869                 :     }
     870                 :     else
     871                 :     {
     872              27 :         if ( poClipSrc )
     873                 :         {
     874               0 :             poSpatialFilter = poClipSrc;
     875               0 :             poClipSrc = NULL;
     876                 :         }
     877                 :     }
     878                 : 
     879                 : /* -------------------------------------------------------------------- */
     880                 : /*      Find the output driver.                                         */
     881                 : /* -------------------------------------------------------------------- */
     882              27 :     hDriver = GDALGetDriverByName( pszFormat );
     883              27 :     if( hDriver == NULL )
     884                 :     {
     885                 :         int iDr;
     886                 :         
     887                 :         fprintf( stderr,
     888               0 :                  "FAILURE: Output driver `%s' not recognised.\n", pszFormat );
     889                 :         fprintf( stderr,
     890               0 :         "The following format drivers are configured and support output:\n" );
     891               0 :         for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
     892                 :         {
     893               0 :             GDALDriverH hDriver = GDALGetDriver(iDr);
     894                 : 
     895               0 :             if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
     896                 :                 || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY,
     897                 :                                         NULL ) != NULL )
     898                 :             {
     899                 :                 fprintf( stderr, "  %s: %s\n",
     900                 :                          GDALGetDriverShortName( hDriver  ),
     901               0 :                          GDALGetDriverLongName( hDriver ) );
     902                 :             }
     903                 :         }
     904               0 :         printf( "\n" );
     905               0 :         Usage();
     906                 :     }
     907                 : 
     908                 : /* -------------------------------------------------------------------- */
     909                 : /*      Open input datasource.                                          */
     910                 : /* -------------------------------------------------------------------- */
     911                 :     OGRDataSourceH hSrcDS;
     912                 : 
     913              27 :     hSrcDS = OGROpen( pszSource, FALSE, NULL );
     914              27 :     if( hSrcDS == NULL )
     915                 :     {
     916                 :         fprintf( stderr, "Unable to open input datasource \"%s\".\n",
     917               0 :                  pszSource );
     918               0 :         fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
     919               0 :         exit( 3 );
     920                 :     }
     921                 : 
     922                 : /* -------------------------------------------------------------------- */
     923                 : /*      Create target raster file.                                      */
     924                 : /* -------------------------------------------------------------------- */
     925                 :     GDALDatasetH    hDstDS;
     926              27 :     int             nLayerCount = CSLCount(papszLayers);
     927              27 :     int             nBands = nLayerCount;
     928                 : 
     929              27 :     if ( pszSQL )
     930               0 :         nBands++;
     931                 : 
     932                 :     // FIXME
     933              27 :     if ( nXSize == 0 )
     934               0 :         nXSize = 256;
     935              27 :     if ( nYSize == 0 )
     936               0 :         nYSize = 256;
     937                 : 
     938              27 :     if (!bQuiet && !bFormatExplicitelySet)
     939              27 :         CheckExtensionConsistency(pszDest, pszFormat);
     940                 : 
     941                 :     hDstDS = GDALCreate( hDriver, pszDest, nXSize, nYSize, nBands,
     942              27 :                          eOutputType, papszCreateOptions );
     943              27 :     if ( hDstDS == NULL )
     944                 :     {
     945                 :         fprintf( stderr, "Unable to create target dataset \"%s\".\n",
     946               0 :                  pszDest );
     947               0 :         fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
     948               0 :         exit( 3 );
     949                 :     }
     950                 : 
     951                 : /* -------------------------------------------------------------------- */
     952                 : /*      If algorithm was not specified assigh default one.              */
     953                 : /* -------------------------------------------------------------------- */
     954              27 :     if ( !pOptions )
     955               0 :         ParseAlgorithmAndOptions( szAlgNameInvDist, &eAlgorithm, &pOptions );
     956                 : 
     957                 : /* -------------------------------------------------------------------- */
     958                 : /*      Process SQL request.                                            */
     959                 : /* -------------------------------------------------------------------- */
     960              27 :     if( pszSQL != NULL )
     961                 :     {
     962                 :         OGRLayerH hLayer;
     963                 : 
     964                 :         hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszSQL,
     965               0 :                                     (OGRGeometryH)poSpatialFilter, NULL ); 
     966               0 :         if( hLayer != NULL )
     967                 :         {
     968                 :             // Custom layer will be rasterized in the first band.
     969                 :             ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize, 1,
     970                 :                           bIsXExtentSet, bIsYExtentSet,
     971                 :                           dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
     972                 :                           eOutputType, eAlgorithm, pOptions,
     973               0 :                           bQuiet, pfnProgress );
     974                 :         }
     975                 :     }
     976                 : 
     977                 : /* -------------------------------------------------------------------- */
     978                 : /*      Process each layer.                                             */
     979                 : /* -------------------------------------------------------------------- */
     980              54 :     for( i = 0; i < nLayerCount; i++ )
     981                 :     {
     982              27 :         OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i] );
     983              27 :         if( hLayer == NULL )
     984                 :         {
     985                 :             fprintf( stderr, "Unable to find layer \"%s\", skipping.\n", 
     986               0 :                      papszLayers[i] );
     987               0 :             continue;
     988                 :         }
     989                 : 
     990              27 :         if( pszWHERE )
     991                 :         {
     992               0 :             if( OGR_L_SetAttributeFilter( hLayer, pszWHERE ) != OGRERR_NONE )
     993               0 :                 break;
     994                 :         }
     995                 : 
     996              27 :         if ( poSpatialFilter != NULL )
     997               0 :             OGR_L_SetSpatialFilter( hLayer, (OGRGeometryH)poSpatialFilter );
     998                 : 
     999                 :         // Fetch the first meaningful SRS definition
    1000              27 :         if ( !pszOutputSRS )
    1001                 :         {
    1002              27 :             OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( hLayer );
    1003              27 :             if ( hSRS )
    1004              26 :                 OSRExportToWkt( hSRS, &pszOutputSRS );
    1005                 :         }
    1006                 : 
    1007                 :         ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize,
    1008                 :                       i + 1 + nBands - nLayerCount,
    1009                 :                       bIsXExtentSet, bIsYExtentSet,
    1010                 :                       dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
    1011                 :                       eOutputType, eAlgorithm, pOptions,
    1012              27 :                       bQuiet, pfnProgress );
    1013                 :     }
    1014                 : 
    1015                 : /* -------------------------------------------------------------------- */
    1016                 : /*      Apply geotransformation matrix.                                 */
    1017                 : /* -------------------------------------------------------------------- */
    1018                 :     double  adfGeoTransform[6];
    1019              27 :     adfGeoTransform[0] = dfXMin;
    1020              27 :     adfGeoTransform[1] = (dfXMax - dfXMin) / nXSize;
    1021              27 :     adfGeoTransform[2] = 0.0;
    1022              27 :     adfGeoTransform[3] = dfYMin;
    1023              27 :     adfGeoTransform[4] = 0.0;
    1024              27 :     adfGeoTransform[5] = (dfYMax - dfYMin) / nYSize;
    1025              27 :     GDALSetGeoTransform( hDstDS, adfGeoTransform );
    1026                 : 
    1027                 : /* -------------------------------------------------------------------- */
    1028                 : /*      Apply SRS definition if set.                                    */
    1029                 : /* -------------------------------------------------------------------- */
    1030              27 :     if ( pszOutputSRS )
    1031                 :     {
    1032              26 :         GDALSetProjection( hDstDS, pszOutputSRS );
    1033              26 :         CPLFree( pszOutputSRS );
    1034                 :     }
    1035                 : 
    1036                 : /* -------------------------------------------------------------------- */
    1037                 : /*      Cleanup                                                         */
    1038                 : /* -------------------------------------------------------------------- */
    1039              27 :     OGR_DS_Destroy( hSrcDS );
    1040              27 :     GDALClose( hDstDS );
    1041              27 :     OGRGeometryFactory::destroyGeometry( poSpatialFilter );
    1042                 : 
    1043              27 :     CPLFree( pOptions );
    1044              27 :     CSLDestroy( papszCreateOptions );
    1045              27 :     CSLDestroy( argv );
    1046              27 :     CSLDestroy( papszLayers );
    1047                 : 
    1048              27 :     OGRCleanupAll();
    1049                 : 
    1050              27 :     GDALDestroyDriverManager();
    1051                 :  
    1052              27 :     return 0;
    1053                 : }
    1054                 : 

Generated by: LCOV version 1.7