~ubuntu-branches/ubuntu/saucy/mapserver/saucy-security

« back to all changes in this revision

Viewing changes to mapogr.cpp.orig

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2011-12-23 14:02:06 UTC
  • mfrom: (26.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20111223140206-n3h9t2hsa8hyslmu
Tags: 6.0.1-2
Added missed stuff for libmapscript-perl.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**********************************************************************
2
 
 * $Id: mapogr.cpp 10545 2010-09-30 11:52:36Z tamas $
3
 
 *
4
 
 * Project:  MapServer
5
 
 * Purpose:  OGR Link
6
 
 * Author:   Daniel Morissette, DM Solutions Group (morissette@dmsolutions.ca)
7
 
 *           Frank Warmerdam (warmerdam@pobox.com)
8
 
 *
9
 
 **********************************************************************
10
 
 * Copyright (c) 2000-2005, Daniel Morissette, DM Solutions Group Inc
11
 
 *
12
 
 * Permission is hereby granted, free of charge, to any person obtaining a
13
 
 * copy of this software and associated documentation files (the "Software"),
14
 
 * to deal in the Software without restriction, including without limitation
15
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16
 
 * and/or sell copies of the Software, and to permit persons to whom the
17
 
 * Software is furnished to do so, subject to the following conditions:
18
 
 * 
19
 
 * The above copyright notice and this permission notice shall be included in 
20
 
 * all copies of this Software or works derived from this Software.
21
 
 * 
22
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
28
 
 * DEALINGS IN THE SOFTWARE.
29
 
 **********************************************************************/
30
 
 
31
 
#include <assert.h>
32
 
#include "mapserver.h"
33
 
#include "mapproject.h"
34
 
#include "mapthread.h"
35
 
 
36
 
#if defined(USE_OGR) || defined(USE_GDAL)
37
 
#  include "gdal_version.h"
38
 
#  include "cpl_conv.h"
39
 
#  include "cpl_string.h"
40
 
#  include "ogr_srs_api.h"
41
 
#endif
42
 
 
43
 
MS_CVSID("$Id: mapogr.cpp 10545 2010-09-30 11:52:36Z tamas $")
44
 
 
45
 
#if defined(GDAL_VERSION_NUM) && (GDAL_VERSION_NUM < 1400)
46
 
#  define ACQUIRE_OLD_OGR_LOCK   msAcquireLock( TLOCK_OGR )
47
 
#  define RELEASE_OLD_OGR_LOCK   msReleaseLock( TLOCK_OGR )
48
 
#else
49
 
#  define ACQUIRE_OLD_OGR_LOCK 
50
 
#  define RELEASE_OLD_OGR_LOCK 
51
 
#endif
52
 
 
53
 
#define ACQUIRE_OGR_LOCK       msAcquireLock( TLOCK_OGR )
54
 
#define RELEASE_OGR_LOCK       msReleaseLock( TLOCK_OGR )
55
 
 
56
 
#ifdef USE_OGR
57
 
 
58
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
59
 
#include "ogr_api.h"
60
 
#else /* Use OGR Style C++ */
61
 
#include "ogrsf_frmts.h"
62
 
#include "ogr_featurestyle.h"
63
 
#endif
64
 
 
65
 
typedef struct ms_ogr_file_info_t
66
 
{
67
 
  char        *pszFname;
68
 
  int         nLayerIndex;
69
 
  OGRDataSourceH hDS;
70
 
  OGRLayerH   hLayer;
71
 
  OGRFeatureH hLastFeature;
72
 
 
73
 
  int         nTileId;                  /* applies on the tiles themselves. */
74
 
 
75
 
  struct ms_ogr_file_info_t *poCurTile; /* exists on tile index, -> tiles */
76
 
  rectObj     rect;                     /* set by WhichShapes */
77
 
 
78
 
  int         last_record_index_read;
79
 
 
80
 
} msOGRFileInfo;
81
 
 
82
 
static int msOGRLayerIsOpen(layerObj *layer);
83
 
static int msOGRLayerInitItemInfo(layerObj *layer);
84
 
static int msOGRLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, 
85
 
                                  int tile, long record);
86
 
static void msOGRCloseConnection( void *conn_handle );
87
 
 
88
 
/* ==================================================================
89
 
 * Geometry conversion functions
90
 
 * ================================================================== */
91
 
 
92
 
/**********************************************************************
93
 
 *                     ogrPointsAddPoint()
94
 
 *
95
 
 * NOTE: This function assumes the line->point array already has been
96
 
 * allocated large enough for the point to be added, but that numpoints
97
 
 * does not include this new point. 
98
 
 **********************************************************************/
99
 
static void ogrPointsAddPoint(lineObj *line, double dX, double dY, 
100
 
                              int lineindex, rectObj *bounds)
101
 
{
102
 
    /* Keep track of shape bounds */
103
 
    if (line->numpoints == 0 && lineindex == 0)
104
 
    {
105
 
        bounds->minx = bounds->maxx = dX;
106
 
        bounds->miny = bounds->maxy = dY;
107
 
    }
108
 
    else
109
 
    {
110
 
        if (dX < bounds->minx)  bounds->minx = dX;
111
 
        if (dX > bounds->maxx)  bounds->maxx = dX;
112
 
        if (dY < bounds->miny)  bounds->miny = dY;
113
 
        if (dY > bounds->maxy)  bounds->maxy = dY;
114
 
    }
115
 
 
116
 
    line->point[line->numpoints].x = dX;
117
 
    line->point[line->numpoints].y = dY;
118
 
#ifdef USE_POINT_Z_M
119
 
    line->point[line->numpoints].z = 0.0;
120
 
    line->point[line->numpoints].m = 0.0;
121
 
#endif
122
 
    line->numpoints++;
123
 
}
124
 
 
125
 
/**********************************************************************
126
 
 *                     ogrGeomPoints()
127
 
 **********************************************************************/
128
 
static int ogrGeomPoints(OGRGeometryH hGeom, shapeObj *outshp) 
129
 
{
130
 
  int   i;
131
 
  int   numpoints;
132
 
 
133
 
  if (hGeom == NULL)   
134
 
      return 0;
135
 
 
136
 
  OGRwkbGeometryType eGType =  wkbFlatten( OGR_G_GetGeometryType( hGeom ) );
137
 
 
138
 
/* -------------------------------------------------------------------- */
139
 
/*      Container types result in recursive invocation on each          */
140
 
/*      subobject to add a set of points to the current list.           */
141
 
/* -------------------------------------------------------------------- */
142
 
  switch( eGType )
143
 
  {
144
 
      case wkbGeometryCollection:
145
 
      case wkbMultiLineString:
146
 
      case wkbMultiPolygon:
147
 
      case wkbPolygon:
148
 
      {
149
 
          /* Treat it as GeometryCollection */
150
 
          for (int iGeom=0; iGeom < OGR_G_GetGeometryCount( hGeom ); iGeom++ )
151
 
          {
152
 
              if( ogrGeomPoints( OGR_G_GetGeometryRef( hGeom, iGeom ), 
153
 
                                 outshp ) == -1 )
154
 
                  return -1;
155
 
          }
156
 
 
157
 
          return 0;                                                     
158
 
      }
159
 
      break;
160
 
 
161
 
      case wkbPoint:
162
 
      case wkbMultiPoint:
163
 
      case wkbLineString:
164
 
      case wkbLinearRing:
165
 
          /* We will handle these directly */
166
 
          break;
167
 
 
168
 
      default:
169
 
          /* There shouldn't be any more cases should there? */
170
 
          msSetError(MS_OGRERR, 
171
 
                     "OGRGeometry type `%s' not supported yet.", 
172
 
                     "ogrGeomPoints()",
173
 
                     OGR_G_GetGeometryName( hGeom ) );
174
 
          return(-1);
175
 
  }
176
 
 
177
 
 
178
 
/* ------------------------------------------------------------------
179
 
 * Count total number of points
180
 
 * ------------------------------------------------------------------ */
181
 
  if ( eGType == wkbPoint )
182
 
  {
183
 
      numpoints = 1;
184
 
  }
185
 
  else if ( eGType == wkbLineString 
186
 
            ||  eGType == wkbLinearRing )
187
 
  {
188
 
      numpoints = OGR_G_GetPointCount( hGeom );
189
 
  }
190
 
  else if ( eGType == wkbMultiPoint )
191
 
  {
192
 
      numpoints = OGR_G_GetGeometryCount( hGeom );
193
 
  }
194
 
  else
195
 
  {
196
 
      msSetError(MS_OGRERR, 
197
 
                 "OGRGeometry type `%s' not supported yet.", 
198
 
                 "ogrGeomPoints()",
199
 
                 OGR_G_GetGeometryName( hGeom ) );
200
 
      return(-1);
201
 
  }
202
 
 
203
 
/* ------------------------------------------------------------------
204
 
 * Do we need to allocate a line object to contain all our points? 
205
 
 * ------------------------------------------------------------------ */
206
 
  if( outshp->numlines == 0 )
207
 
  {
208
 
      lineObj newline;
209
 
      
210
 
      newline.numpoints = 0;
211
 
      newline.point = NULL;
212
 
      msAddLine(outshp, &newline);
213
 
  }
214
 
  
215
 
/* ------------------------------------------------------------------
216
 
 * Extend the point array for the new of points to add from the 
217
 
 * current geometry.
218
 
 * ------------------------------------------------------------------ */
219
 
  lineObj *line = outshp->line + outshp->numlines-1;
220
 
 
221
 
  if( line->point == NULL )
222
 
      line->point = (pointObj *) malloc(sizeof(pointObj) * numpoints);
223
 
  else
224
 
      line->point = (pointObj *) 
225
 
          realloc(line->point,sizeof(pointObj) * (numpoints+line->numpoints));
226
 
  
227
 
  if(!line->point) 
228
 
  {
229
 
      msSetError(MS_MEMERR, "Unable to allocate temporary point cache.", 
230
 
                 "ogrGeomPoints()");
231
 
      return(-1);
232
 
  }
233
 
   
234
 
/* ------------------------------------------------------------------
235
 
 * alloc buffer and filter/transform points
236
 
 * ------------------------------------------------------------------ */
237
 
  if( eGType == wkbPoint )
238
 
  {
239
 
      ogrPointsAddPoint(line, OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0), 
240
 
                        outshp->numlines-1, &(outshp->bounds));
241
 
  }
242
 
  else if( eGType == wkbLineString 
243
 
           || eGType == wkbLinearRing )
244
 
  {
245
 
      for(i=0; i<numpoints; i++)
246
 
          ogrPointsAddPoint(line, OGR_G_GetX(hGeom, i), OGR_G_GetY(hGeom, i),
247
 
                            outshp->numlines-1, &(outshp->bounds));
248
 
  }
249
 
  else if( eGType == wkbMultiPoint )
250
 
  {
251
 
      for(i=0; i<numpoints; i++)
252
 
      {
253
 
          OGRGeometryH hPoint = OGR_G_GetGeometryRef( hGeom, i );
254
 
          ogrPointsAddPoint(line, OGR_G_GetX(hPoint, 0), OGR_G_GetY(hPoint, 0),
255
 
                            outshp->numlines-1, &(outshp->bounds));
256
 
      }
257
 
  }
258
 
 
259
 
  outshp->type = MS_SHAPE_POINT;
260
 
 
261
 
  return(0);
262
 
}
263
 
 
264
 
 
265
 
/**********************************************************************
266
 
 *                     ogrGeomLine()
267
 
 *
268
 
 * Recursively convert any OGRGeometry into a shapeObj.  Each part becomes
269
 
 * a line in the overall shapeObj.
270
 
 **********************************************************************/
271
 
static int ogrGeomLine(OGRGeometryH hGeom, shapeObj *outshp,
272
 
                       int bCloseRings) 
273
 
{
274
 
  if (hGeom == NULL)
275
 
      return 0;
276
 
 
277
 
/* ------------------------------------------------------------------
278
 
 * Use recursive calls for complex geometries
279
 
 * ------------------------------------------------------------------ */
280
 
  OGRwkbGeometryType eGType =  wkbFlatten( OGR_G_GetGeometryType( hGeom ) );
281
 
 
282
 
  
283
 
  if ( eGType == wkbPolygon
284
 
       || eGType == wkbGeometryCollection
285
 
       || eGType == wkbMultiLineString 
286
 
       || eGType == wkbMultiPolygon )
287
 
  {
288
 
      if (eGType == wkbPolygon && outshp->type == MS_SHAPE_NULL)
289
 
          outshp->type = MS_SHAPE_POLYGON;
290
 
 
291
 
      /* Treat it as GeometryCollection */
292
 
      for (int iGeom=0; iGeom < OGR_G_GetGeometryCount( hGeom ); iGeom++ )
293
 
      {
294
 
          if( ogrGeomLine( OGR_G_GetGeometryRef( hGeom, iGeom ), 
295
 
                           outshp, bCloseRings ) == -1 )
296
 
              return -1;
297
 
      }
298
 
  }
299
 
/* ------------------------------------------------------------------
300
 
 * OGRPoint and OGRMultiPoint
301
 
 * ------------------------------------------------------------------ */
302
 
  else if ( eGType == wkbPoint || eGType == wkbMultiPoint )
303
 
  {
304
 
      /* Hummmm a point when we're drawing lines/polygons... just drop it! */
305
 
  }
306
 
/* ------------------------------------------------------------------
307
 
 * OGRLinearRing/OGRLineString ... both are of type wkbLineString
308
 
 * ------------------------------------------------------------------ */
309
 
  else if ( eGType == wkbLineString )
310
 
  {
311
 
      int       j, numpoints;
312
 
      lineObj   line={0,NULL};
313
 
      double    dX, dY;
314
 
 
315
 
      if ((numpoints = OGR_G_GetPointCount( hGeom )) < 2)
316
 
          return 0;
317
 
 
318
 
      if (outshp->type == MS_SHAPE_NULL)
319
 
          outshp->type = MS_SHAPE_LINE;
320
 
 
321
 
      line.numpoints = 0;
322
 
      line.point = (pointObj *)malloc(sizeof(pointObj)*(numpoints+1));
323
 
      if(!line.point) 
324
 
      {
325
 
          msSetError(MS_MEMERR, "Unable to allocate temporary point cache.", 
326
 
                     "ogrGeomLine");
327
 
          return(-1);
328
 
      }
329
 
 
330
 
      for(j=0; j<numpoints; j++)
331
 
      {
332
 
          dX = line.point[j].x = OGR_G_GetX( hGeom, j); 
333
 
          dY = line.point[j].y = OGR_G_GetY( hGeom, j);
334
 
 
335
 
          /* Keep track of shape bounds */
336
 
          if (j == 0 && outshp->numlines == 0)
337
 
          {
338
 
              outshp->bounds.minx = outshp->bounds.maxx = dX;
339
 
              outshp->bounds.miny = outshp->bounds.maxy = dY;
340
 
          }
341
 
          else
342
 
          {
343
 
              if (dX < outshp->bounds.minx)  outshp->bounds.minx = dX;
344
 
              if (dX > outshp->bounds.maxx)  outshp->bounds.maxx = dX;
345
 
              if (dY < outshp->bounds.miny)  outshp->bounds.miny = dY;
346
 
              if (dY > outshp->bounds.maxy)  outshp->bounds.maxy = dY;
347
 
          }
348
 
 
349
 
      }
350
 
      line.numpoints = numpoints; 
351
 
 
352
 
      if (bCloseRings &&
353
 
          ( line.point[line.numpoints-1].x != line.point[0].x ||
354
 
            line.point[line.numpoints-1].y != line.point[0].y  ) )
355
 
      {
356
 
          line.point[line.numpoints].x = line.point[0].x;
357
 
          line.point[line.numpoints].y = line.point[0].y;
358
 
          line.numpoints++;
359
 
      }
360
 
 
361
 
      msAddLineDirectly(outshp, &line);
362
 
  }
363
 
  else
364
 
  {
365
 
      msSetError(MS_OGRERR, 
366
 
                 "OGRGeometry type `%s' not supported.",
367
 
                 "ogrGeomLine()",
368
 
                 OGR_G_GetGeometryName( hGeom ) );
369
 
      return(-1);
370
 
  }
371
 
 
372
 
  return(0);
373
 
}
374
 
 
375
 
 
376
 
/**********************************************************************
377
 
 *                     ogrConvertGeometry()
378
 
 *
379
 
 * Convert OGR geometry into a shape object doing the best possible 
380
 
 * job to match OGR Geometry type and layer type.
381
 
 *
382
 
 * If layer type is incompatible with geometry, then shape is returned with
383
 
 * shape->type = MS_SHAPE_NULL
384
 
 **********************************************************************/
385
 
static int ogrConvertGeometry(OGRGeometryH hGeom, shapeObj *outshp,
386
 
                              enum MS_LAYER_TYPE layertype) 
387
 
{
388
 
/* ------------------------------------------------------------------
389
 
 * Process geometry according to layer type
390
 
 * ------------------------------------------------------------------ */
391
 
  int nStatus = MS_SUCCESS;
392
 
 
393
 
  if (hGeom == NULL)
394
 
  {
395
 
      // Empty geometry... this is not an error... we'll just skip it
396
 
      return MS_SUCCESS;
397
 
  }
398
 
 
399
 
  switch(layertype) 
400
 
  {
401
 
/* ------------------------------------------------------------------
402
 
 *      POINT layer - Any geometry can be converted to point/multipoint
403
 
 * ------------------------------------------------------------------ */
404
 
    case MS_LAYER_POINT:
405
 
      if(ogrGeomPoints(hGeom, outshp) == -1)
406
 
      {
407
 
          nStatus = MS_FAILURE; // Error message already produced.
408
 
      }
409
 
      break;
410
 
/* ------------------------------------------------------------------
411
 
 *      LINE layer
412
 
 * ------------------------------------------------------------------ */
413
 
    case MS_LAYER_LINE:
414
 
      if(ogrGeomLine(hGeom, outshp, MS_FALSE) == -1)
415
 
      {
416
 
          nStatus = MS_FAILURE; // Error message already produced.
417
 
      }
418
 
      if (outshp->type != MS_SHAPE_LINE && outshp->type != MS_SHAPE_POLYGON)
419
 
          outshp->type = MS_SHAPE_NULL;  // Incompatible type for this layer
420
 
      break;
421
 
/* ------------------------------------------------------------------
422
 
 *      POLYGON layer
423
 
 * ------------------------------------------------------------------ */
424
 
    case MS_LAYER_POLYGON:
425
 
      if(ogrGeomLine(hGeom, outshp, MS_TRUE) == -1)
426
 
      {
427
 
          nStatus = MS_FAILURE; // Error message already produced.
428
 
      }
429
 
      if (outshp->type != MS_SHAPE_POLYGON)
430
 
          outshp->type = MS_SHAPE_NULL;  // Incompatible type for this layer
431
 
      break;
432
 
/* ------------------------------------------------------------------
433
 
 *      MS_ANNOTATION layer - return real feature type
434
 
 * ------------------------------------------------------------------ */
435
 
    case MS_LAYER_ANNOTATION:
436
 
    case MS_LAYER_CHART:
437
 
    case MS_LAYER_QUERY:
438
 
      switch( OGR_G_GetGeometryType( hGeom ) )
439
 
      {
440
 
        case wkbPoint:
441
 
        case wkbPoint25D:
442
 
        case wkbMultiPoint:
443
 
        case wkbMultiPoint25D:
444
 
          if(ogrGeomPoints(hGeom, outshp) == -1)
445
 
          {
446
 
              nStatus = MS_FAILURE; // Error message already produced.
447
 
          }
448
 
          break;
449
 
        default:
450
 
          // Handle any non-point types as lines/polygons ... ogrGeomLine()
451
 
          // will decide the shape type
452
 
          if(ogrGeomLine(hGeom, outshp, MS_FALSE) == -1)
453
 
          {
454
 
              nStatus = MS_FAILURE; // Error message already produced.
455
 
          }
456
 
      }
457
 
      break;
458
 
 
459
 
    default:
460
 
      msSetError(MS_MISCERR, "Unknown or unsupported layer type.", 
461
 
                 "msOGRLayerNextShape()");
462
 
      nStatus = MS_FAILURE;
463
 
  } /* switch layertype */
464
 
 
465
 
  return nStatus;
466
 
}
467
 
 
468
 
/**********************************************************************
469
 
 *                     msOGRGeometryToShape()
470
 
 *
471
 
 * Utility function to convert from OGR geometry to a mapserver shape 
472
 
 * object.
473
 
 **********************************************************************/
474
 
int msOGRGeometryToShape(OGRGeometryH hGeometry, shapeObj *psShape,
475
 
                         OGRwkbGeometryType nType)
476
 
{
477
 
    if (hGeometry && psShape && nType > 0)
478
 
    {
479
 
        if (nType == wkbPoint || nType == wkbMultiPoint )
480
 
            return ogrConvertGeometry(hGeometry, psShape,  MS_LAYER_POINT);
481
 
        else if (nType == wkbLineString || nType == wkbMultiLineString)
482
 
            return ogrConvertGeometry(hGeometry, psShape,  MS_LAYER_LINE);
483
 
        else if (nType == wkbPolygon || nType == wkbMultiPolygon)
484
 
            return ogrConvertGeometry(hGeometry, psShape,  MS_LAYER_POLYGON);
485
 
        else
486
 
            return MS_FAILURE;
487
 
    }
488
 
    else
489
 
        return MS_FAILURE;
490
 
}
491
 
 
492
 
 
493
 
