LCOV - code coverage report
Current view: directory - apps - gdal_grid.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 449 194 43.2 %
Date: 2010-01-09 Functions: 7 5 71.4 %

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

Generated by: LCOV version 1.7