1
/**********************************************************************
2
* $Id: mapogr.cpp 10545 2010-09-30 11:52:36Z tamas $
6
* Author: Daniel Morissette, DM Solutions Group (morissette@dmsolutions.ca)
7
* Frank Warmerdam (warmerdam@pobox.com)
9
**********************************************************************
10
* Copyright (c) 2000-2005, Daniel Morissette, DM Solutions Group Inc
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:
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.
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
**********************************************************************/
32
#include "mapserver.h"
33
#include "mapproject.h"
34
#include "mapthread.h"
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"
43
MS_CVSID("$Id: mapogr.cpp 10545 2010-09-30 11:52:36Z tamas $")
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 )
49
# define ACQUIRE_OLD_OGR_LOCK
50
# define RELEASE_OLD_OGR_LOCK
53
#define ACQUIRE_OGR_LOCK msAcquireLock( TLOCK_OGR )
54
#define RELEASE_OGR_LOCK msReleaseLock( TLOCK_OGR )
58
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
60
#else /* Use OGR Style C++ */
61
#include "ogrsf_frmts.h"
62
#include "ogr_featurestyle.h"
65
typedef struct ms_ogr_file_info_t
71
OGRFeatureH hLastFeature;
73
int nTileId; /* applies on the tiles themselves. */
75
struct ms_ogr_file_info_t *poCurTile; /* exists on tile index, -> tiles */
76
rectObj rect; /* set by WhichShapes */
78
int last_record_index_read;
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 );
88
/* ==================================================================
89
* Geometry conversion functions
90
* ================================================================== */
92
/**********************************************************************
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)
102
/* Keep track of shape bounds */
103
if (line->numpoints == 0 && lineindex == 0)
105
bounds->minx = bounds->maxx = dX;
106
bounds->miny = bounds->maxy = dY;
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;
116
line->point[line->numpoints].x = dX;
117
line->point[line->numpoints].y = dY;
119
line->point[line->numpoints].z = 0.0;
120
line->point[line->numpoints].m = 0.0;
125
/**********************************************************************
127
**********************************************************************/
128
static int ogrGeomPoints(OGRGeometryH hGeom, shapeObj *outshp)
136
OGRwkbGeometryType eGType = wkbFlatten( OGR_G_GetGeometryType( hGeom ) );
138
/* -------------------------------------------------------------------- */
139
/* Container types result in recursive invocation on each */
140
/* subobject to add a set of points to the current list. */
141
/* -------------------------------------------------------------------- */
144
case wkbGeometryCollection:
145
case wkbMultiLineString:
146
case wkbMultiPolygon:
149
/* Treat it as GeometryCollection */
150
for (int iGeom=0; iGeom < OGR_G_GetGeometryCount( hGeom ); iGeom++ )
152
if( ogrGeomPoints( OGR_G_GetGeometryRef( hGeom, iGeom ),
165
/* We will handle these directly */
169
/* There shouldn't be any more cases should there? */
170
msSetError(MS_OGRERR,
171
"OGRGeometry type `%s' not supported yet.",
173
OGR_G_GetGeometryName( hGeom ) );
178
/* ------------------------------------------------------------------
179
* Count total number of points
180
* ------------------------------------------------------------------ */
181
if ( eGType == wkbPoint )
185
else if ( eGType == wkbLineString
186
|| eGType == wkbLinearRing )
188
numpoints = OGR_G_GetPointCount( hGeom );
190
else if ( eGType == wkbMultiPoint )
192
numpoints = OGR_G_GetGeometryCount( hGeom );
196
msSetError(MS_OGRERR,
197
"OGRGeometry type `%s' not supported yet.",
199
OGR_G_GetGeometryName( hGeom ) );
203
/* ------------------------------------------------------------------
204
* Do we need to allocate a line object to contain all our points?
205
* ------------------------------------------------------------------ */
206
if( outshp->numlines == 0 )
210
newline.numpoints = 0;
211
newline.point = NULL;
212
msAddLine(outshp, &newline);
215
/* ------------------------------------------------------------------
216
* Extend the point array for the new of points to add from the
218
* ------------------------------------------------------------------ */
219
lineObj *line = outshp->line + outshp->numlines-1;
221
if( line->point == NULL )
222
line->point = (pointObj *) malloc(sizeof(pointObj) * numpoints);
224
line->point = (pointObj *)
225
realloc(line->point,sizeof(pointObj) * (numpoints+line->numpoints));
229
msSetError(MS_MEMERR, "Unable to allocate temporary point cache.",
234
/* ------------------------------------------------------------------
235
* alloc buffer and filter/transform points
236
* ------------------------------------------------------------------ */
237
if( eGType == wkbPoint )
239
ogrPointsAddPoint(line, OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0),
240
outshp->numlines-1, &(outshp->bounds));
242
else if( eGType == wkbLineString
243
|| eGType == wkbLinearRing )
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));
249
else if( eGType == wkbMultiPoint )
251
for(i=0; i<numpoints; i++)
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));
259
outshp->type = MS_SHAPE_POINT;
265
/**********************************************************************
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,
277
/* ------------------------------------------------------------------
278
* Use recursive calls for complex geometries
279
* ------------------------------------------------------------------ */
280
OGRwkbGeometryType eGType = wkbFlatten( OGR_G_GetGeometryType( hGeom ) );
283
if ( eGType == wkbPolygon
284
|| eGType == wkbGeometryCollection
285
|| eGType == wkbMultiLineString
286
|| eGType == wkbMultiPolygon )
288
if (eGType == wkbPolygon && outshp->type == MS_SHAPE_NULL)
289
outshp->type = MS_SHAPE_POLYGON;
291
/* Treat it as GeometryCollection */
292
for (int iGeom=0; iGeom < OGR_G_GetGeometryCount( hGeom ); iGeom++ )
294
if( ogrGeomLine( OGR_G_GetGeometryRef( hGeom, iGeom ),
295
outshp, bCloseRings ) == -1 )
299
/* ------------------------------------------------------------------
300
* OGRPoint and OGRMultiPoint
301
* ------------------------------------------------------------------ */
302
else if ( eGType == wkbPoint || eGType == wkbMultiPoint )
304
/* Hummmm a point when we're drawing lines/polygons... just drop it! */
306
/* ------------------------------------------------------------------
307
* OGRLinearRing/OGRLineString ... both are of type wkbLineString
308
* ------------------------------------------------------------------ */
309
else if ( eGType == wkbLineString )
312
lineObj line={0,NULL};
315
if ((numpoints = OGR_G_GetPointCount( hGeom )) < 2)
318
if (outshp->type == MS_SHAPE_NULL)
319
outshp->type = MS_SHAPE_LINE;
322
line.point = (pointObj *)malloc(sizeof(pointObj)*(numpoints+1));
325
msSetError(MS_MEMERR, "Unable to allocate temporary point cache.",
330
for(j=0; j<numpoints; j++)
332
dX = line.point[j].x = OGR_G_GetX( hGeom, j);
333
dY = line.point[j].y = OGR_G_GetY( hGeom, j);
335
/* Keep track of shape bounds */
336
if (j == 0 && outshp->numlines == 0)
338
outshp->bounds.minx = outshp->bounds.maxx = dX;
339
outshp->bounds.miny = outshp->bounds.maxy = dY;
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;
350
line.numpoints = numpoints;
353
( line.point[line.numpoints-1].x != line.point[0].x ||
354
line.point[line.numpoints-1].y != line.point[0].y ) )
356
line.point[line.numpoints].x = line.point[0].x;
357
line.point[line.numpoints].y = line.point[0].y;
361
msAddLineDirectly(outshp, &line);
365
msSetError(MS_OGRERR,
366
"OGRGeometry type `%s' not supported.",
368
OGR_G_GetGeometryName( hGeom ) );
376
/**********************************************************************
377
* ogrConvertGeometry()
379
* Convert OGR geometry into a shape object doing the best possible
380
* job to match OGR Geometry type and layer type.
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)
388
/* ------------------------------------------------------------------
389
* Process geometry according to layer type
390
* ------------------------------------------------------------------ */
391
int nStatus = MS_SUCCESS;
395
// Empty geometry... this is not an error... we'll just skip it
401
/* ------------------------------------------------------------------
402
* POINT layer - Any geometry can be converted to point/multipoint
403
* ------------------------------------------------------------------ */
405
if(ogrGeomPoints(hGeom, outshp) == -1)
407
nStatus = MS_FAILURE; // Error message already produced.
410
/* ------------------------------------------------------------------
412
* ------------------------------------------------------------------ */
414
if(ogrGeomLine(hGeom, outshp, MS_FALSE) == -1)
416
nStatus = MS_FAILURE; // Error message already produced.
418
if (outshp->type != MS_SHAPE_LINE && outshp->type != MS_SHAPE_POLYGON)
419
outshp->type = MS_SHAPE_NULL; // Incompatible type for this layer
421
/* ------------------------------------------------------------------
423
* ------------------------------------------------------------------ */
424
case MS_LAYER_POLYGON:
425
if(ogrGeomLine(hGeom, outshp, MS_TRUE) == -1)
427
nStatus = MS_FAILURE; // Error message already produced.
429
if (outshp->type != MS_SHAPE_POLYGON)
430
outshp->type = MS_SHAPE_NULL; // Incompatible type for this layer
432
/* ------------------------------------------------------------------
433
* MS_ANNOTATION layer - return real feature type
434
* ------------------------------------------------------------------ */
435
case MS_LAYER_ANNOTATION:
438
switch( OGR_G_GetGeometryType( hGeom ) )
443
case wkbMultiPoint25D:
444
if(ogrGeomPoints(hGeom, outshp) == -1)
446
nStatus = MS_FAILURE; // Error message already produced.
450
// Handle any non-point types as lines/polygons ... ogrGeomLine()
451
// will decide the shape type
452
if(ogrGeomLine(hGeom, outshp, MS_FALSE) == -1)
454
nStatus = MS_FAILURE; // Error message already produced.
460
msSetError(MS_MISCERR, "Unknown or unsupported layer type.",
461
"msOGRLayerNextShape()");
462
nStatus = MS_FAILURE;
463
} /* switch layertype */
468
/**********************************************************************
469
* msOGRGeometryToShape()
471
* Utility function to convert from OGR geometry to a mapserver shape
473
**********************************************************************/
474
int msOGRGeometryToShape(OGRGeometryH hGeometry, shapeObj *psShape,
475
OGRwkbGeometryType nType)
477
if (hGeometry && psShape && nType > 0)
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);
493
/* ==================================================================
494
* Attributes handling functions
495
* ================================================================== */
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
544
/**********************************************************************
547
* Load selected item (i.e. field) values into a char array
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)
558
const char *pszValue = NULL;
561
if(layer->numitems == 0)
564
if(!layer->iteminfo) // Should not happen... but just in case!
565
if (msOGRLayerInitItemInfo(layer) != MS_SUCCESS)
568
if((values = (char **)malloc(sizeof(char *)*layer->numitems)) == NULL)
570
msSetError(MS_MEMERR, NULL, "msOGRGetValues()");
574
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
575
OGRStyleMgrH hStyleMgr = NULL;
576
OGRStyleToolH hLabelStyle = NULL;
578
OGRStyleMgr *poStyleMgr = NULL;
579
OGRStyleLabel *poLabelStyle = NULL;
581
int *itemindexes = (int*)layer->iteminfo;
583
for(i=0;i<layer->numitems;i++)
585
if (itemindexes[i] >= 0)
587
// Extract regular attributes
588
values[i] = strdup(OGR_F_GetFieldAsString( hFeature, itemindexes[i]));
591
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
593
// Handle special OGR attributes coming from StyleString
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;
602
OGR_ST_Destroy(hStylePart);
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);
609
if (itemindexes[i] == MSOGR_LABELTEXTINDEX)
611
if (hLabelStyle == NULL
612
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
613
OGRSTLabelTextString,
614
&bDefault)) == NULL))
615
values[i] = strdup("");
617
values[i] = strdup(pszValue);
619
if (layer->debug >= MS_DEBUGLEVEL_VVV)
620
msDebug(MSOGR_LABELTEXTNAME " = \"%s\"\n", values[i]);
622
else if (itemindexes[i] == MSOGR_LABELANGLEINDEX)
624
if (hLabelStyle == NULL
625
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
627
&bDefault)) == NULL))
628
values[i] = strdup("0");
630
values[i] = strdup(pszValue);
632
if (layer->debug >= MS_DEBUGLEVEL_VVV)
633
msDebug(MSOGR_LABELANGLENAME " = \"%s\"\n", values[i]);
635
else if (itemindexes[i] == MSOGR_LABELSIZEINDEX)
637
if (hLabelStyle == NULL
638
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
640
&bDefault)) == NULL))
641
values[i] = strdup("0");
643
values[i] = strdup(pszValue);
645
if (layer->debug >= MS_DEBUGLEVEL_VVV)
646
msDebug(MSOGR_LABELSIZENAME " = \"%s\"\n", values[i]);
648
else if (itemindexes[i] == MSOGR_LABELFCOLORINDEX)
650
if (hLabelStyle == NULL
651
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
653
&bDefault)) == NULL))
654
values[i] = strdup("#000000");
656
values[i] = strdup(pszValue);
658
if (layer->debug >= MS_DEBUGLEVEL_VVV)
659
msDebug(MSOGR_LABELFCOLORNAME " = \"%s\"\n", values[i]);
661
else if (itemindexes[i] == MSOGR_LABELFONTNAMEINDEX )
663
if (hLabelStyle == NULL
664
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
666
&bDefault)) == NULL))
667
values[i] = strdup("Arial");
669
values[i] = strdup(pszValue);
671
if (layer->debug >= MS_DEBUGLEVEL_VVV)
672
msDebug(MSOGR_LABELFONTNAMENAME " = \"%s\"\n", values[i]);
674
else if (itemindexes[i] == MSOGR_LABELBCOLORINDEX)
676
if (hLabelStyle == NULL
677
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
679
&bDefault)) == NULL))
680
values[i] = strdup("#000000");
682
values[i] = strdup(pszValue);
684
if (layer->debug >= MS_DEBUGLEVEL_VVV)
685
msDebug(MSOGR_LABELBCOLORNAME " = \"%s\"\n", values[i]);
687
else if (itemindexes[i] == MSOGR_LABELPLACEMENTINDEX)
689
if (hLabelStyle == NULL
690
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
692
&bDefault)) == NULL))
693
values[i] = strdup("");
695
values[i] = strdup(pszValue);
697
if (layer->debug >= MS_DEBUGLEVEL_VVV)
698
msDebug(MSOGR_LABELPLACEMENTNAME " = \"%s\"\n", values[i]);
700
else if (itemindexes[i] == MSOGR_LABELANCHORINDEX)
702
if (hLabelStyle == NULL
703
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
705
&bDefault)) == NULL))
706
values[i] = strdup("0");
708
values[i] = strdup(pszValue);
710
if (layer->debug >= MS_DEBUGLEVEL_VVV)
711
msDebug(MSOGR_LABELANCHORNAME " = \"%s\"\n", values[i]);
713
else if (itemindexes[i] == MSOGR_LABELDXINDEX)
715
if (hLabelStyle == NULL
716
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
718
&bDefault)) == NULL))
719
values[i] = strdup("0");
721
values[i] = strdup(pszValue);
723
if (layer->debug >= MS_DEBUGLEVEL_VVV)
724
msDebug(MSOGR_LABELDXNAME " = \"%s\"\n", values[i]);
726
else if (itemindexes[i] == MSOGR_LABELDYINDEX)
728
if (hLabelStyle == NULL
729
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
731
&bDefault)) == NULL))
732
values[i] = strdup("0");
734
values[i] = strdup(pszValue);
736
if (layer->debug >= MS_DEBUGLEVEL_VVV)
737
msDebug(MSOGR_LABELDYNAME " = \"%s\"\n", values[i]);
739
else if (itemindexes[i] == MSOGR_LABELPERPINDEX)
741
if (hLabelStyle == NULL
742
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
744
&bDefault)) == NULL))
745
values[i] = strdup("0");
747
values[i] = strdup(pszValue);
749
if (layer->debug >= MS_DEBUGLEVEL_VVV)
750
msDebug(MSOGR_LABELPERPNAME " = \"%s\"\n", values[i]);
752
else if (itemindexes[i] == MSOGR_LABELBOLDINDEX)
754
if (hLabelStyle == NULL
755
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
757
&bDefault)) == NULL))
758
values[i] = strdup("0");
760
values[i] = strdup(pszValue);
762
if (layer->debug >= MS_DEBUGLEVEL_VVV)
763
msDebug(MSOGR_LABELBOLDNAME " = \"%s\"\n", values[i]);
765
else if (itemindexes[i] == MSOGR_LABELITALICINDEX)
767
if (hLabelStyle == NULL
768
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
770
&bDefault)) == NULL))
771
values[i] = strdup("0");
773
values[i] = strdup(pszValue);
775
if (layer->debug >= MS_DEBUGLEVEL_VVV)
776
msDebug(MSOGR_LABELITALICNAME " = \"%s\"\n", values[i]);
778
else if (itemindexes[i] == MSOGR_LABELUNDERLINEINDEX)
780
if (hLabelStyle == NULL
781
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
783
&bDefault)) == NULL))
784
values[i] = strdup("0");
786
values[i] = strdup(pszValue);
788
if (layer->debug >= MS_DEBUGLEVEL_VVV)
789
msDebug(MSOGR_LABELUNDERLINENAME " = \"%s\"\n", values[i]);
791
else if (itemindexes[i] == MSOGR_LABELPRIORITYINDEX)
793
if (hLabelStyle == NULL
794
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
796
&bDefault)) == NULL))
797
values[i] = strdup("0");
799
values[i] = strdup(pszValue);
801
if (layer->debug >= MS_DEBUGLEVEL_VVV)
802
msDebug(MSOGR_LABELPRIORITYNAME " = \"%s\"\n", values[i]);
804
else if (itemindexes[i] == MSOGR_LABELSTRIKEOUTINDEX)
806
if (hLabelStyle == NULL
807
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
809
&bDefault)) == NULL))
810
values[i] = strdup("0");
812
values[i] = strdup(pszValue);
814
if (layer->debug >= MS_DEBUGLEVEL_VVV)
815
msDebug(MSOGR_LABELSTRIKEOUTNAME " = \"%s\"\n", values[i]);
817
else if (itemindexes[i] == MSOGR_LABELSTRETCHINDEX)
819
if (hLabelStyle == NULL
820
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
822
&bDefault)) == NULL))
823
values[i] = strdup("0");
825
values[i] = strdup(pszValue);
827
if (layer->debug >= MS_DEBUGLEVEL_VVV)
828
msDebug(MSOGR_LABELSTRETCHNAME " = \"%s\"\n", values[i]);
830
else if (itemindexes[i] == MSOGR_LABELADJHORINDEX)
832
if (hLabelStyle == NULL
833
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
835
&bDefault)) == NULL))
836
values[i] = strdup("");
838
values[i] = strdup(pszValue);
840
if (layer->debug >= MS_DEBUGLEVEL_VVV)
841
msDebug(MSOGR_LABELADJHORNAME " = \"%s\"\n", values[i]);
843
else if (itemindexes[i] == MSOGR_LABELADJVERTINDEX)
845
if (hLabelStyle == NULL
846
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
848
&bDefault)) == NULL))
849
values[i] = strdup("");
851
values[i] = strdup(pszValue);
853
if (layer->debug >= MS_DEBUGLEVEL_VVV)
854
msDebug(MSOGR_LABELADJVERTNAME " = \"%s\"\n", values[i]);
856
else if (itemindexes[i] == MSOGR_LABELHCOLORINDEX)
858
if (hLabelStyle == NULL
859
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
861
&bDefault)) == NULL))
862
values[i] = strdup("");
864
values[i] = strdup(pszValue);
866
if (layer->debug >= MS_DEBUGLEVEL_VVV)
867
msDebug(MSOGR_LABELHCOLORNAME " = \"%s\"\n", values[i]);
869
#if GDAL_VERSION_NUM >= 1600
870
else if (itemindexes[i] == MSOGR_LABELOCOLORINDEX)
872
if (hLabelStyle == NULL
873
|| ((pszValue = OGR_ST_GetParamStr(hLabelStyle,
875
&bDefault)) == NULL))
876
values[i] = strdup("");
878
values[i] = strdup(pszValue);
880
if (layer->debug >= MS_DEBUGLEVEL_VVV)
881
msDebug(MSOGR_LABELOCOLORNAME " = \"%s\"\n", values[i]);
883
#endif /* GDAL_VERSION_NUM >= 1600 */
886
msSetError(MS_OGRERR,"Invalid field index!?!","msOGRGetValues()");
890
#else /* OGRStyle C++ */
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)
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);
906
if (itemindexes[i] == MSOGR_LABELTEXTINDEX)
908
if (poLabelStyle == NULL
909
|| ((pszValue = poLabelStyle->TextString(bDefault)) == NULL))
910
values[i] = strdup("");
912
values[i] = strdup(pszValue);
913
if (layer->debug >= MS_DEBUGLEVEL_VVV)
914
msDebug(MSOGR_LABELTEXTNAME " = \"%s\"\n", values[i]);
916
else if (itemindexes[i] == MSOGR_LABELANGLEINDEX)
918
if (poLabelStyle == NULL
919
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAngle,bDefault)) == NULL))
920
values[i] = strdup("0");
922
values[i] = strdup(pszValue);
923
if (layer->debug >= MS_DEBUGLEVEL_VVV)
924
msDebug(MSOGR_LABELANGLENAME " = \"%s\"\n", values[i]);
926
else if (itemindexes[i] == MSOGR_LABELSIZEINDEX)
928
if (poLabelStyle == NULL
929
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelSize,bDefault)) == NULL))
930
values[i] = strdup("0");
932
values[i] = strdup(pszValue);
933
if (layer->debug >= MS_DEBUGLEVEL_VVV)
934
msDebug(MSOGR_LABELSIZENAME " = \"%s\"\n", values[i]);
936
else if (itemindexes[i] == MSOGR_LABELFCOLORINDEX)
938
if (poLabelStyle == NULL
939
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelFColor, bDefault)) == NULL))
940
values[i] = strdup("#000000");
942
values[i] = strdup(pszValue);
944
if (layer->debug >= MS_DEBUGLEVEL_VVV)
945
msDebug(MSOGR_LABELSIZENAME " = \"%s\"\n", values[i]);
947
else if (itemindexes[i] == MSOGR_LABELFONTNAMEINDEX)
949
if (poLabelStyle == NULL
950
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelFontName, bDefault)) == NULL))
951
values[i] = strdup("Arial");
953
values[i] = strdup(pszValue);
955
if (layer->debug >= MS_DEBUGLEVEL_VVV)
956
msDebug(MSOGR_LABELFONTNAMENAME " = \"%s\"\n", values[i]);
958
else if (itemindexes[i] == MSOGR_LABELBCOLORINDEX)
960
if (poLabelStyle == NULL
961
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelBColor, bDefault)) == NULL))
962
values[i] = strdup("#000000");
964
values[i] = strdup(pszValue);
966
if (layer->debug >= MS_DEBUGLEVEL_VVV)
967
msDebug(MSOGR_LABELBCOLORNAME " = \"%s\"\n", values[i]);
969
else if (itemindexes[i] == MSOGR_LABELPLACEMENTINDEX)
971
if (poLabelStyle == NULL
972
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelPlacement, bDefault)) == NULL))
973
values[i] = strdup("");
975
values[i] = strdup(pszValue);
977
if (layer->debug >= MS_DEBUGLEVEL_VVV)
978
msDebug(MSOGR_LABELPLACEMENTNAME " = \"%s\"\n", values[i]);
980
else if (itemindexes[i] == MSOGR_LABELANCHORINDEX)
982
if (poLabelStyle == NULL
983
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAnchor, bDefault)) == NULL))
984
values[i] = strdup("0");
986
values[i] = strdup(pszValue);
988
if (layer->debug >= MS_DEBUGLEVEL_VVV)
989
msDebug(MSOGR_LABELANCHORNAME " = \"%s\"\n", values[i]);
991
else if (itemindexes[i] == MSOGR_LABELDXINDEX)
993
if (poLabelStyle == NULL
994
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelDx, bDefault)) == NULL))
995
values[i] = strdup("0");
997
values[i] = strdup(pszValue);
999
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1000
msDebug(MSOGR_LABELDXNAME " = \"%s\"\n", values[i]);
1002
else if (itemindexes[i] == MSOGR_LABELDYINDEX)
1004
if (poLabelStyle == NULL
1005
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelDy, bDefault)) == NULL))
1006
values[i] = strdup("0");
1008
values[i] = strdup(pszValue);
1010
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1011
msDebug(MSOGR_LABELDYNAME " = \"%s\"\n", values[i]);
1013
else if (itemindexes[i] == MSOGR_LABELPERPINDEX)
1015
if (poLabelStyle == NULL
1016
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelPerp, bDefault)) == NULL))
1017
values[i] = strdup("0");
1019
values[i] = strdup(pszValue);
1021
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1022
msDebug(MSOGR_LABELPERPNAME " = \"%s\"\n", values[i]);
1024
else if (itemindexes[i] == MSOGR_LABELBOLDINDEX)
1026
if (poLabelStyle == NULL
1027
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelBold, bDefault)) == NULL))
1028
values[i] = strdup("0");
1030
values[i] = strdup(pszValue);
1032
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1033
msDebug(MSOGR_LABELBOLDNAME " = \"%s\"\n", values[i]);
1035
else if (itemindexes[i] == MSOGR_LABELITALICINDEX)
1037
if (poLabelStyle == NULL
1038
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelItalic, bDefault)) == NULL))
1039
values[i] = strdup("0");
1041
values[i] = strdup(pszValue);
1043
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1044
msDebug(MSOGR_LABELITALICNAME " = \"%s\"\n", values[i]);
1046
else if (itemindexes[i] == MSOGR_LABELUNDERLINEINDEX)
1048
if (poLabelStyle == NULL
1049
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelUnderline, bDefault)) == NULL))
1050
values[i] = strdup("0");
1052
values[i] = strdup(pszValue);
1053
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1054
msDebug(MSOGR_LABELUNDERLINENAME " = \"%s\"\n", values[i]);
1056
else if (itemindexes[i] == MSOGR_LABELPRIORITYINDEX)
1058
if (poLabelStyle == NULL
1059
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelPriority, bDefault)) == NULL))
1060
values[i] = strdup("0");
1062
values[i] = strdup(pszValue);
1064
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1065
msDebug(MSOGR_LABELPRIORITYNAME " = \"%s\"\n", values[i]);
1067
#if GDAL_VERSION_NUM >= 1400
1068
else if (itemindexes[i] == MSOGR_LABELSTRIKEOUTINDEX)
1070
if (poLabelStyle == NULL
1071
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelStrikeout, bDefault)) == NULL))
1072
values[i] = strdup("0");
1074
values[i] = strdup(pszValue);
1076
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1077
msDebug(MSOGR_LABELSTRIKEOUTNAME " = \"%s\"\n", values[i]);
1079
else if (itemindexes[i] == MSOGR_LABELSTRETCHINDEX)
1081
if (poLabelStyle == NULL
1082
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelStretch, bDefault)) == NULL))
1083
values[i] = strdup("0");
1085
values[i] = strdup(pszValue);
1087
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1088
msDebug(MSOGR_LABELSTRETCHNAME " = \"%s\"\n", values[i]);
1090
else if (itemindexes[i] == MSOGR_LABELADJHORINDEX)
1092
if (poLabelStyle == NULL
1093
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAdjHor, bDefault)) == NULL))
1094
values[i] = strdup("");
1096
values[i] = strdup(pszValue);
1098
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1099
msDebug(MSOGR_LABELADJHORNAME " = \"%s\"\n", values[i]);
1101
else if (itemindexes[i] == MSOGR_LABELADJVERTINDEX)
1103
if (poLabelStyle == NULL
1104
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelAdjVert, bDefault)) == NULL))
1105
values[i] = strdup("");
1107
values[i] = strdup(pszValue);
1109
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1110
msDebug(MSOGR_LABELADJVERTNAME " = \"%s\"\n", values[i]);
1112
else if (itemindexes[i] == MSOGR_LABELHCOLORINDEX)
1114
if (poLabelStyle == NULL
1115
|| ((pszValue = poLabelStyle->GetParamStr(OGRSTLabelHColor, bDefault)) == NULL))
1116
values[i] = strdup("");
1118
values[i] = strdup(pszValue);
1120
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1121
msDebug(MSOGR_LABELHCOLORNAME " = \"%s\"\n", values[i]);
1126
msSetError(MS_OGRERR,"Invalid field index!?!","msOGRGetValues()");
1130
#endif /* OGRStyle C API */
1133
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
1134
OGR_SM_Destroy(hStyleMgr);
1135
OGR_ST_Destroy(hLabelStyle);
1138
delete poLabelStyle;
1144
#endif /* USE_OGR */
1146
#if defined(USE_OGR) || defined(USE_GDAL)
1148
/**********************************************************************
1149
* msOGRSpatialRef2ProjectionObj()
1151
* Init a MapServer projectionObj using an OGRSpatialRef
1152
* Works only with PROJECTION AUTO
1154
* Returns MS_SUCCESS/MS_FAILURE
1155
**********************************************************************/
1156
static int msOGRSpatialRef2ProjectionObj(OGRSpatialReferenceH hSRS,
1157
projectionObj *proj, int debug_flag )
1160
// First flush the "auto" name from the projargs[]...
1161
msFreeProjection( proj );
1163
if (hSRS == NULL || OSRIsLocal( hSRS ) )
1165
// Dataset had no set projection or is NonEarth (LOCAL_CS)...
1166
// Nothing else to do. Leave proj empty and no reprojection will happen!
1170
// Export OGR SRS to a PROJ4 string
1171
char *pszProj = NULL;
1173
ACQUIRE_OLD_OGR_LOCK;
1174
if (OSRExportToProj4( hSRS, &pszProj ) != OGRERR_NONE ||
1175
pszProj == NULL || strlen(pszProj) == 0)
1177
RELEASE_OLD_OGR_LOCK;
1178
msSetError(MS_OGRERR, "Conversion from OGR SRS to PROJ4 failed.",
1179
"msOGRSpatialRef2ProjectionObj()");
1184
RELEASE_OLD_OGR_LOCK;
1187
msDebug( "AUTO = %s\n", pszProj );
1189
if( msLoadProjectionString( proj, pszProj ) != 0 )
1197
#endif // defined(USE_OGR) || defined(USE_GDAL)
1199
/**********************************************************************
1200
* msOGCWKT2ProjectionObj()
1202
* Init a MapServer projectionObj using an OGC WKT definition.
1203
* Works only with PROJECTION AUTO
1205
* Returns MS_SUCCESS/MS_FAILURE
1206
**********************************************************************/
1208
int msOGCWKT2ProjectionObj( const char *pszWKT,
1209
projectionObj *proj,
1213
#if defined(USE_OGR) || defined(USE_GDAL)
1215
OGRSpatialReferenceH hSRS;
1216
char *pszAltWKT = (char *) pszWKT;
1220
ACQUIRE_OLD_OGR_LOCK;
1221
hSRS = OSRNewSpatialReference( NULL );
1223
if( !EQUALN(pszWKT,"GEOGCS",6)
1224
&& !EQUALN(pszWKT,"PROJCS",6)
1225
&& !EQUALN(pszWKT,"LOCAL_CS",8) )
1226
eErr = OSRSetFromUserInput( hSRS, pszWKT );
1228
eErr = OSRImportFromWkt( hSRS, &pszAltWKT );
1230
RELEASE_OLD_OGR_LOCK;
1232
if( eErr != OGRERR_NONE )
1234
OSRDestroySpatialReference( hSRS );
1235
msSetError(MS_OGRERR,
1236
"Ingestion of WKT string '%s' failed.",
1237
"msOGCWKT2ProjectionObj()",
1242
ms_result = msOGRSpatialRef2ProjectionObj( hSRS, proj, debug_flag );
1244
OSRDestroySpatialReference( hSRS );
1247
msSetError(MS_OGRERR,
1248
"Not implemented since neither OGR nor GDAL is enabled.",
1249
"msOGCWKT2ProjectionObj()");
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
1258
* ================================================================== */
1262
/**********************************************************************
1265
* Open an OGR connection, and initialize a msOGRFileInfo.
1266
**********************************************************************/
1268
static int bOGRDriversRegistered = MS_FALSE;
1270
static msOGRFileInfo *
1271
msOGRFileOpen(layerObj *layer, const char *connection )
1274
char *conn_decrypted = NULL;
1276
/* ------------------------------------------------------------------
1277
* Register OGR Drivers, only once per execution
1278
* ------------------------------------------------------------------ */
1279
if (!bOGRDriversRegistered)
1284
CPLPushErrorHandler( CPLQuietErrorHandler );
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");
1293
bOGRDriversRegistered = MS_TRUE;
1298
/* ------------------------------------------------------------------
1299
* Make sure any encrypted token in the connection string are decrypted
1300
* ------------------------------------------------------------------ */
1303
conn_decrypted = msDecryptStringTokens(layer->map, connection);
1304
if (conn_decrypted == NULL)
1305
return NULL; /* An error should already have been reported */
1308
/* ------------------------------------------------------------------
1309
* Parse connection string into dataset name, and layer name.
1310
* ------------------------------------------------------------------ */
1311
char *pszDSName = NULL, *pszLayerDef = NULL;
1313
if( conn_decrypted == NULL )
1315
/* we don't have anything */
1317
else if( layer->data != NULL )
1319
pszDSName = CPLStrdup(conn_decrypted);
1320
pszLayerDef = CPLStrdup(layer->data);
1324
char **papszTokens = NULL;
1326
papszTokens = CSLTokenizeStringComplex( conn_decrypted, ",", TRUE, FALSE );
1328
if( CSLCount(papszTokens) > 0 )
1329
pszDSName = CPLStrdup( papszTokens[0] );
1330
if( CSLCount(papszTokens) > 1 )
1331
pszLayerDef = CPLStrdup( papszTokens[1] );
1333
CSLDestroy(papszTokens);
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.
1339
msFree(conn_decrypted);
1340
conn_decrypted = NULL;
1342
if( pszDSName == NULL )
1344
msSetError(MS_OGRERR,
1345
"Error parsing OGR connection information in layer `%s'",
1347
layer->name?layer->name:"(null)" );
1351
if( pszLayerDef == NULL )
1352
pszLayerDef = CPLStrdup("0");
1354
/* -------------------------------------------------------------------- */
1355
/* Can we get an existing connection for this layer? */
1356
/* -------------------------------------------------------------------- */
1359
hDS = (OGRDataSourceH) msConnPoolRequest( layer );
1361
/* -------------------------------------------------------------------- */
1362
/* If not, open now, and register this connection with the */
1364
/* -------------------------------------------------------------------- */
1367
char szPath[MS_MAXPATHLEN] = "";
1368
const char *pszDSSelectedName = pszDSName;
1371
msDebug("msOGRFileOpen(%s)...\n", connection);
1374
if (msTryBuildPath3(szPath, layer->map->mappath,
1375
layer->map->shapepath, pszDSName) != NULL ||
1376
msTryBuildPath(szPath, layer->map->mappath, pszDSName) != NULL)
1378
/* Use relative path */
1379
pszDSSelectedName = szPath;
1383
msDebug("OGROPen(%s)\n", pszDSSelectedName);
1386
hDS = OGROpen( pszDSSelectedName, MS_FALSE, NULL );
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.",
1396
layer->name?layer->name:"(null)" );
1398
msSetError(MS_OGRERR,
1399
"Open failed for OGR connection in layer `%s'.\n%s\n",
1401
layer->name?layer->name:"(null)",
1402
CPLGetLastErrorMsg() );
1403
CPLFree( pszDSName );
1404
CPLFree( pszLayerDef );
1408
msConnPoolRegister( layer, hDS, msOGRCloseConnection );
1411
CPLFree( pszDSName );
1414
/* ------------------------------------------------------------------
1415
* Find the layer selected.
1416
* ------------------------------------------------------------------ */
1418
int nLayerIndex = 0;
1419
OGRLayerH hLayer = NULL;
1423
for( iLayer = 0; iLayer < OGR_DS_GetLayerCount(hDS); iLayer++ )
1425
hLayer = OGR_DS_GetLayer( hDS, iLayer );
1427
&& EQUAL(OGR_FD_GetName( OGR_L_GetLayerDefn(hLayer) ),pszLayerDef) )
1429
nLayerIndex = iLayer;
1436
if( hLayer == NULL && (atoi(pszLayerDef) > 0 || EQUAL(pszLayerDef,"0")) )
1438
nLayerIndex = atoi(pszLayerDef);
1439
if( nLayerIndex < OGR_DS_GetLayerCount(hDS) )
1440
hLayer = OGR_DS_GetLayer( hDS, nLayerIndex );
1443
if( hLayer == NULL && EQUALN(pszLayerDef,"SELECT",6) )
1446
hLayer = OGR_DS_ExecuteSQL( hDS, pszLayerDef, NULL, NULL );
1447
if( hLayer == NULL )
1449
msSetError(MS_OGRERR,
1450
"ExecuteSQL(%s) failed.\n%s",
1452
pszLayerDef, CPLGetLastErrorMsg() );
1453
OGR_DS_Destroy( hDS );
1454
CPLFree( pszLayerDef );
1464
msSetError(MS_OGRERR, "GetLayer(%s) failed for OGR connection `%s'.",
1466
pszLayerDef, connection );
1467
CPLFree( pszLayerDef );
1469
OGR_DS_Destroy( hDS );
1474
CPLFree( pszLayerDef );
1476
/* ------------------------------------------------------------------
1477
* OK... open succeded... alloc and fill msOGRFileInfo inside layer obj
1478
* ------------------------------------------------------------------ */
1479
msOGRFileInfo *psInfo =(msOGRFileInfo*)CPLCalloc(1,sizeof(msOGRFileInfo));
1481
psInfo->pszFname = CPLStrdup(OGR_DS_GetName( hDS ));
1482
psInfo->nLayerIndex = nLayerIndex;
1484
psInfo->hLayer = hLayer;
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;
1495
/************************************************************************/
1496
/* msOGRCloseConnection() */
1498
/* Callback for thread pool to actually release an OGR */
1500
/************************************************************************/
1502
static void msOGRCloseConnection( void *conn_handle )
1505
OGRDataSourceH hDS = (OGRDataSourceH) conn_handle;
1508
OGR_DS_Destroy( hDS );
1512
/**********************************************************************
1514
**********************************************************************/
1515
static int msOGRFileClose(layerObj *layer, msOGRFileInfo *psInfo )
1521
msDebug("msOGRFileClose(%s,%d).\n",
1522
psInfo->pszFname, psInfo->nLayerIndex);
1524
CPLFree(psInfo->pszFname);
1527
if (psInfo->hLastFeature)
1528
OGR_F_Destroy( psInfo->hLastFeature );
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 );
1534
// Release (potentially close) the datasource connection.
1535
// Make sure we aren't holding the lock when the callback may need it.
1537
msConnPoolRelease( layer, psInfo->hDS );
1540
// Free current tile if there is one.
1541
if( psInfo->poCurTile != NULL )
1542
msOGRFileClose( layer, psInfo->poCurTile );
1551
/**********************************************************************
1552
* msOGRFileWhichShapes()
1554
* Init OGR layer structs ready for calls to msOGRFileNextShape().
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 )
1562
if (psInfo == NULL || psInfo->hLayer == NULL)
1564
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
1565
"msOGRFileWhichShapes()");
1569
/* ------------------------------------------------------------------
1570
* Set Spatial filter... this may result in no features being returned
1571
* if layer does not overlap current view.
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
* ------------------------------------------------------------------ */
1579
OGRGeometryH hSpatialFilterPolygon = OGR_G_CreateGeometry( wkbPolygon );
1580
OGRGeometryH hRing = OGR_G_CreateGeometry( wkbLinearRing );
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);
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);
1596
OGR_G_AddGeometryDirectly( hSpatialFilterPolygon, hRing );
1598
OGR_L_SetSpatialFilter( psInfo->hLayer, hSpatialFilterPolygon );
1600
OGR_G_DestroyGeometry( hSpatialFilterPolygon );
1602
psInfo->rect = rect;
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 );
1608
/* ------------------------------------------------------------------
1609
* Apply an attribute filter if we have one prefixed with a WHERE
1610
* keyword in the filter string. Otherwise, ensure the attribute
1612
* ------------------------------------------------------------------ */
1613
if( layer->filter.string && EQUALN(layer->filter.string,"WHERE ",6) )
1616
if( OGR_L_SetAttributeFilter( psInfo->hLayer, layer->filter.string+6 )
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() );
1629
OGR_L_SetAttributeFilter( psInfo->hLayer, NULL );
1631
/* ------------------------------------------------------------------
1632
* Reset current feature pointer
1633
* ------------------------------------------------------------------ */
1634
OGR_L_ResetReading( psInfo->hLayer );
1635
psInfo->last_record_index_read = -1;
1642
/**********************************************************************
1643
* msOGRFileGetItems()
1645
* Returns a list of field names in a NULL terminated list of strings.
1646
**********************************************************************/
1647
static char **msOGRFileGetItems(layerObj *layer, msOGRFileInfo *psInfo )
1649
OGRFeatureDefnH hDefn;
1650
int i, numitems,totalnumitems;
1651
int numStyleItems = MSOGR_LABELNUMITEMS;
1653
const char *getShapeStyleItems;
1655
if((hDefn = OGR_L_GetLayerDefn( psInfo->hLayer )) == NULL)
1657
msSetError(MS_OGRERR,
1658
"OGR Connection for layer `%s' contains no field definition.",
1659
"msOGRFileGetItems()",
1660
layer->name?layer->name:"(null)" );
1664
totalnumitems = numitems = OGR_FD_GetFieldCount( hDefn );
1666
getShapeStyleItems = msLayerGetProcessingKey( layer, "GETSHAPE_STYLE_ITEMS" );
1667
if (getShapeStyleItems && EQUAL(getShapeStyleItems, "all"))
1668
totalnumitems += numStyleItems;
1670
if((items = (char**)malloc(sizeof(char *)*(totalnumitems+1))) == NULL)
1672
msSetError(MS_MEMERR, NULL, "msOGRFileGetItems()");
1676
for(i=0;i<numitems;i++)
1678
OGRFieldDefnH hField = OGR_FD_GetFieldDefn( hDefn, i );
1679
items[i] = strdup( OGR_Fld_GetNameRef( hField ));
1682
if (getShapeStyleItems && EQUAL(getShapeStyleItems, "all"))
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 );
1712
/**********************************************************************
1713
* msOGRFileNextShape()
1715
* Returns shape sequentially from OGR data source.
1716
* msOGRLayerWhichShape() must have been called first.
1718
* Returns MS_SUCCESS/MS_FAILURE
1719
**********************************************************************/
1721
msOGRFileNextShape(layerObj *layer, shapeObj *shape,
1722
msOGRFileInfo *psInfo )
1724
OGRFeatureH hFeature = NULL;
1726
if (psInfo == NULL || psInfo->hLayer == NULL)
1728
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
1729
"msOGRFileNextShape()");
1733
/* ------------------------------------------------------------------
1734
* Read until we find a feature that matches attribute filter and
1735
* whose geometry is compatible with current layer type.
1736
* ------------------------------------------------------------------ */
1738
shape->type = MS_SHAPE_NULL;
1741
while (shape->type == MS_SHAPE_NULL)
1744
OGR_F_Destroy( hFeature );
1746
if( (hFeature = OGR_L_GetNextFeature( psInfo->hLayer )) == NULL )
1748
psInfo->last_record_index_read = -1;
1749
if( CPLGetLastErrorType() == CE_Failure )
1751
msSetError(MS_OGRERR, "%s", "msOGRFileNextShape()",
1752
CPLGetLastErrorMsg() );
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
1765
psInfo->last_record_index_read++;
1767
if(layer->numitems > 0)
1769
shape->values = msOGRGetValues(layer, hFeature);
1770
shape->numvalues = layer->numitems;
1773
OGR_F_Destroy( hFeature );
1779
// Check the expression unless it is a WHERE clause already
1781
if( (layer->filter.string && EQUALN(layer->filter.string,"WHERE ",6))
1782
|| msEvalExpression(&(layer->filter), layer->filteritemindex,
1783
shape->values, layer->numitems) == MS_TRUE)
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)
1790
if (shape->type != MS_SHAPE_NULL)
1791
break; // Shape is ready to be returned!
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 ) ) ),
1803
OGR_F_Destroy( hFeature );
1805
return MS_FAILURE; // Error message already produced.
1809
// Feature rejected... free shape to clear attributes values.
1811
shape->type = MS_SHAPE_NULL;
1814
shape->index = psInfo->last_record_index_read;
1815
shape->tileindex = psInfo->nTileId;
1817
if (layer->debug >= MS_DEBUGLEVEL_VVV)
1818
msDebug("msOGRFileNextShape: Returning shape=%d, tile=%d\n",
1819
shape->index, shape->tileindex );
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;
1831
/**********************************************************************
1832
* msOGRFileGetShape()
1834
* Returns shape from OGR data source by id.
1836
* Returns MS_SUCCESS/MS_FAILURE
1837
**********************************************************************/
1839
msOGRFileGetShape(layerObj *layer, shapeObj *shape, long record,
1840
msOGRFileInfo *psInfo, int record_is_fid )
1842
OGRFeatureH hFeature;
1844
if (psInfo == NULL || psInfo->hLayer == NULL)
1846
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
1847
"msOGRFileNextShape()");
1851
/* -------------------------------------------------------------------- */
1852
/* Clear previously loaded shape. */
1853
/* -------------------------------------------------------------------- */
1855
shape->type = MS_SHAPE_NULL;
1857
/* -------------------------------------------------------------------- */
1858
/* Support reading feature by fid. */
1859
/* -------------------------------------------------------------------- */
1863
if( (hFeature = OGR_L_GetFeature( psInfo->hLayer, record )) == NULL )
1870
/* -------------------------------------------------------------------- */
1871
/* Support reading shape by offset within the current */
1873
/* -------------------------------------------------------------------- */
1874
else if( !record_is_fid )
1877
if( record <= psInfo->last_record_index_read
1878
|| psInfo->last_record_index_read == -1 )
1880
OGR_L_ResetReading( psInfo->hLayer );
1881
psInfo->last_record_index_read = -1;
1885
while( psInfo->last_record_index_read < record )
1887
if( hFeature != NULL )
1889
OGR_F_Destroy( hFeature );
1892
if( (hFeature = OGR_L_GetNextFeature( psInfo->hLayer )) == NULL )
1897
psInfo->last_record_index_read++;
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)
1909
return MS_FAILURE; // Error message already produced.
1912
if (shape->type == MS_SHAPE_NULL)
1914
msSetError(MS_OGRERR,
1915
"Requested feature is incompatible with layer type",
1916
"msOGRLayerGetShape()");
1921
/* ------------------------------------------------------------------
1922
* Process shape attributes
1923
* ------------------------------------------------------------------ */
1924
if(layer->numitems > 0)
1926
shape->values = msOGRGetValues(layer, hFeature);
1927
shape->numvalues = layer->numitems;
1936
shape->index = record;
1937
shape->tileindex = psInfo->nTileId;
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;
1949
/************************************************************************/
1950
/* msOGRFileReadTile() */
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. */
1957
/* Newly loaded tiles are automatically "WhichShaped" based on */
1958
/* the current rectangle. */
1959
/************************************************************************/
1961
int msOGRFileReadTile( layerObj *layer, msOGRFileInfo *psInfo,
1962
int targetTile = -1 )
1967
/* -------------------------------------------------------------------- */
1968
/* Close old tile if one is open. */
1969
/* -------------------------------------------------------------------- */
1970
if( psInfo->poCurTile != NULL )
1972
msOGRFileClose( layer, psInfo->poCurTile );
1973
psInfo->poCurTile = NULL;
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
/* -------------------------------------------------------------------- */
1982
if( targetTile == -2 )
1984
OGR_L_ResetReading( psInfo->hLayer );
1987
/* -------------------------------------------------------------------- */
1988
/* Get the name (connection string really) of the next tile. */
1989
/* -------------------------------------------------------------------- */
1990
OGRFeatureH hFeature;
1991
char *connection = NULL;
1992
msOGRFileInfo *psTileInfo = NULL;
1995
#ifndef IGNORE_MISSING_DATA
1999
if( targetTile < 0 )
2000
hFeature = OGR_L_GetNextFeature( psInfo->hLayer );
2003
hFeature = OGR_L_GetFeature( psInfo->hLayer, targetTile );
2005
if( hFeature == NULL )
2008
if( targetTile == -1 )
2015
connection = strdup( OGR_F_GetFieldAsString( hFeature,
2016
layer->tileitemindex ));
2018
nFeatureId = OGR_F_GetFID( hFeature );
2020
OGR_F_Destroy( hFeature );
2024
/* -------------------------------------------------------------------- */
2025
/* Open the new tile file. */
2026
/* -------------------------------------------------------------------- */
2027
psTileInfo = msOGRFileOpen( layer, connection );
2031
#ifndef IGNORE_MISSING_DATA
2032
if( psTileInfo == NULL && targetTile == -1 )
2036
if( psTileInfo == NULL )
2039
psTileInfo->nTileId = nFeatureId;
2041
/* -------------------------------------------------------------------- */
2042
/* Initialize the spatial query on this file. */
2043
/* -------------------------------------------------------------------- */
2044
if( psInfo->rect.minx != 0 || psInfo->rect.maxx != 0 )
2046
status = msOGRFileWhichShapes( layer, psInfo->rect, psTileInfo );
2047
if( status != MS_SUCCESS )
2051
psInfo->poCurTile = psTileInfo;
2053
/* -------------------------------------------------------------------- */
2054
/* Update the iteminfo in case this layer has a different field */
2056
/* -------------------------------------------------------------------- */
2057
msOGRLayerInitItemInfo( layer );
2062
#endif /* def USE_OGR */
2064
/* ==================================================================
2065
* Here comes the REAL stuff... the functions below are called by maplayer.c
2066
* ================================================================== */
2068
/**********************************************************************
2071
* Open OGR data source for the specified map layer.
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.
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.
2083
* One can use the "ogrinfo" program to find out the layer indices in a dataset
2085
* Returns MS_SUCCESS/MS_FAILURE
2086
**********************************************************************/
2087
int msOGRLayerOpen(layerObj *layer, const char *pszOverrideConnection)
2091
msOGRFileInfo *psInfo;
2093
if (layer->layerinfo != NULL)
2095
return MS_SUCCESS; // Nothing to do... layer is already opened
2098
/* -------------------------------------------------------------------- */
2099
/* If this is not a tiled layer, just directly open the target. */
2100
/* -------------------------------------------------------------------- */
2101
if( layer->tileindex == NULL )
2103
psInfo = msOGRFileOpen( layer,
2104
(pszOverrideConnection ? pszOverrideConnection:
2105
layer->connection) );
2106
layer->layerinfo = psInfo;
2107
layer->tileitemindex = -1;
2109
if( layer->layerinfo == NULL )
2113
/* -------------------------------------------------------------------- */
2114
/* Otherwise we open the tile index, identify the tile item */
2115
/* index and try to select the first file matching our query */
2117
/* -------------------------------------------------------------------- */
2122
psInfo = msOGRFileOpen( layer, layer->tileindex );
2123
layer->layerinfo = psInfo;
2125
if( layer->layerinfo == NULL )
2128
// Identify TILEITEM
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) ),
2135
layer->tileitemindex++ ) {}
2137
if( layer->tileitemindex == OGR_FD_GetFieldCount( hDefn ) )
2139
msSetError(MS_OGRERR,
2140
"Can't identify TILEITEM %s field in TILEINDEX `%s'.",
2142
layer->tileitem, layer->tileindex );
2143
msOGRFileClose( layer, psInfo );
2144
layer->layerinfo = NULL;
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
* ------------------------------------------------------------------ */
2154
if (layer->projection.numargs > 0 &&
2155
EQUAL(layer->projection.args[0], "auto"))
2158
OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( psInfo->hLayer );
2160
if (msOGRSpatialRef2ProjectionObj(hSRS,
2161
&(layer->projection),
2162
layer->debug ) != MS_SUCCESS)
2164
errorObj *ms_error = msGetErrorObj();
2167
msSetError(MS_OGRERR,
2169
"PROJECTION AUTO cannot be used for this "
2170
"OGR connection (in layer `%s').",
2173
layer->name?layer->name:"(null)" );
2174
msOGRFileClose( layer, psInfo );
2175
layer->layerinfo = NULL;
2185
/* ------------------------------------------------------------------
2186
* OGR Support not included...
2187
* ------------------------------------------------------------------ */
2189
msSetError(MS_MISCERR, "OGR support is not available.", "msOGRLayerOpen()");
2192
#endif /* USE_OGR */
2195
/**********************************************************************
2196
* msOGRLayerOpenVT()
2198
* Overloaded version of msOGRLayerOpen for virtual table architecture
2199
**********************************************************************/
2200
static int msOGRLayerOpenVT(layerObj *layer)
2202
return msOGRLayerOpen(layer, NULL);
2205
/**********************************************************************
2207
**********************************************************************/
2208
int msOGRLayerClose(layerObj *layer)
2211
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2216
msDebug("msOGRLayerClose(%s).\n", layer->connection);
2218
msOGRFileClose( layer, psInfo );
2219
layer->layerinfo = NULL;
2225
/* ------------------------------------------------------------------
2226
* OGR Support not included...
2227
* ------------------------------------------------------------------ */
2229
msSetError(MS_MISCERR, "OGR support is not available.", "msOGRLayerClose()");
2232
#endif /* USE_OGR */
2235
/**********************************************************************
2236
* msOGRLayerIsOpen()
2237
**********************************************************************/
2238
static int msOGRLayerIsOpen(layerObj *layer)
2241
if (layer->layerinfo)
2247
/* ------------------------------------------------------------------
2248
* OGR Support not included...
2249
* ------------------------------------------------------------------ */
2251
msSetError(MS_MISCERR, "OGR support is not available.", "msOGRLayerIsOpen()");
2254
#endif /* USE_OGR */
2257
/**********************************************************************
2258
* msOGRLayerWhichShapes()
2260
* Init OGR layer structs ready for calls to msOGRLayerNextShape().
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)
2268
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2271
if (psInfo == NULL || psInfo->hLayer == NULL)
2273
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2274
"msOGRLayerWhichShapes()");
2278
status = msOGRFileWhichShapes( layer, rect, psInfo );
2280
if( status != MS_SUCCESS || layer->tileindex == NULL )
2283
// If we are using a tile index, we need to advance to the first
2284
// tile matching the spatial query, and load it.
2286
return msOGRFileReadTile( layer, psInfo );
2289
/* ------------------------------------------------------------------
2290
* OGR Support not included...
2291
* ------------------------------------------------------------------ */
2293
msSetError(MS_MISCERR, "OGR support is not available.",
2294
"msOGRLayerWhichShapes()");
2297
#endif /* USE_OGR */
2300
/**********************************************************************
2301
* msOGRLayerGetItems()
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)
2310
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2312
if (psInfo == NULL || psInfo->hLayer == NULL)
2314
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2315
"msOGRLayerGetItems()");
2319
if( layer->tileindex != NULL )
2321
if( psInfo->poCurTile == NULL
2322
&& msOGRFileReadTile( layer, psInfo ) != MS_SUCCESS )
2325
psInfo = psInfo->poCurTile;
2328
layer->numitems = 0;
2329
layer->items = msOGRFileGetItems(layer, psInfo);
2330
if( layer->items == NULL )
2333
while( layer->items[layer->numitems] != NULL )
2336
return msOGRLayerInitItemInfo(layer);
2339
/* ------------------------------------------------------------------
2340
* OGR Support not included...
2341
* ------------------------------------------------------------------ */
2343
msSetError(MS_MISCERR, "OGR support is not available.",
2344
"msOGRLayerGetItems()");
2347
#endif /* USE_OGR */
2350
/**********************************************************************
2351
* msOGRLayerInitItemInfo()
2353
* Init the itemindexes array after items[] has been reset in a layer.
2354
**********************************************************************/
2355
static int msOGRLayerInitItemInfo(layerObj *layer)
2358
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2360
OGRFeatureDefnH hDefn;
2362
if (layer->numitems == 0)
2365
if( layer->tileindex != NULL )
2367
if( psInfo->poCurTile == NULL
2368
&& msOGRFileReadTile( layer, psInfo, -2 ) != MS_SUCCESS )
2371
psInfo = psInfo->poCurTile;
2374
if (psInfo == NULL || psInfo->hLayer == NULL)
2376
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2377
"msOGRLayerInitItemInfo()");
2381
if((hDefn = OGR_L_GetLayerDefn( psInfo->hLayer )) == NULL)
2383
msSetError(MS_OGRERR, "Layer contains no fields.",
2384
"msOGRLayerInitItemInfo()");
2388
if (layer->iteminfo)
2389
free(layer->iteminfo);
2390
if((layer->iteminfo = (int *)malloc(sizeof(int)*layer->numitems))== NULL)
2392
msSetError(MS_MEMERR, NULL, "msOGRLayerInitItemInfo()");
2396
int *itemindexes = (int*)layer->iteminfo;
2397
for(i=0;i<layer->numitems;i++)
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 */
2448
itemindexes[i] = OGR_FD_GetFieldIndex( hDefn, layer->items[i] );
2449
if(itemindexes[i] == -1)
2451
msSetError(MS_OGRERR,
2452
(char*)CPLSPrintf("Invalid Field name: %s",
2454
"msOGRLayerInitItemInfo()");
2461
/* ------------------------------------------------------------------
2462
* OGR Support not included...
2463
* ------------------------------------------------------------------ */
2465
msSetError(MS_MISCERR, "OGR support is not available.",
2466
"msOGRLayerInitItemInfo()");
2469
#endif /* USE_OGR */
2472
/**********************************************************************
2473
* msOGRLayerFreeItemInfo()
2475
* Free the itemindexes array in a layer.
2476
**********************************************************************/
2477
void msOGRLayerFreeItemInfo(layerObj *layer)
2481
if (layer->iteminfo)
2482
free(layer->iteminfo);
2483
layer->iteminfo = NULL;
2486
/* ------------------------------------------------------------------
2487
* OGR Support not included...
2488
* ------------------------------------------------------------------ */
2490
msSetError(MS_MISCERR, "OGR support is not available.",
2491
"msOGRLayerFreeItemInfo()");
2493
#endif /* USE_OGR */
2497
/**********************************************************************
2498
* msOGRLayerNextShape()
2500
* Returns shape sequentially from OGR data source.
2501
* msOGRLayerWhichShape() must have been called first.
2503
* Returns MS_SUCCESS/MS_FAILURE
2504
**********************************************************************/
2505
int msOGRLayerNextShape(layerObj *layer, shapeObj *shape)
2508
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2511
if (psInfo == NULL || psInfo->hLayer == NULL)
2513
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2514
"msOGRLayerNextShape()");
2518
if( layer->tileindex == NULL )
2519
return msOGRFileNextShape( layer, shape, psInfo );
2521
// Do we need to load the first tile?
2522
if( psInfo->poCurTile == NULL )
2524
status = msOGRFileReadTile( layer, psInfo );
2525
if( status != MS_SUCCESS )
2531
// Try getting a shape from this tile.
2532
status = msOGRFileNextShape( layer, shape, psInfo->poCurTile );
2533
if( status != MS_DONE )
2537
status = msOGRFileReadTile( layer, psInfo );
2538
if( status != MS_SUCCESS )
2540
} while( status == MS_SUCCESS );
2545
/* ------------------------------------------------------------------
2546
* OGR Support not included...
2547
* ------------------------------------------------------------------ */
2549
msSetError(MS_MISCERR, "OGR support is not available.",
2550
"msOGRLayerNextShape()");
2553
#endif /* USE_OGR */
2556
/**********************************************************************
2557
* msOGRLayerGetShape()
2559
* Returns shape from OGR data source by fid.
2561
* Returns MS_SUCCESS/MS_FAILURE
2562
**********************************************************************/
2563
int msOGRLayerGetShape(layerObj *layer, shapeObj *shape, int tile,
2567
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2569
if (psInfo == NULL || psInfo->hLayer == NULL)
2571
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2572
"msOGRLayerNextShape()");
2576
if( layer->tileindex == NULL )
2577
return msOGRFileGetShape(layer, shape, fid, psInfo, TRUE );
2580
if( psInfo->poCurTile == NULL
2581
|| psInfo->poCurTile->nTileId != tile )
2583
if( msOGRFileReadTile( layer, psInfo, tile ) != MS_SUCCESS )
2587
return msOGRFileGetShape(layer, shape, fid, psInfo->poCurTile, TRUE );
2590
/* ------------------------------------------------------------------
2591
* OGR Support not included...
2592
* ------------------------------------------------------------------ */
2594
msSetError(MS_MISCERR, "OGR support is not available.",
2595
"msOGRLayerGetShape()");
2598
#endif /* USE_OGR */
2601
/**********************************************************************
2602
* msOGRLayerResultGetShape()
2604
* Returns shape from OGR data source by index into the current results
2607
* Returns MS_SUCCESS/MS_FAILURE
2608
**********************************************************************/
2609
int msOGRLayerResultGetShape(layerObj *layer, shapeObj *shape, int tile,
2613
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2615
if (psInfo == NULL || psInfo->hLayer == NULL)
2617
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2618
"msOGRLayerNextShape()");
2622
if( layer->tileindex == NULL )
2623
return msOGRFileGetShape(layer, shape, record, psInfo, FALSE );
2626
if( psInfo->poCurTile == NULL
2627
|| psInfo->poCurTile->nTileId != tile )
2629
if( msOGRFileReadTile( layer, psInfo, tile ) != MS_SUCCESS )
2633
return msOGRFileGetShape(layer, shape, record, psInfo->poCurTile, FALSE );
2636
/* ------------------------------------------------------------------
2637
* OGR Support not included...
2638
* ------------------------------------------------------------------ */
2640
msSetError(MS_MISCERR, "OGR support is not available.",
2641
"msOGRLayerGetShape()");
2644
#endif /* USE_OGR */
2647
/**********************************************************************
2648
* msOGRLayerGetExtent()
2650
* Returns the layer extents.
2652
* Returns MS_SUCCESS/MS_FAILURE
2653
**********************************************************************/
2654
int msOGRLayerGetExtent(layerObj *layer, rectObj *extent)
2657
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2658
OGREnvelope oExtent;
2660
if (psInfo == NULL || psInfo->hLayer == NULL)
2662
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2663
"msOGRLayerGetExtent()");
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.
2671
* For tile indexes layers we assume it is sufficient to get the
2672
* extents of the tile index.
2673
* ------------------------------------------------------------------ */
2675
if (OGR_L_GetExtent( psInfo->hLayer, &oExtent, TRUE) != OGRERR_NONE)
2678
msSetError(MS_MISCERR, "Unable to get extents for this layer.",
2679
"msOGRLayerGetExtent()");
2684
extent->minx = oExtent.MinX;
2685
extent->miny = oExtent.MinY;
2686
extent->maxx = oExtent.MaxX;
2687
extent->maxy = oExtent.MaxY;
2691
/* ------------------------------------------------------------------
2692
* OGR Support not included...
2693
* ------------------------------------------------------------------ */
2695
msSetError(MS_MISCERR, "OGR support is not available.",
2696
"msOGRLayerGetExtent()");
2699
#endif /* USE_OGR */
2703
/**********************************************************************
2704
* msOGRGetSymbolId()
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
**********************************************************************/
2711
static int msOGRGetSymbolId(symbolSetObj *symbolset, const char *pszSymbolId,
2712
const char *pszDefaultSymbol)
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.
2722
if (pszSymbolId && pszSymbolId[0] != '\0')
2724
#if GDAL_VERSION_NUM >= 1800 /* Use comma as the separator */
2725
params = msStringSplit(pszSymbolId, ',', &numparams);
2727
params = msStringSplit(pszSymbolId, '.', &numparams);
2731
for(int j=0; j<numparams && nSymbol == -1; j++)
2733
nSymbol = msGetSymbolIndex(symbolset, params[j], MS_FALSE);
2735
msFreeCharArray(params, numparams);
2738
if (nSymbol == -1 && pszDefaultSymbol)
2740
nSymbol = msGetSymbolIndex(symbolset,(char*)pszDefaultSymbol,MS_FALSE);
2749
/**********************************************************************
2750
* msOGRLayerGetAutoStyle()
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
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)
2764
msOGRFileInfo *psInfo =(msOGRFileInfo*)layer->layerinfo;
2766
if (psInfo == NULL || psInfo->hLayer == NULL)
2768
msSetError(MS_MISCERR, "Assertion failed: OGR layer not opened!!!",
2769
"msOGRLayerGetAutoStyle()");
2773
if( layer->tileindex != NULL )
2775
if( (psInfo->poCurTile == NULL || tile != psInfo->poCurTile->nTileId)
2776
&& msOGRFileReadTile( layer, psInfo ) != MS_SUCCESS )
2779
psInfo = psInfo->poCurTile;
2782
/* ------------------------------------------------------------------
2783
* Read shape or reuse ref. to last shape read.
2784
* ------------------------------------------------------------------ */
2786
if (psInfo->hLastFeature == NULL ||
2787
psInfo->last_record_index_read != record)
2790
msSetError(MS_MISCERR,
2791
"Assertion failed: AutoStyle not requested on loaded shape.",
2792
"msOGRLayerGetAutoStyle()");
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
* ------------------------------------------------------------------ */
2801
if (msMaybeAllocateStyle(c, 0)) {
2806
// __TODO__ label cache incompatible with styleitem feature.
2807
layer->labelcache = MS_OFF;
2809
/* ------------------------------------------------------------------
2811
* ------------------------------------------------------------------ */
2812
if (psInfo->hLastFeature)
2814
GBool bIsNull, bIsBrush=MS_FALSE, bIsPen=MS_FALSE;
2815
int r=0,g=0,b=0,t=0;
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 */
2827
for(int i=0; i<numParts; i++)
2829
OGRSTClassId eStylePartType;
2830
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
2831
OGRStyleToolH hStylePart = OGR_SM_GetPart(hStyleMgr, i, NULL);
2834
eStylePartType = OGR_ST_GetType(hStylePart);
2835
#else /* OGRStyle C++ */
2836
OGRStyleTool *poStylePart = poStyleMgr->GetPart(i);
2839
eStylePartType = poStylePart->GetType();
2840
#endif /* OGRStyle C API */
2842
// We want all size values returned in pixels.
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
2852
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
2853
OGR_ST_SetUnit(hStylePart, OGRSTUPixel, map->cellsize*72.0*39.37);
2855
poStylePart->SetUnit(OGRSTUPixel, map->cellsize*72.0*39.37);
2858
if (eStylePartType == OGRSTCLabel)
2859
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
2861
OGRStyleToolH hLabelStyle = hStylePart;
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,
2871
c->label.angle = OGR_ST_GetParamDbl(hLabelStyle,
2872
OGRSTLabelAngle, &bIsNull);
2874
c->label.size = OGR_ST_GetParamDbl(hLabelStyle,
2875
OGRSTLabelSize, &bIsNull);
2876
if( c->label.size < 1 ) /* no point dropping to zero size */
2879
// OGR default is anchor point = LL, so label is at UR of anchor
2880
c->label.position = MS_UR;
2882
const char *pszColor = OGR_ST_GetParamStr(hLabelStyle,
2885
if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2888
MS_INIT_COLOR(c->label.color, r, g, b);
2891
pszColor = OGR_ST_GetParamStr(hLabelStyle,
2894
if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2897
MS_INIT_COLOR(c->label.backgroundcolor, r, g, b);
2900
pszColor = OGR_ST_GetParamStr(hLabelStyle,
2903
if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2906
MS_INIT_COLOR(c->label.shadowcolor, r, g, b);
2909
#if GDAL_VERSION_NUM >= 1600
2910
pszColor = OGR_ST_GetParamStr(hLabelStyle,
2913
if (!bIsNull && OGR_ST_GetRGBFromString(hLabelStyle, pszColor,
2916
MS_INIT_COLOR(c->label.outlinecolor, r, g, b);
2918
#endif /* GDAL_VERSION_NUM >= 1600 */
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,
2925
&bIsNull) ? "-bold" : "";
2926
const char *pszItalic = OGR_ST_GetParamNum(hLabelStyle,
2928
&bIsNull) ? "-italic" : "";
2929
const char *pszFontName = OGR_ST_GetParamStr(hLabelStyle,
2932
const char *pszName = CPLSPrintf("%s%s%s", pszFontName, pszBold, pszItalic);
2935
if (pszFontName != NULL && !bIsNull && pszFontName[0] != '\0')
2937
if (msLookupHashTable(&(map->fontset.fonts), (char*)pszName) != NULL)
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);
2944
else if ( (strcmp(pszFontName,pszName) != 0) &&
2945
msLookupHashTable(&(map->fontset.fonts), (char*)pszFontName) != NULL)
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);
2952
else if (msLookupHashTable(&(map->fontset.fonts),"default") != NULL)
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");
2964
#endif /* USE_GD_FT || USE_GD_FT */
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");
2972
#else /* OGR Style C++ */
2974
OGRStyleLabel *poLabelStyle = (OGRStyleLabel*)poStylePart;
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)));
2982
c->label.angle = poLabelStyle->Angle(bIsNull);
2984
c->label.size = (int)poLabelStyle->Size(bIsNull);
2985
if( c->label.size < 1 ) /* no point dropping to zero size */
2988
// OGR default is anchor point = LL, so label is at UR of anchor
2989
c->label.position = MS_UR;
2991
const char *pszColor = poLabelStyle->ForeColor(bIsNull);
2992
if (!bIsNull && poLabelStyle->GetRGBFromString(pszColor,r,g,b,t))
2994
MS_INIT_COLOR(c->label.color, r, g, b);
2997
pszColor = poLabelStyle->BackColor(bIsNull);
2998
if (!bIsNull && poLabelStyle->GetRGBFromString(pszColor,r,g,b,t))
3000
MS_INIT_COLOR(c->label.backgroundcolor, r, g, b);
3002
#if GDAL_VERSION_NUM >= 1400
3003
pszColor = poLabelStyle->ShadowColor(bIsNull);
3004
if (!bIsNull && poLabelStyle->GetRGBFromString(pszColor,r,g,b,t))
3006
MS_INIT_COLOR(c->label.shadowcolor, r, g, b);
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);
3018
if (pszFontName != NULL && !bIsNull && pszFontName[0] != '\0')
3020
if (msLookupHashTable(&(map->fontset.fonts), (char*)pszName) != NULL)
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);
3027
else if ( (strcmp(pszFontName,pszName) != 0) &&
3028
msLookupHashTable(&(map->fontset.fonts), (char*)pszFontName) != NULL)
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);
3035
else if (msLookupHashTable(&(map->fontset.fonts),"default") != NULL)
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");
3047
#endif /* USE_GD_FT || USE_GD_FT */
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");
3055
#endif /* OGRStyle C API */
3056
else if (eStylePartType == OGRSTCPen)
3057
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3059
OGRStyleToolH hPenStyle = hStylePart;
3062
const char *pszPenName = OGR_ST_GetParamStr(hPenStyle,
3065
if (bIsNull) pszPenName = NULL;
3070
// Make sure pen is always initialized
3071
MS_INIT_COLOR(oPenColor, -1, -1, -1);
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)
3077
MS_INIT_COLOR(oPenColor, -1, -1, -1);
3081
const char *pszColor = OGR_ST_GetParamStr(hPenStyle,
3084
if (!bIsNull && OGR_ST_GetRGBFromString(hPenStyle, pszColor,
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);
3092
nPenSize = OGR_ST_GetParamNum(hPenStyle,
3093
OGRSTPenWidth, &bIsNull);
3096
if (pszPenName!=NULL)
3098
// Try to match pen name in symbol file
3099
nPenSymbol = msOGRGetSymbolId(&(map->symbolset),
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)
3107
// This is a multipart symbology, so pen defn goes in the
3108
// overlaysymbol params
3109
if (msMaybeAllocateStyle(c, 1))
3115
c->styles[1]->outlinecolor = oPenColor;
3116
c->styles[1]->size = nPenSize;
3117
c->styles[1]->symbol = nPenSymbol;
3118
c->styles[1]->width = nPenSize;
3122
// Single part symbology
3123
if (msMaybeAllocateStyle(c, 0))
3129
if(layer->type == MS_LAYER_POLYGON)
3130
c->styles[0]->outlinecolor = c->styles[0]->color =
3133
c->styles[0]->color = oPenColor;
3134
c->styles[0]->symbol = nPenSymbol;
3135
c->styles[0]->size = nPenSize;
3136
c->styles[0]->width = nPenSize;
3140
#else /* OGR Style C++ */
3142
OGRStylePen *poPenStyle = (OGRStylePen*)poStylePart;
3145
const char *pszPenName = poPenStyle->Id(bIsNull);
3146
if (bIsNull) pszPenName = NULL;
3151
// Make sure pen is always initialized
3152
MS_INIT_COLOR(oPenColor, -1, -1, -1);
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)
3158
MS_INIT_COLOR(oPenColor, -1, -1, -1);
3162
const char *pszColor = poPenStyle->Color(bIsNull);
3163
if (!bIsNull && poPenStyle->GetRGBFromString(pszColor,r,g,b,t))
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);
3170
nPenSize = (int)poPenStyle->Width(bIsNull);
3173
if (pszPenName!=NULL)
3175
// Try to match pen name in symbol file
3176
nPenSymbol = msOGRGetSymbolId(&(map->symbolset),
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)
3184
// This is a multipart symbology, so pen defn goes in the
3185
// overlaysymbol params
3186
if (msMaybeAllocateStyle(c, 1))
3192
c->styles[1]->outlinecolor = oPenColor;
3193
c->styles[1]->size = nPenSize;
3194
c->styles[1]->symbol = nPenSymbol;
3195
c->styles[1]->width = nPenSize;
3199
// Single part symbology
3200
if (msMaybeAllocateStyle(c, 0))
3206
if(layer->type == MS_LAYER_POLYGON)
3207
c->styles[0]->outlinecolor = c->styles[0]->color =
3210
c->styles[0]->color = oPenColor;
3211
c->styles[0]->symbol = nPenSymbol;
3212
c->styles[0]->size = nPenSize;
3213
c->styles[0]->width = nPenSize;
3217
#endif /* OGRStyle C API */
3218
else if (eStylePartType == OGRSTCBrush)
3219
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3221
OGRStyleToolH hBrushStyle = hStylePart;
3223
const char *pszBrushName = OGR_ST_GetParamStr(hBrushStyle,
3226
if (bIsNull) pszBrushName = NULL;
3228
/* We need 1 style */
3229
if (msMaybeAllocateStyle(c, 0))
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)
3239
MS_INIT_COLOR(c->styles[0]->color, -1, -1, -1);
3244
const char *pszColor = OGR_ST_GetParamStr(hBrushStyle,
3247
if (!bIsNull && OGR_ST_GetRGBFromString(hBrushStyle,
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);
3256
pszColor = OGR_ST_GetParamStr(hBrushStyle,
3257
OGRSTBrushBColor, &bIsNull);
3258
if (!bIsNull && OGR_ST_GetRGBFromString(hBrushStyle,
3262
MS_INIT_COLOR(c->styles[0]->backgroundcolor, r, g, b);
3265
// Symbol name mapping:
3266
// First look for the native symbol name, then the ogr-...
3268
// If none provided or found then use 0: solid fill
3270
const char *pszName = OGR_ST_GetParamStr(hBrushStyle,
3273
c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset),
3277
#else /* OGR Style C++ */
3279
OGRStyleBrush *poBrushStyle = (OGRStyleBrush*)poStylePart;
3281
const char *pszBrushName = poBrushStyle->Id(bIsNull);
3282
if (bIsNull) pszBrushName = NULL;
3284
/* We need 1 style */
3285
if (msMaybeAllocateStyle(c, 0))
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)
3295
MS_INIT_COLOR(c->styles[0]->color, -1, -1, -1);
3300
const char *pszColor = poBrushStyle->ForeColor(bIsNull);
3301
if (!bIsNull && poBrushStyle->GetRGBFromString(pszColor,r,g,b,t))
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);
3308
pszColor = poBrushStyle->BackColor(bIsNull);
3309
if (!bIsNull && poBrushStyle->GetRGBFromString(pszColor,r,g,b,t))
3311
MS_INIT_COLOR(c->styles[0]->backgroundcolor, r, g, b);
3314
// Symbol name mapping:
3315
// First look for the native symbol name, then the ogr-...
3317
// If none provided or found then use 0: solid fill
3319
const char *pszName = poBrushStyle->Id(bIsNull);
3322
c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset),
3326
#endif /* OGRStyle C API */
3327
else if (eStylePartType == OGRSTCSymbol)
3328
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3330
OGRStyleToolH hSymbolStyle = hStylePart;
3332
/* We need 1 style */
3333
if (msMaybeAllocateStyle(c, 0))
3339
const char *pszColor = OGR_ST_GetParamStr(hSymbolStyle,
3342
if (!bIsNull && OGR_ST_GetRGBFromString(hSymbolStyle,
3346
MS_INIT_COLOR(c->styles[0]->color, r, g, b);
3349
#if GDAL_VERSION_NUM >= 1600
3350
pszColor = OGR_ST_GetParamStr(hSymbolStyle,
3353
if (!bIsNull && OGR_ST_GetRGBFromString(hSymbolStyle,
3357
MS_INIT_COLOR(c->styles[0]->outlinecolor, r, g, b);
3359
#endif /* GDAL_VERSION_NUM >= 1600 */
3360
c->styles[0]->angle = OGR_ST_GetParamNum(hSymbolStyle,
3364
c->styles[0]->size = OGR_ST_GetParamNum(hSymbolStyle,
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,
3378
c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset),
3382
#else /* OGR Style C++ */
3384
OGRStyleSymbol *poSymbolStyle = (OGRStyleSymbol*)poStylePart;
3386
/* We need 1 style */
3387
if (msMaybeAllocateStyle(c, 0))
3393
const char *pszColor = poSymbolStyle->Color(bIsNull);
3394
if (!bIsNull && poSymbolStyle->GetRGBFromString(pszColor,r,g,b,t))
3396
MS_INIT_COLOR(c->styles[0]->color, r, g, b);
3399
c->styles[0]->angle = poSymbolStyle->Angle(bIsNull);
3401
c->styles[0]->size = (int)poSymbolStyle->Size(bIsNull);
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);
3411
c->styles[0]->symbol = msOGRGetSymbolId(&(map->symbolset),
3415
#endif /* OGRStyle C API */
3417
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3418
OGR_ST_Destroy(hStylePart);
3425
#if GDAL_VERSION_NUM >= 1500 /* Use OGR Style C API */
3426
OGR_SM_Destroy(hStyleMgr);
3436
/* ------------------------------------------------------------------
3437
* OGR Support not included...
3438
* ------------------------------------------------------------------ */
3440
msSetError(MS_MISCERR, "OGR support is not available.",
3441
"msOGRLayerGetAutoStyle()");
3444
#endif /* USE_OGR */
3447
/************************************************************************/
3448
/* msOGRLCleanup() */
3449
/************************************************************************/
3451
void msOGRCleanup( void )
3454
#if defined(USE_OGR)
3456
if( bOGRDriversRegistered == MS_TRUE )
3458
#if GDAL_VERSION_NUM >= 1400
3460
bOGRDriversRegistered = MS_FALSE;
3467
/************************************************************************/
3468
/* msOGRLayerInitializeVirtualTable() */
3469
/************************************************************************/
3471
msOGRLayerInitializeVirtualTable(layerObj *layer)
3473
assert(layer != NULL);
3474
assert(layer->vtable != NULL);
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 */
3497
/************************************************************************/
3498
/* msOGRShapeFromWKT() */
3499
/************************************************************************/
3500
shapeObj *msOGRShapeFromWKT(const char *string)
3503
OGRGeometryH hGeom = NULL;
3504
shapeObj *shape=NULL;
3509
ACQUIRE_OLD_OGR_LOCK;
3510
if( OGR_G_CreateFromWkt( (char **)&string, NULL, &hGeom ) != OGRERR_NONE )
3512
msSetError(MS_OGRERR, "Failed to parse WKT string.",
3513
"msOGRShapeFromWKT()" );
3514
RELEASE_OLD_OGR_LOCK;
3518
/* Initialize a corresponding shapeObj */
3520
shape = (shapeObj *) malloc(sizeof(shapeObj));
3523
/* translate WKT into an OGRGeometry. */
3525
if( msOGRGeometryToShape( hGeom, shape,
3526
wkbFlatten(OGR_G_GetGeometryType(hGeom)) )
3529
RELEASE_OLD_OGR_LOCK;
3534
OGR_G_DestroyGeometry( hGeom );
3536
RELEASE_OLD_OGR_LOCK;
3539
msSetError(MS_OGRERR, "OGR support is not available.","msOGRShapeFromWKT()");
3544
/************************************************************************/
3545
/* msOGRShapeToWKT() */
3546
/************************************************************************/
3547
char *msOGRShapeToWKT(shapeObj *shape)
3550
OGRGeometryH hGeom = NULL;
3557
ACQUIRE_OLD_OGR_LOCK;
3558
if( shape->type == MS_SHAPE_POINT && shape->numlines == 1
3559
&& shape->line[0].numpoints == 1 )
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 );
3567
OGR_G_SetPoint( hGeom, 0,
3568
shape->line[0].point[0].x,
3569
shape->line[0].point[0].y,
3573
else if( shape->type == MS_SHAPE_POINT && shape->numlines == 1
3574
&& shape->line[0].numpoints > 1 )
3576
hGeom = OGR_G_CreateGeometry( wkbMultiPoint );
3577
for( i = 0; i < shape->line[0].numpoints; i++ )
3579
OGRGeometryH hPoint;
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 );
3587
OGR_G_SetPoint( hPoint, 0,
3588
shape->line[0].point[i].x,
3589
shape->line[0].point[i].y,
3592
OGR_G_AddGeometryDirectly( hGeom, hPoint );
3595
else if( shape->type == MS_SHAPE_LINE && shape->numlines == 1 )
3597
hGeom = OGR_G_CreateGeometry( wkbLineString );
3598
for( i = 0; i < shape->line[0].numpoints; i++ )
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 );
3605
OGR_G_AddPoint( hGeom,
3606
shape->line[0].point[i].x,
3607
shape->line[0].point[i].y,
3612
else if( shape->type == MS_SHAPE_LINE && shape->numlines > 1 )
3614
OGRGeometryH hMultiLine = OGR_G_CreateGeometry( wkbMultiLineString );
3617
for( iLine = 0; iLine < shape->numlines; iLine++ )
3619
hGeom = OGR_G_CreateGeometry( wkbLineString );
3620
for( i = 0; i < shape->line[iLine].numpoints; i++ )
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 );
3627
OGR_G_AddPoint( hGeom,
3628
shape->line[iLine].point[i].x,
3629
shape->line[iLine].point[i].y,
3634
OGR_G_AddGeometryDirectly( hMultiLine, hGeom );
3639
else if( shape->type == MS_SHAPE_POLYGON )
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++ )
3648
hRing = OGR_G_CreateGeometry( wkbLinearRing );
3650
for( i = 0; i < shape->line[iLine].numpoints; i++ )
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 );
3657
OGR_G_AddPoint( hRing,
3658
shape->line[iLine].point[i].x,
3659
shape->line[iLine].point[i].y,
3663
OGR_G_AddGeometryDirectly( hGeom, hRing );
3668
msSetError(MS_OGRERR, "OGR support is not available.", "msOGRShapeToWKT()");
3675
OGR_G_ExportToWkt( hGeom, &pszOGRWkt );
3676
wkt = strdup( pszOGRWkt );
3677
CPLFree( pszOGRWkt );
3680
RELEASE_OLD_OGR_LOCK;
3683
msSetError(MS_OGRERR, "OGR support is not available.", "msOGRShapeToWKT()");