/* ==================================================================
494
 
 * Attributes handling functions
495
 
 * ================================================================== */
496
 
 
497
 
// Special field index codes for handling text string and angle coming from
498
 
// OGR style strings.
499
 
#define MSOGR_LABELNUMITEMS        21
500
 
#define MSOGR_LABELFONTNAMENAME    "OGR:LabelFont"
501
 
#define MSOGR_LABELFONTNAMEINDEX   -100
502
 
#define MSOGR_LABELSIZENAME        "OGR:LabelSize"
503
 
#define MSOGR_LABELSIZEINDEX       -101
504
 
#define MSOGR_LABELTEXTNAME        "OGR:LabelText"
505
 
#define MSOGR_LABELTEXTINDEX       -102
506
 
#define MSOGR_LABELANGLENAME       "OGR:LabelAngle"
507
 
#define MSOGR_LABELANGLEINDEX      -103
508
 
#define MSOGR_LABELFCOLORNAME      "OGR:LabelFColor"
509
 
#define MSOGR_LABELFCOLORINDEX     -104
510
 
#define MSOGR_LABELBCOLORNAME      "OGR:LabelBColor"
511
 
#define MSOGR_LABELBCOLORINDEX     -105
512
 
#define MSOGR_LABELPLACEMENTNAME   "OGR:LabelPlacement"
513
 
#define MSOGR_LABELPLACEMENTINDEX  -106
514
 
#define MSOGR_LABELANCHORNAME      "OGR:LabelAnchor"
515
 
#define MSOGR_LABELANCHORINDEX     -107
516
 
#define MSOGR_LABELDXNAME          "OGR:LabelDx"
517
 
#define MSOGR_LABELDXINDEX         -108
518
 
#define MSOGR_LABELDYNAME          "OGR:LabelDy"
519
 
#define MSOGR_LABELDYINDEX         -109
520
 
#define MSOGR_LABELPERPNAME        "OGR:LabelPerp"
521
 
#define MSOGR_LABELPERPINDEX       -110
522
 
#define MSOGR_LABELBOLDNAME        "OGR:LabelBold"
523
 
#define MSOGR_LABELBOLDINDEX       -111
524
 
#define MSOGR_LABELITALICNAME      "OGR:LabelItalic"
525
 
#define MSOGR_LABELITALICINDEX     -112
526
 
#define MSOGR_LABELUNDERLINENAME   "OGR:LabelUnderline"
527
 
#define MSOGR_LABELUNDERLINEINDEX  -113
528
 
#define MSOGR_LABELPRIORITYNAME    "OGR:LabelPriority"
529
 
#define MSOGR_LABELPRIORITYINDEX   -114
530
 
#define MSOGR_LABELSTRIKEOUTNAME   "OGR:LabelStrikeout"
531
 
#define MSOGR_LABELSTRIKEOUTINDEX  -115
532
 
#define MSOGR_LABELSTRETCHNAME     "OGR:LabelStretch"
533
 
#define MSOGR_LABELSTRETCHINDEX    -116
534
 
#define MSOGR_LABELADJHORNAME      "OGR:LabelAdjHor"
535
 
#define MSOGR_LABELADJHORINDEX     -117
536
 
#define MSOGR_LABELADJVERTNAME     "OGR:LabelAdjVert"
537
 
#define MSOGR_LABELADJVERTINDEX    -118
538
 
#define MSOGR_LABELHCOLORNAME      "OGR:LabelHColor"
539
 
#define MSOGR_LABELHCOLORINDEX     -119
540
 
#define MSOGR_LABELOCOLORNAME      "OGR:LabelOColor"
541
 
#define MSOGR_LABELOCOLORINDEX     -120
542
 
 
543
 
 
544
 
/**********************************************************************
545
 
 *                     msOGRGetValues()
546
 
 *
547
 
 * Load selected item (i.e. field) values into a char array
548
 
 *
549
 
 * Some special attribute names are used to return some OGRFeature params
550
 
 * like for instance stuff encoded in the OGRStyleString.
551
 
 * For now the following pseudo-attribute names are supported:
552
 
 *  "OGR:TextString"  OGRFeatureStyle's text string if present
553
 
 *  "OGR:TextAngle"   OGRFeatureStyle's text angle, or 0 if not set
554
 
 **********************************************************************/
555
 
static char **msOGRGetValues(layerObj *layer, OGRFeatureH hFeature)
556
 
{
557
 
  char **values;
558
 
  const char *pszValue = NULL;
559
 
  int i;
560
 
 
561
 
  if(layer->numitems == 0) 
562
 
      return(NULL);
563
 
 
564
 
  if(!layer->iteminfo)  // Should not happen... but just in case!
565
 
      if (msOGRLayerInitItemInfo(layer) != MS_SUCCESS)
566
 
          return NULL;
567
 
 
568
 
  if((values = (char **)malloc(sizeof(char *)*layer->numitems)) == NULL) 
569
 
  {
570
 
    msSetError(MS_MEMERR, NULL, "msOGRGetValues()");
571
 
    return(NULL);
572
 
  }
573
 
 
574
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
575
 
  OGRStyleMgrH  hStyleMgr = NULL;
576
 
  OGRStyleToolH hLabelStyle = NULL;
577
 
#else
578
 
  OGRStyleMgr *poStyleMgr = NULL;
579
 
  OGRStyleLabel *poLabelStyle = NULL;
580
 
#endif
581
 
  int *itemindexes = (int*)layer->iteminfo;
582
 
 
583
 
  for(i=0;i<layer->numitems;i++)
584
 
  {
585
 
    if (itemindexes[i] >= 0)
586
 
    {
587
 
        // Extract regular attributes
588
 
        values[i] = strdup(OGR_F_GetFieldAsString( hFeature, itemindexes[i]));
589
 
    }
590
 
    else
591
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
592
 
    {
593
 
        // Handle special OGR attributes coming from StyleString
594
 
        if (!hStyleMgr)
595
 
        {
596
 
            hStyleMgr = OGR_SM_Create(NULL);
597
 
            OGR_SM_InitFromFeature(hStyleMgr, hFeature);
598
 
            OGRStyleToolH hStylePart = OGR_SM_GetPart(hStyleMgr, 0, NULL);
599
 
            if (hStylePart && OGR_ST_GetType(hStylePart) == OGRSTCLabel)
600
 
                hLabelStyle = hStylePart;
601
 
            else if (hStylePart)
602
 
                OGR_ST_Destroy(hStylePart);
603
 
 
604
 
          /* Setting up the size units according to msOGRLayerGetAutoStyle*/
605
 
          if (hStylePart && layer->map)
606
 
            OGR_ST_SetUnit(hStylePart, OGRSTUPixel, layer->map->cellsize*72.0*39.37);
607
 
        }
608
 
        int bDefault;
609
 
        if (itemindexes[i] == MSOGR_LABELTEXTINDEX)
610
 
        {
611
 
            if (hLabelStyle == NULL 
612
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
613
 
                                                          OGRSTLabelTextString,
614
 
                                                          &bDefault)) == NULL))
615
 
                values[i] = strdup("");
616
 
            else
617
 
                values[i] = strdup(pszValue);
618
 
 
619
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
620
 
                msDebug(MSOGR_LABELTEXTNAME " = \"%s\"\n", values[i]);
621
 
        }
622
 
        else if (itemindexes[i] == MSOGR_LABELANGLEINDEX)
623
 
        {
624
 
            if (hLabelStyle == NULL 
625
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
626
 
                                                          OGRSTLabelAngle,
627
 
                                                          &bDefault)) == NULL))
628
 
                values[i] = strdup("0");
629
 
            else
630
 
                values[i] = strdup(pszValue);
631
 
 
632
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
633
 
                msDebug(MSOGR_LABELANGLENAME " = \"%s\"\n", values[i]);
634
 
        }
635
 
        else if (itemindexes[i] == MSOGR_LABELSIZEINDEX)
636
 
        {
637
 
            if (hLabelStyle == NULL 
638
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
639
 
                                                          OGRSTLabelSize,
640
 
                                                          &bDefault)) == NULL))
641
 
                values[i] = strdup("0");
642
 
            else
643
 
                values[i] = strdup(pszValue);
644
 
 
645
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
646
 
                msDebug(MSOGR_LABELSIZENAME " = \"%s\"\n", values[i]);
647
 
        }
648
 
        else if (itemindexes[i] == MSOGR_LABELFCOLORINDEX)
649
 
        {
650
 
            if (hLabelStyle == NULL 
651
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
652
 
                                                          OGRSTLabelFColor,
653
 
                                                          &bDefault)) == NULL))
654
 
                values[i] = strdup("#000000");
655
 
            else
656
 
                values[i] = strdup(pszValue);
657
 
 
658
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
659
 
                msDebug(MSOGR_LABELFCOLORNAME " = \"%s\"\n", values[i]);
660
 
        }
661
 
        else if (itemindexes[i] == MSOGR_LABELFONTNAMEINDEX )
662
 
        {
663
 
            if (hLabelStyle == NULL 
664
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
665
 
                                                          OGRSTLabelFontName,
666
 
                                                          &bDefault)) == NULL))
667
 
                values[i] = strdup("Arial");
668
 
            else
669
 
                values[i] = strdup(pszValue);
670
 
 
671
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
672
 
                msDebug(MSOGR_LABELFONTNAMENAME " =       \"%s\"\n", values[i]);
673
 
        }
674
 
        else if (itemindexes[i] == MSOGR_LABELBCOLORINDEX)
675
 
        {
676
 
            if (hLabelStyle == NULL 
677
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
678
 
                                                          OGRSTLabelBColor,
679
 
                                                          &bDefault)) == NULL))
680
 
                values[i] = strdup("#000000");
681
 
            else
682
 
                values[i] = strdup(pszValue);
683
 
 
684
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
685
 
                msDebug(MSOGR_LABELBCOLORNAME " = \"%s\"\n", values[i]);
686
 
        }
687
 
        else if (itemindexes[i] == MSOGR_LABELPLACEMENTINDEX)
688
 
        {
689
 
            if (hLabelStyle == NULL 
690
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
691
 
                                                          OGRSTLabelPlacement,
692
 
                                                          &bDefault)) == NULL))
693
 
                values[i] = strdup("");
694
 
            else
695
 
                values[i] = strdup(pszValue);
696
 
 
697
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
698
 
                msDebug(MSOGR_LABELPLACEMENTNAME " = \"%s\"\n", values[i]);
699
 
        }
700
 
        else if (itemindexes[i] == MSOGR_LABELANCHORINDEX)
701
 
        {
702
 
            if (hLabelStyle == NULL 
703
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
704
 
                                                          OGRSTLabelAnchor,
705
 
                                                          &bDefault)) == NULL))
706
 
                values[i] = strdup("0");
707
 
            else
708
 
                values[i] = strdup(pszValue);
709
 
 
710
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
711
 
                msDebug(MSOGR_LABELANCHORNAME " = \"%s\"\n", values[i]);
712
 
        }
713
 
        else if (itemindexes[i] == MSOGR_LABELDXINDEX)
714
 
        {
715
 
            if (hLabelStyle == NULL 
716
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
717
 
                                                          OGRSTLabelDx,
718
 
                                                          &bDefault)) == NULL))
719
 
                values[i] = strdup("0");
720
 
            else
721
 
                values[i] = strdup(pszValue);
722
 
 
723
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
724
 
                msDebug(MSOGR_LABELDXNAME " = \"%s\"\n", values[i]);
725
 
        }
726
 
        else if (itemindexes[i] == MSOGR_LABELDYINDEX)
727
 
        {
728
 
            if (hLabelStyle == NULL 
729
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
730
 
                                                          OGRSTLabelDy,
731
 
                                                          &bDefault)) == NULL))
732
 
                values[i] = strdup("0");
733
 
            else
734
 
                values[i] = strdup(pszValue);
735
 
 
736
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
737
 
                msDebug(MSOGR_LABELDYNAME " = \"%s\"\n", values[i]);
738
 
        }
739
 
        else if (itemindexes[i] == MSOGR_LABELPERPINDEX)
740
 
        {
741
 
            if (hLabelStyle == NULL 
742
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
743
 
                                                          OGRSTLabelPerp,
744
 
                                                          &bDefault)) == NULL))
745
 
                values[i] = strdup("0");
746
 
            else
747
 
                values[i] = strdup(pszValue);
748
 
 
749
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
750
 
                msDebug(MSOGR_LABELPERPNAME " = \"%s\"\n", values[i]);
751
 
        }
752
 
        else if (itemindexes[i] == MSOGR_LABELBOLDINDEX)
753
 
        {
754
 
            if (hLabelStyle == NULL 
755
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
756
 
                                                          OGRSTLabelBold,
757
 
                                                          &bDefault)) == NULL))
758
 
                values[i] = strdup("0");
759
 
            else
760
 
                values[i] = strdup(pszValue);
761
 
 
762
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
763
 
                msDebug(MSOGR_LABELBOLDNAME " = \"%s\"\n", values[i]);
764
 
        }
765
 
        else if (itemindexes[i] == MSOGR_LABELITALICINDEX)
766
 
        {
767
 
            if (hLabelStyle == NULL 
768
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
769
 
                                                          OGRSTLabelItalic,
770
 
                                                          &bDefault)) == NULL))
771
 
                values[i] = strdup("0");
772
 
            else
773
 
                values[i] = strdup(pszValue);
774
 
 
775
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
776
 
                msDebug(MSOGR_LABELITALICNAME " = \"%s\"\n", values[i]);
777
 
        }
778
 
        else if (itemindexes[i] == MSOGR_LABELUNDERLINEINDEX)
779
 
        {
780
 
            if (hLabelStyle == NULL 
781
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
782
 
                                                          OGRSTLabelUnderline,
783
 
                                                          &bDefault)) == NULL))
784
 
                values[i] = strdup("0");
785
 
            else
786
 
                values[i] = strdup(pszValue);
787
 
 
788
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
789
 
                msDebug(MSOGR_LABELUNDERLINENAME " = \"%s\"\n", values[i]);
790
 
        }
791
 
        else if (itemindexes[i] == MSOGR_LABELPRIORITYINDEX)
792
 
        {
793
 
            if (hLabelStyle == NULL 
794
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
795
 
                                                          OGRSTLabelPriority,
796
 
                                                          &bDefault)) == NULL))
797
 
                values[i] = strdup("0");
798
 
            else
799
 
                values[i] = strdup(pszValue);
800
 
 
801
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
802
 
                msDebug(MSOGR_LABELPRIORITYNAME " = \"%s\"\n", values[i]);
803
 
        }
804
 
        else if (itemindexes[i] == MSOGR_LABELSTRIKEOUTINDEX)
805
 
        {
806
 
            if (hLabelStyle == NULL 
807
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
808
 
                                                          OGRSTLabelStrikeout,
809
 
                                                          &bDefault)) == NULL))
810
 
                values[i] = strdup("0");
811
 
            else
812
 
                values[i] = strdup(pszValue);
813
 
 
814
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
815
 
                msDebug(MSOGR_LABELSTRIKEOUTNAME " = \"%s\"\n", values[i]);
816
 
        }
817
 
        else if (itemindexes[i] == MSOGR_LABELSTRETCHINDEX)
818
 
        {
819
 
            if (hLabelStyle == NULL 
820
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
821
 
                                                          OGRSTLabelStretch,
822
 
                                                          &bDefault)) == NULL))
823
 
                values[i] = strdup("0");
824
 
            else
825
 
                values[i] = strdup(pszValue);
826
 
 
827
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
828
 
                msDebug(MSOGR_LABELSTRETCHNAME " = \"%s\"\n", values[i]);
829
 
        }
830
 
        else if (itemindexes[i] == MSOGR_LABELADJHORINDEX)
831
 
        {
832
 
            if (hLabelStyle == NULL 
833
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
834
 
                                                          OGRSTLabelAdjHor,
835
 
                                                          &bDefault)) == NULL))
836
 
                values[i] = strdup("");
837
 
            else
838
 
                values[i] = strdup(pszValue);
839
 
 
840
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
841
 
                msDebug(MSOGR_LABELADJHORNAME " = \"%s\"\n", values[i]);
842
 
        }
843
 
        else if (itemindexes[i] == MSOGR_LABELADJVERTINDEX)
844
 
        {
845
 
            if (hLabelStyle == NULL 
846
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
847
 
                                                          OGRSTLabelAdjVert,
848
 
                                                          &bDefault)) == NULL))
849
 
                values[i] = strdup("");
850
 
            else
851
 
                values[i] = strdup(pszValue);
852
 
 
853
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
854
 
                msDebug(MSOGR_LABELADJVERTNAME " = \"%s\"\n", values[i]);
855
 
        }
856
 
        else if (itemindexes[i] == MSOGR_LABELHCOLORINDEX)
857
 
        {
858
 
            if (hLabelStyle == NULL 
859
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
860
 
                                                          OGRSTLabelHColor,
861
 
                                                          &bDefault)) == NULL))
862
 
                values[i] = strdup("");
863
 
            else
864
 
                values[i] = strdup(pszValue);
865
 
 
866
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
867
 
                msDebug(MSOGR_LABELHCOLORNAME " = \"%s\"\n", values[i]);
868
 
        }
869
 
#if GDAL_VERSION_NUM >= 1600
870
 
        else if (itemindexes[i] == MSOGR_LABELOCOLORINDEX)
871
 
        {
872
 
            if (hLabelStyle == NULL 
873
 
                || ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
874
 
                                                          OGRSTLabelOColor,
875
 
                                                          &bDefault)) == NULL))
876
 
                values[i] = strdup("");
877
 
            else
878
 
                values[i] = strdup(pszValue);
879
 
 
880
 
            if (layer->debug >= MS_DEBUGLEVEL_VVV)
881
 
                msDebug(MSOGR_LABELOCOLORNAME " = \"%s\"\n", values[i]);
882
 
        }
883
 
#endif /* GDAL_VERSION_NUM >= 1600 */
884
 
        else
885
 
        {
886
 
            msSetError(MS_OGRERR,"Invalid field index!?!","msOGRGetValues()");
887
 
            return(NULL);
888
 
        }
889
 
    }
890
 
#else /* OGRStyle C++ */
891
 
    {
892
 
    if (!poStyleMgr)
893
 
    {
894
 
        poStyleMgr = new OGRStyleMgr(NULL);
895
 
        poStyleMgr->InitFromFeature((OGRFeature *)hFeature);
896
 
        OGRStyleTool *poStylePart = poStyleMgr->GetPart(0);
897
 
        if (poStylePart && poStylePart->GetType() == OGRSTCLabel)
898
 
            poLabelStyle = (OGRStyleLabel*)poStylePart;
899
 
        else if (poStylePart)
900
 
            delete poStylePart;
901
 
        /* Setting up the size units according to msOGRLayerGetAutoStyle*/
902
 
        if (poStylePart && layer->map)
903
 
            poStylePart->SetUnit(OGRSTUPixel, layer->map->cellsize*72.0*39.37);
904
 
    }
905
 
    GBool bDefault;
906
 
    if (itemindexes[i] == MSOGR_LABELTEXTINDEX)
907
 
    {
908
 
        if (poLabelStyle == NULL 
909
 
            || ((pszValue = poLabelStyle->TextString(bDefault)) == NULL))
910
 
           values[i] = strdup("");
911
 
        else
912
 
            values[i] = strdup(pszValue);
913
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
914
 
            msDebug(MSOGR_LABELTEXTNAME " = \"%s\"\n", values[i]);
915
 
    }
916
 
    else if (itemindexes[i] == MSOGR_LABELANGLEINDEX)
917
 
    {
918
 
        if (poLabelStyle == NULL
919
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAngle,bDefault)) == NULL))
920
 
           values[i] = strdup("0");
921
 
        else
922
 
           values[i] = strdup(pszValue);
923
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
924
 
            msDebug(MSOGR_LABELANGLENAME " = \"%s\"\n", values[i]);
925
 
    }
926
 
    else if (itemindexes[i] == MSOGR_LABELSIZEINDEX)
927
 
    {
928
 
        if (poLabelStyle == NULL
929
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelSize,bDefault)) == NULL))
930
 
           values[i] = strdup("0");
931
 
        else
932
 
           values[i] = strdup(pszValue);
933
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
934
 
            msDebug(MSOGR_LABELSIZENAME " = \"%s\"\n", values[i]);
935
 
    }
936
 
    else if (itemindexes[i] == MSOGR_LABELFCOLORINDEX)
937
 
    {
938
 
        if (poLabelStyle == NULL
939
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelFColor, bDefault)) == NULL))
940
 
           values[i] = strdup("#000000");
941
 
        else
942
 
           values[i] = strdup(pszValue);
943
 
 
944
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
945
 
            msDebug(MSOGR_LABELSIZENAME " = \"%s\"\n", values[i]);
946
 
    }
947
 
    else if (itemindexes[i] == MSOGR_LABELFONTNAMEINDEX)
