source: branches/branch-1.2/zoo-services/gdal/grid/service.c @ 733

Last change on this file since 733 was 301, checked in by djay, 13 years ago

Merge branch-1.2 r268:r296.

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

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png