948
 
    {
949
 
        if (poLabelStyle == NULL
950
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelFontName, bDefault)) == NULL))
951
 
           values[i] = strdup("Arial");
952
 
        else
953
 
           values[i] = strdup(pszValue);
954
 
 
955
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
956
 
            msDebug(MSOGR_LABELFONTNAMENAME " = \"%s\"\n", values[i]);
957
 
    }
958
 
    else if (itemindexes[i] == MSOGR_LABELBCOLORINDEX)
959
 
    {
960
 
        if (poLabelStyle == NULL
961
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelBColor, bDefault)) == NULL))
962
 
           values[i] = strdup("#000000");
963
 
        else
964
 
           values[i] = strdup(pszValue);
965
 
 
966
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
967
 
            msDebug(MSOGR_LABELBCOLORNAME " = \"%s\"\n", values[i]);
968
 
    }
969
 
    else if (itemindexes[i] == MSOGR_LABELPLACEMENTINDEX)
970
 
    {
971
 
        if (poLabelStyle == NULL
972
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelPlacement, bDefault)) == NULL))
973
 
           values[i] = strdup("");
974
 
        else
975
 
           values[i] = strdup(pszValue);
976
 
 
977
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
978
 
            msDebug(MSOGR_LABELPLACEMENTNAME " = \"%s\"\n", values[i]);
979
 
    }
980
 
    else if (itemindexes[i] == MSOGR_LABELANCHORINDEX)
981
 
    {
982
 
        if (poLabelStyle == NULL
983
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAnchor, bDefault)) == NULL))
984
 
           values[i] = strdup("0");
985
 
        else
986
 
           values[i] = strdup(pszValue);
987
 
 
988
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
989
 
            msDebug(MSOGR_LABELANCHORNAME " = \"%s\"\n", values[i]);
990
 
    }
991
 
    else if (itemindexes[i] == MSOGR_LABELDXINDEX)
992
 
    {
993
 
        if (poLabelStyle == NULL
994
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelDx, bDefault)) == NULL))
995
 
           values[i] = strdup("0");
996
 
        else
997
 
           values[i] = strdup(pszValue);
998
 
 
999
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1000
 
            msDebug(MSOGR_LABELDXNAME " = \"%s\"\n", values[i]);
1001
 
    }
1002
 
    else if (itemindexes[i] == MSOGR_LABELDYINDEX)
1003
 
    {
1004
 
        if (poLabelStyle == NULL
1005
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelDy, bDefault)) == NULL))
1006
 
           values[i] = strdup("0");
1007
 
        else
1008
 
           values[i] = strdup(pszValue);
1009
 
 
1010
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1011
 
            msDebug(MSOGR_LABELDYNAME " = \"%s\"\n", values[i]);
1012
 
    }
1013
 
    else if (itemindexes[i] == MSOGR_LABELPERPINDEX)
1014
 
    {
1015
 
        if (poLabelStyle == NULL
1016
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelPerp, bDefault)) == NULL))
1017
 
           values[i] = strdup("0");
1018
 
        else
1019
 
           values[i] = strdup(pszValue);
1020
 
 
1021
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1022
 
            msDebug(MSOGR_LABELPERPNAME " = \"%s\"\n", values[i]);
1023
 
    }
1024
 
    else if (itemindexes[i] == MSOGR_LABELBOLDINDEX)
1025
 
    {
1026
 
        if (poLabelStyle == NULL
1027
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelBold, bDefault)) == NULL))
1028
 
           values[i] = strdup("0");
1029
 
        else
1030
 
           values[i] = strdup(pszValue);
1031
 
 
1032
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1033
 
            msDebug(MSOGR_LABELBOLDNAME " = \"%s\"\n", values[i]);
1034
 
    }
1035
 
    else if (itemindexes[i] == MSOGR_LABELITALICINDEX)
1036
 
    {
1037
 
        if (poLabelStyle == NULL
1038
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelItalic, bDefault)) == NULL))
1039
 
           values[i] = strdup("0");
1040
 
        else
1041
 
           values[i] = strdup(pszValue);
1042
 
 
1043
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1044
 
            msDebug(MSOGR_LABELITALICNAME " = \"%s\"\n", values[i]);
1045
 
    }
1046
 
    else if (itemindexes[i] == MSOGR_LABELUNDERLINEINDEX)
1047
 
    {
1048
 
        if (poLabelStyle == NULL
1049
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelUnderline, bDefault)) == NULL))
1050
 
           values[i] = strdup("0");
1051
 
        else
1052
 
           values[i] = strdup(pszValue);
1053
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1054
 
            msDebug(MSOGR_LABELUNDERLINENAME " = \"%s\"\n", values[i]);
1055
 
    }
1056
 
    else if (itemindexes[i] == MSOGR_LABELPRIORITYINDEX)
1057
 
    {
1058
 
        if (poLabelStyle == NULL
1059
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelPriority, bDefault)) == NULL))
1060
 
           values[i] = strdup("0");
1061
 
        else
1062
 
           values[i] = strdup(pszValue);
1063
 
 
1064
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1065
 
            msDebug(MSOGR_LABELPRIORITYNAME " = \"%s\"\n", values[i]);
1066
 
    }
1067
 
#if GDAL_VERSION_NUM >= 1400
1068
 
    else if (itemindexes[i] == MSOGR_LABELSTRIKEOUTINDEX)
1069
 
    {
1070
 
        if (poLabelStyle == NULL
1071
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelStrikeout, bDefault)) == NULL))
1072
 
            values[i] = strdup("0");
1073
 
        else
1074
 
           values[i] = strdup(pszValue);
1075
 
 
1076
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1077
 
            msDebug(MSOGR_LABELSTRIKEOUTNAME " = \"%s\"\n", values[i]);
1078
 
    }
1079
 
    else if (itemindexes[i] == MSOGR_LABELSTRETCHINDEX)
1080
 
    {
1081
 
        if (poLabelStyle == NULL
1082
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelStretch, bDefault)) == NULL))
1083
 
           values[i] = strdup("0");
1084
 
        else
1085
 
           values[i] = strdup(pszValue);
1086
 
 
1087
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1088
 
            msDebug(MSOGR_LABELSTRETCHNAME " = \"%s\"\n", values[i]);
1089
 
    }
1090
 
    else if (itemindexes[i] == MSOGR_LABELADJHORINDEX)
1091
 
    {
1092
 
        if (poLabelStyle == NULL
1093
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAdjHor, bDefault)) == NULL))
1094
 
           values[i] = strdup("");
1095
 
        else
1096
 
           values[i] = strdup(pszValue);
1097
 
 
1098
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1099
 
            msDebug(MSOGR_LABELADJHORNAME " = \"%s\"\n", values[i]);
1100
 
    }
1101
 
    else if (itemindexes[i] == MSOGR_LABELADJVERTINDEX)
1102
 
    {
1103
 
        if (poLabelStyle == NULL
1104
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAdjVert, bDefault)) == NULL))
1105
 
           values[i] = strdup("");
1106
 
        else
1107
 
           values[i] = strdup(pszValue);
1108
 
 
1109
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1110
 
            msDebug(MSOGR_LABELADJVERTNAME " = \"%s\"\n", values[i]);
1111
 
    }
1112
 
    else if (itemindexes[i] == MSOGR_LABELHCOLORINDEX)
1113
 
    {
1114
 
        if (poLabelStyle == NULL
1115
 
            || ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelHColor, bDefault)) == NULL))
1116
 
            values[i] = strdup("");
1117
 
        else
1118
 
           values[i] = strdup(pszValue);
1119
 
 
1120
 
        if (layer->debug >= MS_DEBUGLEVEL_VVV)
1121
 
            msDebug(MSOGR_LABELHCOLORNAME " = \"%s\"\n", values[i]);
1122
 
    }
1123
 
#endif
1124
 
    else
1125
 
    {
1126
 
        msSetError(MS_OGRERR,"Invalid field index!?!","msOGRGetValues()");
1127
 
        return(NULL);
1128
 
    }
1129
 
  }
1130
 
#endif /* OGRStyle C API */
1131
 
  }
1132
 
 
1133
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
1134
 
  OGR_SM_Destroy(hStyleMgr);
1135
 
  OGR_ST_Destroy(hLabelStyle);
1136
 
#else
1137
 
  delete poStyleMgr;
1138
 
  delete poLabelStyle;
1139
 
#endif
1140
 
 
1141
 
  return(values);
1142
 
}
1143
 
 
1144
 
#endif  /* USE_OGR */
1145
 
 
1146
 
#if defined(USE_OGR) || defined(USE_GDAL)
1147
 
 
1148
 
/**********************************************************************
1149
 
 *                     msOGRSpatialRef2ProjectionObj()
1150
 
 *
1151
 
 * Init a MapServer projectionObj using an OGRSpatialRef
1152
 
 * Works only with PROJECTION AUTO
1153
 
 *
1154
 
 * Returns MS_SUCCESS/MS_FAILURE
1155
 
 **********************************************************************/
1156
 
static int msOGRSpatialRef2ProjectionObj(OGRSpatialReferenceH hSRS,
1157
 
                                         projectionObj *proj, int debug_flag )
1158
 
{
1159
 
#ifdef USE_PROJ
1160
 
  // First flush the "auto" name from the projargs[]... 
1161
 
  msFreeProjection( proj );
1162
 
 
1163
 
  if (hSRS == NULL || OSRIsLocal( hSRS ) )
1164
 
  {
1165
 
      // Dataset had no set projection or is NonEarth (LOCAL_CS)... 
1166
 
      // Nothing else to do. Leave proj empty and no reprojection will happen!
1167
 
      return MS_SUCCESS;  
1168
 
  }
1169
 
 
1170
 
  // Export OGR SRS to a PROJ4 string
1171
 
  char *pszProj = NULL;
1172
 
 
1173
 
  ACQUIRE_OLD_OGR_LOCK;
1174
 
  if (OSRExportToProj4( hSRS, &pszProj ) != OGRERR_NONE ||
1175
 
      pszProj == NULL || strlen(pszProj) == 0)
1176
 
  {
1177
 
      RELEASE_OLD_OGR_LOCK;
1178
 
      msSetError(MS_OGRERR, "Conversion from OGR SRS to PROJ4 failed.",
1179
 
                 "msOGRSpatialRef2ProjectionObj()");
1180
 
      CPLFree(pszProj);
1181
 
      return(MS_FAILURE);
1182
 
  }
1183
 
 
1184
 
  RELEASE_OLD_OGR_LOCK;
1185
 
 
1186
 
  if( debug_flag )
1187
 
      msDebug( "AUTO = %s\n", pszProj );
1188
 
 
1189
 
  if( msLoadProjectionString( proj, pszProj ) != 0 )
1190
 
      return MS_FAILURE;
1191
 
 
1192
 
  CPLFree(pszProj);
1193
 
#endif
1194
 
 
1195
 
  return MS_SUCCESS;
1196
 
}
1197
 
#endif // defined(USE_OGR) || defined(USE_GDAL)
1198
 
 
1199
 
/**********************************************************************
1200
 
 *                     msOGCWKT2ProjectionObj()
1201
 
 *
1202
 
 * Init a MapServer projectionObj using an OGC WKT definition.
1203
 
 * Works only with PROJECTION AUTO
1204
 
 *
1205
 
 * Returns MS_SUCCESS/MS_FAILURE
1206
 
 **********************************************************************/
1207
 
 
1208
 
int msOGCWKT2ProjectionObj( const char *pszWKT, 
1209
 
                            projectionObj *proj,
1210
 
                            int debug_flag )
1211
 
 
1212
 
{
1213
 
#if defined(USE_OGR) || defined(USE_GDAL)
1214
 
 
1215
 
    OGRSpatialReferenceH        hSRS;
1216
 
    char                        *pszAltWKT = (char *) pszWKT;
1217
 
    OGRErr  eErr;
1218
 
    int     ms_result;
1219
 
 
1220
 
    ACQUIRE_OLD_OGR_LOCK;
1221
 
    hSRS = OSRNewSpatialReference( NULL );
1222
 
 
1223
 
    if( !EQUALN(pszWKT,"GEOGCS",6) 
1224
 
        && !EQUALN(pszWKT,"PROJCS",6)
1225
 
        && !EQUALN(pszWKT,"LOCAL_CS",8) )
1226
 
        eErr = OSRSetFromUserInput( hSRS, pszWKT );
1227
 
    else
1228
 
        eErr = OSRImportFromWkt( hSRS, &pszAltWKT );
1229
 
 
1230
 
    RELEASE_OLD_OGR_LOCK;
1231
 
 
1232
 
    if( eErr != OGRERR_NONE )
1233
 
    {
1234
 
        OSRDestroySpatialReference( hSRS );
1235
 
        msSetError(MS_OGRERR, 
1236
 
                   "Ingestion of WKT string '%s' failed.",
1237
 
                   "msOGCWKT2ProjectionObj()",
1238
 
                   pszWKT );
1239
 
        return MS_FAILURE;
1240
 
    }
1241
 
 
1242
 
    ms_result = msOGRSpatialRef2ProjectionObj( hSRS, proj, debug_flag );
1243
 
 
1244
 
    OSRDestroySpatialReference( hSRS );
1245
 
    return ms_result;
1246
 
#else
1247
 
    msSetError(MS_OGRERR, 
1248
 
               "Not implemented since neither OGR nor GDAL is enabled.",
1249
 
               "msOGCWKT2ProjectionObj()");
1250
 
    return MS_FAILURE;
1251
 
#endif
1252
 
}
1253
 
 
1254
 
/* ==================================================================
1255
 
 * The following functions closely relate to the API called from
1256
 
 * maplayer.c, but are intended to be used for the tileindex or direct
1257
 
 * layer access.
1258
 
 * ================================================================== */
1259
 
 
1260
 
#ifdef USE_OGR
1261
 
 
1262
 
/**********************************************************************
1263
 
 *                     msOGRFileOpen()
1264
 
 *
1265
 
 * Open an OGR connection, and initialize a msOGRFileInfo.
1266
 
 **********************************************************************/
1267
 
 
1268
 
static int bOGRDriversRegistered = MS_FALSE;
1269
 
 
1270
 
static msOGRFileInfo *
1271
 
msOGRFileOpen(layerObj *layer, const char *connection ) 
1272
 
 
1273
 
{
1274
 
  char *conn_decrypted = NULL;
1275
 
 
1276
 
/* ------------------------------------------------------------------
1277
 
 * Register OGR Drivers, only once per execution
1278
 
 * ------------------------------------------------------------------ */
1279
 
  if (!bOGRDriversRegistered)
1280
 
  {
1281
 
      ACQUIRE_OGR_LOCK;
1282
 
 
1283
 
      OGRRegisterAll();
1284
 
      CPLPushErrorHandler( CPLQuietErrorHandler );
1285
 
 
1286
 
/* ------------------------------------------------------------------
1287
 
 * Pass config option GML_FIELDTYPES=ALWAYS_STRING to OGR so that all
1288
 
 * GML attributes are returned as strings to MapServer. This is most efficient
1289
 
 * and prevents problems with autodetection of some attribute types.
1290
 
 * ------------------------------------------------------------------ */
1291
 
      CPLSetConfigOption("GML_FIELDTYPES","ALWAYS_STRING");
1292
 
 
1293
 
      bOGRDriversRegistered = MS_TRUE;
1294
 
      
1295
 
      RELEASE_OGR_LOCK;
1296
 
  }
1297
 
 
1298
 
/* ------------------------------------------------------------------
1299
 
 * Make sure any encrypted token in the connection string are decrypted
1300
 
 * ------------------------------------------------------------------ */
1301
 
  if (connection)
1302
 
  {
1303
 
      conn_decrypted = msDecryptStringTokens(layer->map, connection);
1304
 
      if (conn_decrypted == NULL)
1305
 
          return NULL;  /* An error should already have been reported */
1306
 
  }
1307
 
 
1308
 
/* ------------------------------------------------------------------
1309
 
 * Parse connection string into dataset name, and layer name. 
1310
 
 * ------------------------------------------------------------------ */
1311
 
  char *pszDSName = NULL, *pszLayerDef = NULL;
1312
 
 
1313
 
  if( conn_decrypted == NULL )
1314
 
  {
1315
 
      /* we don't have anything */
1316
 
  }
1317
 
  else if( layer->data != NULL )
1318
 
  {
1319
 
      pszDSName = CPLStrdup(conn_decrypted);
1320
 
      pszLayerDef = CPLStrdup(layer->data);
1321
 
  }
1322
 
  else
1323
 
  {
1324
 
      char **papszTokens = NULL;
1325
 
 
1326
 
      papszTokens = CSLTokenizeStringComplex( conn_decrypted, ",", TRUE, FALSE );
1327
 
 
1328
 
      if( CSLCount(papszTokens) > 0 )
1329
 
          pszDSName = CPLStrdup( papszTokens[0] );
1330
 
      if( CSLCount(papszTokens) > 1 )
1331
 
          pszLayerDef = CPLStrdup( papszTokens[1] );
1332
 
 
1333
 
      CSLDestroy(papszTokens);
1334
 
  }
1335
 
 
1336
 
  /* Get rid of decrypted connection string. We'll use the original (not
1337
 
   * decrypted) string for debug and error messages in the rest of the code.
1338
 
   */
1339
 
  msFree(conn_decrypted);
1340
 
  conn_decrypted = NULL;
1341
 
 
1342
 
  if( pszDSName == NULL )
1343
 
  {
1344
 
      msSetError(MS_OGRERR, 
1345
 
                 "Error parsing OGR connection information in layer `%s'", 
1346
 
                 "msOGRFileOpen()",
1347
 
                 layer->name?layer->name:"(null)" );
1348
 
      return NULL;
1349
 
  }
1350
 
 
1351
 
  if( pszLayerDef == NULL )
1352
 
      pszLayerDef = CPLStrdup("0");
1353
 
 
1354
 
/* -------------------------------------------------------------------- */
1355
 
/*      Can we get an existing connection for this layer?               */
1356
 
/* -------------------------------------------------------------------- */
1357
 
  OGRDataSourceH hDS;
1358
 
 
1359
 
  hDS = (OGRDataSourceH) msConnPoolRequest( layer );
1360
 
 
1361
 
/* -------------------------------------------------------------------- */
1362
 
/*      If not, open now, and register this connection with the         */
1363
 
/*      pool.                                                           */
1364
 
/* -------------------------------------------------------------------- */
1365
 
  if( hDS == NULL )
1366
 
  {
1367
 
      char szPath[MS_MAXPATHLEN] = "";
1368
 
      const char *pszDSSelectedName = pszDSName;
1369
 
      
1370
 
      if( layer->debug )
1371
 
          msDebug("msOGRFileOpen(%s)...\n", connection);
1372
 
      
1373
 
      CPLErrorReset();
1374
 
      if (msTryBuildPath3(szPath, layer->map->mappath, 
1375
 
                          layer->map->shapepath, pszDSName) != NULL ||
1376
 
          msTryBuildPath(szPath, layer->map->mappath, pszDSName) != NULL)
1377
 
      {
1378
 
          /* Use relative path */
1379
 
          pszDSSelectedName = szPath;
1380
 
      }
1381
 
      
1382
 
      if( layer->debug )
1383
 
          msDebug("OGROPen(%s)\n", pszDSSelectedName);
1384
 
 
1385
 
      ACQUIRE_OGR_LOCK;
1386
 
      hDS = OGROpen( pszDSSelectedName, MS_FALSE, NULL );
1387
 
      RELEASE_OGR_LOCK;
1388
 
      
1389
 
      if( hDS == NULL )
1390
 
      {
1391
 
          if( strlen(CPLGetLastErrorMsg()) == 0 )
1392
 
              msSetError(MS_OGRERR, 
1393
 
                         "Open failed for OGR connection in layer `%s'.  "
1394
 
                         "File not found or unsupported format.", 
1395
 
                         "msOGRFileOpen()",
1396
 
                         layer->name?layer->name:"(null)" );
1397
 
          else
1398
 
              msSetError(MS_OGRERR, 
1399
 
                         "Open failed for OGR connection in layer `%s'.\n%s\n",
1400
 
                         "msOGRFileOpen()", 
1401
 
                         layer->name?layer->name:"(null)", 
1402
 
                         CPLGetLastErrorMsg() );
1403
 
          CPLFree( pszDSName );
1404
 
          CPLFree( pszLayerDef );
1405
 
          return NULL;
1406
 
      }
1407
 
 
1408
 
      msConnPoolRegister( layer, hDS, msOGRCloseConnection );
1409
 
  }
1410
 
      
1411
 
  CPLFree( pszDSName );
1412
 
  pszDSName = NULL;
1413
 
 
1414
 
/* ------------------------------------------------------------------
1415
 
 * Find the layer selected.
1416
 
 * ------------------------------------------------------------------ */
1417
 
  
1418
 
  int   nLayerIndex = 0;
1419
 
  OGRLayerH     hLayer = NULL;
1420
 
 
1421
 
  int  iLayer;
1422
 
 
1423
 
  for( iLayer = 0; iLayer < OGR_DS_GetLayerCount(hDS); iLayer++ )
1424
 
  {
1425
 
      hLayer = OGR_DS_GetLayer( hDS, iLayer );
1426
 
      if( hLayer != NULL 
1427
 
          && EQUAL(OGR_FD_GetName( OGR_L_GetLayerDefn(hLayer) ),pszLayerDef) )
1428
 
      {
1429
 
          nLayerIndex = iLayer;
1430
 
          break;
1431
 
      }
1432
 
      else
1433
 
          hLayer = NULL;
1434
 
  }
1435
 
  
1436
 
  if( hLayer == NULL && (atoi(pszLayerDef) > 0 || EQUAL(pszLayerDef,"0")) )
1437
 
  {
1438
 
      nLayerIndex = atoi(pszLayerDef);
1439
 
      if( nLayerIndex <  OGR_DS_GetLayerCount(hDS) )
1440
 
          hLayer = OGR_DS_GetLayer( hDS, nLayerIndex );
1441
 
  }
1442
 
 
1443
 
  if( hLayer == NULL && EQUALN(pszLayerDef,"SELECT",6) )
1444
 
  {
1445
 
      ACQUIRE_OGR_LOCK;
1446
 
      hLayer = OGR_DS_ExecuteSQL( hDS, pszLayerDef, NULL, NULL );
1447
 
      if( hLayer == NULL )
1448
 
      {
1449
 
          msSetError(MS_OGRERR, 
1450
 
                     "ExecuteSQL(%s) failed.\n%s",
1451
 
                     "msOGRFileOpen()", 
1452
 
                     pszLayerDef, CPLGetLastErrorMsg() );
1453
 
          OGR_DS_Destroy( hDS );
1454
 
          CPLFree( pszLayerDef );
1455
 
          RELEASE_OGR_LOCK;
1456
 
          return NULL;
1457
 
      }
1458
 
      RELEASE_OGR_LOCK;
1459
 
      nLayerIndex = -1;
1460
 
  }
1461
 
 
1462
 
  if (hLayer == NULL)
1463
 
  {
1464
 
      msSetError(MS_OGRERR, "GetLayer(%s) failed for OGR connection `%s'.",
1465
 
                 "msOGRFileOpen()", 
1466
 
                 pszLayerDef, connection );
1467
 
      CPLFree( pszLayerDef );
1468
 
      ACQUIRE_OGR_LOCK;
1469
 
      OGR_DS_Destroy( hDS );
1470
 
      RELEASE_OGR_LOCK;
1471
 
      return NULL;
1472
 
  }
1473
 
 
1474
 
  CPLFree( pszLayerDef );
1475
 
 
1476
 
/* ------------------------------------------------------------------
1477
 
 * OK... open succeded... alloc and fill msOGRFileInfo inside layer obj
1478
 
 * ------------------------------------------------------------------ */
1479
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)CPLCalloc(1,sizeof(msOGRFileInfo));
1480
 
 
1481
 
  psInfo->pszFname = CPLStrdup(OGR_DS_GetName( hDS ));
1482
 
  psInfo->nLayerIndex = nLayerIndex;
1483
 
  psInfo->hDS = hDS;
1484
 
  psInfo->hLayer = hLayer;
1485
 
 
1486
 
  psInfo->nTileId = 0;
1487
 
  psInfo->poCurTile = NULL;
1488
 
  psInfo->rect.minx = psInfo->rect.maxx = 0;
1489
 
  psInfo->rect.miny = psInfo->rect.maxy = 0;
1490
 
  psInfo->last_record_index_read = -1;
1491
 
 
1492
 
  return psInfo;
1493
 
}
1494
 
 
1495
 
/************************************************************************/
1496
 
/*                        msOGRCloseConnection()                        */
1497
 
/*                                                                      */
1498
 
/*      Callback for thread pool to actually release an OGR             */
1499
 
/*      connection.                                                     */
1500
 
/************************************************************************/
1501
 
 
1502
 
static void msOGRCloseConnection( void *conn_handle )
1503
 
 
1504
 
{
1505
 
    OGRDataSourceH hDS = (OGRDataSourceH) conn_handle;
1506
 
 
1507
 
    ACQUIRE_OGR_LOCK;
1508
 
    OGR_DS_Destroy( hDS );
1509
 
    RELEASE_OGR_LOCK;
1510
 
}
1511
 
 
1512
 
/**********************************************************************
1513
 
 *                     msOGRFileClose()
1514
 
 **********************************************************************/
1515
 
static int msOGRFileClose(layerObj *layer, msOGRFileInfo *psInfo ) 
1516
 
{
1517
 
  if (!psInfo)
1518
 
      return MS_SUCCESS;
1519
 
 
1520
 
  if( layer->debug )
1521
 
      msDebug("msOGRFileClose(%s,%d).\n", 
1522
 
              psInfo->pszFname, psInfo->nLayerIndex);
1523
 
 
1524
 
  CPLFree(psInfo->pszFname);
1525
 
 
1526
 
  ACQUIRE_OGR_LOCK;
1527
 
  if (psInfo->hLastFeature)
1528
 
      OGR_F_Destroy( psInfo->hLastFeature );
1529
 
 
1530
 
  /* If nLayerIndex == -1 then the layer is an SQL result ... free it */
1531
 
  if( psInfo->nLayerIndex == -1 )
1532
 
      OGR_DS_ReleaseResultSet( psInfo->hDS, psInfo->hLayer );
1533
 
 
1534
 
  // Release (potentially close) the datasource connection.
1535
 
  // Make sure we aren't holding the lock when the callback may need it.
1536
 
  RELEASE_OGR_LOCK;
1537
 
  msConnPoolRelease( layer, psInfo->hDS );
1538
 
  ACQUIRE_OGR_LOCK;
1539
 
 
1540
 
  // Free current tile if there is one.
1541
 
  if( psInfo->poCurTile != NULL )
1542
 
      msOGRFileClose( layer, psInfo->poCurTile );
1543
 
 
1544
 
  CPLFree(psInfo);
1545
 
 
1546
 
  RELEASE_OGR_LOCK;
1547
 
 
1548
 
  return MS_SUCCESS;
1549
 
}
1550
 
 
1551
 
/**********************************************************************
1552
 
 *                     msOGRFileWhichShapes()
1553
 
 *
1554
 
 * Init OGR layer structs ready for calls to msOGRFileNextShape().
1555
 
 *
1556
 
 * Returns MS_SUCCESS/MS_FAILURE, or MS_DONE if no shape matching the
1557
 
 * layer's FILTER overlaps the selected region.
1558
 
 **********************************************************************/
1559
 
static int msOGRFileWhichShapes(layerObj *layer, rectObj rect,
1560
 
                                msOGRFileInfo *psInfo ) 
1561
 
{
1562
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
1563
 
  {
1564
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
1565
 
               "msOGRFileWhichShapes()");
1566
 
    return(MS_FAILURE);
1567
 
  }
1568
 
 
1569
 
/* ------------------------------------------------------------------
1570
 
 * Set Spatial filter... this may result in no features being returned
1571
 
 * if layer does not overlap current view.
1572
 
 *
1573
 
 * __TODO__ We should return MS_DONE if no shape overlaps the selected 
1574
 
 * region and matches the layer's FILTER expression, but there is currently
1575
 
 * no _efficient_ way to do that with OGR.
1576
 
 * ------------------------------------------------------------------ */
1577
 
  ACQUIRE_OGR_LOCK;
1578
 
 
1579
 
  OGRGeometryH hSpatialFilterPolygon = OGR_G_CreateGeometry( wkbPolygon );
1580
 
  OGRGeometryH hRing = OGR_G_CreateGeometry( wkbLinearRing );
1581
 
 
1582
 
#if GDAL_VERSION_NUM >= 1310
1583
 
  OGR_G_AddPoint_2D( hRing, rect.minx, rect.miny);
1584
 
  OGR_G_AddPoint_2D( hRing, rect.maxx, rect.miny);
1585
 
  OGR_G_AddPoint_2D( hRing, rect.maxx, rect.maxy);
1586
 
  OGR_G_AddPoint_2D( hRing, rect.minx, rect.maxy);
1587
 
  OGR_G_AddPoint_2D( hRing, rect.minx, rect.miny);
1588
 
#else
1589
 
  OGR_G_AddPoint( hRing, rect.minx, rect.miny, 0);
1590
 
  OGR_G_AddPoint( hRing, rect.maxx, rect.miny, 0);
1591
 
  OGR_G_AddPoint( hRing, rect.maxx, rect.maxy, 0);
1592
 
  OGR_G_AddPoint( hRing, rect.minx, rect.maxy, 0);
1593
 
  OGR_G_AddPoint( hRing, rect.minx, rect.miny, 0);
1594
 
#endif
1595
 
 
1596
 
  OGR_G_AddGeometryDirectly( hSpatialFilterPolygon, hRing );
1597
 
 
1598
 
  OGR_L_SetSpatialFilter( psInfo->hLayer, hSpatialFilterPolygon );
1599
 
 
1600
 
  OGR_G_DestroyGeometry( hSpatialFilterPolygon );
1601
 
 
1602
 
  psInfo->rect = rect;
1603
 
 
1604
 
  if (layer->debug >= MS_DEBUGLEVEL_VVV)
1605
 
      msDebug("msOGRFileWhichShapes: Setting spatial filter to %f %f %f %f\n",
1606
 
              rect.minx, rect.miny, rect.maxx, rect.maxy );
1607
 
 
1608
 
/* ------------------------------------------------------------------
1609
 
 * Apply an attribute filter if we have one prefixed with a WHERE 
1610
 
 * keyword in the filter string.  Otherwise, ensure the attribute
1611
 
 * filter is clear. 
1612
 
 * ------------------------------------------------------------------ */
1613
 
  if( layer->filter.string && EQUALN(layer->filter.string,"WHERE ",6) )
1614
 
  {
1615
 
      CPLErrorReset();
1616
 
      if( OGR_L_SetAttributeFilter( psInfo->hLayer, layer->filter.string+6 )
1617
 
          != OGRERR_NONE )
1618
 
      {
1619
 
          msSetError(MS_OGRERR,
1620
 
                     "SetAttributeFilter(%s) failed on layer %s.\n%s", 
1621
 
                     "msOGRFileWhichShapes()",
1622
 
                     layer->filter.string+6, layer->name?layer->name:"(null)", 
1623
 
                     CPLGetLastErrorMsg() );
1624
 
          RELEASE_OGR_LOCK;
1625
 
          return MS_FAILURE;
1626
 
      }
1627
 
  }
1628
 
  else
1629
 
      OGR_L_SetAttributeFilter( psInfo->hLayer, NULL );
1630
 
 
1631
 
/* ------------------------------------------------------------------
1632
 
 * Reset current feature pointer
1633
 
 * ------------------------------------------------------------------ */
1634
 
  OGR_L_ResetReading( psInfo->hLayer );
1635
 
  psInfo->last_record_index_read = -1;
1636
 
 
1637
 
  RELEASE_OGR_LOCK;
1638
 
 
1639
 
  return MS_SUCCESS;
1640
 
}
1641
 
 
1642
 
/**********************************************************************
1643
 
 *                     msOGRFileGetItems()
1644
 
 *
1645
 
 * Returns a list of field names in a NULL terminated list of strings.
1646
 
 **********************************************************************/
1647
 
static char **msOGRFileGetItems(layerObj *layer, msOGRFileInfo *psInfo )
1648
 
{
1649
 
  OGRFeatureDefnH hDefn;
1650
 
  int i, numitems,totalnumitems;
1651
 
  int numStyleItems = MSOGR_LABELNUMITEMS;
1652
 
  char **items;
1653
 
  const char *getShapeStyleItems;
1654
 
 
1655
 
  if((hDefn = OGR_L_GetLayerDefn( psInfo->hLayer )) == NULL) 
1656
 
  {
1657
 
    msSetError(MS_OGRERR, 
1658
 
               "OGR Connection for layer `%s' contains no field definition.", 
1659
 
               "msOGRFileGetItems()",
1660
 
               layer->name?layer->name:"(null)" );
1661
 
    return NULL;
1662
 
  }
1663
 
 
1664
 
  totalnumitems = numitems = OGR_FD_GetFieldCount( hDefn );
1665
 
 
1666
 
  getShapeStyleItems = msLayerGetProcessingKey( layer, "GETSHAPE_STYLE_ITEMS" );
1667
 
  if (getShapeStyleItems && EQUAL(getShapeStyleItems, "all"))
1668
 
      totalnumitems += numStyleItems;
1669
 
 
1670
 
  if((items = (char**)malloc(sizeof(char *)*(totalnumitems+1))) == NULL) 
1671
 
  {
1672
 
    msSetError(MS_MEMERR, NULL, "msOGRFileGetItems()");
1673
 
    return NULL;
1674
 
  }
1675
 
 
1676
 
  for(i=0;i<numitems;i++)
1677
 
  {
1678
 
      OGRFieldDefnH hField = OGR_FD_GetFieldDefn( hDefn, i );
1679
 
      items[i] = strdup( OGR_Fld_GetNameRef( hField ));
1680
 
  }
1681
 
 
1682
 
  if (getShapeStyleItems && EQUAL(getShapeStyleItems, "all"))
1683
 
  {
1684
 
      assert(numStyleItems == 21);
1685
 
      items[i++] = strdup( MSOGR_LABELFONTNAMENAME );
1686
 
      items[i++] = strdup( MSOGR_LABELSIZENAME );
1687
 
      items[i++] = strdup( MSOGR_LABELTEXTNAME );
1688
 
      items[i++] = strdup( MSOGR_LABELANGLENAME );
1689
 
      items[i++] = strdup( MSOGR_LABELFCOLORNAME );
1690
 
      items[i++] = strdup( MSOGR_LABELBCOLORNAME );
1691
 
      items[i++] = strdup( MSOGR_LABELPLACEMENTNAME );
1692
 
      items[i++] = strdup( MSOGR_LABELANCHORNAME );
1693
 
      items[i++] = strdup( MSOGR_LABELDXNAME );
1694
 
      items[i++] = strdup( MSOGR_LABELDYNAME );
1695
 
      items[i++] = strdup( MSOGR_LABELPERPNAME );
1696
 
      items[i++] = strdup( MSOGR_LABELBOLDNAME );
1697
 
      items[i++] = strdup( MSOGR_LABELITALICNAME );
1698
 
      items[i++] = strdup( MSOGR_LABELUNDERLINENAME );
1699
 
      items[i++] = strdup( MSOGR_LABELPRIORITYNAME );
1700
 
      items[i++] = strdup( MSOGR_LABELSTRIKEOUTNAME );
1701
 
      items[i++] = strdup( MSOGR_LABELSTRETCHNAME );
1702
 
      items[i++] = strdup( MSOGR_LABELADJHORNAME );
1703
 
      items[i++] = strdup( MSOGR_LABELADJVERTNAME );
1704
 
      items[i++] = strdup( MSOGR_LABELHCOLORNAME );
1705
 
      items[i++] = strdup( MSOGR_LABELOCOLORNAME );
1706
 
  }
1707
 
  items[i++] = NULL;
1708
 
 
1709
 
  return items;
1710
 
}
1711
 
 
1712
 
/**********************************************************************
1713
 
 *                     msOGRFileNextShape()
1714
 
 *
1715
 
 * Returns shape sequentially from OGR data source.
1716
 
 * msOGRLayerWhichShape() must have been called first.
1717
 
 *
1718
 
 * Returns MS_SUCCESS/MS_FAILURE
1719
 
 **********************************************************************/
1720
 
static int 
1721
 
msOGRFileNextShape(layerObj *layer, shapeObj *shape,
1722
 
                   msOGRFileInfo *psInfo ) 
1723
 
{
1724
 
  OGRFeatureH hFeature = NULL;
1725
 
 
1726
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
1727
 
  {
1728
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
1729
 
               "msOGRFileNextShape()");
1730
 
    return(MS_FAILURE);
1731
 
  }
1732
 
 
1733
 
/* ------------------------------------------------------------------
1734
 
 * Read until we find a feature that matches attribute filter and 
1735
 
 * whose geometry is compatible with current layer type.
1736
 
 * ------------------------------------------------------------------ */
1737
 
  msFreeShape(shape);
1738
 
  shape->type = MS_SHAPE_NULL;
1739
 
 
1740
 
  ACQUIRE_OGR_LOCK;
1741
 
  while (shape->type == MS_SHAPE_NULL)
1742
 
  {
1743
 
      if( hFeature )
1744
 
          OGR_F_Destroy( hFeature );
1745
 
 
1746
 
      if( (hFeature = OGR_L_GetNextFeature( psInfo->hLayer )) == NULL )
1747
 
      {
1748
 
          psInfo->last_record_index_read = -1;
1749
 
          if( CPLGetLastErrorType() == CE_Failure )
1750
 
          {
1751
 
              msSetError(MS_OGRERR, "%s", "msOGRFileNextShape()",
1752
 
                         CPLGetLastErrorMsg() );
1753
 
              RELEASE_OGR_LOCK;
1754
 
              return MS_FAILURE;
1755
 
          }
1756
 
          else
1757
 
          {
1758
 
              RELEASE_OGR_LOCK;
1759
 
              if (layer->debug >= MS_DEBUGLEVEL_VV)
1760
 
                  msDebug("msOGRFileNextShape: Returning MS_DONE (no more shapes)\n" );
1761
 
              return MS_DONE;  // No more features to read
1762
 
          }
1763
 
      }
1764
 
 
1765
 
      psInfo->last_record_index_read++;
1766
 
 
1767
 
      if(layer->numitems > 0) 
1768
 
      {
1769
 
          shape->values = msOGRGetValues(layer, hFeature);
1770
 
          shape->numvalues = layer->numitems;
1771
 
          if(!shape->values)
1772
 
          {
1773
 
              OGR_F_Destroy( hFeature );
1774
 
              RELEASE_OGR_LOCK;
1775
 
              return(MS_FAILURE);
1776
 
          }
1777
 
      }
1778
 
 
1779
 
      // Check the expression unless it is a WHERE clause already 
1780
 
      // handled by OGR. 
1781
 
      if( (layer->filter.string && EQUALN(layer->filter.string,"WHERE ",6))
1782
 
          || msEvalExpression(&(layer->filter), layer->filteritemindex, 
1783
 
                              shape->values, layer->numitems) == MS_TRUE)
1784
 
      {
1785
 
          // Feature matched filter expression... process geometry
1786
 
          // shape->type will be set if geom is compatible with layer type
1787
 
          if (ogrConvertGeometry(OGR_F_GetGeometryRef( hFeature ), shape,
1788
 
                                 layer->type) == MS_SUCCESS)
1789
 
          {
1790
 
              if (shape->type != MS_SHAPE_NULL)
1791
 
                  break; // Shape is ready to be returned!
1792
 
 
1793
 
              if (layer->debug >= MS_DEBUGLEVEL_VVV)
1794
 
                  msDebug("msOGRFileNextShape: Rejecting feature (shapeid = %d, tileid=%d) of incompatible type for this layer (feature wkbType %d, layer type %d)\n",
1795
 
                          OGR_F_GetFID( hFeature ), psInfo->nTileId, 
1796
 
                          wkbFlatten( OGR_G_GetGeometryType( OGR_F_GetGeometryRef( hFeature ) ) ), 
1797
 
                          layer->type);
1798
 
 
1799
 
          }
1800
 
          else
1801
 
          {
1802
 
              msFreeShape(shape);
1803
 
              OGR_F_Destroy( hFeature );
1804
 
              RELEASE_OGR_LOCK;
1805
 
              return MS_FAILURE; // Error message already produced.
1806
 
          }
1807
 
      }
1808
 
 
1809
 
      // Feature rejected... free shape to clear attributes values.
1810
 
      msFreeShape(shape);
1811
 
      shape->type = MS_SHAPE_NULL;
1812
 
  }
1813
 
 
1814
 
  shape->index = psInfo->last_record_index_read;
1815
 
  shape->tileindex = psInfo->nTileId;
1816
 
 
1817
 
  if (layer->debug >= MS_DEBUGLEVEL_VVV)
1818
 
      msDebug("msOGRFileNextShape: Returning shape=%d, tile=%d\n",
1819
 
              shape->index, shape->tileindex );
1820
 
 
1821
 
  // Keep ref. to last feature read in case we need style info.
1822
 
  if (psInfo->hLastFeature)
1823
 
      OGR_F_Destroy( psInfo->hLastFeature );
1824
 
  psInfo->hLastFeature = hFeature;
1825
 
 
1826
 
  RELEASE_OGR_LOCK;
1827
 
 
1828
 
  return MS_SUCCESS;
1829
 
}
1830
 
 
1831
 
/**********************************************************************
1832
 
 *                     msOGRFileGetShape()
1833
 
 *
1834
 
 * Returns shape from OGR data source by id.
1835
 
 *
1836
 
 * Returns MS_SUCCESS/MS_FAILURE
1837
 
 **********************************************************************/
1838
 
static int 
1839
 
msOGRFileGetShape(layerObj *layer, shapeObj *shape, long record,
1840
 
                  msOGRFileInfo *psInfo, int record_is_fid )
1841
 
{
1842
 
  OGRFeatureH hFeature;
1843
 
 
1844
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
1845
 
  {
1846
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
1847
 
               "msOGRFileNextShape()");
1848
 
    return(MS_FAILURE);
1849
 
  }
1850
 
 
1851
 
/* -------------------------------------------------------------------- */
1852
 
/*      Clear previously loaded shape.                                  */
1853
 
/* -------------------------------------------------------------------- */
1854
 
  msFreeShape(shape);
1855
 
  shape->type = MS_SHAPE_NULL;
1856
 
 
1857
 
/* -------------------------------------------------------------------- */
1858
 
/*      Support reading feature by fid.                                 */
1859
 
/* -------------------------------------------------------------------- */
1860
 
  if( record_is_fid )
1861
 
  {
1862
 
      ACQUIRE_OGR_LOCK;
1863
 
      if( (hFeature = OGR_L_GetFeature( psInfo->hLayer, record )) == NULL )
1864
 
      {
1865
 
          RELEASE_OGR_LOCK;
1866
 
          return MS_FAILURE;
1867
 
      }
1868
 
  }
1869
 
 
1870
 
/* -------------------------------------------------------------------- */
1871
 
/*      Support reading shape by offset within the current              */
1872
 
/*      resultset.                                                      */
1873
 
/* -------------------------------------------------------------------- */
1874
 
  else if( !record_is_fid )
1875
 
  {
1876
 
      ACQUIRE_OGR_LOCK;
1877
 
      if( record <= psInfo->last_record_index_read 
1878
 
          || psInfo->last_record_index_read == -1 )
1879
 
      {
1880
 
          OGR_L_ResetReading( psInfo->hLayer );
1881
 
          psInfo->last_record_index_read = -1;
1882
 
      }
1883
 
 
1884
 
      hFeature = NULL;
1885
 
      while( psInfo->last_record_index_read < record )
1886
 
      {
1887
 
          if( hFeature != NULL )
1888
 
          {
1889
 
              OGR_F_Destroy( hFeature );
1890
 
              hFeature = NULL;
1891
 
          }
1892
 
          if( (hFeature = OGR_L_GetNextFeature( psInfo->hLayer )) == NULL )
1893
 
          {
1894
 
              RELEASE_OGR_LOCK;
1895
 
              return MS_FAILURE;
1896
 
          }
1897
 
          psInfo->last_record_index_read++;
1898
 
      }
1899
 
  }
1900
 
 
1901
 
/* ------------------------------------------------------------------
1902
 
 * Handle shape geometry... 
1903
 
 * ------------------------------------------------------------------ */
1904
 
  // shape->type will be set if geom is compatible with layer type
1905
 
  if (ogrConvertGeometry(OGR_F_GetGeometryRef( hFeature ), shape,
1906
 
                         layer->type) != MS_SUCCESS)
1907
 
  {
1908
 
      RELEASE_OGR_LOCK;
1909
 
      return MS_FAILURE; // Error message already produced.
1910
 
  }
1911
 
  
1912
 
  if (shape->type == MS_SHAPE_NULL)
1913
 
  {
1914
 
      msSetError(MS_OGRERR, 
1915
 
                 "Requested feature is incompatible with layer type",
1916
 
                 "msOGRLayerGetShape()");
1917
 
      RELEASE_OGR_LOCK;
1918
 
      return MS_FAILURE;
1919
 
  }
1920
 
 
1921
 
/* ------------------------------------------------------------------
1922
 
 * Process shape attributes
1923
 
 * ------------------------------------------------------------------ */
1924
 
  if(layer->numitems > 0) 
1925
 
  {
1926
 
      shape->values = msOGRGetValues(layer, hFeature);
1927
 
      shape->numvalues = layer->numitems;
1928
 
      if(!shape->values)
1929
 
      {
1930
 
          RELEASE_OGR_LOCK;
1931
 
          return(MS_FAILURE);
1932
 
      }
1933
 
 
1934
 
  }   
1935
 
 
1936
 
  shape->index = record;
1937
 
  shape->tileindex = psInfo->nTileId;
1938
 
 
1939
 
  // Keep ref. to last feature read in case we need style info.
1940
 
  if (psInfo->hLastFeature)
1941
 
      OGR_F_Destroy( psInfo->hLastFeature );
1942
 
  psInfo->hLastFeature = hFeature;
1943
 
 
1944
 
  RELEASE_OGR_LOCK;
1945
 
 
1946
 
  return MS_SUCCESS;
1947
 
}
1948
 
 
1949
 
/************************************************************************/
1950
 
/*                         msOGRFileReadTile()                          */
1951
 
/*                                                                      */
1952
 
/*      Advance to the next tile (or if targetTile is not -1 advance    */
1953
 
/*      to that tile), causing the tile to become the poCurTile in      */
1954
 
/*      the tileindexes psInfo structure.  Returns MS_DONE if there     */
1955
 
/*      are no more available tiles.                                    */
1956
 
/*                                                                      */
1957
 
/*      Newly loaded tiles are automatically "WhichShaped" based on     */
1958
 
/*      the current rectangle.                                          */
1959
 
/************************************************************************/
1960
 
 
1961
 
int msOGRFileReadTile( layerObj *layer, msOGRFileInfo *psInfo, 
1962
 
                       int targetTile = -1 )
1963
 
 
1964
 
{
1965
 
    int nFeatureId;
1966
 
 
1967
 
/* -------------------------------------------------------------------- */
1968
 
/*      Close old tile if one is open.                                  */
1969
 
/* -------------------------------------------------------------------- */
1970
 
    if( psInfo->poCurTile != NULL )
1971
 
    {
1972
 
        msOGRFileClose( layer, psInfo->poCurTile );
1973
 
        psInfo->poCurTile = NULL;
1974
 
    }
1975
 
 
1976
 
/* -------------------------------------------------------------------- */
1977
 
/*      If -2 is passed, then seek reset reading of the tileindex.      */
1978
 
/*      We want to start from the beginning even if this file is        */
1979
 
/*      shared between layers or renders.                               */
1980
 
/* -------------------------------------------------------------------- */
1981
 
    ACQUIRE_OGR_LOCK;
1982
 
    if( targetTile == -2 )
1983
 
    {
1984
 
        OGR_L_ResetReading( psInfo->hLayer );
1985
 
    }
1986
 
        
1987
 
/* -------------------------------------------------------------------- */
1988
 
/*      Get the name (connection string really) of the next tile.       */
1989
 
/* -------------------------------------------------------------------- */
1990
 
    OGRFeatureH hFeature;
1991
 
    char       *connection = NULL;
1992
 
    msOGRFileInfo *psTileInfo = NULL;
1993
 
    int status;
1994
 
 
1995
 
#ifndef IGNORE_MISSING_DATA
1996
 
  NextFile:
1997
 
#endif
1998
 
 
1999
 
    if( targetTile < 0 )
2000
 
        hFeature = OGR_L_GetNextFeature( psInfo->hLayer );
2001
 
    
2002
 
    else
2003
 
        hFeature = OGR_L_GetFeature( psInfo->hLayer, targetTile );
2004
 
 
2005
 
    if( hFeature == NULL )
2006
 
    {
2007
 
        RELEASE_OGR_LOCK;
2008
 
        if( targetTile == -1 )
2009
 
            return MS_DONE;
2010
 
        else
2011
 
            return MS_FAILURE;
2012
 
        
2013
 
    }
2014
 
 
2015
 
    connection = strdup( OGR_F_GetFieldAsString( hFeature, 
2016
 
                                                 layer->tileitemindex ));
2017
 
    
2018
 
    nFeatureId = OGR_F_GetFID( hFeature );
2019
 
 
2020
 
    OGR_F_Destroy( hFeature );
2021
 
                        
2022
 
    RELEASE_OGR_LOCK;
2023
 
 
2024
 
/* -------------------------------------------------------------------- */
2025
 
/*      Open the new tile file.                                         */
2026
 
/* -------------------------------------------------------------------- */
2027
 
    psTileInfo = msOGRFileOpen( layer, connection );
2028
 
 
2029
 
    free( connection );
2030
 
 
2031
 
#ifndef IGNORE_MISSING_DATA
2032
 
    if( psTileInfo == NULL && targetTile == -1 )
2033
 
        goto NextFile;
2034
 
#endif
2035
 
 
2036
 
    if( psTileInfo == NULL )
2037
 
        return MS_FAILURE;
2038
 
 
2039
 
    psTileInfo->nTileId = nFeatureId;
2040
 
 
2041
 
/* -------------------------------------------------------------------- */
2042
 
/*      Initialize the spatial query on this file.                      */
2043
 
/* -------------------------------------------------------------------- */
2044
 
    if( psInfo->rect.minx != 0 || psInfo->rect.maxx != 0 )
2045
 
    {
2046
 
        status = msOGRFileWhichShapes( layer, psInfo->rect, psTileInfo );
2047
 
        if( status != MS_SUCCESS )
2048
 
            return status;
2049
 
    }
2050
 
    
2051
 
    psInfo->poCurTile = psTileInfo;
2052
 
    
2053
 
/* -------------------------------------------------------------------- */
2054
 
/*      Update the iteminfo in case this layer has a different field    */
2055
 
/*      list.                                                           */
2056
 
/* -------------------------------------------------------------------- */
2057
 
    msOGRLayerInitItemInfo( layer );
2058
 
 
2059
 
    return MS_SUCCESS;
2060
 
}
2061
 
 
2062
 
#endif /* def USE_OGR */
2063
 
 
2064
 
/* ==================================================================
2065
 
 * Here comes the REAL stuff... the functions below are called by maplayer.c
2066
 
 * ================================================================== */
2067
 
 
2068
 
/**********************************************************************
2069
 
 *                     msOGRLayerOpen()
2070
 
 *
2071
 
 * Open OGR data source for the specified map layer.
2072
 
 *
2073
 
 * If pszOverrideConnection != NULL then this value is used as the connection
2074
 
 * string instead of lp->connection.  This is used for instance to open
2075
 
 * a WFS layer, in this case lp->connection is the WFS url, but we want
2076
 
 * OGR to open the local file on disk that was previously downloaded.
2077
 
 *
2078
 
 * An OGR connection string is:   <dataset_filename>[,<layer_index>]
2079
 
 *  <dataset_filename>   is file format specific
2080
 
 *  <layer_index>        (optional) is the OGR layer index
2081
 
 *                       default is 0, the first layer.
2082
 
 *
2083
 
 * One can use the "ogrinfo" program to find out the layer indices in a dataset
2084
 
 *
2085
 
 * Returns MS_SUCCESS/MS_FAILURE
2086
 
 **********************************************************************/
2087
 
int msOGRLayerOpen(layerObj *layer, const char *pszOverrideConnection) 
2088
 
{
2089
 
#ifdef USE_OGR
2090
 
 
2091
 
  msOGRFileInfo *psInfo;
2092
 
 
2093
 
  if (layer->layerinfo != NULL)
2094
 
  {
2095
 
      return MS_SUCCESS;  // Nothing to do... layer is already opened
2096
 
  }
2097
 
 
2098
 
/* -------------------------------------------------------------------- */
2099
 
/*      If this is not a tiled layer, just directly open the target.    */
2100
 
/* -------------------------------------------------------------------- */
2101
 
  if( layer->tileindex == NULL )
2102
 
  {
2103
 
      psInfo = msOGRFileOpen( layer, 
2104
 
                              (pszOverrideConnection ? pszOverrideConnection:
2105
 
                                                       layer->connection) );
2106
 
      layer->layerinfo = psInfo;
2107
 
      layer->tileitemindex = -1;
2108
 
      
2109
 
      if( layer->layerinfo == NULL )
2110
 
          return MS_FAILURE;
2111
 
  }
2112
 
 
2113
 
/* -------------------------------------------------------------------- */
2114
 
/*      Otherwise we open the tile index, identify the tile item        */
2115
 
/*      index and try to select the first file matching our query       */
2116
 
/*      region.                                                         */
2117
 
/* -------------------------------------------------------------------- */
2118
 
  else
2119
 
  {
2120
 
      // Open tile index
2121
 
 
2122
 
      psInfo = msOGRFileOpen( layer, layer->tileindex );
2123
 
      layer->layerinfo = psInfo;
2124
 
      
2125
 
      if( layer->layerinfo == NULL )
2126
 
          return MS_FAILURE;
2127
 
 
2128
 
      // Identify TILEITEM
2129
 
 
2130
 
      OGRFeatureDefnH hDefn = OGR_L_GetLayerDefn( psInfo->hLayer );
2131
 
      for( layer->tileitemindex = 0; 
2132
 
           layer->tileitemindex < OGR_FD_GetFieldCount( hDefn )
2133
 
           && !EQUAL( OGR_Fld_GetNameRef( OGR_FD_GetFieldDefn( hDefn, layer->tileitemindex) ),
2134
 
                      layer->tileitem); 
2135
 
           layer->tileitemindex++ ) {}
2136
 
 
2137
 
      if( layer->tileitemindex == OGR_FD_GetFieldCount( hDefn ) )
2138
 
      {
2139
 
          msSetError(MS_OGRERR, 
2140
 
                     "Can't identify TILEITEM %s field in TILEINDEX `%s'.",
2141
 
                     "msOGRLayerOpen()", 
2142
 
                     layer->tileitem, layer->tileindex );
2143
 
          msOGRFileClose( layer, psInfo );
2144
 
          layer->layerinfo = NULL;
2145
 
          return MS_FAILURE;
2146
 
      }
2147
 
  }
2148
 
 
2149
 
/* ------------------------------------------------------------------
2150
 
 * If projection was "auto" then set proj to the dataset's projection.
2151
 
 * For a tile index, it is assume the tile index has the projection.
2152
 
 * ------------------------------------------------------------------ */
2153
 
#ifdef USE_PROJ
2154
 
  if (layer->projection.numargs > 0 && 
2155
 
      EQUAL(layer->projection.args[0], "auto"))
2156
 
  {
2157
 
      ACQUIRE_OGR_LOCK;
2158
 
      OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( psInfo->hLayer );
2159
 
 
2160
 
      if (msOGRSpatialRef2ProjectionObj(hSRS,
2161
 
                                        &(layer->projection),
2162
 
                                        layer->debug ) != MS_SUCCESS)
2163
 
      {
2164
 
          errorObj *ms_error = msGetErrorObj();
2165
 
 
2166
 
          RELEASE_OGR_LOCK;
2167
 
          msSetError(MS_OGRERR, 
2168
 
                     "%s  "
2169
 
                     "PROJECTION AUTO cannot be used for this "
2170
 
                     "OGR connection (in layer `%s').",
2171
 
                     "msOGRLayerOpen()",
2172
 
                     ms_error->message, 
2173
 
                     layer->name?layer->name:"(null)" );
2174
 
          msOGRFileClose( layer, psInfo );
2175
 
          layer->layerinfo = NULL;
2176
 
          return(MS_FAILURE);
2177
 
      }
2178
 
      RELEASE_OGR_LOCK;
2179
 
  }
2180
 
#endif
2181
 
 
2182
 
  return MS_SUCCESS;
2183
 
 
2184
 
#else
2185
 
/* ------------------------------------------------------------------
2186
 
 * OGR Support not included...
2187
 
 * ------------------------------------------------------------------ */
2188
 
 
2189
 
  msSetError(MS_MISCERR, "OGR support is not available.", "msOGRLayerOpen()");
2190
 
  return(MS_FAILURE);
2191
 
 
2192
 
#endif /* USE_OGR */
2193
 
}
2194
 
 
2195
 
/**********************************************************************
2196
 
 *                     msOGRLayerOpenVT()
2197
 
 *
2198
 
 * Overloaded version of msOGRLayerOpen for virtual table architecture
2199
 
 **********************************************************************/
2200
 
static int msOGRLayerOpenVT(layerObj *layer) 
2201
 
{
2202
 
    return msOGRLayerOpen(layer, NULL);
2203
 
}
2204
 
 
2205
 
/**********************************************************************
2206
 
 *                     msOGRLayerClose()
2207
 
 **********************************************************************/
2208
 
int msOGRLayerClose(layerObj *layer) 
2209
 
{
2210
 
#ifdef USE_OGR
2211
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2212
 
 
2213
 
  if (psInfo)
2214
 
  {
2215
 
      if( layer->debug )
2216
 
          msDebug("msOGRLayerClose(%s).\n", layer->connection);
2217
 
 
2218
 
      msOGRFileClose( layer, psInfo );
2219
 
      layer->layerinfo = NULL;
2220
 
  }
2221
 
 
2222
 
  return MS_SUCCESS;
2223
 
 
2224
 
#else
2225
 
/* ------------------------------------------------------------------
2226
 
 * OGR Support not included...
2227
 
 * ------------------------------------------------------------------ */
2228
 
 
2229
 
  msSetError(MS_MISCERR, "OGR support is not available.", "msOGRLayerClose()");
2230
 
  return(MS_FAILURE);
2231
 
 
2232
 
#endif /* USE_OGR */
2233
 
}
2234
 
 
2235
 
/**********************************************************************
2236
 
 *                     msOGRLayerIsOpen()
2237
 
 **********************************************************************/
2238
 
static int msOGRLayerIsOpen(layerObj *layer) 
2239
 
{
2240
 
#ifdef USE_OGR
2241
 
  if (layer->layerinfo)
2242
 
      return MS_TRUE;
2243
 
 
2244
 
  return MS_FALSE;
2245
 
 
2246
 
#else
2247
 
/* ------------------------------------------------------------------
2248
 
 * OGR Support not included...
2249
 
 * ------------------------------------------------------------------ */
2250
 
 
2251
 
  msSetError(MS_MISCERR, "OGR support is not available.", "msOGRLayerIsOpen()");
2252
 
  return(MS_FALSE);
2253
 
 
2254
 
#endif /* USE_OGR */
2255
 
}
2256
 
 
2257
 
/**********************************************************************
2258
 
 *                     msOGRLayerWhichShapes()
2259
 
 *
2260
 
 * Init OGR layer structs ready for calls to msOGRLayerNextShape().
2261
 
 *
2262
 
 * Returns MS_SUCCESS/MS_FAILURE, or MS_DONE if no shape matching the
2263
 
 * layer's FILTER overlaps the selected region.
2264
 
 **********************************************************************/
2265
 
int msOGRLayerWhichShapes(layerObj *layer, rectObj rect) 
2266
 
{
2267
 
#ifdef USE_OGR
2268
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2269
 
  int   status;
2270
 
 
2271
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2272
 
  {
2273
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2274
 
               "msOGRLayerWhichShapes()");
2275
 
    return(MS_FAILURE);
2276
 
  }
2277
 
 
2278
 
  status = msOGRFileWhichShapes( layer, rect, psInfo );
2279
 
 
2280
 
  if( status != MS_SUCCESS || layer->tileindex == NULL )
2281
 
      return status;
2282
 
 
2283
 
  // If we are using a tile index, we need to advance to the first
2284
 
  // tile matching the spatial query, and load it. 
2285
 
 
2286
 
  return msOGRFileReadTile( layer, psInfo );
2287
 
 
2288
 
#else
2289
 
/* ------------------------------------------------------------------
2290
 
 * OGR Support not included...
2291
 
 * ------------------------------------------------------------------ */
2292
 
 
2293
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2294
 
             "msOGRLayerWhichShapes()");
2295
 
  return(MS_FAILURE);
2296
 
 
2297
 
#endif /* USE_OGR */
2298
 
}
2299
 
 
2300
 
/**********************************************************************
2301
 
 *                     msOGRLayerGetItems()
2302
 
 *
2303
 
 * Load item (i.e. field) names in a char array.  If we are working
2304
 
 * with a tiled layer, ensure a tile is loaded and use it for the items.
2305
 
 * It is implicitly assumed that the schemas will match on all tiles. 
2306
 
 **********************************************************************/
2307
 
int msOGRLayerGetItems(layerObj *layer)
2308
 
{
2309
 
#ifdef USE_OGR
2310
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2311
 
  
2312
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2313
 
  {
2314
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2315
 
               "msOGRLayerGetItems()");
2316
 
    return(MS_FAILURE);
2317
 
  }
2318
 
 
2319
 
  if( layer->tileindex != NULL )
2320
 
  {
2321
 
      if( psInfo->poCurTile == NULL 
2322
 
          && msOGRFileReadTile( layer, psInfo ) != MS_SUCCESS )
2323
 
          return MS_FAILURE;
2324
 
      
2325
 
      psInfo = psInfo->poCurTile;
2326
 
  }
2327
 
 
2328
 
  layer->numitems = 0;
2329
 
  layer->items = msOGRFileGetItems(layer, psInfo);
2330
 
  if( layer->items == NULL )
2331
 
      return MS_FAILURE;
2332
 
 
2333
 
  while( layer->items[layer->numitems] != NULL )
2334
 
      layer->numitems++;
2335
 
 
2336
 
  return msOGRLayerInitItemInfo(layer);
2337
 
 
2338
 
#else
2339
 
/* ------------------------------------------------------------------
2340
 
 * OGR Support not included...
2341
 
 * ------------------------------------------------------------------ */
2342
 
 
2343
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2344
 
             "msOGRLayerGetItems()");
2345
 
  return(MS_FAILURE);
2346
 
 
2347
 
#endif /* USE_OGR */
2348
 
}
2349
 
 
2350
 
/**********************************************************************
2351
 
 *                     msOGRLayerInitItemInfo()
2352
 
 *
2353
 
 * Init the itemindexes array after items[] has been reset in a layer.
2354
 
 **********************************************************************/
2355
 
static int msOGRLayerInitItemInfo(layerObj *layer)
2356
 
{
2357
 
#ifdef USE_OGR
2358
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2359
 
  int   i;
2360
 
  OGRFeatureDefnH hDefn;
2361
 
 
2362
 
  if (layer->numitems == 0)
2363
 
      return MS_SUCCESS;
2364
 
 
2365
 
  if( layer->tileindex != NULL )
2366
 
  {
2367
 
      if( psInfo->poCurTile == NULL 
2368
 
          && msOGRFileReadTile( layer, psInfo, -2 ) != MS_SUCCESS )
2369
 
          return MS_FAILURE;
2370
 
      
2371
 
      psInfo = psInfo->poCurTile;
2372
 
  }
2373
 
 
2374
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2375
 
  {
2376
 
      msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2377
 
                 "msOGRLayerInitItemInfo()");
2378
 
      return(MS_FAILURE);
2379
 
  }
2380
 
 
2381
 
  if((hDefn = OGR_L_GetLayerDefn( psInfo->hLayer )) == NULL) 
2382
 
  {
2383
 
    msSetError(MS_OGRERR, "Layer contains no fields.",  
2384
 
               "msOGRLayerInitItemInfo()");
2385
 
    return(MS_FAILURE);
2386
 
  }
2387
 
 
2388
 
  if (layer->iteminfo)
2389
 
      free(layer->iteminfo);
2390
 
  if((layer->iteminfo = (int *)malloc(sizeof(int)*layer->numitems))== NULL) 
2391
 
  {
2392
 
    msSetError(MS_MEMERR, NULL, "msOGRLayerInitItemInfo()");
2393
 
    return(MS_FAILURE);
2394
 
  }
2395
 
 
2396
 
  int *itemindexes = (int*)layer->iteminfo;
2397
 
  for(i=0;i<layer->numitems;i++) 
2398
 
  {
2399
 
      // Special case for handling text string and angle coming from
2400
 
      // OGR style strings.  We use special attribute snames.
2401
 
      if (EQUAL(layer->items[i], MSOGR_LABELFONTNAMENAME))
2402
 
          itemindexes[i] = MSOGR_LABELFONTNAMEINDEX;
2403
 
      else if (EQUAL(layer->items[i], MSOGR_LABELSIZENAME))
2404
 
          itemindexes[i] = MSOGR_LABELSIZEINDEX;
2405
 
      else if (EQUAL(layer->items[i], MSOGR_LABELTEXTNAME))
2406
 
          itemindexes[i] = MSOGR_LABELTEXTINDEX;
2407
 
      else if (EQUAL(layer->items[i], MSOGR_LABELANGLENAME))
2408
 
          itemindexes[i] = MSOGR_LABELANGLEINDEX;
2409
 
      else if (EQUAL(layer->items[i], MSOGR_LABELFCOLORNAME))
2410
 
          itemindexes[i] = MSOGR_LABELFCOLORINDEX;
2411
 
      else if (EQUAL(layer->items[i], MSOGR_LABELBCOLORNAME))
2412
 
          itemindexes[i] = MSOGR_LABELBCOLORINDEX;
2413
 
      else if (EQUAL(layer->items[i], MSOGR_LABELPLACEMENTNAME))
2414
 
          itemindexes[i] = MSOGR_LABELPLACEMENTINDEX;
2415
 
      else if (EQUAL(layer->items[i], MSOGR_LABELANCHORNAME))
2416
 
          itemindexes[i] = MSOGR_LABELANCHORINDEX;
2417
 
      else if (EQUAL(layer->items[i], MSOGR_LABELDXNAME))
2418
 
          itemindexes[i] = MSOGR_LABELDXINDEX;
2419
 
      else if (EQUAL(layer->items[i], MSOGR_LABELDYNAME))
2420
 
          itemindexes[i] = MSOGR_LABELDYINDEX;
2421
 
      else if (EQUAL(layer->items[i], MSOGR_LABELPERPNAME))
2422
 
          itemindexes[i] = MSOGR_LABELPERPINDEX;
2423
 
      else if (EQUAL(layer->items[i], MSOGR_LABELBOLDNAME))
2424
 
          itemindexes[i] = MSOGR_LABELBOLDINDEX;
2425
 
      else if (EQUAL(layer->items[i], MSOGR_LABELITALICNAME))
2426
 
          itemindexes[i] = MSOGR_LABELITALICINDEX;
2427
 
      else if (EQUAL(layer->items[i], MSOGR_LABELUNDERLINENAME))
2428
 
          itemindexes[i] = MSOGR_LABELUNDERLINEINDEX;
2429
 
      else if (EQUAL(layer->items[i], MSOGR_LABELPRIORITYNAME))
2430
 
          itemindexes[i] = MSOGR_LABELPRIORITYINDEX;
2431
 
#if GDAL_VERSION_NUM >= 1400
2432
 
      else if (EQUAL(layer->items[i], MSOGR_LABELSTRIKEOUTNAME))
2433
 
          itemindexes[i] = MSOGR_LABELSTRIKEOUTINDEX;
2434
 
      else if (EQUAL(layer->items[i], MSOGR_LABELSTRETCHNAME))
2435
 
          itemindexes[i] = MSOGR_LABELSTRETCHINDEX;
2436
 
      else if (EQUAL(layer->items[i], MSOGR_LABELADJHORNAME))
2437
 
          itemindexes[i] = MSOGR_LABELADJHORINDEX;
2438
 
      else if (EQUAL(layer->items[i], MSOGR_LABELADJVERTNAME))
2439
 
          itemindexes[i] = MSOGR_LABELADJVERTINDEX;
2440
 
      else if (EQUAL(layer->items[i], MSOGR_LABELHCOLORNAME))
2441
 
          itemindexes[i] = MSOGR_LABELHCOLORINDEX;
2442
 
#endif /* GDAL_VERSION_NUM >= 1400 */
2443
 
#if GDAL_VERSION_NUM >= 1600
2444
 
      else if (EQUAL(layer->items[i], MSOGR_LABELOCOLORNAME))
2445
 
          itemindexes[i] = MSOGR_LABELOCOLORINDEX;
2446
 
#endif /* GDAL_VERSION_NUM >= 1600 */
2447
 
      else
2448
 
          itemindexes[i] = OGR_FD_GetFieldIndex( hDefn, layer->items[i] );
2449
 
      if(itemindexes[i] == -1)
2450
 
      {
2451
 
          msSetError(MS_OGRERR, 
2452
 
                     (char*)CPLSPrintf("Invalid Field name: %s", 
2453
 
                                       layer->items[i]), 
2454
 
                     "msOGRLayerInitItemInfo()");
2455
 
          return(MS_FAILURE);
2456
 
      }
2457
 
  }
2458
 
 
2459
 
  return(MS_SUCCESS);
2460
 
#else
2461
 
/* ------------------------------------------------------------------
2462
 
 * OGR Support not included...
2463
 
 * ------------------------------------------------------------------ */
2464
 
 
2465
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2466
 
             "msOGRLayerInitItemInfo()");
2467
 
  return(MS_FAILURE);
2468
 
 
2469
 
#endif /* USE_OGR */
2470
 
}
2471
 
 
2472
 
/**********************************************************************
2473
 
 *                     msOGRLayerFreeItemInfo()
2474
 
 *
2475
 
 * Free the itemindexes array in a layer.
2476
 
 **********************************************************************/
2477
 
void msOGRLayerFreeItemInfo(layerObj *layer)
2478
 
{
2479
 
#ifdef USE_OGR
2480
 
 
2481
 
  if (layer->iteminfo)
2482
 
      free(layer->iteminfo);
2483
 
  layer->iteminfo = NULL;
2484
 
 
2485
 
#else
2486
 
/* ------------------------------------------------------------------
2487
 
 * OGR Support not included...
2488
 
 * ------------------------------------------------------------------ */
2489
 
 
2490
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2491
 
             "msOGRLayerFreeItemInfo()");
2492
 
 
2493
 
#endif /* USE_OGR */
2494
 
}
2495
 
 
2496
 
 
2497
 
/**********************************************************************
2498
 
 *                     msOGRLayerNextShape()
2499
 
 *
2500
 
 * Returns shape sequentially from OGR data source.
2501
 
 * msOGRLayerWhichShape() must have been called first.
2502
 
 *
2503
 
 * Returns MS_SUCCESS/MS_FAILURE
2504
 
 **********************************************************************/
2505
 
int msOGRLayerNextShape(layerObj *layer, shapeObj *shape) 
2506
 
{
2507
 
#ifdef USE_OGR
2508
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2509
 
  int  status;
2510
 
 
2511
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2512
 
  {
2513
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2514
 
               "msOGRLayerNextShape()");
2515
 
    return(MS_FAILURE);
2516
 
  }
2517
 
 
2518
 
  if( layer->tileindex == NULL )
2519
 
      return msOGRFileNextShape( layer, shape, psInfo );
2520
 
 
2521
 
  // Do we need to load the first tile? 
2522
 
  if( psInfo->poCurTile == NULL )
2523
 
  {
2524
 
      status = msOGRFileReadTile( layer, psInfo );
2525
 
      if( status != MS_SUCCESS )
2526
 
          return status;
2527
 
  }
2528
 
 
2529
 
  do 
2530
 
  {
2531
 
      // Try getting a shape from this tile.
2532
 
      status = msOGRFileNextShape( layer, shape, psInfo->poCurTile );
2533
 
      if( status != MS_DONE )
2534
 
          return status;
2535
 
  
2536
 
      // try next tile.
2537
 
      status = msOGRFileReadTile( layer, psInfo );
2538
 
      if( status != MS_SUCCESS )
2539
 
          return status;
2540
 
  } while( status == MS_SUCCESS );
2541
 
 
2542
 
  return status;
2543
 
  
2544
 
#else
2545
 
/* ------------------------------------------------------------------
2546
 
 * OGR Support not included...
2547
 
 * ------------------------------------------------------------------ */
2548
 
 
2549
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2550
 
             "msOGRLayerNextShape()");
2551
 
  return(MS_FAILURE);
2552
 
 
2553
 
#endif /* USE_OGR */
2554
 
}
2555
 
 
2556
 
/**********************************************************************
2557
 
 *                     msOGRLayerGetShape()
2558
 
 *
2559
 
 * Returns shape from OGR data source by fid.
2560
 
 *
2561
 
 * Returns MS_SUCCESS/MS_FAILURE
2562
 
 **********************************************************************/
2563
 
int msOGRLayerGetShape(layerObj *layer, shapeObj *shape, int tile, 
2564
 
                       long fid)
2565
 
{
2566
 
#ifdef USE_OGR
2567
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2568
 
 
2569
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2570
 
  {
2571
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2572
 
               "msOGRLayerNextShape()");
2573
 
    return(MS_FAILURE);
2574
 
  }
2575
 
 
2576
 
  if( layer->tileindex == NULL )
2577
 
      return msOGRFileGetShape(layer, shape, fid, psInfo, TRUE );
2578
 
  else
2579
 
  {
2580
 
      if( psInfo->poCurTile == NULL
2581
 
          || psInfo->poCurTile->nTileId != tile )
2582
 
      {
2583
 
          if( msOGRFileReadTile( layer, psInfo, tile ) != MS_SUCCESS )
2584
 
              return MS_FAILURE;
2585
 
      }
2586
 
 
2587
 
      return msOGRFileGetShape(layer, shape, fid, psInfo->poCurTile, TRUE );
2588
 
  }
2589
 
#else
2590
 
/* ------------------------------------------------------------------
2591
 
 * OGR Support not included...
2592
 
 * ------------------------------------------------------------------ */
2593
 
 
2594
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2595
 
             "msOGRLayerGetShape()");
2596
 
  return(MS_FAILURE);
2597
 
 
2598
 
#endif /* USE_OGR */
2599
 
}
2600
 
 
2601
 
/**********************************************************************
2602
 
 *                     msOGRLayerResultGetShape()
2603
 
 *
2604
 
 * Returns shape from OGR data source by index into the current results
2605
 
 * set.
2606
 
 *
2607
 
 * Returns MS_SUCCESS/MS_FAILURE
2608
 
 **********************************************************************/
2609
 
int msOGRLayerResultGetShape(layerObj *layer, shapeObj *shape, int tile, 
2610
 
                             long record)
2611
 
{
2612
 
#ifdef USE_OGR
2613
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2614
 
 
2615
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2616
 
  {
2617
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2618
 
               "msOGRLayerNextShape()");
2619
 
    return(MS_FAILURE);
2620
 
  }
2621
 
 
2622
 
  if( layer->tileindex == NULL )
2623
 
      return msOGRFileGetShape(layer, shape, record, psInfo, FALSE );
2624
 
  else
2625
 
  {
2626
 
      if( psInfo->poCurTile == NULL
2627
 
          || psInfo->poCurTile->nTileId != tile )
2628
 
      {
2629
 
          if( msOGRFileReadTile( layer, psInfo, tile ) != MS_SUCCESS )
2630
 
              return MS_FAILURE;
2631
 
      }
2632
 
 
2633
 
      return msOGRFileGetShape(layer, shape, record, psInfo->poCurTile, FALSE );
2634
 
  }
2635
 
#else
2636
 
/* ------------------------------------------------------------------
2637
 
 * OGR Support not included...
2638
 
 * ------------------------------------------------------------------ */
2639
 
 
2640
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2641
 
             "msOGRLayerGetShape()");
2642
 
  return(MS_FAILURE);
2643
 
 
2644
 
#endif /* USE_OGR */
2645
 
}
2646
 
 
2647
 
/**********************************************************************
2648
 
 *                     msOGRLayerGetExtent()
2649
 
 *
2650
 
 * Returns the layer extents.
2651
 
 *
2652
 
 * Returns MS_SUCCESS/MS_FAILURE
2653
 
 **********************************************************************/
2654
 
int msOGRLayerGetExtent(layerObj *layer, rectObj *extent) 
2655
 
{
2656
 
#ifdef USE_OGR
2657
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2658
 
  OGREnvelope oExtent;
2659
 
 
2660
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2661
 
  {
2662
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2663
 
               "msOGRLayerGetExtent()");
2664
 
    return(MS_FAILURE);
2665
 
  }
2666
 
 
2667
 
/* ------------------------------------------------------------------
2668
 
 * Call OGR's GetExtent()... note that for some formats this will
2669
 
 * result in a scan of the whole layer and can be an expensive call.
2670
 
 *
2671
 
 * For tile indexes layers we assume it is sufficient to get the
2672
 
 * extents of the tile index.
2673
 
 * ------------------------------------------------------------------ */
2674
 
  ACQUIRE_OGR_LOCK;
2675
 
  if (OGR_L_GetExtent( psInfo->hLayer, &oExtent, TRUE) != OGRERR_NONE)
2676
 
  {
2677
 
      RELEASE_OGR_LOCK;
2678
 
    msSetError(MS_MISCERR, "Unable to get extents for this layer.", 
2679
 
               "msOGRLayerGetExtent()");
2680
 
    return(MS_FAILURE);
2681
 
  }
2682
 
  RELEASE_OGR_LOCK;
2683
 
 
2684
 
  extent->minx = oExtent.MinX;
2685
 
  extent->miny = oExtent.MinY;
2686
 
  extent->maxx = oExtent.MaxX;
2687
 
  extent->maxy = oExtent.MaxY;
2688
 
 
2689
 
  return MS_SUCCESS;
2690
 
#else
2691
 
/* ------------------------------------------------------------------
2692
 
 * OGR Support not included...
2693
 
 * ------------------------------------------------------------------ */
2694
 
 
2695
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
2696
 
             "msOGRLayerGetExtent()");
2697
 
  return(MS_FAILURE);
2698
 
 
2699
 
#endif /* USE_OGR */
2700
 
}
2701
 
 
2702
 
 
2703
 
/**********************************************************************
2704
 
 *                     msOGRGetSymbolId()
2705
 
 *
2706
 
 * Returns a MapServer symbol number matching one of the symbols from
2707
 
 * the OGR symbol id string.  If not found then try to locate the
2708
 
 * default symbol name, and if not found return 0.
2709
 
 **********************************************************************/
2710
 
#ifdef USE_OGR
2711
 
static int msOGRGetSymbolId(symbolSetObj *symbolset, const char *pszSymbolId, 
2712
 
                            const char *pszDefaultSymbol)
2713
 
{
2714
 
    // Symbol name mapping:
2715
 
    // First look for the native symbol name, then the ogr-...
2716
 
    // generic name, and in last resort try pszDefaultSymbol if
2717
 
    // provided by user.
2718
 
    char  **params;
2719
 
    int   numparams;
2720
 
    int   nSymbol = -1;
2721
 
 
2722
 
    if (pszSymbolId && pszSymbolId[0] != '\0')
2723
 
    {
2724
 
#if GDAL_VERSION_NUM >= 1800 /* Use comma as the separator */
2725
 
        params = msStringSplit(pszSymbolId, ',', &numparams);
2726
 
#else
2727
 
        params = msStringSplit(pszSymbolId, '.', &numparams);
2728
 
#endif
2729
 
        if (params != NULL)
2730
 
        {
2731
 
            for(int j=0; j<numparams && nSymbol == -1; j++)
2732
 
            {
2733
 
                nSymbol = msGetSymbolIndex(symbolset, params[j], MS_FALSE);
2734
 
            }
2735
 
            msFreeCharArray(params, numparams);
2736
 
        }
2737
 
    }
2738
 
    if (nSymbol == -1 && pszDefaultSymbol)
2739
 
    {
2740
 
        nSymbol = msGetSymbolIndex(symbolset,(char*)pszDefaultSymbol,MS_FALSE);
2741
 
    }
2742
 
    if (nSymbol == -1)
2743
 
        nSymbol = 0;
2744
 
 
2745
 
    return nSymbol;
2746
 
}
2747
 
#endif
2748
 
 
2749
 
/**********************************************************************
2750
 
 *                     msOGRLayerGetAutoStyle()
2751
 
 *
2752
 
 * Fills a classObj with style info from the specified shape.
2753
 
 * For optimal results, this should be called immediately after 
2754
 
 * GetNextShape() or GetShape() so that the shape doesn't have to be read
2755
 
 * twice.
2756
 
 *
2757
 
 * The returned classObj is a ref. to a static structure valid only until
2758
 
 * the next call and that shouldn't be freed by the caller.
2759
 
 **********************************************************************/
2760
 
static int msOGRLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c,
2761
 
                                  int tile, long record)
2762
 
{
2763
 
#ifdef USE_OGR
2764
 
  msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2765
 
 
2766
 
  if (psInfo == NULL || psInfo->hLayer == NULL)
2767
 
  {
2768
 
    msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!", 
2769
 
               "msOGRLayerGetAutoStyle()");
2770
 
    return(MS_FAILURE);
2771
 
  }
2772
 
 
2773
 
  if( layer->tileindex != NULL )
2774
 
  {
2775
 
      if( (psInfo->poCurTile == NULL || tile != psInfo->poCurTile->nTileId)
2776
 
          && msOGRFileReadTile( layer, psInfo ) != MS_SUCCESS )
2777
 
          return MS_FAILURE;
2778
 
      
2779
 
      psInfo = psInfo->poCurTile;
2780
 
  }
2781
 
 
2782
 
/* ------------------------------------------------------------------
2783
 
 * Read shape or reuse ref. to last shape read.
2784
 
 * ------------------------------------------------------------------ */
2785
 
  ACQUIRE_OGR_LOCK;
2786
 
  if (psInfo->hLastFeature == NULL || 
2787
 
      psInfo->last_record_index_read != record)
2788
 
  {
2789
 
      RELEASE_OGR_LOCK;
2790
 
      msSetError(MS_MISCERR, 
2791
 
                 "Assertion failed: AutoStyle not requested on loaded shape.",
2792
 
                 "msOGRLayerGetAutoStyle()");
2793
 
      return(MS_FAILURE);
2794
 
  }
2795
 
 
2796
 
/* ------------------------------------------------------------------
2797
 
 * Reset style info in the class to defaults
2798
 
 * the only members we don't touch are name, expression, and join/query stuff
2799
 
 * ------------------------------------------------------------------ */
2800
 
  resetClassStyle(c);
2801
 
  if (msMaybeAllocateStyle(c, 0)) {
2802
 
      RELEASE_OGR_LOCK;
2803
 
      return(MS_FAILURE);
2804
 
  }
2805
 
 
2806
 
  // __TODO__ label cache incompatible with styleitem feature.
2807
 
  layer->labelcache = MS_OFF;
2808
 
 
2809
 
/* ------------------------------------------------------------------
2810
 
 * Handle each part
2811
 
 * ------------------------------------------------------------------ */
2812
 
  if (psInfo->hLastFeature)
2813
 
  {
2814
 
      GBool bIsNull, bIsBrush=MS_FALSE, bIsPen=MS_FALSE;
2815
 
      int r=0,g=0,b=0,t=0;
2816
 
 
2817
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
2818
 
      OGRStyleMgrH hStyleMgr = OGR_SM_Create(NULL);
2819
 
      OGR_SM_InitFromFeature(hStyleMgr, psInfo->hLastFeature);
2820
 
      int numParts = OGR_SM_GetPartCount(hStyleMgr, NULL);
2821
 
#else /* OGRStyle C++ */
2822
 
      OGRStyleMgr *poStyleMgr = new OGRStyleMgr(NULL);
2823
 
      poStyleMgr->InitFromFeature((OGRFeature *)psInfo->hLastFeature);
2824
 
      int numParts = poStyleMgr->GetPartCount();
2825
 
#endif /* OGRStyle C API */
2826
 
 
2827
 
      for(int i=0; i<numParts; i++)
2828
 
      {
2829
 
          OGRSTClassId eStylePartType;
2830
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
2831
 
          OGRStyleToolH hStylePart = OGR_SM_GetPart(hStyleMgr, i, NULL);
2832
 
          if (!hStylePart)
2833
 
              continue;
2834
 
          eStylePartType = OGR_ST_GetType(hStylePart);
2835
 
#else /* OGRStyle C++ */
2836
 
          OGRStyleTool *poStylePart = poStyleMgr->GetPart(i);
2837
 
          if (!poStylePart)
2838
 
              continue;
2839
 
          eStylePartType = poStylePart->GetType();
2840
 
#endif /* OGRStyle C API */
2841
 
 
2842
 
          // We want all size values returned in pixels.
2843
 
          //
2844
 
          // The scale factor that OGR expect is the ground/paper scale
2845
 
          // e.g. if 1 ground unit = 0.01 paper unit then scale=1/0.01=100
2846
 
          // cellsize if number of ground units/pixel, and OGR assumes that
2847
 
          // there is 72*39.37 pixels/ground units (since meter is assumed 
2848
 
          // for ground... but what ground units we have does not matter
2849
 
          // as long as use the same assumptions everywhere)
2850
 
          // That gives scale = cellsize*72*39.37
2851
 
 
2852
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
2853
 
          OGR_ST_SetUnit(hStylePart, OGRSTUPixel, map->cellsize*72.0*39.37);
2854
 
#else
2855
 
          poStylePart->SetUnit(OGRSTUPixel, map->cellsize*72.0*39.37);
2856
 
#endif
2857
 
 
2858
 
          if (eStylePartType == OGRSTCLabel)
2859
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
2860
 
          {
2861
 
              OGRStyleToolH hLabelStyle = hStylePart;
2862
 
 
2863
 
              // Enclose the text string inside quotes to make sure it is seen
2864
 
              // as a string by the parser inside loadExpression(). (bug185)
2865
 
              msLoadExpressionString(&(c->text), 
2866
 
                         (char*)CPLSPrintf("\"%s\"", 
2867
 
                                           OGR_ST_GetParamStr(hLabelStyle, 
2868
 
                                                              OGRSTLabelTextString, 
2869
 
                                                              &bIsNull)));
2870
 
 
2871
 
              c->label.angle = OGR_ST_GetParamDbl(hLabelStyle, 
2872
 
                                                  OGRSTLabelAngle, &bIsNull);
2873
 
 
2874
 
              c->label.size = OGR_ST_GetParamDbl(hLabelStyle, 
2875
 
                                                 OGRSTLabelSize, &bIsNull);
2876
 
              if( c->label.size < 1 ) /* no point dropping to zero size */
2877
 
                  c->label.size = 1;
2878
 
 
2879
 
              // OGR default is anchor point = LL, so label is at UR of anchor
2880
 
              c->label.position = MS_UR;
2881
 
 
2882
 
              const char *pszColor = OGR_ST_GetParamStr(hLabelStyle, 
2883
 
                                                        OGRSTLabelFColor,
2884
 
                                                        &bIsNull);
2885
 
              if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2886
 
                                                      &r, &g, &b, &t))
2887
 
              {
2888
 
                  MS_INIT_COLOR(c->label.color, r, g, b);
2889
 
              }
2890
 
 
2891
 
              pszColor = OGR_ST_GetParamStr(hLabelStyle, 
2892
 
                                            OGRSTLabelBColor,
2893
 
                                            &bIsNull);
2894
 
              if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2895
 
                                                      &r, &g, &b, &t))
2896
 
              {
2897
 
                  MS_INIT_COLOR(c->label.backgroundcolor, r, g, b);
2898
 
              }
2899
 
 
2900
 
              pszColor = OGR_ST_GetParamStr(hLabelStyle, 
2901
 
                                            OGRSTLabelHColor,
2902
 
                                            &bIsNull);
2903
 
              if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2904
 
                                                      &r, &g, &b, &t))
2905
 
              {
2906
 
                  MS_INIT_COLOR(c->label.shadowcolor, r, g, b);
2907
 
              }
2908
 
 
2909
 
#if GDAL_VERSION_NUM >= 1600
2910
 
              pszColor = OGR_ST_GetParamStr(hLabelStyle, 
2911
 
                                            OGRSTLabelOColor,
2912
 
                                            &bIsNull);
2913
 
              if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2914
 
                                                      &r, &g, &b, &t))
2915
 
              {
2916
 
                  MS_INIT_COLOR(c->label.outlinecolor, r, g, b);
2917
 
              }
2918
 
#endif /* GDAL_VERSION_NUM >= 1600 */
2919
 
 
2920
 
              // Label font... do our best to use TrueType fonts, otherwise
2921
 
              // fallback on bitmap fonts.
2922
 
#if defined(USE_GD_TTF) || defined (USE_GD_FT)
2923
 
              const char *pszBold = OGR_ST_GetParamNum(hLabelStyle, 
2924
 
                                                           OGRSTLabelBold, 
2925
 
                                                           &bIsNull) ? "-bold" : "";
2926
 
              const char *pszItalic = OGR_ST_GetParamNum(hLabelStyle, 
2927
 
                                                           OGRSTLabelItalic, 
2928
 
                                                           &bIsNull) ? "-italic" : "";
2929
 
              const char *pszFontName = OGR_ST_GetParamStr(hLabelStyle, 
2930
 
                                                           OGRSTLabelFontName,
2931
 
                                                           &bIsNull);
2932
 
              const char *pszName = CPLSPrintf("%s%s%s", pszFontName, pszBold, pszItalic);
2933
 
              bool bFont = true;
2934
 
 
2935
 
              if (pszFontName != NULL && !bIsNull && pszFontName[0] != '\0')
2936
 
              {
2937
 
                  if (msLookupHashTable(&(map->fontset.fonts), (char*)pszName) != NULL)
2938
 
                  {
2939
 
                      c->label.type = MS_TRUETYPE;
2940
 
                      c->label.font = strdup(pszName);
2941
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
2942
 
                          msDebug("** Using '%s' TTF font **\n", pszName);
2943
 
                  }
2944
 
                  else if ( (strcmp(pszFontName,pszName) != 0) &&
2945
 
                            msLookupHashTable(&(map->fontset.fonts), (char*)pszFontName) != NULL)
2946
 
                  {
2947
 
                      c->label.type = MS_TRUETYPE;
2948
 
                      c->label.font = strdup(pszFontName);
2949
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
2950
 
                          msDebug("** Using '%s' TTF font **\n", pszFontName);
2951
 
                  }
2952
 
                  else if (msLookupHashTable(&(map->fontset.fonts),"default") != NULL)
2953
 
                  {
2954
 
                      c->label.type = MS_TRUETYPE;
2955
 
                      c->label.font = strdup("default");
2956
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
2957
 
                          msDebug("** Using 'default' TTF font **\n");
2958
 
                  }
2959
 
                  else
2960
 
                      bFont = false;
2961
 
              }
2962
 
 
2963
 
              if (!bFont)
2964
 
#endif /* USE_GD_FT || USE_GD_FT */
2965
 
              {
2966
 
                  c->label.type = MS_BITMAP;
2967
 
                  c->label.size = MS_MEDIUM;
2968
 
                  if (layer->debug >= MS_DEBUGLEVEL_VVV)
2969
 
                      msDebug("** Using 'medium' BITMAP font **\n");
2970
 
              }
2971
 
          }
2972
 
#else /* OGR Style C++ */
2973
 
          {
2974
 
              OGRStyleLabel *poLabelStyle = (OGRStyleLabel*)poStylePart;
2975
 
 
2976
 
              // Enclose the text string inside quotes to make sure it is seen
2977
 
              // as a string by the parser inside loadExpression(). (bug185)
2978
 
              msLoadExpressionString(&(c->text), 
2979
 
                         (char*)CPLSPrintf("\"%s\"", 
2980
 
                                           poLabelStyle->TextString(bIsNull)));
2981
 
 
2982
 
              c->label.angle = poLabelStyle->Angle(bIsNull);
2983
 
 
2984
 
              c->label.size = (int)poLabelStyle->Size(bIsNull);
2985
 
              if( c->label.size < 1 ) /* no point dropping to zero size */
2986
 
                  c->label.size = 1;
2987
 
 
2988
 
              // OGR default is anchor point = LL, so label is at UR of anchor
2989
 
              c->label.position = MS_UR;
2990
 
 
2991
 
              const char *pszColor = poLabelStyle->ForeColor(bIsNull);
2992
 
              if (!bIsNull && poLabelStyle->GetRGBFromString(pszColor,r,g,b,t))
2993
 
              {
2994
 
                  MS_INIT_COLOR(c->label.color, r, g, b);
2995
 
              }
2996
 
 
2997
 
              pszColor = poLabelStyle->BackColor(bIsNull);
2998
 
              if (!bIsNull && poLabelStyle->GetRGBFromString(pszColor,r,g,b,t))
2999
 
              {
3000
 
                  MS_INIT_COLOR(c->label.backgroundcolor, r, g, b);
3001
 
              }
3002
 
#if GDAL_VERSION_NUM >= 1400
3003
 
              pszColor = poLabelStyle->ShadowColor(bIsNull);
3004
 
              if (!bIsNull && poLabelStyle->GetRGBFromString(pszColor,r,g,b,t))
3005
 
              {
3006
 
                  MS_INIT_COLOR(c->label.shadowcolor, r, g, b);
3007
 
              }
3008
 
#endif
3009
 
              // Label font... do our best to use TrueType fonts, otherwise
3010
 
              // fallback on bitmap fonts.
3011
 
#if defined(USE_GD_TTF) || defined (USE_GD_FT)
3012
 
              const char *pszBold = poLabelStyle->Bold(bIsNull)  ? "-bold" : "";
3013
 
              const char *pszItalic = poLabelStyle->Italic(bIsNull) ? "-italic" : "";
3014
 
              const char *pszFontName = poLabelStyle->FontName(bIsNull);
3015
 
              const char *pszName = CPLSPrintf("%s%s%s", pszFontName, pszBold, pszItalic);
3016
 
              bool bFont = true;
3017
 
 
3018
 
              if (pszFontName != NULL && !bIsNull && pszFontName[0] != '\0')
3019
 
              {
3020
 
                  if (msLookupHashTable(&(map->fontset.fonts), (char*)pszName) != NULL)
3021
 
                  {
3022
 
                      c->label.type = MS_TRUETYPE;
3023
 
                      c->label.font = strdup(pszName);
3024
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
3025
 
                          msDebug("** Using '%s' TTF font **\n", pszName);
3026
 
                  }
3027
 
                  else if ( (strcmp(pszFontName,pszName) != 0) &&
3028
 
                            msLookupHashTable(&(map->fontset.fonts), (char*)pszFontName) != NULL)
3029
 
                  {
3030
 
                      c->label.type = MS_TRUETYPE;
3031
 
                      c->label.font = strdup(pszFontName);
3032
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
3033
 
                          msDebug("** Using '%s' TTF font **\n", pszFontName);
3034
 
                  }
3035
 
                  else if (msLookupHashTable(&(map->fontset.fonts),"default") != NULL)
3036
 
                  {
3037
 
                      c->label.type = MS_TRUETYPE;
3038
 
                      c->label.font = strdup("default");
3039
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
3040
 
                          msDebug("** Using 'default' TTF font **\n");
3041
 
                  }
3042
 
                  else
3043
 
                      bFont = false;
3044
 
              }
3045
 
 
3046
 
              if (!bFont)
3047
 
#endif /* USE_GD_FT || USE_GD_FT */
3048
 
              {
3049
 
                  c->label.type = MS_BITMAP;
3050
 
                  c->label.size = MS_MEDIUM;
3051
 
                  if (layer->debug >= MS_DEBUGLEVEL_VVV)
3052
 
                      msDebug("** Using 'medium' BITMAP font **\n");
3053
 
              }
3054
 
          }
3055
 
#endif /* OGRStyle C API */
3056
 
          else if (eStylePartType == OGRSTCPen)
3057
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3058
 
          {
3059
 
              OGRStyleToolH hPenStyle = hStylePart;
3060
 
              bIsPen = TRUE;
3061
 
 
3062
 
              const char *pszPenName = OGR_ST_GetParamStr(hPenStyle, 
3063
 
                                                          OGRSTPenId, 
3064
 
                                                          &bIsNull);
3065
 
              if (bIsNull) pszPenName = NULL;
3066
 
              colorObj oPenColor;
3067
 
              int nPenSymbol = 0;
3068
 
              int nPenSize = 1;
3069
 
 
3070
 
              // Make sure pen is always initialized
3071
 
              MS_INIT_COLOR(oPenColor, -1, -1, -1);
3072
 
 
3073
 
              // Check for Pen Pattern "ogr-pen-1": the invisible pen
3074
 
              // If that's what we have then set pen color to -1
3075
 
              if (pszPenName && strstr(pszPenName, "ogr-pen-1") != NULL)
3076
 
              {
3077
 
                  MS_INIT_COLOR(oPenColor, -1, -1, -1);
3078
 
              }
3079
 
              else
3080
 
              {
3081
 
                  const char *pszColor = OGR_ST_GetParamStr(hPenStyle, 
3082
 
                                                            OGRSTPenColor,
3083
 
                                                            &bIsNull);
3084
 
                  if (!bIsNull && OGR_ST_GetRGBFromString(hPenStyle, pszColor,
3085
 
                                                          &r, &g, &b, &t))
3086
 
                  {
3087
 
                      MS_INIT_COLOR(oPenColor, r, g, b);
3088
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
3089
 
                          msDebug("** PEN COLOR = %d %d %d **\n", r,g,b);
3090
 
                  }
3091
 
 
3092
 
                  nPenSize = OGR_ST_GetParamNum(hPenStyle, 
3093
 
                                                OGRSTPenWidth, &bIsNull);
3094
 
                  if (bIsNull)
3095
 
                      nPenSize = 1;
3096
 
                  if (pszPenName!=NULL)
3097
 
                  {
3098
 
                      // Try to match pen name in symbol file
3099
 
                      nPenSymbol = msOGRGetSymbolId(&(map->symbolset),
3100
 
                                                    pszPenName, NULL);
3101
 
                  }
3102
 
              }
3103
 
              if (layer->debug >= MS_DEBUGLEVEL_VVV)
3104
 
                  msDebug("** PEN COLOR = %d %d %d **\n", oPenColor.red,oPenColor.green,oPenColor.blue);
3105
 
              if (bIsBrush || layer->type == MS_LAYER_POLYGON)
3106
 
              {
3107
 
                  // This is a multipart symbology, so pen defn goes in the
3108
 
                  // overlaysymbol params 
3109
 
                  if (msMaybeAllocateStyle(c, 1))
3110
 
                  {
3111
 
                      RELEASE_OGR_LOCK;
3112
 
                      return(MS_FAILURE);
3113
 
                  }
3114
 
 
3115
 
                  c->styles[1]->outlinecolor = oPenColor;
3116
 
                  c->styles[1]->size = nPenSize;
3117
 
                  c->styles[1]->symbol = nPenSymbol;
3118
 
                  c->styles[1]->width = nPenSize;
3119
 
              }
3120
 
              else
3121
 
              {
3122
 
                  // Single part symbology
3123
 
                  if (msMaybeAllocateStyle(c, 0))
3124
 
                  {
3125
 
                      RELEASE_OGR_LOCK;
3126
 
                      return(MS_FAILURE);
3127
 
                  }
3128
 
 
3129
 
                  if(layer->type == MS_LAYER_POLYGON)
3130
 
                      c->styles[0]->outlinecolor = c->styles[0]->color = 
3131
 
                          oPenColor;
3132
 
                  else
3133
 
                      c->styles[0]->color = oPenColor;
3134
 
                  c->styles[0]->symbol = nPenSymbol;
3135
 
                  c->styles[0]->size = nPenSize;
3136
 
                  c->styles[0]->width = nPenSize;
3137
 
              }
3138
 
 
3139
 
          }
3140
 
#else /* OGR Style C++ */
3141
 
          {
3142
 
              OGRStylePen *poPenStyle = (OGRStylePen*)poStylePart;
3143
 
              bIsPen = TRUE;
3144
 
 
3145
 
              const char *pszPenName = poPenStyle->Id(bIsNull);
3146
 
              if (bIsNull) pszPenName = NULL;
3147
 
              colorObj oPenColor;
3148
 
              int nPenSymbol = 0;
3149
 
              int nPenSize = 1;
3150
 
 
3151
 
              // Make sure pen is always initialized
3152
 
              MS_INIT_COLOR(oPenColor, -1, -1, -1);
3153
 
 
3154
 
              // Check for Pen Pattern "ogr-pen-1": the invisible pen
3155
 
              // If that's what we have then set pen color to -1
3156
 
              if (pszPenName && strstr(pszPenName, "ogr-pen-1") != NULL)
3157
 
              {
3158
 
                  MS_INIT_COLOR(oPenColor, -1, -1, -1);
3159
 
              }
3160
 
              else
3161
 
              {
3162
 
                  const char *pszColor = poPenStyle->Color(bIsNull);
3163
 
                  if (!bIsNull && poPenStyle->GetRGBFromString(pszColor,r,g,b,t))
3164
 
                  {
3165
 
                      MS_INIT_COLOR(oPenColor, r, g, b);
3166
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
3167
 
                          msDebug("** PEN COLOR = %d %d %d **\n", r,g,b);
3168
 
                  }
3169
 
 
3170
 
                  nPenSize = (int)poPenStyle->Width(bIsNull);
3171
 
                  if (bIsNull)
3172
 
                      nPenSize = 1;
3173
 
                  if (pszPenName!=NULL)
3174
 
                  {
3175
 
                      // Try to match pen name in symbol file
3176
 
                      nPenSymbol = msOGRGetSymbolId(&(map->symbolset),
3177
 
                                                    pszPenName, NULL);
3178
 
                  }
3179
 
              }
3180
 
              if (layer->debug >= MS_DEBUGLEVEL_VVV)
3181
 
                  msDebug("** PEN COLOR = %d %d %d **\n", oPenColor.red,oPenColor.green,oPenColor.blue);
3182
 
              if (bIsBrush || layer->type == MS_LAYER_POLYGON)
3183
 
              {
3184
 
                  // This is a multipart symbology, so pen defn goes in the
3185
 
                  // overlaysymbol params 
3186
 
                  if (msMaybeAllocateStyle(c, 1))
3187
 
                  {
3188
 
                      RELEASE_OGR_LOCK;
3189
 
                      return(MS_FAILURE);
3190
 
                  }
3191
 
 
3192
 
                  c->styles[1]->outlinecolor = oPenColor;
3193
 
                  c->styles[1]->size = nPenSize;
3194
 
                  c->styles[1]->symbol = nPenSymbol;
3195
 
                  c->styles[1]->width = nPenSize;
3196
 
              }
3197
 
              else
3198
 
              {
3199
 
                  // Single part symbology
3200
 
                  if (msMaybeAllocateStyle(c, 0))
3201
 
                  {
3202
 
                      RELEASE_OGR_LOCK;
3203
 
                      return(MS_FAILURE);
3204
 
                  }
3205
 
 
3206
 
                  if(layer->type == MS_LAYER_POLYGON)
3207
 
                      c->styles[0]->outlinecolor = c->styles[0]->color = 
3208
 
                          oPenColor;
3209
 
                  else
3210
 
                      c->styles[0]->color = oPenColor;
3211
 
                  c->styles[0]->symbol = nPenSymbol;
3212
 
                  c->styles[0]->size = nPenSize;
3213
 
                  c->styles[0]->width = nPenSize;
3214
 
              }
3215
 
 
3216
 
          }
3217
 
#endif /* OGRStyle C API */
3218
 
          else if (eStylePartType == OGRSTCBrush)
3219
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3220
 
          {
3221
 
              OGRStyleToolH hBrushStyle = hStylePart;
3222
 
 
3223
 
              const char *pszBrushName = OGR_ST_GetParamStr(hBrushStyle, 
3224
 
                                                            OGRSTBrushId, 
3225
 
                                                            &bIsNull);
3226
 
              if (bIsNull) pszBrushName = NULL;
3227
 
 
3228
 
              /* We need 1 style */
3229
 
              if (msMaybeAllocateStyle(c, 0))
3230
 
              {
3231
 
                  RELEASE_OGR_LOCK;
3232
 
                  return(MS_FAILURE);
3233
 
              }
3234
 
 
3235
 
              // Check for Brush Pattern "ogr-brush-1": the invisible fill
3236
 
              // If that's what we have then set fill color to -1
3237
 
              if (pszBrushName && strstr(pszBrushName, "ogr-brush-1") != NULL)
3238
 
              {
3239
 
                  MS_INIT_COLOR(c->styles[0]->color, -1, -1, -1);
3240
 
              }
3241
 
              else
3242
 
              {
3243
 
                  bIsBrush = TRUE;
3244
 
                  const char *pszColor = OGR_ST_GetParamStr(hBrushStyle, 
3245
 
                                                            OGRSTBrushFColor,
3246
 
                                                            &bIsNull);
3247
 
                  if (!bIsNull && OGR_ST_GetRGBFromString(hBrushStyle, 
3248
 
                                                          pszColor,
3249
 
                                                          &r, &g, &b, &t))
3250
 
                  {
3251
 
                      MS_INIT_COLOR(c->styles[0]->color, r, g, b);
3252
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
3253
 
                          msDebug("** BRUSH COLOR = %d %d %d **\n", r,g,b);
3254
 
                  }
3255
 
 
3256
 
                  pszColor = OGR_ST_GetParamStr(hBrushStyle, 
3257
 
                                                OGRSTBrushBColor, &bIsNull);
3258
 
                  if (!bIsNull && OGR_ST_GetRGBFromString(hBrushStyle, 
3259
 
                                                          pszColor,
3260
 
                                                          &r, &g, &b, &t))
3261
 
                  {
3262
 
                      MS_INIT_COLOR(c->styles[0]->backgroundcolor, r, g, b);
3263
 
                  }
3264
 
 
3265
 
                  // Symbol name mapping:
3266
 
                  // First look for the native symbol name, then the ogr-...
3267
 
                  // generic name.  
3268
 
                  // If none provided or found then use 0: solid fill
3269
 
              
3270
 
                  const char *pszName = OGR_ST_GetParamStr(hBrushStyle, 
3271
 
                                                            OGRSTBrushId, 
3272
 
                                                            &bIsNull);
3273
 
                  c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset), 
3274
 
                                                         pszName, NULL);
3275
 
              }
3276
 
          }
3277
 
#else /* OGR Style C++ */
3278
 
          {
3279
 
              OGRStyleBrush *poBrushStyle = (OGRStyleBrush*)poStylePart;
3280
 
 
3281
 
              const char *pszBrushName = poBrushStyle->Id(bIsNull);
3282
 
              if (bIsNull) pszBrushName = NULL;
3283
 
 
3284
 
              /* We need 1 style */
3285
 
              if (msMaybeAllocateStyle(c, 0))
3286
 
              {
3287
 
                  RELEASE_OGR_LOCK;
3288
 
                  return(MS_FAILURE);
3289
 
              }
3290
 
 
3291
 
              // Check for Brush Pattern "ogr-brush-1": the invisible fill
3292
 
              // If that's what we have then set fill color to -1
3293
 
              if (pszBrushName && strstr(pszBrushName, "ogr-brush-1") != NULL)
3294
 
              {
3295
 
                  MS_INIT_COLOR(c->styles[0]->color, -1, -1, -1);
3296
 
              }
3297
 
              else
3298
 
              {
3299
 
                  bIsBrush = TRUE;
3300
 
                  const char *pszColor = poBrushStyle->ForeColor(bIsNull);
3301
 
                  if (!bIsNull && poBrushStyle->GetRGBFromString(pszColor,r,g,b,t))
3302
 
                  {
3303
 
                      MS_INIT_COLOR(c->styles[0]->color, r, g, b);
3304
 
                      if (layer->debug >= MS_DEBUGLEVEL_VVV)
3305
 
                          msDebug("** BRUSH COLOR = %d %d %d **\n", r,g,b);
3306
 
                  }
3307
 
 
3308
 
                  pszColor = poBrushStyle->BackColor(bIsNull);
3309
 
                  if (!bIsNull && poBrushStyle->GetRGBFromString(pszColor,r,g,b,t))
3310
 
                  {
3311
 
                      MS_INIT_COLOR(c->styles[0]->backgroundcolor, r, g, b);
3312
 
                  }
3313
 
 
3314
 
                  // Symbol name mapping:
3315
 
                  // First look for the native symbol name, then the ogr-...
3316
 
                  // generic name.  
3317
 
                  // If none provided or found then use 0: solid fill
3318
 
              
3319
 
                  const char *pszName = poBrushStyle->Id(bIsNull);
3320
 
                  if (bIsNull)
3321
 
                      pszName = NULL;
3322
 
                  c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset), 
3323
 
                                                         pszName, NULL);
3324
 
              }
3325
 
          }
3326
 
#endif /* OGRStyle C API */
3327
 
          else if (eStylePartType == OGRSTCSymbol)
3328
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3329
 
          {
3330
 
              OGRStyleToolH hSymbolStyle = hStylePart;
3331
 
 
3332
 
              /* We need 1 style */
3333
 
              if (msMaybeAllocateStyle(c, 0))
3334
 
              {
3335
 
                  RELEASE_OGR_LOCK;
3336
 
                  return(MS_FAILURE);
3337
 
              }
3338
 
 
3339
 
              const char *pszColor = OGR_ST_GetParamStr(hSymbolStyle, 
3340
 
                                                        OGRSTSymbolColor,
3341
 
                                                        &bIsNull);
3342
 
              if (!bIsNull && OGR_ST_GetRGBFromString(hSymbolStyle, 
3343
 
                                                      pszColor,
3344
 
                                                      &r, &g, &b, &t))
3345
 
              {
3346
 
                  MS_INIT_COLOR(c->styles[0]->color, r, g, b);
3347
 
              }
3348
 
 
3349
 
#if GDAL_VERSION_NUM >= 1600              
3350
 
              pszColor = OGR_ST_GetParamStr(hSymbolStyle,
3351
 
                                            OGRSTSymbolOColor,
3352
 
                                            &bIsNull);
3353
 
              if (!bIsNull && OGR_ST_GetRGBFromString(hSymbolStyle,
3354
 
                                                      pszColor,
3355
 
                                                      &r, &g, &b, &t))
3356
 
              {
3357
 
                  MS_INIT_COLOR(c->styles[0]->outlinecolor, r, g, b);
3358
 
              }
3359
 
#endif /* GDAL_VERSION_NUM >= 1600 */
3360
 
              c->styles[0]->angle = OGR_ST_GetParamNum(hSymbolStyle,
3361
 
                                                       OGRSTSymbolAngle,
3362
 
                                                       &bIsNull);
3363
 
              
3364
 
              c->styles[0]->size = OGR_ST_GetParamNum(hSymbolStyle, 
3365
 
                                                      OGRSTSymbolSize, 
3366
 
                                                      &bIsNull);
3367
 
 
3368
 
              // Symbol name mapping:
3369
 
              // First look for the native symbol name, then the ogr-...
3370
 
              // generic name, and in last resort try "default-marker" if
3371
 
              // provided by user.
3372
 
              const char *pszName = OGR_ST_GetParamStr(hSymbolStyle, 
3373
 
                                                       OGRSTSymbolId, 
3374
 
                                                       &bIsNull);
3375
 
              if (bIsNull)
3376
 
                  pszName = NULL;
3377
 
 
3378
 
              c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset),
3379
 
                                                    pszName, 
3380
 
                                                    "default-marker");
3381
 
          }
3382
 
#else /* OGR Style C++ */
3383
 
          {
3384
 
              OGRStyleSymbol *poSymbolStyle = (OGRStyleSymbol*)poStylePart;
3385
 
 
3386
 
              /* We need 1 style */
3387
 
              if (msMaybeAllocateStyle(c, 0))
3388
 
              {
3389
 
                  RELEASE_OGR_LOCK;
3390
 
                  return(MS_FAILURE);
3391
 
              }
3392
 
 
3393
 
              const char *pszColor = poSymbolStyle->Color(bIsNull);
3394
 
              if (!bIsNull && poSymbolStyle->GetRGBFromString(pszColor,r,g,b,t))
3395
 
              {
3396
 
                  MS_INIT_COLOR(c->styles[0]->color, r, g, b);
3397
 
              }
3398
 
 
3399
 
              c->styles[0]->angle = poSymbolStyle->Angle(bIsNull);
3400
 
                  
3401
 
              c->styles[0]->size = (int)poSymbolStyle->Size(bIsNull);
3402
 
 
3403
 
              // Symbol name mapping:
3404
 
              // First look for the native symbol name, then the ogr-...
3405
 
              // generic name, and in last resort try "default-marker" if
3406
 
              // provided by user.
3407
 
              const char *pszName = poSymbolStyle->Id(bIsNull);
3408
 
              if (bIsNull)
3409
 
                  pszName = NULL;
3410
 
 
3411
 
              c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset),
3412
 
                                                    pszName, 
3413
 
                                                    "default-marker");
3414
 
          }
3415
 
#endif /* OGRStyle C API */
3416
 
 
3417
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3418
 
          OGR_ST_Destroy(hStylePart);
3419
 
#else
3420
 
          delete poStylePart;
3421
 
#endif
3422
 
 
3423
 
      }
3424
 
 
3425
 
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3426
 
      OGR_SM_Destroy(hStyleMgr);
3427
 
#else
3428
 
      delete poStyleMgr;
3429
 
#endif
3430
 
 
3431
 
  }
3432
 
 
3433
 
  RELEASE_OGR_LOCK;
3434
 
  return MS_SUCCESS;
3435
 
#else
3436
 
/* ------------------------------------------------------------------
3437
 
 * OGR Support not included...
3438
 
 * ------------------------------------------------------------------ */
3439
 
 
3440
 
  msSetError(MS_MISCERR, "OGR support is not available.", 
3441
 
             "msOGRLayerGetAutoStyle()");
3442
 
  return(MS_FAILURE);
3443
 
 
3444
 
#endif /* USE_OGR */
3445
 
}
3446
 
 
3447
 
/************************************************************************/
3448
 
/*                           msOGRLCleanup()                            */
3449
 
/************************************************************************/
3450
 
 
3451
 
void msOGRCleanup( void )
3452
 
 
3453
 
{
3454
 
#if defined(USE_OGR)
3455
 
    ACQUIRE_OGR_LOCK;
3456
 
    if( bOGRDriversRegistered == MS_TRUE )
3457
 
    {
3458
 
#if GDAL_VERSION_NUM >= 1400
3459
 
        OGRCleanupAll();
3460
 
        bOGRDriversRegistered = MS_FALSE;
3461
 
#endif
3462
 
    }
3463
 
    RELEASE_OGR_LOCK;
3464
 
#endif
3465
 
}
3466
 
 
3467
 
/************************************************************************/
3468
 
/*                  msOGRLayerInitializeVirtualTable()                  */
3469
 
/************************************************************************/
3470
 
int
3471
 
msOGRLayerInitializeVirtualTable(layerObj *layer)
3472
 
{
3473
 
    assert(layer != NULL);
3474
 
    assert(layer->vtable != NULL);
3475
 
 
3476
 
    layer->vtable->LayerInitItemInfo = msOGRLayerInitItemInfo;
3477
 
    layer->vtable->LayerFreeItemInfo = msOGRLayerFreeItemInfo;
3478
 
    layer->vtable->LayerOpen = msOGRLayerOpenVT;
3479
 
    layer->vtable->LayerIsOpen = msOGRLayerIsOpen;
3480
 
    layer->vtable->LayerWhichShapes = msOGRLayerWhichShapes;
3481
 
    layer->vtable->LayerNextShape = msOGRLayerNextShape;
3482
 
    layer->vtable->LayerResultsGetShape = msOGRLayerResultGetShape; 
3483
 
    layer->vtable->LayerGetShape = msOGRLayerGetShape;
3484
 
    layer->vtable->LayerClose = msOGRLayerClose;
3485
 
    layer->vtable->LayerGetItems = msOGRLayerGetItems;
3486
 
    layer->vtable->LayerGetExtent = msOGRLayerGetExtent;
3487
 
    layer->vtable->LayerGetAutoStyle = msOGRLayerGetAutoStyle;
3488
 
    /* layer->vtable->LayerCloseConnection, use default */
3489
 
    layer->vtable->LayerApplyFilterToLayer = msLayerApplyCondSQLFilterToLayer;
3490
 
    layer->vtable->LayerSetTimeFilter = msLayerMakeBackticsTimeFilter;
3491
 
    /* layer->vtable->LayerCreateItems, use default */
3492
 
    /* layer->vtable->LayerGetNumFeatures, use default */
3493
 
 
3494
 
    return MS_SUCCESS;
3495
 
}
3496
 
 
3497
 
/************************************************************************/
3498
 
/*                         msOGRShapeFromWKT()                          */
3499
 
/************************************************************************/
3500
 
shapeObj *msOGRShapeFromWKT(const char *string)
3501
 
{
3502
 
#ifdef USE_OGR
3503
 
    OGRGeometryH hGeom = NULL;
3504
 
    shapeObj *shape=NULL;
3505
 
    
3506
 
    if(!string) 
3507
 
        return NULL;
3508
 
    
3509
 
    ACQUIRE_OLD_OGR_LOCK;
3510
 
    if( OGR_G_CreateFromWkt( (char **)&string, NULL, &hGeom ) != OGRERR_NONE )
3511
 
    {
3512
 
        msSetError(MS_OGRERR, "Failed to parse WKT string.", 
3513
 
                   "msOGRShapeFromWKT()" );
3514
 
        RELEASE_OLD_OGR_LOCK;
3515
 
        return NULL;
3516
 
    }
3517
 
 
3518
 
    /* Initialize a corresponding shapeObj */
3519
 
 
3520
 
    shape = (shapeObj *) malloc(sizeof(shapeObj));
3521
 
    msInitShape(shape);
3522
 
 
3523
 
    /* translate WKT into an OGRGeometry. */
3524
 
  
3525
 
    if( msOGRGeometryToShape( hGeom, shape, 
3526
 
                              wkbFlatten(OGR_G_GetGeometryType(hGeom)) )
3527
 
                              == MS_FAILURE )
3528
 
    {
3529
 
        RELEASE_OLD_OGR_LOCK;
3530
 
        free( shape );
3531
 
        return NULL;
3532
 
    }
3533
 
 
3534
 
    OGR_G_DestroyGeometry( hGeom );
3535
 
 
3536
 
    RELEASE_OLD_OGR_LOCK;
3537
 
    return shape;
3538
 
#else
3539
 
  msSetError(MS_OGRERR, "OGR support is not available.","msOGRShapeFromWKT()");
3540
 
  return NULL;
3541
 
#endif
3542
 
}
3543
 
 
3544
 
/************************************************************************/
3545
 
/*                          msOGRShapeToWKT()                           */
3546
 
/************************************************************************/
3547
 
char *msOGRShapeToWKT(shapeObj *shape)
3548
 
{
3549
 
#ifdef USE_OGR
3550
 
    OGRGeometryH hGeom = NULL;
3551
 
    int          i;
3552
 
    char        *wkt = NULL;
3553
 
 
3554
 
    if(!shape) 
3555
 
        return NULL;
3556
 
 
3557
 
    ACQUIRE_OLD_OGR_LOCK;
3558
 
    if( shape->type == MS_SHAPE_POINT && shape->numlines == 1
3559
 
        && shape->line[0].numpoints == 1 )
3560
 
    {
3561
 
        hGeom = OGR_G_CreateGeometry( wkbPoint );
3562
 
#if GDAL_VERSION_NUM >= 1310
3563
 
        OGR_G_SetPoint_2D( hGeom, 0, 
3564
 
                           shape->line[0].point[0].x, 
3565
 
                           shape->line[0].point[0].y );
3566
 
#else
3567
 
        OGR_G_SetPoint( hGeom, 0, 
3568
 
                        shape->line[0].point[0].x, 
3569
 
                        shape->line[0].point[0].y,
3570
 
                        0.0 );
3571
 
#endif
3572
 
    }
3573
 
    else if( shape->type == MS_SHAPE_POINT && shape->numlines == 1 
3574
 
             && shape->line[0].numpoints > 1 )
3575
 
    {
3576
 
        hGeom = OGR_G_CreateGeometry( wkbMultiPoint );
3577
 
        for( i = 0; i < shape->line[0].numpoints; i++ )
3578
 
        {
3579
 
            OGRGeometryH hPoint;
3580
 
            
3581
 
            hPoint = OGR_G_CreateGeometry( wkbPoint );
3582
 
#if GDAL_VERSION_NUM >= 1310
3583
 
            OGR_G_SetPoint_2D( hPoint, 0, 
3584
 
                               shape->line[0].point[i].x, 
3585
 
                               shape->line[0].point[i].y );
3586
 
#else
3587
 
            OGR_G_SetPoint( hPoint, 0, 
3588
 
                            shape->line[0].point[i].x, 
3589
 
                            shape->line[0].point[i].y,
3590
 
                            0.0 );
3591
 
#endif
3592
 
            OGR_G_AddGeometryDirectly( hGeom, hPoint );
3593
 
        }
3594
 
    }
3595
 
    else if( shape->type == MS_SHAPE_LINE && shape->numlines == 1 )
3596
 
    {
3597
 
        hGeom = OGR_G_CreateGeometry( wkbLineString );
3598
 
        for( i = 0; i < shape->line[0].numpoints; i++ )
3599
 
        {
3600
 
#if GDAL_VERSION_NUM >= 1310
3601
 
            OGR_G_AddPoint_2D( hGeom, 
3602
 
                               shape->line[0].point[i].x, 
3603
 
                               shape->line[0].point[i].y );
3604
 
#else
3605
 
            OGR_G_AddPoint( hGeom, 
3606
 
                            shape->line[0].point[i].x, 
3607
 
                            shape->line[0].point[i].y,
3608
 
                            0.0 );
3609
 
#endif
3610
 
        }
3611
 
    }
3612
 
    else if( shape->type == MS_SHAPE_LINE && shape->numlines > 1 )
3613
 
    {
3614
 
        OGRGeometryH hMultiLine = OGR_G_CreateGeometry( wkbMultiLineString );
3615
 
        int iLine;
3616
 
 
3617
 
        for( iLine = 0; iLine < shape->numlines; iLine++ )
3618
 
        {
3619
 
            hGeom = OGR_G_CreateGeometry( wkbLineString );
3620
 
            for( i = 0; i < shape->line[iLine].numpoints; i++ )
3621
 
            {
3622
 
#if GDAL_VERSION_NUM >= 1310
3623
 
                OGR_G_AddPoint_2D( hGeom, 
3624
 
                                   shape->line[iLine].point[i].x, 
3625
 
                                   shape->line[iLine].point[i].y );
3626
 
#else
3627
 
                OGR_G_AddPoint( hGeom, 
3628
 
                            shape->line[iLine].point[i].x, 
3629
 
                            shape->line[iLine].point[i].y,
3630
 
                            0.0 );
3631
 
#endif
3632
 
            }
3633
 
 
3634
 
            OGR_G_AddGeometryDirectly( hMultiLine, hGeom );
3635
 
        }
3636
 
 
3637
 
        hGeom = hMultiLine;
3638
 
    }
3639
 
    else if( shape->type == MS_SHAPE_POLYGON )
3640
 
    {
3641
 
        int iLine;
3642
 
 
3643
 
        /* actually, it is pretty hard to be sure rings 1+ are interior */
3644
 
        hGeom = OGR_G_CreateGeometry( wkbPolygon );
3645
 
        for( iLine = 0; iLine < shape->numlines; iLine++ )
3646
 
        {
3647
 
            OGRGeometryH hRing;
3648
 
            hRing = OGR_G_CreateGeometry( wkbLinearRing );
3649
 
            
3650
 
            for( i = 0; i < shape->line[iLine].numpoints; i++ )
3651
 
            {
3652
 
#if GDAL_VERSION_NUM >= 1310
3653
 
                OGR_G_AddPoint_2D( hRing, 
3654
 
                                   shape->line[iLine].point[i].x, 
3655
 
                                   shape->line[iLine].point[i].y );
3656
 
#else
3657
 
                OGR_G_AddPoint( hRing, 
3658
 
                                shape->line[iLine].point[i].x, 
3659
 
                                shape->line[iLine].point[i].y, 
3660
 
                                0.0 );
3661
 
#endif
3662
 
            }
3663
 
            OGR_G_AddGeometryDirectly( hGeom, hRing );
3664
 
        }
3665
 
    }
3666
 
    else
3667
 
    {
3668
 
        msSetError(MS_OGRERR, "OGR support is not available.", "msOGRShapeToWKT()");
3669
 
    }
3670
 
 
3671
 
    if( hGeom != NULL )
3672
 
    {
3673
 
        char *pszOGRWkt;
3674
 
 
3675
 
        OGR_G_ExportToWkt( hGeom, &pszOGRWkt );
3676
 
        wkt = strdup( pszOGRWkt );
3677
 
        CPLFree( pszOGRWkt );
3678
 
    }
3679
 
 
3680
 
    RELEASE_OLD_OGR_LOCK;
3681
 
    return wkt;
3682
 
#else
3683
 
    msSetError(MS_OGRERR, "OGR support is not available.", "msOGRShapeToWKT()");
3684
 
    return NULL;
3685
 
#endif
3686
 
}
3687