Coverage Report

Created: 2025-06-13 06:18

/src/gdal/ogr/ogrfeaturestyle.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  Feature Representation string API
5
 * Author:   Stephane Villeneuve, stephane.v@videotron.ca
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2000-2001, Stephane Villeneuve
9
 * Copyright (c) 2008-2010, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#include "cpl_port.h"
15
#include "ogr_featurestyle.h"
16
17
#include <cstddef>
18
#include <cstdio>
19
#include <cstdlib>
20
#include <cstring>
21
22
#include <string>
23
24
#include "cpl_conv.h"
25
#include "cpl_error.h"
26
#include "cpl_string.h"
27
#include "cpl_vsi.h"
28
#include "ogr_api.h"
29
#include "ogr_core.h"
30
#include "ogr_feature.h"
31
32
/****************************************************************************/
33
/*                Class Parameter (used in the String)                      */
34
/*                                                                          */
35
/*      The order of all parameter MUST be the same than in the definition. */
36
/****************************************************************************/
37
static const OGRStyleParamId asStylePen[] = {
38
    {OGRSTPenColor, "c", FALSE, OGRSTypeString},
39
    {OGRSTPenWidth, "w", TRUE, OGRSTypeDouble},
40
    // Georefed, but multiple times.
41
    {OGRSTPenPattern, "p", FALSE, OGRSTypeString},
42
    {OGRSTPenId, "id", FALSE, OGRSTypeString},
43
    {OGRSTPenPerOffset, "dp", TRUE, OGRSTypeDouble},
44
    {OGRSTPenCap, "cap", FALSE, OGRSTypeString},
45
    {OGRSTPenJoin, "j", FALSE, OGRSTypeString},
46
    {OGRSTPenPriority, "l", FALSE, OGRSTypeInteger}};
47
48
static const OGRStyleParamId asStyleBrush[] = {
49
    {OGRSTBrushFColor, "fc", FALSE, OGRSTypeString},
50
    {OGRSTBrushBColor, "bc", FALSE, OGRSTypeString},
51
    {OGRSTBrushId, "id", FALSE, OGRSTypeString},
52
    {OGRSTBrushAngle, "a", FALSE, OGRSTypeDouble},
53
    {OGRSTBrushSize, "s", TRUE, OGRSTypeDouble},
54
    {OGRSTBrushDx, "dx", TRUE, OGRSTypeDouble},
55
    {OGRSTBrushDy, "dy", TRUE, OGRSTypeDouble},
56
    {OGRSTBrushPriority, "l", FALSE, OGRSTypeInteger}};
57
58
static const OGRStyleParamId asStyleSymbol[] = {
59
    {OGRSTSymbolId, "id", FALSE, OGRSTypeString},
60
    {OGRSTSymbolAngle, "a", FALSE, OGRSTypeDouble},
61
    {OGRSTSymbolColor, "c", FALSE, OGRSTypeString},
62
    {OGRSTSymbolSize, "s", TRUE, OGRSTypeDouble},
63
    {OGRSTSymbolDx, "dx", TRUE, OGRSTypeDouble},
64
    {OGRSTSymbolDy, "dy", TRUE, OGRSTypeDouble},
65
    {OGRSTSymbolStep, "ds", TRUE, OGRSTypeDouble},
66
    {OGRSTSymbolPerp, "dp", TRUE, OGRSTypeDouble},
67
    {OGRSTSymbolOffset, "di", TRUE, OGRSTypeDouble},
68
    {OGRSTSymbolPriority, "l", FALSE, OGRSTypeInteger},
69
    {OGRSTSymbolFontName, "f", FALSE, OGRSTypeString},
70
    {OGRSTSymbolOColor, "o", FALSE, OGRSTypeString}};
71
72
static const OGRStyleParamId asStyleLabel[] = {
73
    {OGRSTLabelFontName, "f", FALSE, OGRSTypeString},
74
    {OGRSTLabelSize, "s", TRUE, OGRSTypeDouble},
75
    {OGRSTLabelTextString, "t", FALSE, OGRSTypeString},
76
    {OGRSTLabelAngle, "a", FALSE, OGRSTypeDouble},
77
    {OGRSTLabelFColor, "c", FALSE, OGRSTypeString},
78
    {OGRSTLabelBColor, "b", FALSE, OGRSTypeString},
79
    {OGRSTLabelPlacement, "m", FALSE, OGRSTypeString},
80
    {OGRSTLabelAnchor, "p", FALSE, OGRSTypeInteger},
81
    {OGRSTLabelDx, "dx", TRUE, OGRSTypeDouble},
82
    {OGRSTLabelDy, "dy", TRUE, OGRSTypeDouble},
83
    {OGRSTLabelPerp, "dp", TRUE, OGRSTypeDouble},
84
    {OGRSTLabelBold, "bo", FALSE, OGRSTypeBoolean},
85
    {OGRSTLabelItalic, "it", FALSE, OGRSTypeBoolean},
86
    {OGRSTLabelUnderline, "un", FALSE, OGRSTypeBoolean},
87
    {OGRSTLabelPriority, "l", FALSE, OGRSTypeInteger},
88
    {OGRSTLabelStrikeout, "st", FALSE, OGRSTypeBoolean},
89
    {OGRSTLabelStretch, "w", FALSE, OGRSTypeDouble},
90
    {-1, nullptr, FALSE, OGRSTypeUnused},  // was OGRSTLabelAdjHor
91
    {-1, nullptr, FALSE, OGRSTypeUnused},  // was OGRSTLabelAdjVert
92
    {OGRSTLabelHColor, "h", FALSE, OGRSTypeString},
93
    {OGRSTLabelOColor, "o", FALSE, OGRSTypeString}};
94
95
/* ======================================================================== */
96
/* OGRStyleMgr                                                              */
97
/* ======================================================================== */
98
99
/****************************************************************************/
100
/*             OGRStyleMgr::OGRStyleMgr(OGRStyleTable *poDataSetStyleTable) */
101
/*                                                                          */
102
/****************************************************************************/
103
/**
104
 * \brief Constructor.
105
 *
106
 * This method is the same as the C function OGR_SM_Create()
107
 *
108
 * @param poDataSetStyleTable (currently unused, reserved for future use),
109
 * pointer to OGRStyleTable. Pass NULL for now.
110
 */
111
OGRStyleMgr::OGRStyleMgr(OGRStyleTable *poDataSetStyleTable)
112
0
    : m_poDataSetStyleTable(poDataSetStyleTable)
113
0
{
114
0
}
115
116
/************************************************************************/
117
/*                            OGR_SM_Create()                           */
118
/************************************************************************/
119
/**
120
 * \brief OGRStyleMgr factory.
121
 *
122
 * This function is the same as the C++ method OGRStyleMgr::OGRStyleMgr().
123
 *
124
 * @param hStyleTable pointer to OGRStyleTable or NULL if not working with
125
 *  a style table.
126
 *
127
 * @return a handle to the new style manager object.
128
 */
129
130
OGRStyleMgrH OGR_SM_Create(OGRStyleTableH hStyleTable)
131
132
0
{
133
0
    return reinterpret_cast<OGRStyleMgrH>(
134
0
        new OGRStyleMgr(reinterpret_cast<OGRStyleTable *>(hStyleTable)));
135
0
}
136
137
/****************************************************************************/
138
/*             OGRStyleMgr::~OGRStyleMgr()                                  */
139
/*                                                                          */
140
/****************************************************************************/
141
/**
142
 * \brief Destructor.
143
 *
144
 * This method is the same as the C function OGR_SM_Destroy()
145
 */
146
OGRStyleMgr::~OGRStyleMgr()
147
0
{
148
0
    CPLFree(m_pszStyleString);
149
0
}
150
151
/************************************************************************/
152
/*                           OGR_SM_Destroy()                            */
153
/************************************************************************/
154
/**
155
 * \brief Destroy Style Manager
156
 *
157
 * This function is the same as the C++ method OGRStyleMgr::~OGRStyleMgr().
158
 *
159
 * @param hSM handle to the style manager to destroy.
160
 */
161
162
void OGR_SM_Destroy(OGRStyleMgrH hSM)
163
164
0
{
165
0
    delete reinterpret_cast<OGRStyleMgr *>(hSM);
166
0
}
167
168
/****************************************************************************/
169
/*      GBool OGRStyleMgr::SetFeatureStyleString(OGRFeature *poFeature,     */
170
/*                                       char *pszStyleString,              */
171
/*                                       GBool bNoMatching)                 */
172
/*      Set the given representation to the feature,                        */
173
/*      if bNoMatching == TRUE, don't try to find it in the styletable      */
174
/*      otherwise, we will use the name defined in the styletable.          */
175
/****************************************************************************/
176
177
/**
178
 * \brief Set a style in a feature
179
 *
180
 * @param poFeature       the feature object to store the style in
181
 * @param pszStyleString  the style to store
182
 * @param bNoMatching     TRUE to lookup the style in the style table and
183
 *  add the name to the feature
184
 *
185
 * @return TRUE on success, FALSE on error.
186
 */
187
188
GBool OGRStyleMgr::SetFeatureStyleString(OGRFeature *poFeature,
189
                                         const char *pszStyleString,
190
                                         GBool bNoMatching)
191
0
{
192
0
    if (poFeature == nullptr)
193
0
        return FALSE;
194
195
0
    const char *pszName = nullptr;
196
197
0
    if (pszStyleString == nullptr)
198
0
        poFeature->SetStyleString("");
199
0
    else if (bNoMatching == TRUE)
200
0
        poFeature->SetStyleString(pszStyleString);
201
0
    else if ((pszName = GetStyleName(pszStyleString)) != nullptr)
202
0
        poFeature->SetStyleString(pszName);
203
0
    else
204
0
        poFeature->SetStyleString(pszStyleString);
205
206
0
    return TRUE;
207
0
}
208
209
/****************************************************************************/
210
/*            const char *OGRStyleMgr::InitFromFeature(OGRFeature *)        */
211
/*                                                                          */
212
/****************************************************************************/
213
214
/**
215
 * \brief Initialize style manager from the style string of a feature.
216
 *
217
 * This method is the same as the C function OGR_SM_InitFromFeature().
218
 *
219
 * @param poFeature feature object from which to read the style.
220
 *
221
 * @return a reference to the style string read from the feature, or NULL
222
 * in case of error..
223
 */
224
225
const char *OGRStyleMgr::InitFromFeature(OGRFeature *poFeature)
226
0
{
227
0
    CPLFree(m_pszStyleString);
228
0
    m_pszStyleString = nullptr;
229
230
0
    if (poFeature)
231
0
        InitStyleString(poFeature->GetStyleString());
232
0
    else
233
0
        m_pszStyleString = nullptr;
234
235
0
    return m_pszStyleString;
236
0
}
237
238
/************************************************************************/
239
/*                     OGR_SM_InitFromFeature()                         */
240
/************************************************************************/
241
242
/**
243
 * \brief Initialize style manager from the style string of a feature.
244
 *
245
 * This function is the same as the C++ method
246
 * OGRStyleMgr::InitFromFeature().
247
 *
248
 * @param hSM handle to the style manager.
249
 * @param hFeat handle to the new feature from which to read the style.
250
 *
251
 * @return a reference to the style string read from the feature, or NULL
252
 * in case of error.
253
 */
254
255
const char *OGR_SM_InitFromFeature(OGRStyleMgrH hSM, OGRFeatureH hFeat)
256
257
0
{
258
0
    VALIDATE_POINTER1(hSM, "OGR_SM_InitFromFeature", nullptr);
259
0
    VALIDATE_POINTER1(hFeat, "OGR_SM_InitFromFeature", nullptr);
260
261
0
    return reinterpret_cast<OGRStyleMgr *>(hSM)->InitFromFeature(
262
0
        reinterpret_cast<OGRFeature *>(hFeat));
263
0
}
264
265
/****************************************************************************/
266
/*            GBool OGRStyleMgr::InitStyleString(char *pszStyleString)      */
267
/*                                                                          */
268
/****************************************************************************/
269
270
/**
271
 * \brief Initialize style manager from the style string.
272
 *
273
 * Style string can be an expanded style string (e.g. "PEN(c:#FF0000,w:5px)"),
274
 * or (starting with GDAL 3.5.1), a reference to a style name starting with @
275
 * (e.g. "@my_style") registered in the associated style table.
276
 *
277
 * This method is the same as the C function OGR_SM_InitStyleString().
278
 *
279
 * @param pszStyleString the style string to use (can be NULL).
280
 *
281
 * @return TRUE on success, FALSE on errors.
282
 */
283
GBool OGRStyleMgr::InitStyleString(const char *pszStyleString)
284
0
{
285
0
    CPLFree(m_pszStyleString);
286
0
    m_pszStyleString = nullptr;
287
288
0
    if (pszStyleString && pszStyleString[0] == '@')
289
0
    {
290
0
        const char *pszStyleStringFromName = GetStyleByName(pszStyleString + 1);
291
0
        if (pszStyleStringFromName == nullptr)
292
0
            return FALSE;
293
0
        m_pszStyleString = CPLStrdup(pszStyleStringFromName);
294
0
    }
295
0
    else if (pszStyleString)
296
0
        m_pszStyleString = CPLStrdup(pszStyleString);
297
298
0
    return TRUE;
299
0
}
300
301
/************************************************************************/
302
/*                     OGR_SM_InitStyleString()                         */
303
/************************************************************************/
304
305
/**
306
 * \brief Initialize style manager from the style string.
307
 *
308
 * Style string can be an expanded style string (e.g. "PEN(c:#FF0000,w:5px)"),
309
 * or (starting with GDAL 3.5.1), a reference to a style name starting with @
310
 * (e.g. "@my_style") registered in the associated style table.
311
 *
312
 * This function is the same as the C++ method OGRStyleMgr::InitStyleString().
313
 *
314
 * @param hSM handle to the style manager.
315
 * @param pszStyleString the style string to use (can be NULL).
316
 *
317
 * @return TRUE on success, FALSE on errors.
318
 */
319
320
int OGR_SM_InitStyleString(OGRStyleMgrH hSM, const char *pszStyleString)
321
322
0
{
323
0
    VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
324
325
0
    return reinterpret_cast<OGRStyleMgr *>(hSM)->InitStyleString(
326
0
        pszStyleString);
327
0
}
328
329
/****************************************************************************/
330
/*      const char *OGRStyleMgr::GetStyleName(const char *pszStyleString)   */
331
/****************************************************************************/
332
333
/**
334
 * \brief Get the name of a style from the style table.
335
 *
336
 * @param pszStyleString the style to search for, or NULL to use the style
337
 *   currently stored in the manager.
338
 *
339
 * @return The name if found, or NULL on error.
340
 */
341
342
const char *OGRStyleMgr::GetStyleName(const char *pszStyleString)
343
0
{
344
    // SECURITY: The unit and the value for all parameter should be the same,
345
    // a text comparison is executed.
346
347
0
    const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
348
349
0
    if (pszStyle)
350
0
    {
351
0
        if (m_poDataSetStyleTable)
352
0
            return m_poDataSetStyleTable->GetStyleName(pszStyle);
353
0
    }
354
0
    return nullptr;
355
0
}
356
357
/****************************************************************************/
358
/*      const char *OGRStyleMgr::GetStyleByName(const char *pszStyleName)   */
359
/*                                                                          */
360
/****************************************************************************/
361
362
/**
363
 * \brief find a style in the current style table.
364
 *
365
 *
366
 * @param pszStyleName the name of the style to add.
367
 *
368
 * @return the style string matching the name or NULL if not found or error.
369
 */
370
const char *OGRStyleMgr::GetStyleByName(const char *pszStyleName)
371
0
{
372
0
    if (m_poDataSetStyleTable)
373
0
    {
374
0
        return m_poDataSetStyleTable->Find(pszStyleName);
375
0
    }
376
0
    return nullptr;
377
0
}
378
379
/****************************************************************************/
380
/*            GBool OGRStyleMgr::AddStyle(char *pszStyleName,               */
381
/*                                   char *pszStyleString)                  */
382
/*                                                                          */
383
/****************************************************************************/
384
385
/**
386
 * \brief Add a style to the current style table.
387
 *
388
 * This method is the same as the C function OGR_SM_AddStyle().
389
 *
390
 * @param pszStyleName the name of the style to add.
391
 * @param pszStyleString the style string to use, or NULL to use the style
392
 *                       stored in the manager.
393
 *
394
 * @return TRUE on success, FALSE on errors.
395
 */
396
397
GBool OGRStyleMgr::AddStyle(const char *pszStyleName,
398
                            const char *pszStyleString)
399
0
{
400
0
    const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
401
402
0
    if (m_poDataSetStyleTable)
403
0
    {
404
0
        return m_poDataSetStyleTable->AddStyle(pszStyleName, pszStyle);
405
0
    }
406
0
    return FALSE;
407
0
}
408
409
/************************************************************************/
410
/*                     OGR_SM_AddStyle()                         */
411
/************************************************************************/
412
413
/**
414
 * \brief Add a style to the current style table.
415
 *
416
 * This function is the same as the C++ method OGRStyleMgr::AddStyle().
417
 *
418
 * @param hSM handle to the style manager.
419
 * @param pszStyleName the name of the style to add.
420
 * @param pszStyleString the style string to use, or NULL to use the style
421
 *                       stored in the manager.
422
 *
423
 * @return TRUE on success, FALSE on errors.
424
 */
425
426
int OGR_SM_AddStyle(OGRStyleMgrH hSM, const char *pszStyleName,
427
                    const char *pszStyleString)
428
0
{
429
0
    VALIDATE_POINTER1(hSM, "OGR_SM_AddStyle", FALSE);
430
0
    VALIDATE_POINTER1(pszStyleName, "OGR_SM_AddStyle", FALSE);
431
432
0
    return reinterpret_cast<OGRStyleMgr *>(hSM)->AddStyle(pszStyleName,
433
0
                                                          pszStyleString);
434
0
}
435
436
/****************************************************************************/
437
/*            const char *OGRStyleMgr::GetStyleString(OGRFeature *)         */
438
/*                                                                          */
439
/****************************************************************************/
440
441
/**
442
 * \brief Get the style string from the style manager.
443
 *
444
 * @param poFeature feature object from which to read the style or NULL to
445
 *                  get the style string stored in the manager.
446
 *
447
 * @return the style string stored in the feature or the style string stored
448
 *          in the style manager if poFeature is NULL
449
 *
450
 * NOTE: this method will call OGRStyleMgr::InitFromFeature() if poFeature is
451
 *       not NULL and replace the style string stored in the style manager
452
 */
453
454
const char *OGRStyleMgr::GetStyleString(OGRFeature *poFeature)
455
0
{
456
0
    if (poFeature == nullptr)
457
0
        return m_pszStyleString;
458
459
0
    return InitFromFeature(poFeature);
460
0
}
461
462
/****************************************************************************/
463
/*            GBool OGRStyleMgr::AddPart(const char *pszPart)               */
464
/*            Add a new part in the current style                           */
465
/****************************************************************************/
466
467
/**
468
 * \brief Add a part (style string) to the current style.
469
 *
470
 * @param pszPart the style string defining the part to add.
471
 *
472
 * @return TRUE on success, FALSE on errors.
473
 */
474
475
GBool OGRStyleMgr::AddPart(const char *pszPart)
476
0
{
477
0
    if (pszPart == nullptr)
478
0
        return FALSE;
479
480
0
    if (m_pszStyleString)
481
0
    {
482
0
        char *pszTmp =
483
0
            CPLStrdup(CPLString().Printf("%s;%s", m_pszStyleString, pszPart));
484
0
        CPLFree(m_pszStyleString);
485
0
        m_pszStyleString = pszTmp;
486
0
    }
487
0
    else
488
0
    {
489
0
        char *pszTmp = CPLStrdup(CPLString().Printf("%s", pszPart));
490
0
        CPLFree(m_pszStyleString);
491
0
        m_pszStyleString = pszTmp;
492
0
    }
493
0
    return TRUE;
494
0
}
495
496
/****************************************************************************/
497
/*            GBool OGRStyleMgr::AddPart(OGRStyleTool *)                    */
498
/*            Add a new part in the current style                           */
499
/****************************************************************************/
500
501
/**
502
 * \brief Add a part (style tool) to the current style.
503
 *
504
 * This method is the same as the C function OGR_SM_AddPart().
505
 *
506
 * @param poStyleTool the style tool defining the part to add.
507
 *
508
 * @return TRUE on success, FALSE on errors.
509
 */
510
511
GBool OGRStyleMgr::AddPart(OGRStyleTool *poStyleTool)
512
0
{
513
0
    if (poStyleTool == nullptr || !poStyleTool->GetStyleString())
514
0
        return FALSE;
515
516
0
    if (m_pszStyleString)
517
0
    {
518
0
        char *pszTmp = CPLStrdup(CPLString().Printf(
519
0
            "%s;%s", m_pszStyleString, poStyleTool->GetStyleString()));
520
0
        CPLFree(m_pszStyleString);
521
0
        m_pszStyleString = pszTmp;
522
0
    }
523
0
    else
524
0
    {
525
0
        char *pszTmp =
526
0
            CPLStrdup(CPLString().Printf("%s", poStyleTool->GetStyleString()));
527
0
        CPLFree(m_pszStyleString);
528
0
        m_pszStyleString = pszTmp;
529
0
    }
530
0
    return TRUE;
531
0
}
532
533
/************************************************************************/
534
/*                     OGR_SM_AddPart()                                 */
535
/************************************************************************/
536
537
/**
538
 * \brief Add a part (style tool) to the current style.
539
 *
540
 * This function is the same as the C++ method OGRStyleMgr::AddPart().
541
 *
542
 * @param hSM handle to the style manager.
543
 * @param hST the style tool defining the part to add.
544
 *
545
 * @return TRUE on success, FALSE on errors.
546
 */
547
548
int OGR_SM_AddPart(OGRStyleMgrH hSM, OGRStyleToolH hST)
549
550
0
{
551
0
    VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
552
0
    VALIDATE_POINTER1(hST, "OGR_SM_InitStyleString", FALSE);
553
554
0
    return reinterpret_cast<OGRStyleMgr *>(hSM)->AddPart(
555
0
        reinterpret_cast<OGRStyleTool *>(hST));
556
0
}
557
558
/****************************************************************************/
559
/*            int OGRStyleMgr::GetPartCount(const char *pszStyleString)     */
560
/*            return the number of part in the stylestring                  */
561
/* FIXME: this function should actually parse style string instead of simple*/
562
/*        semicolon counting, we should not count broken and empty parts.   */
563
/****************************************************************************/
564
565
/**
566
 * \brief Get the number of parts in a style.
567
 *
568
 * This method is the same as the C function OGR_SM_GetPartCount().
569
 *
570
 * @param pszStyleString (optional) the style string on which to operate.
571
 * If NULL then the current style string stored in the style manager is used.
572
 *
573
 * @return the number of parts (style tools) in the style.
574
 */
575
576
int OGRStyleMgr::GetPartCount(const char *pszStyleString)
577
0
{
578
0
    const char *pszString =
579
0
        pszStyleString != nullptr ? pszStyleString : m_pszStyleString;
580
581
0
    if (pszString == nullptr)
582
0
        return 0;
583
584
0
    int nPartCount = 1;
585
0
    const char *pszStrTmp = pszString;
586
    // Search for parts separated by semicolons not counting the possible
587
    // semicolon at the and of string.
588
0
    const char *pszPart = nullptr;
589
0
    while ((pszPart = strstr(pszStrTmp, ";")) != nullptr && pszPart[1] != '\0')
590
0
    {
591
0
        pszStrTmp = &pszPart[1];
592
0
        nPartCount++;
593
0
    }
594
0
    return nPartCount;
595
0
}
596
597
/************************************************************************/
598
/*                     OGR_SM_GetPartCount()                            */
599
/************************************************************************/
600
601
/**
602
 * \brief Get the number of parts in a style.
603
 *
604
 * This function is the same as the C++ method OGRStyleMgr::GetPartCount().
605
 *
606
 * @param hSM handle to the style manager.
607
 * @param pszStyleString (optional) the style string on which to operate.
608
 * If NULL then the current style string stored in the style manager is used.
609
 *
610
 * @return the number of parts (style tools) in the style.
611
 */
612
613
int OGR_SM_GetPartCount(OGRStyleMgrH hSM, const char *pszStyleString)
614
615
0
{
616
0
    VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
617
618
0
    return reinterpret_cast<OGRStyleMgr *>(hSM)->GetPartCount(pszStyleString);
619
0
}
620
621
/****************************************************************************/
622
/*            OGRStyleTool *OGRStyleMgr::GetPart(int nPartId,               */
623
/*                                 const char *pszStyleString)              */
624
/*                                                                          */
625
/*     Return a StyleTool of the type of the wanted part, could return NULL */
626
/****************************************************************************/
627
628
/**
629
 * \brief Fetch a part (style tool) from the current style.
630
 *
631
 * This method is the same as the C function OGR_SM_GetPart().
632
 *
633
 * This method instantiates a new object that should be freed with
634
 * OGR_ST_Destroy().
635
 *
636
 * @param nPartId the part number (0-based index).
637
 * @param pszStyleString (optional) the style string on which to operate.
638
 * If NULL then the current style string stored in the style manager is used.
639
 *
640
 * @return OGRStyleTool of the requested part (style tools) or NULL on error.
641
 */
642
643
OGRStyleTool *OGRStyleMgr::GetPart(int nPartId, const char *pszStyleString)
644
0
{
645
0
    const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
646
647
0
    if (pszStyle == nullptr)
648
0
        return nullptr;
649
650
0
    char **papszStyleString = CSLTokenizeString2(
651
0
        pszStyle, ";",
652
0
        CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
653
654
0
    const char *pszString = CSLGetField(papszStyleString, nPartId);
655
656
0
    OGRStyleTool *poStyleTool = nullptr;
657
0
    if (strlen(pszString) > 0)
658
0
    {
659
0
        poStyleTool = CreateStyleToolFromStyleString(pszString);
660
0
        if (poStyleTool)
661
0
            poStyleTool->SetStyleString(pszString);
662
0
    }
663
664
0
    CSLDestroy(papszStyleString);
665
666
0
    return poStyleTool;
667
0
}
668
669
/************************************************************************/
670
/*                     OGR_SM_GetPart()                                 */
671
/************************************************************************/
672
673
/**
674
 * \brief Fetch a part (style tool) from the current style.
675
 *
676
 * This function is the same as the C++ method OGRStyleMgr::GetPart().
677
 *
678
 * This function instantiates a new object that should be freed with
679
 * OGR_ST_Destroy().
680
 *
681
 * @param hSM handle to the style manager.
682
 * @param nPartId the part number (0-based index).
683
 * @param pszStyleString (optional) the style string on which to operate.
684
 * If NULL then the current style string stored in the style manager is used.
685
 *
686
 * @return OGRStyleToolH of the requested part (style tools) or NULL on error.
687
 */
688
689
OGRStyleToolH OGR_SM_GetPart(OGRStyleMgrH hSM, int nPartId,
690
                             const char *pszStyleString)
691
692
0
{
693
0
    VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", nullptr);
694
695
0
    return reinterpret_cast<OGRStyleToolH>(
696
0
        reinterpret_cast<OGRStyleMgr *>(hSM)->GetPart(nPartId, pszStyleString));
697
0
}
698
699
/****************************************************************************/
700
/* OGRStyleTool *CreateStyleToolFromStyleString(const char *pszStyleString) */
701
/*                                                                          */
702
/* create a Style tool from the given StyleString, it should contain only a */
703
/* part of a StyleString.                                                    */
704
/****************************************************************************/
705
706
//! @cond Doxygen_Suppress
707
OGRStyleTool *
708
OGRStyleMgr::CreateStyleToolFromStyleString(const char *pszStyleString)
709
0
{
710
0
    char **papszToken = CSLTokenizeString2(
711
0
        pszStyleString, "();",
712
0
        CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
713
0
    OGRStyleTool *poStyleTool = nullptr;
714
715
0
    if (CSLCount(papszToken) < 2)
716
0
        poStyleTool = nullptr;
717
0
    else if (EQUAL(papszToken[0], "PEN"))
718
0
        poStyleTool = new OGRStylePen();
719
0
    else if (EQUAL(papszToken[0], "BRUSH"))
720
0
        poStyleTool = new OGRStyleBrush();
721
0
    else if (EQUAL(papszToken[0], "SYMBOL"))
722
0
        poStyleTool = new OGRStyleSymbol();
723
0
    else if (EQUAL(papszToken[0], "LABEL"))
724
0
        poStyleTool = new OGRStyleLabel();
725
0
    else
726
0
        poStyleTool = nullptr;
727
728
0
    CSLDestroy(papszToken);
729
730
0
    return poStyleTool;
731
0
}
732
733
//! @endcond
734
735
/* ======================================================================== */
736
/*                OGRStyleTable                                             */
737
/*     Object Used to manage and store a styletable                         */
738
/* ======================================================================== */
739
740
/****************************************************************************/
741
/*              OGRStyleTable::OGRStyleTable()                              */
742
/*                                                                          */
743
/****************************************************************************/
744
OGRStyleTable::OGRStyleTable()
745
0
{
746
0
    m_papszStyleTable = nullptr;
747
0
    iNextStyle = 0;
748
0
}
749
750
/************************************************************************/
751
/*                            OGR_STBL_Create()                           */
752
/************************************************************************/
753
/**
754
 * \brief OGRStyleTable factory.
755
 *
756
 * This function is the same as the C++ method OGRStyleTable::OGRStyleTable().
757
 *
758
 *
759
 * @return a handle to the new style table object.
760
 */
761
762
OGRStyleTableH OGR_STBL_Create(void)
763
764
0
{
765
0
    return reinterpret_cast<OGRStyleTableH>(new OGRStyleTable());
766
0
}
767
768
/****************************************************************************/
769
/*                void OGRStyleTable::Clear()                               */
770
/*                                                                          */
771
/****************************************************************************/
772
773
/**
774
 * \brief Clear a style table.
775
 *
776
 */
777
778
void OGRStyleTable::Clear()
779
0
{
780
0
    if (m_papszStyleTable)
781
0
        CSLDestroy(m_papszStyleTable);
782
0
    m_papszStyleTable = nullptr;
783
0
}
784
785
/****************************************************************************/
786
/*          OGRStyleTable::~OGRStyleTable()                                 */
787
/*                                                                          */
788
/****************************************************************************/
789
OGRStyleTable::~OGRStyleTable()
790
0
{
791
0
    Clear();
792
0
}
793
794
/************************************************************************/
795
/*                           OGR_STBL_Destroy()                            */
796
/************************************************************************/
797
/**
798
 * \brief Destroy Style Table
799
 *
800
 * @param hSTBL handle to the style table to destroy.
801
 */
802
803
void OGR_STBL_Destroy(OGRStyleTableH hSTBL)
804
805
0
{
806
0
    delete reinterpret_cast<OGRStyleTable *>(hSTBL);
807
0
}
808
809
/****************************************************************************/
810
/*    const char *OGRStyleTable::GetStyleName(const char *pszStyleString)   */
811
/*                                                                          */
812
/*    return the Name of a given stylestring otherwise NULL.                */
813
/****************************************************************************/
814
815
/**
816
 * \brief Get style name by style string.
817
 *
818
 * @param pszStyleString the style string to look up.
819
 *
820
 * @return the Name of the matching style string or NULL on error.
821
 */
822
823
const char *OGRStyleTable::GetStyleName(const char *pszStyleString)
824
0
{
825
0
    for (int i = 0; i < CSLCount(m_papszStyleTable); i++)
826
0
    {
827
0
        const char *pszStyleStringBegin = strstr(m_papszStyleTable[i], ":");
828
829
0
        if (pszStyleStringBegin &&
830
0
            EQUAL(&pszStyleStringBegin[1], pszStyleString))
831
0
        {
832
0
            osLastRequestedStyleName = m_papszStyleTable[i];
833
0
            const size_t nColon = osLastRequestedStyleName.find(':');
834
0
            if (nColon != std::string::npos)
835
0
                osLastRequestedStyleName =
836
0
                    osLastRequestedStyleName.substr(0, nColon);
837
838
0
            return osLastRequestedStyleName;
839
0
        }
840
0
    }
841
842
0
    return nullptr;
843
0
}
844
845
/****************************************************************************/
846
/*            GBool OGRStyleTable::AddStyle(char *pszName,                  */
847
/*                                          char *pszStyleString)           */
848
/*                                                                          */
849
/*   Add a new style in the table, no comparison will be done on the        */
850
/*   Style string, only on the name, TRUE success, FALSE error              */
851
/****************************************************************************/
852
853
/**
854
 * \brief Add a new style in the table.
855
 * No comparison will be done on the
856
 * Style string, only on the name.
857
 *
858
 * @param pszName the name the style to add.
859
 * @param pszStyleString the style string to add.
860
 *
861
 * @return TRUE on success, FALSE on error
862
 */
863
864
GBool OGRStyleTable::AddStyle(const char *pszName, const char *pszStyleString)
865
0
{
866
0
    if (pszName == nullptr || pszStyleString == nullptr)
867
0
        return FALSE;
868
869
0
    const int nPos = IsExist(pszName);
870
0
    if (nPos != -1)
871
0
        return FALSE;
872
873
0
    m_papszStyleTable =
874
0
        CSLAddString(m_papszStyleTable,
875
0
                     CPLString().Printf("%s:%s", pszName, pszStyleString));
876
0
    return TRUE;
877
0
}
878
879
/************************************************************************/
880
/*                       OGR_STBL_AddStyle()                            */
881
/************************************************************************/
882
883
/**
884
 * \brief Add a new style in the table.
885
 * No comparison will be done on the
886
 * Style string, only on the name.
887
 * This function is the same as the C++ method OGRStyleTable::AddStyle().
888
 *
889
 * @param hStyleTable handle to the style table.
890
 * @param pszName the name the style to add.
891
 * @param pszStyleString the style string to add.
892
 *
893
 * @return TRUE on success, FALSE on error
894
 */
895
896
int OGR_STBL_AddStyle(OGRStyleTableH hStyleTable, const char *pszName,
897
                      const char *pszStyleString)
898
0
{
899
0
    VALIDATE_POINTER1(hStyleTable, "OGR_STBL_AddStyle", FALSE);
900
901
0
    return reinterpret_cast<OGRStyleTable *>(hStyleTable)
902
0
        ->AddStyle(pszName, pszStyleString);
903
0
}
904
905
/****************************************************************************/
906
/*            GBool OGRStyleTable::RemoveStyle(char *pszName)               */
907
/*                                                                          */
908
/*    Remove the given style in the table based on the name, return TRUE    */
909
/*    on success otherwise FALSE.                                           */
910
/****************************************************************************/
911
912
/**
913
 * \brief Remove a style in the table by its name.
914
 *
915
 * @param pszName the name of the style to remove.
916
 *
917
 * @return TRUE on success, FALSE on error
918
 */
919
920
GBool OGRStyleTable::RemoveStyle(const char *pszName)
921
0
{
922
0
    const int nPos = IsExist(pszName);
923
0
    if (nPos == -1)
924
0
        return FALSE;
925
926
0
    m_papszStyleTable = CSLRemoveStrings(m_papszStyleTable, nPos, 1, nullptr);
927
0
    return TRUE;
928
0
}
929
930
/****************************************************************************/
931
/*            GBool OGRStyleTable::ModifyStyle(char *pszName,               */
932
/*                                             char *pszStyleString)        */
933
/*                                                                          */
934
/*    Modify the given style, if the style doesn't exist, it will be added  */
935
/*    return TRUE on success otherwise return FALSE.                        */
936
/****************************************************************************/
937
938
/**
939
 * \brief Modify a style in the table by its name
940
 * If the style does not exist, it will be added.
941
 *
942
 * @param pszName the name of the style to modify.
943
 * @param pszStyleString the style string.
944
 *
945
 * @return TRUE on success, FALSE on error
946
 */
947
948
GBool OGRStyleTable::ModifyStyle(const char *pszName,
949
                                 const char *pszStyleString)
950
0
{
951
0
    if (pszName == nullptr || pszStyleString == nullptr)
952
0
        return FALSE;
953
954
0
    RemoveStyle(pszName);
955
0
    return AddStyle(pszName, pszStyleString);
956
0
}
957
958
/****************************************************************************/
959
/*            GBool OGRStyleTable::SaveStyleTable(char *)                   */
960
/*                                                                          */
961
/*    Save the StyleTable in the given file, return TRUE on success         */
962
/*    otherwise return FALSE.                                               */
963
/****************************************************************************/
964
965
/**
966
 * \brief Save a style table to a file.
967
 *
968
 * @param pszFilename the name of the file to save to.
969
 *
970
 * @return TRUE on success, FALSE on error
971
 */
972
973
GBool OGRStyleTable::SaveStyleTable(const char *pszFilename)
974
0
{
975
0
    if (pszFilename == nullptr)
976
0
        return FALSE;
977
978
0
    if (CSLSave(m_papszStyleTable, pszFilename) == 0)
979
0
        return FALSE;
980
981
0
    return TRUE;
982
0
}
983
984
/************************************************************************/
985
/*                     OGR_STBL_SaveStyleTable()                        */
986
/************************************************************************/
987
988
/**
989
 * \brief Save a style table to a file.
990
 *
991
 * This function is the same as the C++ method OGRStyleTable::SaveStyleTable().
992
 *
993
 * @param hStyleTable handle to the style table.
994
 * @param pszFilename the name of the file to save to.
995
 *
996
 * @return TRUE on success, FALSE on error
997
 */
998
999
int OGR_STBL_SaveStyleTable(OGRStyleTableH hStyleTable, const char *pszFilename)
1000
0
{
1001
0
    VALIDATE_POINTER1(hStyleTable, "OGR_STBL_SaveStyleTable", FALSE);
1002
0
    VALIDATE_POINTER1(pszFilename, "OGR_STBL_SaveStyleTable", FALSE);
1003
1004
0
    return reinterpret_cast<OGRStyleTable *>(hStyleTable)
1005
0
        ->SaveStyleTable(pszFilename);
1006
0
}
1007
1008
/****************************************************************************/
1009
/*            GBool OGRStyleTable::LoadStyleTable(char *)                   */
1010
/*                                                                          */
1011
/*            Read the Style table from a file, return TRUE on success      */
1012
/*            otherwise return FALSE                                        */
1013
/****************************************************************************/
1014
1015
/**
1016
 * \brief Load a style table from a file.
1017
 *
1018
 * @param pszFilename the name of the file to load from.
1019
 *
1020
 * @return TRUE on success, FALSE on error
1021
 */
1022
1023
GBool OGRStyleTable::LoadStyleTable(const char *pszFilename)
1024
0
{
1025
0
    if (pszFilename == nullptr)
1026
0
        return FALSE;
1027
1028
0
    CSLDestroy(m_papszStyleTable);
1029
1030
0
    m_papszStyleTable = CSLLoad(pszFilename);
1031
1032
0
    return m_papszStyleTable != nullptr;
1033
0
}
1034
1035
/************************************************************************/
1036
/*                     OGR_STBL_LoadStyleTable()                        */
1037
/************************************************************************/
1038
1039
/**
1040
 * \brief Load a style table from a file.
1041
 *
1042
 * This function is the same as the C++ method OGRStyleTable::LoadStyleTable().
1043
 *
1044
 * @param hStyleTable handle to the style table.
1045
 * @param pszFilename the name of the file to load from.
1046
 *
1047
 * @return TRUE on success, FALSE on error
1048
 */
1049
1050
int OGR_STBL_LoadStyleTable(OGRStyleTableH hStyleTable, const char *pszFilename)
1051
0
{
1052
0
    VALIDATE_POINTER1(hStyleTable, "OGR_STBL_LoadStyleTable", FALSE);
1053
0
    VALIDATE_POINTER1(pszFilename, "OGR_STBL_LoadStyleTable", FALSE);
1054
1055
0
    return reinterpret_cast<OGRStyleTable *>(hStyleTable)
1056
0
        ->LoadStyleTable(pszFilename);
1057
0
}
1058
1059
/****************************************************************************/
1060
/*             const char *OGRStyleTable::Find(const char *pszName)         */
1061
/*                                                                          */
1062
/*             return the StyleString based on the given name,              */
1063
/*             otherwise return NULL.                                       */
1064
/****************************************************************************/
1065
1066
/**
1067
 * \brief Get a style string by name.
1068
 *
1069
 * @param pszName the name of the style string to find.
1070
 *
1071
 * @return the style string matching the name, NULL if not found or error.
1072
 */
1073
1074
const char *OGRStyleTable::Find(const char *pszName)
1075
0
{
1076
0
    const int nPos = IsExist(pszName);
1077
0
    if (nPos == -1)
1078
0
        return nullptr;
1079
1080
0
    const char *pszOutput = CSLGetField(m_papszStyleTable, nPos);
1081
1082
0
    const char *pszDash = strstr(pszOutput, ":");
1083
1084
0
    if (pszDash == nullptr)
1085
0
        return nullptr;
1086
1087
0
    return &pszDash[1];
1088
0
}
1089
1090
/************************************************************************/
1091
/*                     OGR_STBL_Find()                                  */
1092
/************************************************************************/
1093
1094
/**
1095
 * \brief Get a style string by name.
1096
 *
1097
 * This function is the same as the C++ method OGRStyleTable::Find().
1098
 *
1099
 * @param hStyleTable handle to the style table.
1100
 * @param pszName the name of the style string to find.
1101
 *
1102
 * @return the style string matching the name or NULL if not found or error.
1103
 */
1104
1105
const char *OGR_STBL_Find(OGRStyleTableH hStyleTable, const char *pszName)
1106
0
{
1107
0
    VALIDATE_POINTER1(hStyleTable, "OGR_STBL_Find", nullptr);
1108
0
    VALIDATE_POINTER1(pszName, "OGR_STBL_Find", nullptr);
1109
1110
0
    return reinterpret_cast<OGRStyleTable *>(hStyleTable)->Find(pszName);
1111
0
}
1112
1113
/****************************************************************************/
1114
/*              OGRStyleTable::Print(FILE *fpOut)                           */
1115
/*                                                                          */
1116
/****************************************************************************/
1117
1118
/**
1119
 * \brief Print a style table to a FILE pointer.
1120
 *
1121
 * @param fpOut the FILE pointer to print to.
1122
 *
1123
 */
1124
1125
void OGRStyleTable::Print(FILE *fpOut)
1126
0
{
1127
1128
0
    CPL_IGNORE_RET_VAL(VSIFPrintf(fpOut, "#OFS-Version: 1.0\n"));
1129
0
    CPL_IGNORE_RET_VAL(VSIFPrintf(fpOut, "#StyleField: style\n"));
1130
0
    if (m_papszStyleTable)
1131
0
    {
1132
0
        CSLPrint(m_papszStyleTable, fpOut);
1133
0
    }
1134
0
}
1135
1136
/****************************************************************************/
1137
/*             int OGRStyleTable::IsExist(const char *pszName)              */
1138
/*                                                                          */
1139
/*   return a index of the style in the table otherwise return -1           */
1140
/****************************************************************************/
1141
1142
/**
1143
 * \brief Get the index of a style in the table by its name.
1144
 *
1145
 * @param pszName the name to look for.
1146
 *
1147
 * @return The index of the style if found, -1 if not found or error.
1148
 */
1149
1150
int OGRStyleTable::IsExist(const char *pszName)
1151
0
{
1152
0
    if (pszName == nullptr)
1153
0
        return -1;
1154
1155
0
    const int nCount = CSLCount(m_papszStyleTable);
1156
0
    const char *pszNewString = CPLSPrintf("%s:", pszName);
1157
1158
0
    for (int i = 0; i < nCount; i++)
1159
0
    {
1160
0
        if (strstr(m_papszStyleTable[i], pszNewString) != nullptr)
1161
0
        {
1162
0
            return i;
1163
0
        }
1164
0
    }
1165
1166
0
    return -1;
1167
0
}
1168
1169
/************************************************************************/
1170
/*                               Clone()                                */
1171
/************************************************************************/
1172
1173
/**
1174
 * \brief Duplicate style table.
1175
 *
1176
 * The newly created style table is owned by the caller, and will have its
1177
 * own reference to the OGRStyleTable.
1178
 *
1179
 * @return new style table, exactly matching this style table.
1180
 */
1181
1182
OGRStyleTable *OGRStyleTable::Clone()
1183
1184
0
{
1185
0
    OGRStyleTable *poNew = new OGRStyleTable();
1186
1187
0
    poNew->m_papszStyleTable = CSLDuplicate(m_papszStyleTable);
1188
1189
0
    return poNew;
1190
0
}
1191
1192
/************************************************************************/
1193
/*                            ResetStyleStringReading()                 */
1194
/************************************************************************/
1195
1196
/** Reset the next style pointer to 0 */
1197
void OGRStyleTable::ResetStyleStringReading()
1198
1199
0
{
1200
0
    iNextStyle = 0;
1201
0
}
1202
1203
/************************************************************************/
1204
/*                     OGR_STBL_ResetStyleStringReading()               */
1205
/************************************************************************/
1206
1207
/**
1208
 * \brief Reset the next style pointer to 0
1209
 *
1210
 * This function is the same as the C++ method
1211
 * OGRStyleTable::ResetStyleStringReading().
1212
 *
1213
 * @param hStyleTable handle to the style table.
1214
 *
1215
 */
1216
1217
void OGR_STBL_ResetStyleStringReading(OGRStyleTableH hStyleTable)
1218
0
{
1219
0
    VALIDATE_POINTER0(hStyleTable, "OGR_STBL_ResetStyleStringReading");
1220
1221
0
    reinterpret_cast<OGRStyleTable *>(hStyleTable)->ResetStyleStringReading();
1222
0
}
1223
1224
/************************************************************************/
1225
/*                           GetNextStyle()                             */
1226
/************************************************************************/
1227
1228
/**
1229
 * \brief Get the next style string from the table.
1230
 *
1231
 * @return the next style string or NULL on error.
1232
 */
1233
1234
const char *OGRStyleTable::GetNextStyle()
1235
0
{
1236
0
    while (iNextStyle < CSLCount(m_papszStyleTable))
1237
0
    {
1238
0
        const char *pszOutput = CSLGetField(m_papszStyleTable, iNextStyle++);
1239
0
        if (pszOutput == nullptr)
1240
0
            continue;
1241
1242
0
        const char *pszDash = strstr(pszOutput, ":");
1243
1244
0
        osLastRequestedStyleName = pszOutput;
1245
0
        const size_t nColon = osLastRequestedStyleName.find(':');
1246
0
        if (nColon != std::string::npos)
1247
0
            osLastRequestedStyleName =
1248
0
                osLastRequestedStyleName.substr(0, nColon);
1249
1250
0
        if (pszDash)
1251
0
            return pszDash + 1;
1252
0
    }
1253
0
    return nullptr;
1254
0
}
1255
1256
/************************************************************************/
1257
/*                     OGR_STBL_GetNextStyle()                          */
1258
/************************************************************************/
1259
1260
/**
1261
 * \brief Get the next style string from the table.
1262
 *
1263
 * This function is the same as the C++ method OGRStyleTable::GetNextStyle().
1264
 *
1265
 * @param hStyleTable handle to the style table.
1266
 *
1267
 * @return the next style string or NULL on error.
1268
 */
1269
1270
const char *OGR_STBL_GetNextStyle(OGRStyleTableH hStyleTable)
1271
0
{
1272
0
    VALIDATE_POINTER1(hStyleTable, "OGR_STBL_GetNextStyle", nullptr);
1273
1274
0
    return reinterpret_cast<OGRStyleTable *>(hStyleTable)->GetNextStyle();
1275
0
}
1276
1277
/************************************************************************/
1278
/*                           GetLastStyleName()                         */
1279
/************************************************************************/
1280
1281
/**
1282
 * Get the style name of the last style string fetched with
1283
 * OGR_STBL_GetNextStyle.
1284
 *
1285
 * @return the Name of the last style string or NULL on error.
1286
 */
1287
1288
const char *OGRStyleTable::GetLastStyleName()
1289
0
{
1290
0
    return osLastRequestedStyleName;
1291
0
}
1292
1293
/************************************************************************/
1294
/*                     OGR_STBL_GetLastStyleName()                      */
1295
/************************************************************************/
1296
1297
/**
1298
 * Get the style name of the last style string fetched with
1299
 * OGR_STBL_GetNextStyle.
1300
 *
1301
 * This function is the same as the C++ method OGRStyleTable::GetStyleName().
1302
 *
1303
 * @param hStyleTable handle to the style table.
1304
 *
1305
 * @return the Name of the last style string or NULL on error.
1306
 */
1307
1308
const char *OGR_STBL_GetLastStyleName(OGRStyleTableH hStyleTable)
1309
0
{
1310
0
    VALIDATE_POINTER1(hStyleTable, "OGR_STBL_GetLastStyleName", nullptr);
1311
1312
0
    return reinterpret_cast<OGRStyleTable *>(hStyleTable)->GetLastStyleName();
1313
0
}
1314
1315
/****************************************************************************/
1316
/*                          OGRStyleTool::OGRStyleTool()                    */
1317
/*                                                                          */
1318
/****************************************************************************/
1319
1320
/** Constructor */
1321
0
OGRStyleTool::OGRStyleTool(OGRSTClassId eClassId) : m_eClassId(eClassId)
1322
0
{
1323
0
}
1324
1325
/************************************************************************/
1326
/*                            OGR_ST_Create()                           */
1327
/************************************************************************/
1328
/**
1329
 * \brief OGRStyleTool factory.
1330
 *
1331
 * This function is a constructor for OGRStyleTool derived classes.
1332
 *
1333
 * @param eClassId subclass of style tool to create. One of OGRSTCPen (1),
1334
 * OGRSTCBrush (2), OGRSTCSymbol (3) or OGRSTCLabel (4).
1335
 *
1336
 * @return a handle to the new style tool object or NULL if the creation
1337
 * failed.
1338
 */
1339
1340
OGRStyleToolH OGR_ST_Create(OGRSTClassId eClassId)
1341
1342
0
{
1343
0
    switch (eClassId)
1344
0
    {
1345
0
        case OGRSTCPen:
1346
0
            return reinterpret_cast<OGRStyleToolH>(new OGRStylePen());
1347
0
        case OGRSTCBrush:
1348
0
            return reinterpret_cast<OGRStyleToolH>(new OGRStyleBrush());
1349
0
        case OGRSTCSymbol:
1350
0
            return reinterpret_cast<OGRStyleToolH>(new OGRStyleSymbol());
1351
0
        case OGRSTCLabel:
1352
0
            return reinterpret_cast<OGRStyleToolH>(new OGRStyleLabel());
1353
0
        default:
1354
0
            return nullptr;
1355
0
    }
1356
0
}
1357
1358
/****************************************************************************/
1359
/*                       OGRStyleTool::~OGRStyleTool()                      */
1360
/*                                                                          */
1361
/****************************************************************************/
1362
OGRStyleTool::~OGRStyleTool()
1363
0
{
1364
0
    CPLFree(m_pszStyleString);
1365
0
}
1366
1367
/************************************************************************/
1368
/*                           OGR_ST_Destroy()                            */
1369
/************************************************************************/
1370
/**
1371
 * \brief Destroy Style Tool
1372
 *
1373
 * @param hST handle to the style tool to destroy.
1374
 */
1375
1376
void OGR_ST_Destroy(OGRStyleToolH hST)
1377
1378
0
{
1379
0
    delete reinterpret_cast<OGRStyleTool *>(hST);
1380
0
}
1381
1382
/****************************************************************************/
1383
/*      void OGRStyleTool::SetStyleString(const char *pszStyleString)       */
1384
/*                                                                          */
1385
/****************************************************************************/
1386
1387
/** Undocumented
1388
 * @param pszStyleString undocumented.
1389
 */
1390
void OGRStyleTool::SetStyleString(const char *pszStyleString)
1391
0
{
1392
0
    m_pszStyleString = CPLStrdup(pszStyleString);
1393
0
}
1394
1395
/****************************************************************************/
1396
/*const char *OGRStyleTool::GetStyleString( OGRStyleParamId *pasStyleParam, */
1397
/*                          OGRStyleValue *pasStyleValue, int nSize)        */
1398
/*                                                                          */
1399
/****************************************************************************/
1400
1401
/** Undocumented
1402
 * @param pasStyleParam undocumented.
1403
 * @param pasStyleValue undocumented.
1404
 * @param nSize undocumented.
1405
 * @return undocumented.
1406
 */
1407
const char *OGRStyleTool::GetStyleString(const OGRStyleParamId *pasStyleParam,
1408
                                         OGRStyleValue *pasStyleValue,
1409
                                         int nSize)
1410
0
{
1411
0
    if (IsStyleModified())
1412
0
    {
1413
0
        CPLFree(m_pszStyleString);
1414
1415
0
        const char *pszClass = nullptr;
1416
0
        switch (GetType())
1417
0
        {
1418
0
            case OGRSTCPen:
1419
0
                pszClass = "PEN(";
1420
0
                break;
1421
0
            case OGRSTCBrush:
1422
0
                pszClass = "BRUSH(";
1423
0
                break;
1424
0
            case OGRSTCSymbol:
1425
0
                pszClass = "SYMBOL(";
1426
0
                break;
1427
0
            case OGRSTCLabel:
1428
0
                pszClass = "LABEL(";
1429
0
                break;
1430
0
            default:
1431
0
                pszClass = "UNKNOWN(";
1432
0
        }
1433
1434
0
        CPLString osCurrent = pszClass;
1435
1436
0
        bool bFound = false;
1437
0
        for (int i = 0; i < nSize; i++)
1438
0
        {
1439
0
            if (!pasStyleValue[i].bValid ||
1440
0
                pasStyleParam[i].eType == OGRSTypeUnused)
1441
0
            {
1442
0
                continue;
1443
0
            }
1444
1445
0
            if (bFound)
1446
0
                osCurrent += ",";
1447
0
            bFound = true;
1448
1449
0
            osCurrent += pasStyleParam[i].pszToken;
1450
0
            switch (pasStyleParam[i].eType)
1451
0
            {
1452
0
                case OGRSTypeString:
1453
0
                    osCurrent += ":";
1454
0
                    osCurrent += pasStyleValue[i].pszValue;
1455
0
                    break;
1456
0
                case OGRSTypeDouble:
1457
0
                    osCurrent +=
1458
0
                        CPLString().Printf(":%f", pasStyleValue[i].dfValue);
1459
0
                    break;
1460
0
                case OGRSTypeInteger:
1461
0
                    osCurrent +=
1462
0
                        CPLString().Printf(":%d", pasStyleValue[i].nValue);
1463
0
                    break;
1464
0
                case OGRSTypeBoolean:
1465
0
                    osCurrent +=
1466
0
                        CPLString().Printf(":%d", pasStyleValue[i].nValue != 0);
1467
0
                    break;
1468
0
                default:
1469
0
                    break;
1470
0
            }
1471
0
            if (pasStyleParam[i].bGeoref)
1472
0
                switch (pasStyleValue[i].eUnit)
1473
0
                {
1474
0
                    case OGRSTUGround:
1475
0
                        osCurrent += "g";
1476
0
                        break;
1477
0
                    case OGRSTUPixel:
1478
0
                        osCurrent += "px";
1479
0
                        break;
1480
0
                    case OGRSTUPoints:
1481
0
                        osCurrent += "pt";
1482
0
                        break;
1483
0
                    case OGRSTUCM:
1484
0
                        osCurrent += "cm";
1485
0
                        break;
1486
0
                    case OGRSTUInches:
1487
0
                        osCurrent += "in";
1488
0
                        break;
1489
0
                    case OGRSTUMM:
1490
                        // osCurrent += "mm";
1491
0
                    default:
1492
0
                        break;  // imp
1493
0
                }
1494
0
        }
1495
0
        osCurrent += ")";
1496
1497
0
        m_pszStyleString = CPLStrdup(osCurrent);
1498
1499
0
        m_bModified = FALSE;
1500
0
    }
1501
1502
0
    return m_pszStyleString;
1503
0
}
1504
1505
/************************************************************************/
1506
/*                          GetRGBFromString()                          */
1507
/************************************************************************/
1508
/**
1509
 * \brief Return the r,g,b,a components of a color encoded in \#RRGGBB[AA]
1510
 * format.
1511
 *
1512
 * Maps to OGRStyleTool::GetRGBFromString().
1513
 *
1514
 * @param pszColor the color to parse
1515
 * @param nRed reference to an int in which the red value will be returned.
1516
 * @param nGreen reference to an int in which the green value will be returned.
1517
 * @param nBlue reference to an int in which the blue value will be returned.
1518
 * @param nTransparance reference to an int in which the (optional) alpha value
1519
 * will be returned.
1520
 *
1521
 * @return TRUE if the color could be successfully parsed, or FALSE in case of
1522
 * errors.
1523
 */
1524
GBool OGRStyleTool::GetRGBFromString(const char *pszColor, int &nRed,
1525
                                     int &nGreen, int &nBlue,
1526
                                     int &nTransparance)
1527
0
{
1528
0
    int nCount = 0;
1529
1530
0
    nTransparance = 255;
1531
1532
    // FIXME: should we really use sscanf here?
1533
0
    unsigned int unRed = 0;
1534
0
    unsigned int unGreen = 0;
1535
0
    unsigned int unBlue = 0;
1536
0
    unsigned int unTransparance = 0;
1537
0
    if (pszColor)
1538
0
        nCount = sscanf(pszColor, "#%2x%2x%2x%2x", &unRed, &unGreen, &unBlue,
1539
0
                        &unTransparance);
1540
0
    nRed = static_cast<int>(unRed);
1541
0
    nGreen = static_cast<int>(unGreen);
1542
0
    nBlue = static_cast<int>(unBlue);
1543
0
    if (nCount == 4)
1544
0
        nTransparance = static_cast<int>(unTransparance);
1545
0
    return nCount >= 3;
1546
0
}
1547
1548
/************************************************************************/
1549
/*                           GetSpecificId()                            */
1550
/*                                                                      */
1551
/*      return -1, if the wanted type is not found, ex:                 */
1552
/*      if you want ogr-pen value, pszWanted should be ogr-pen(case     */
1553
/*      sensitive)                                                      */
1554
/************************************************************************/
1555
1556
/** Undocumented
1557
 * @param pszId Undocumented
1558
 * @param pszWanted Undocumented
1559
 * @return Undocumented
1560
 */
1561
int OGRStyleTool::GetSpecificId(const char *pszId, const char *pszWanted)
1562
0
{
1563
0
    const char *pszRealWanted = pszWanted;
1564
1565
0
    if (pszWanted == nullptr || strlen(pszWanted) == 0)
1566
0
        pszRealWanted = "ogr-pen";
1567
1568
0
    if (pszId == nullptr)
1569
0
        return -1;
1570
1571
0
    int nValue = -1;
1572
0
    const char *pszFound = strstr(pszId, pszRealWanted);
1573
0
    if (pszFound != nullptr)
1574
0
    {
1575
        // We found the string, it could be no value after it, use default one.
1576
0
        nValue = 0;
1577
1578
0
        if (pszFound[strlen(pszRealWanted)] == '-')
1579
0
            nValue = atoi(&pszFound[strlen(pszRealWanted) + 1]);
1580
0
    }
1581
1582
0
    return nValue;
1583
0
}
1584
1585
/************************************************************************/
1586
/*                              GetType()                               */
1587
/************************************************************************/
1588
1589
/**
1590
 * \brief Determine type of Style Tool
1591
 *
1592
 * @return the style tool type, one of OGRSTCPen (1), OGRSTCBrush (2),
1593
 * OGRSTCSymbol (3) or OGRSTCLabel (4). Returns OGRSTCNone (0) if the
1594
 * OGRStyleToolH is invalid.
1595
 */
1596
OGRSTClassId OGRStyleTool::GetType()
1597
0
{
1598
0
    return m_eClassId;
1599
0
}
1600
1601
/************************************************************************/
1602
/*                           OGR_ST_GetType()                           */
1603
/************************************************************************/
1604
/**
1605
 * \brief Determine type of Style Tool
1606
 *
1607
 * @param hST handle to the style tool.
1608
 *
1609
 * @return the style tool type, one of OGRSTCPen (1), OGRSTCBrush (2),
1610
 * OGRSTCSymbol (3) or OGRSTCLabel (4). Returns OGRSTCNone (0) if the
1611
 * OGRStyleToolH is invalid.
1612
 */
1613
1614
OGRSTClassId OGR_ST_GetType(OGRStyleToolH hST)
1615
1616
0
{
1617
0
    VALIDATE_POINTER1(hST, "OGR_ST_GetType", OGRSTCNone);
1618
0
    return reinterpret_cast<OGRStyleTool *>(hST)->GetType();
1619
0
}
1620
1621
/************************************************************************/
1622
/*                           OGR_ST_GetUnit()                           */
1623
/************************************************************************/
1624
1625
/**
1626
 * \fn OGRStyleTool::GetUnit()
1627
 * \brief Get Style Tool units
1628
 *
1629
 * @return the style tool units.
1630
 */
1631
1632
/**
1633
 * \brief Get Style Tool units
1634
 *
1635
 * @param hST handle to the style tool.
1636
 *
1637
 * @return the style tool units.
1638
 */
1639
1640
OGRSTUnitId OGR_ST_GetUnit(OGRStyleToolH hST)
1641
1642
0
{
1643
0
    VALIDATE_POINTER1(hST, "OGR_ST_GetUnit", OGRSTUGround);
1644
0
    return reinterpret_cast<OGRStyleTool *>(hST)->GetUnit();
1645
0
}
1646
1647
/************************************************************************/
1648
/*                              SetUnit()                               */
1649
/************************************************************************/
1650
1651
/**
1652
 * \brief Set Style Tool units
1653
 *
1654
 * @param eUnit the new unit.
1655
 * @param dfGroundPaperScale ground to paper scale factor.
1656
 *
1657
 */
1658
void OGRStyleTool::SetUnit(OGRSTUnitId eUnit, double dfGroundPaperScale)
1659
0
{
1660
0
    m_eUnit = eUnit;
1661
0
    m_dfScale = dfGroundPaperScale;
1662
0
}
1663
1664
/************************************************************************/
1665
/*                           OGR_ST_SetUnit()                           */
1666
/************************************************************************/
1667
/**
1668
 * \brief Set Style Tool units
1669
 *
1670
 * This function is the same as OGRStyleTool::SetUnit()
1671
 *
1672
 * @param hST handle to the style tool.
1673
 * @param eUnit the new unit.
1674
 * @param dfGroundPaperScale ground to paper scale factor.
1675
 *
1676
 */
1677
1678
void OGR_ST_SetUnit(OGRStyleToolH hST, OGRSTUnitId eUnit,
1679
                    double dfGroundPaperScale)
1680
1681
0
{
1682
0
    VALIDATE_POINTER0(hST, "OGR_ST_SetUnit");
1683
0
    reinterpret_cast<OGRStyleTool *>(hST)->SetUnit(eUnit, dfGroundPaperScale);
1684
0
}
1685
1686
/************************************************************************/
1687
/*                               Parse()                                */
1688
/************************************************************************/
1689
1690
//! @cond Doxygen_Suppress
1691
GBool OGRStyleTool::Parse(const OGRStyleParamId *pasStyle,
1692
                          OGRStyleValue *pasValue, int nCount)
1693
0
{
1694
0
    if (IsStyleParsed())
1695
0
        return TRUE;
1696
1697
0
    StyleParsed();
1698
1699
0
    if (m_pszStyleString == nullptr)
1700
0
        return FALSE;
1701
1702
    // Token to contains StyleString Type and content.
1703
    // Tokenize the String to get the Type and the content
1704
    // Example: Type(elem1:val2,elem2:val2)
1705
0
    char **papszToken = CSLTokenizeString2(
1706
0
        m_pszStyleString, "()",
1707
0
        CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
1708
1709
0
    if (CSLCount(papszToken) > 2 || CSLCount(papszToken) == 0)
1710
0
    {
1711
0
        CSLDestroy(papszToken);
1712
0
        CPLError(CE_Failure, CPLE_AppDefined,
1713
0
                 "Error in the format of the StyleTool %s", m_pszStyleString);
1714
0
        return FALSE;
1715
0
    }
1716
1717
    // Token that will contains StyleString elements.
1718
    // Tokenize the content of the StyleString to get paired components in it.
1719
0
    char **papszToken2 = CSLTokenizeString2(
1720
0
        papszToken[1], ",",
1721
0
        CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
1722
1723
    // Valid that we have the right StyleString for this feature type.
1724
0
    switch (GetType())
1725
0
    {
1726
0
        case OGRSTCPen:
1727
0
            if (!EQUAL(papszToken[0], "PEN"))
1728
0
            {
1729
0
                CPLError(
1730
0
                    CE_Failure, CPLE_AppDefined,
1731
0
                    "Error in the Type of StyleTool %s should be a PEN Type",
1732
0
                    papszToken[0]);
1733
0
                CSLDestroy(papszToken);
1734
0
                CSLDestroy(papszToken2);
1735
0
                return FALSE;
1736
0
            }
1737
0
            break;
1738
0
        case OGRSTCBrush:
1739
0
            if (!EQUAL(papszToken[0], "BRUSH"))
1740
0
            {
1741
0
                CPLError(
1742
0
                    CE_Failure, CPLE_AppDefined,
1743
0
                    "Error in the Type of StyleTool %s should be a BRUSH Type",
1744
0
                    papszToken[0]);
1745
0
                CSLDestroy(papszToken);
1746
0
                CSLDestroy(papszToken2);
1747
0
                return FALSE;
1748
0
            }
1749
0
            break;
1750
0
        case OGRSTCSymbol:
1751
0
            if (!EQUAL(papszToken[0], "SYMBOL"))
1752
0
            {
1753
0
                CPLError(CE_Failure, CPLE_AppDefined,
1754
0
                         "Error in the Type of StyleTool %s should be "
1755
0
                         "a SYMBOL Type",
1756
0
                         papszToken[0]);
1757
0
                CSLDestroy(papszToken);
1758
0
                CSLDestroy(papszToken2);
1759
0
                return FALSE;
1760
0
            }
1761
0
            break;
1762
0
        case OGRSTCLabel:
1763
0
            if (!EQUAL(papszToken[0], "LABEL"))
1764
0
            {
1765
0
                CPLError(
1766
0
                    CE_Failure, CPLE_AppDefined,
1767
0
                    "Error in the Type of StyleTool %s should be a LABEL Type",
1768
0
                    papszToken[0]);
1769
0
                CSLDestroy(papszToken);
1770
0
                CSLDestroy(papszToken2);
1771
0
                return FALSE;
1772
0
            }
1773
0
            break;
1774
0
        default:
1775
0
            CPLError(CE_Failure, CPLE_AppDefined,
1776
0
                     "Error in the Type of StyleTool, Type undetermined");
1777
0
            CSLDestroy(papszToken);
1778
0
            CSLDestroy(papszToken2);
1779
0
            return FALSE;
1780
0
            break;
1781
0
    }
1782
1783
    ////////////////////////////////////////////////////////////////////////
1784
    // Here we will loop on each element in the StyleString. If it is
1785
    // a valid element, we will add it in the StyleTool with
1786
    // SetParamStr().
1787
    //
1788
    // It is important to note that the SetInternalUnit...() is use to update
1789
    // the unit of the StyleTool param (m_eUnit).
1790
    // See OGRStyleTool::SetParamStr().
1791
    // There's a StyleTool unit (m_eUnit), which is the output unit, and each
1792
    // parameter of the style have its own unit value (the input unit). Here we
1793
    // set m_eUnit to the input unit and in SetParamStr(), we will use this
1794
    // value to set the input unit. Then after the loop we will reset m_eUnit
1795
    // to its original value. (Yes it is a side effect / black magic)
1796
    //
1797
    // The pasStyle variable is a global variable passed in argument to the
1798
    // function. See at the top of this file the four OGRStyleParamId
1799
    // variable. They are used to register the valid parameter of each
1800
    // StyleTool.
1801
    ////////////////////////////////////////////////////////////////////////
1802
1803
    // Save Scale and output Units because the parsing code will alter
1804
    // the values.
1805
0
    OGRSTUnitId eLastUnit = m_eUnit;
1806
0
    double dSavedScale = m_dfScale;
1807
0
    const int nElements = CSLCount(papszToken2);
1808
1809
0
    for (int i = 0; i < nElements; i++)
1810
0
    {
1811
0
        char **papszStylePair =
1812
0
            CSLTokenizeString2(papszToken2[i], ":",
1813
0
                               CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES |
1814
0
                                   CSLT_STRIPENDSPACES | CSLT_ALLOWEMPTYTOKENS);
1815
1816
0
        const int nTokens = CSLCount(papszStylePair);
1817
1818
0
        if (nTokens < 1 || nTokens > 2)
1819
0
        {
1820
0
            CPLError(CE_Warning, CPLE_AppDefined,
1821
0
                     "Error in the StyleTool String %s", m_pszStyleString);
1822
0
            CPLError(CE_Warning, CPLE_AppDefined,
1823
0
                     "Malformed element #%d (\"%s\") skipped", i,
1824
0
                     papszToken2[i]);
1825
0
            CSLDestroy(papszStylePair);
1826
0
            continue;
1827
0
        }
1828
1829
0
        for (int j = 0; j < nCount; j++)
1830
0
        {
1831
0
            if (pasStyle[j].pszToken &&
1832
0
                EQUAL(pasStyle[j].pszToken, papszStylePair[0]))
1833
0
            {
1834
0
                if (papszStylePair[1] != nullptr && pasStyle[j].bGeoref == TRUE)
1835
0
                    SetInternalInputUnitFromParam(papszStylePair[1]);
1836
1837
                // Set either the actual value of style parameter or "1"
1838
                // for boolean parameters which do not have values (legacy
1839
                // behavior).
1840
0
                OGRStyleTool::SetParamStr(
1841
0
                    pasStyle[j], pasValue[j],
1842
0
                    papszStylePair[1] != nullptr ? papszStylePair[1] : "1");
1843
1844
0
                break;
1845
0
            }
1846
0
        }
1847
1848
0
        CSLDestroy(papszStylePair);
1849
0
    }
1850
1851
0
    m_eUnit = eLastUnit;
1852
0
    m_dfScale = dSavedScale;
1853
1854
0
    CSLDestroy(papszToken2);
1855
0
    CSLDestroy(papszToken);
1856
1857
0
    return TRUE;
1858
0
}
1859
1860
//! @endcond
1861
1862
/************************************************************************/
1863
/*                   SetInternalInputUnitFromParam()                    */
1864
/************************************************************************/
1865
1866
//! @cond Doxygen_Suppress
1867
void OGRStyleTool::SetInternalInputUnitFromParam(char *pszString)
1868
0
{
1869
0
    if (pszString == nullptr)
1870
0
        return;
1871
1872
0
    char *pszUnit = strstr(pszString, "g");
1873
0
    if (pszUnit)
1874
0
    {
1875
0
        SetUnit(OGRSTUGround);
1876
0
        pszUnit[0] = '\0';
1877
0
        return;
1878
0
    }
1879
0
    pszUnit = strstr(pszString, "px");
1880
0
    if (pszUnit)
1881
0
    {
1882
0
        SetUnit(OGRSTUPixel);
1883
0
        pszUnit[0] = '\0';
1884
0
        return;
1885
0
    }
1886
0
    pszUnit = strstr(pszString, "pt");
1887
0
    if (pszUnit)
1888
0
    {
1889
0
        SetUnit(OGRSTUPoints);
1890
0
        pszUnit[0] = '\0';
1891
0
        return;
1892
0
    }
1893
0
    pszUnit = strstr(pszString, "mm");
1894
0
    if (pszUnit)
1895
0
    {
1896
0
        SetUnit(OGRSTUMM);
1897
0
        pszUnit[0] = '\0';
1898
0
        return;
1899
0
    }
1900
0
    pszUnit = strstr(pszString, "cm");
1901
0
    if (pszUnit)
1902
0
    {
1903
0
        SetUnit(OGRSTUCM);
1904
0
        pszUnit[0] = '\0';
1905
0
        return;
1906
0
    }
1907
0
    pszUnit = strstr(pszString, "in");
1908
0
    if (pszUnit)
1909
0
    {
1910
0
        SetUnit(OGRSTUInches);
1911
0
        pszUnit[0] = '\0';
1912
0
        return;
1913
0
    }
1914
1915
0
    SetUnit(OGRSTUMM);
1916
0
}
1917
1918
/************************************************************************/
1919
/*                          ComputeWithUnit()                           */
1920
/************************************************************************/
1921
double OGRStyleTool::ComputeWithUnit(double dfValue, OGRSTUnitId eInputUnit)
1922
0
{
1923
0
    OGRSTUnitId eOutputUnit = GetUnit();
1924
1925
0
    double dfNewValue = dfValue;  // dfValue in meters;
1926
1927
0
    if (eOutputUnit == eInputUnit)
1928
0
        return dfValue;
1929
1930
0
    switch (eInputUnit)
1931
0
    {
1932
0
        case OGRSTUGround:
1933
0
            dfNewValue = dfValue / m_dfScale;
1934
0
            break;
1935
0
        case OGRSTUPixel:
1936
0
            dfNewValue = dfValue / (72.0 * 39.37);
1937
0
            break;
1938
0
        case OGRSTUPoints:
1939
0
            dfNewValue = dfValue / (72.0 * 39.37);
1940
0
            break;
1941
0
        case OGRSTUMM:
1942
0
            dfNewValue = 0.001 * dfValue;
1943
0
            break;
1944
0
        case OGRSTUCM:
1945
0
            dfNewValue = 0.01 * dfValue;
1946
0
            break;
1947
0
        case OGRSTUInches:
1948
0
            dfNewValue = dfValue / 39.37;
1949
0
            break;
1950
0
        default:
1951
0
            break;  // imp.
1952
0
    }
1953
1954
0
    switch (eOutputUnit)
1955
0
    {
1956
0
        case OGRSTUGround:
1957
0
            dfNewValue *= m_dfScale;
1958
0
            break;
1959
0
        case OGRSTUPixel:
1960
0
            dfNewValue *= 72.0 * 39.37;
1961
0
            break;
1962
0
        case OGRSTUPoints:
1963
0
            dfNewValue *= 72.0 * 39.37;
1964
0
            break;
1965
0
        case OGRSTUMM:
1966
0
            dfNewValue *= 1000.0;
1967
0
            break;
1968
0
        case OGRSTUCM:
1969
0
            dfNewValue *= 100.0;
1970
0
            break;
1971
0
        case OGRSTUInches:
1972
0
            dfNewValue *= 39.37;
1973
0
            break;
1974
0
        default:
1975
0
            break;  // imp.
1976
0
    }
1977
0
    return dfNewValue;
1978
0
}
1979
1980
/************************************************************************/
1981
/*                          ComputeWithUnit()                           */
1982
/************************************************************************/
1983
int OGRStyleTool::ComputeWithUnit(int nValue, OGRSTUnitId eUnit)
1984
0
{
1985
0
    return static_cast<int>(
1986
0
        ComputeWithUnit(static_cast<double>(nValue), eUnit));
1987
0
}
1988
1989
//! @endcond
1990
1991
/************************************************************************/
1992
/*                            GetParamStr()                             */
1993
/************************************************************************/
1994
1995
/** Undocumented
1996
 * @param sStyleParam undocumented.
1997
 * @param sStyleValue undocumented.
1998
 * @param bValueIsNull undocumented.
1999
 * @return Undocumented.
2000
 */
2001
const char *OGRStyleTool::GetParamStr(const OGRStyleParamId &sStyleParam,
2002
                                      const OGRStyleValue &sStyleValue,
2003
                                      GBool &bValueIsNull)
2004
0
{
2005
0
    if (!Parse())
2006
0
    {
2007
0
        bValueIsNull = TRUE;
2008
0
        return nullptr;
2009
0
    }
2010
2011
0
    bValueIsNull = !sStyleValue.bValid;
2012
2013
0
    if (bValueIsNull == TRUE)
2014
0
        return nullptr;
2015
2016
0
    switch (sStyleParam.eType)
2017
0
    {
2018
        // If sStyleParam.bGeoref == TRUE, need to convert to output value.
2019
0
        case OGRSTypeString:
2020
0
            return sStyleValue.pszValue;
2021
0
        case OGRSTypeDouble:
2022
0
            if (sStyleParam.bGeoref)
2023
0
                return CPLSPrintf("%f", ComputeWithUnit(sStyleValue.dfValue,
2024
0
                                                        sStyleValue.eUnit));
2025
0
            else
2026
0
                return CPLSPrintf("%f", sStyleValue.dfValue);
2027
2028
0
        case OGRSTypeInteger:
2029
0
            if (sStyleParam.bGeoref)
2030
0
                return CPLSPrintf("%d", ComputeWithUnit(sStyleValue.nValue,
2031
0
                                                        sStyleValue.eUnit));
2032
0
            else
2033
0
                return CPLSPrintf("%d", sStyleValue.nValue);
2034
0
        case OGRSTypeBoolean:
2035
0
            return CPLSPrintf("%d", sStyleValue.nValue != 0);
2036
0
        default:
2037
0
            bValueIsNull = TRUE;
2038
0
            return nullptr;
2039
0
    }
2040
0
}
2041
2042
/****************************************************************************/
2043
/*    int OGRStyleTool::GetParamNum(OGRStyleParamId sStyleParam ,           */
2044
/*                               OGRStyleValue sStyleValue,                 */
2045
/*                               GBool &bValueIsNull)                       */
2046
/*                                                                          */
2047
/****************************************************************************/
2048
2049
/** Undocumented
2050
 * @param sStyleParam undocumented.
2051
 * @param sStyleValue undocumented.
2052
 * @param bValueIsNull undocumented.
2053
 * @return Undocumented.
2054
 */
2055
int OGRStyleTool::GetParamNum(const OGRStyleParamId &sStyleParam,
2056
                              const OGRStyleValue &sStyleValue,
2057
                              GBool &bValueIsNull)
2058
0
{
2059
0
    return static_cast<int>(
2060
0
        GetParamDbl(sStyleParam, sStyleValue, bValueIsNull));
2061
0
}
2062
2063
/****************************************************************************/
2064
/*       double OGRStyleTool::GetParamDbl(OGRStyleParamId sStyleParam ,     */
2065
/*                               OGRStyleValue sStyleValue,                 */
2066
/*                               GBool &bValueIsNull)                       */
2067
/*                                                                          */
2068
/****************************************************************************/
2069
2070
/** Undocumented
2071
 * @param sStyleParam undocumented.
2072
 * @param sStyleValue undocumented.
2073
 * @param bValueIsNull undocumented.
2074
 * @return Undocumented.
2075
 */
2076
double OGRStyleTool::GetParamDbl(const OGRStyleParamId &sStyleParam,
2077
                                 const OGRStyleValue &sStyleValue,
2078
                                 GBool &bValueIsNull)
2079
0
{
2080
0
    if (!Parse())
2081
0
    {
2082
0
        bValueIsNull = TRUE;
2083
0
        return 0.0;
2084
0
    }
2085
2086
0
    bValueIsNull = !sStyleValue.bValid;
2087
2088
0
    if (bValueIsNull == TRUE)
2089
0
        return 0.0;
2090
2091
0
    switch (sStyleParam.eType)
2092
0
    {
2093
        // if sStyleParam.bGeoref == TRUE, need to convert to output value.
2094
0
        case OGRSTypeString:
2095
0
            if (sStyleParam.bGeoref)
2096
0
                return ComputeWithUnit(CPLAtof(sStyleValue.pszValue),
2097
0
                                       sStyleValue.eUnit);
2098
0
            else
2099
0
                return CPLAtof(sStyleValue.pszValue);
2100
0
        case OGRSTypeDouble:
2101
0
            if (sStyleParam.bGeoref)
2102
0
                return ComputeWithUnit(sStyleValue.dfValue, sStyleValue.eUnit);
2103
0
            else
2104
0
                return sStyleValue.dfValue;
2105
0
        case OGRSTypeInteger:
2106
0
            if (sStyleParam.bGeoref)
2107
0
                return static_cast<double>(
2108
0
                    ComputeWithUnit(sStyleValue.nValue, sStyleValue.eUnit));
2109
0
            else
2110
0
                return static_cast<double>(sStyleValue.nValue);
2111
0
        case OGRSTypeBoolean:
2112
0
            return static_cast<double>(sStyleValue.nValue != 0);
2113
0
        default:
2114
0
            bValueIsNull = TRUE;
2115
0
            return 0.0;
2116
0
    }
2117
0
}
2118
2119
/****************************************************************************/
2120
/*      void OGRStyleTool::SetParamStr(OGRStyleParamId &sStyleParam ,       */
2121
/*                             OGRStyleValue &sStyleValue,                  */
2122
/*                             const char *pszParamString)                  */
2123
/*                                                                          */
2124
/****************************************************************************/
2125
2126
/** Undocumented
2127
 * @param sStyleParam undocumented.
2128
 * @param sStyleValue undocumented.
2129
 * @param pszParamString undocumented.
2130
 */
2131
void OGRStyleTool::SetParamStr(const OGRStyleParamId &sStyleParam,
2132
                               OGRStyleValue &sStyleValue,
2133
                               const char *pszParamString)
2134
0
{
2135
0
    Parse();
2136
0
    StyleModified();
2137
0
    sStyleValue.bValid = TRUE;
2138
0
    sStyleValue.eUnit = GetUnit();
2139
0
    switch (sStyleParam.eType)
2140
0
    {
2141
        // If sStyleParam.bGeoref == TRUE, need to convert to output value;
2142
0
        case OGRSTypeString:
2143
0
            sStyleValue.pszValue = CPLStrdup(pszParamString);
2144
0
            break;
2145
0
        case OGRSTypeDouble:
2146
0
            sStyleValue.dfValue = CPLAtof(pszParamString);
2147
0
            break;
2148
0
        case OGRSTypeInteger:
2149
0
            sStyleValue.nValue = atoi(pszParamString);
2150
0
            break;
2151
0
        case OGRSTypeBoolean:
2152
0
            sStyleValue.nValue = atoi(pszParamString) != 0;
2153
0
            break;
2154
0
        default:
2155
0
            sStyleValue.bValid = FALSE;
2156
0
            break;
2157
0
    }
2158
0
}
2159
2160
/****************************************************************************/
2161
/*    void OGRStyleTool::SetParamNum(OGRStyleParamId &sStyleParam ,         */
2162
/*                             OGRStyleValue &sStyleValue,                  */
2163
/*                             int nParam)                                  */
2164
/*                                                                          */
2165
/****************************************************************************/
2166
2167
/** Undocumented
2168
 * @param sStyleParam undocumented.
2169
 * @param sStyleValue undocumented.
2170
 * @param nParam undocumented.
2171
 */
2172
void OGRStyleTool::SetParamNum(const OGRStyleParamId &sStyleParam,
2173
                               OGRStyleValue &sStyleValue, int nParam)
2174
0
{
2175
0
    Parse();
2176
0
    StyleModified();
2177
0
    sStyleValue.bValid = TRUE;
2178
0
    sStyleValue.eUnit = GetUnit();
2179
0
    switch (sStyleParam.eType)
2180
0
    {
2181
2182
        // If sStyleParam.bGeoref == TRUE, need to convert to output value;
2183
0
        case OGRSTypeString:
2184
0
            sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%d", nParam));
2185
0
            break;
2186
0
        case OGRSTypeDouble:
2187
0
            sStyleValue.dfValue = static_cast<double>(nParam);
2188
0
            break;
2189
0
        case OGRSTypeInteger:
2190
0
            sStyleValue.nValue = nParam;
2191
0
            break;
2192
0
        case OGRSTypeBoolean:
2193
0
            sStyleValue.nValue = nParam != 0;
2194
0
            break;
2195
0
        default:
2196
0
            sStyleValue.bValid = FALSE;
2197
0
            break;
2198
0
    }
2199
0
}
2200
2201
/****************************************************************************/
2202
/*      void OGRStyleTool::SetParamDbl(OGRStyleParamId &sStyleParam ,       */
2203
/*                             OGRStyleValue &sStyleValue,                  */
2204
/*                             double dfParam)                              */
2205
/*                                                                          */
2206
/****************************************************************************/
2207
2208
/** Undocumented
2209
 * @param sStyleParam undocumented.
2210
 * @param sStyleValue undocumented.
2211
 * @param dfParam undocumented.
2212
 */
2213
void OGRStyleTool::SetParamDbl(const OGRStyleParamId &sStyleParam,
2214
                               OGRStyleValue &sStyleValue, double dfParam)
2215
0
{
2216
0
    Parse();
2217
0
    StyleModified();
2218
0
    sStyleValue.bValid = TRUE;
2219
0
    sStyleValue.eUnit = GetUnit();
2220
0
    switch (sStyleParam.eType)
2221
0
    {
2222
        // If sStyleParam.bGeoref == TRUE, need to convert to output value;
2223
0
        case OGRSTypeString:
2224
0
            sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%f", dfParam));
2225
0
            break;
2226
0
        case OGRSTypeDouble:
2227
0
            sStyleValue.dfValue = dfParam;
2228
0
            break;
2229
0
        case OGRSTypeInteger:
2230
0
            sStyleValue.nValue = static_cast<int>(dfParam);
2231
0
            break;
2232
0
        case OGRSTypeBoolean:
2233
0
            sStyleValue.nValue = static_cast<int>(dfParam) != 0;
2234
0
            break;
2235
0
        default:
2236
0
            sStyleValue.bValid = FALSE;
2237
0
            break;
2238
0
    }
2239
0
}
2240
2241
/************************************************************************/
2242
/*                           OGR_ST_GetParamStr()                       */
2243
/************************************************************************/
2244
/**
2245
 * \brief Get Style Tool parameter value as string
2246
 *
2247
 * Maps to the OGRStyleTool subclasses' GetParamStr() methods.
2248
 *
2249
 * @param hST handle to the style tool.
2250
 * @param eParam the parameter id from the enumeration corresponding to the
2251
 * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2252
 * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2253
 * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
2254
 * to indicate whether the parameter value is NULL.
2255
 *
2256
 * @return the parameter value as string and sets bValueIsNull.
2257
 */
2258
2259
const char *OGR_ST_GetParamStr(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2260
0
{
2261
0
    VALIDATE_POINTER1(hST, "OGR_ST_GetParamStr", "");
2262
0
    VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamStr", "");
2263
2264
0
    GBool bIsNull = TRUE;
2265
0
    const char *pszVal = "";
2266
2267
0
    switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2268
0
    {
2269
0
        case OGRSTCPen:
2270
0
            pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamStr(
2271
0
                static_cast<OGRSTPenParam>(eParam), bIsNull);
2272
0
            break;
2273
0
        case OGRSTCBrush:
2274
0
            pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamStr(
2275
0
                static_cast<OGRSTBrushParam>(eParam), bIsNull);
2276
0
            break;
2277
0
        case OGRSTCSymbol:
2278
0
            pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamStr(
2279
0
                static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2280
0
            break;
2281
0
        case OGRSTCLabel:
2282
0
            pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamStr(
2283
0
                static_cast<OGRSTLabelParam>(eParam), bIsNull);
2284
0
            break;
2285
0
        default:
2286
0
            break;
2287
0
    }
2288
2289
0
    *bValueIsNull = bIsNull;
2290
0
    return pszVal;
2291
0
}
2292
2293
/************************************************************************/
2294
/*                           OGR_ST_GetParamNum()                       */
2295
/************************************************************************/
2296
/**
2297
 * \brief Get Style Tool parameter value as an integer
2298
 *
2299
 * Maps to the OGRStyleTool subclasses' GetParamNum() methods.
2300
 *
2301
 * @param hST handle to the style tool.
2302
 * @param eParam the parameter id from the enumeration corresponding to the
2303
 * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2304
 * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2305
 * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
2306
 * to indicate whether the parameter value is NULL.
2307
 *
2308
 * @return the parameter value as integer and sets bValueIsNull.
2309
 */
2310
2311
int OGR_ST_GetParamNum(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2312
0
{
2313
0
    VALIDATE_POINTER1(hST, "OGR_ST_GetParamNum", 0);
2314
0
    VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamNum", 0);
2315
2316
0
    GBool bIsNull = TRUE;
2317
0
    int nVal = 0;
2318
2319
0
    switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2320
0
    {
2321
0
        case OGRSTCPen:
2322
0
            nVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamNum(
2323
0
                static_cast<OGRSTPenParam>(eParam), bIsNull);
2324
0
            break;
2325
0
        case OGRSTCBrush:
2326
0
            nVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamNum(
2327
0
                static_cast<OGRSTBrushParam>(eParam), bIsNull);
2328
0
            break;
2329
0
        case OGRSTCSymbol:
2330
0
            nVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamNum(
2331
0
                static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2332
0
            break;
2333
0
        case OGRSTCLabel:
2334
0
            nVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamNum(
2335
0
                static_cast<OGRSTLabelParam>(eParam), bIsNull);
2336
0
            break;
2337
0
        default:
2338
0
            break;
2339
0
    }
2340
2341
0
    *bValueIsNull = bIsNull;
2342
0
    return nVal;
2343
0
}
2344
2345
/************************************************************************/
2346
/*                           OGR_ST_GetParamDbl()                       */
2347
/************************************************************************/
2348
/**
2349
 * \brief Get Style Tool parameter value as a double
2350
 *
2351
 * Maps to the OGRStyleTool subclasses' GetParamDbl() methods.
2352
 *
2353
 * @param hST handle to the style tool.
2354
 * @param eParam the parameter id from the enumeration corresponding to the
2355
 * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2356
 * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2357
 * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
2358
 * to indicate whether the parameter value is NULL.
2359
 *
2360
 * @return the parameter value as double and sets bValueIsNull.
2361
 */
2362
2363
double OGR_ST_GetParamDbl(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2364
0
{
2365
0
    VALIDATE_POINTER1(hST, "OGR_ST_GetParamDbl", 0.0);
2366
0
    VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamDbl", 0.0);
2367
2368
0
    GBool bIsNull = TRUE;
2369
0
    double dfVal = 0.0;
2370
2371
0
    switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2372
0
    {
2373
0
        case OGRSTCPen:
2374
0
            dfVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamDbl(
2375
0
                static_cast<OGRSTPenParam>(eParam), bIsNull);
2376
0
            break;
2377
0
        case OGRSTCBrush:
2378
0
            dfVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamDbl(
2379
0
                static_cast<OGRSTBrushParam>(eParam), bIsNull);
2380
0
            break;
2381
0
        case OGRSTCSymbol:
2382
0
            dfVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamDbl(
2383
0
                static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2384
0
            break;
2385
0
        case OGRSTCLabel:
2386
0
            dfVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamDbl(
2387
0
                static_cast<OGRSTLabelParam>(eParam), bIsNull);
2388
0
            break;
2389
0
        default:
2390
0
            break;
2391
0
    }
2392
2393
0
    *bValueIsNull = bIsNull;
2394
0
    return dfVal;
2395
0
}
2396
2397
/************************************************************************/
2398
/*                           OGR_ST_SetParamStr()                       */
2399
/************************************************************************/
2400
/**
2401
 * \brief Set Style Tool parameter value from a string
2402
 *
2403
 * Maps to the OGRStyleTool subclasses' SetParamStr() methods.
2404
 *
2405
 * @param hST handle to the style tool.
2406
 * @param eParam the parameter id from the enumeration corresponding to the
2407
 * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2408
 * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2409
 * @param pszValue the new parameter value
2410
 *
2411
 */
2412
2413
void OGR_ST_SetParamStr(OGRStyleToolH hST, int eParam, const char *pszValue)
2414
0
{
2415
0
    VALIDATE_POINTER0(hST, "OGR_ST_SetParamStr");
2416
0
    VALIDATE_POINTER0(pszValue, "OGR_ST_SetParamStr");
2417
2418
0
    switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2419
0
    {
2420
0
        case OGRSTCPen:
2421
0
            reinterpret_cast<OGRStylePen *>(hST)->SetParamStr(
2422
0
                static_cast<OGRSTPenParam>(eParam), pszValue);
2423
0
            break;
2424
0
        case OGRSTCBrush:
2425
0
            reinterpret_cast<OGRStyleBrush *>(hST)->SetParamStr(
2426
0
                static_cast<OGRSTBrushParam>(eParam), pszValue);
2427
0
            break;
2428
0
        case OGRSTCSymbol:
2429
0
            reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamStr(
2430
0
                static_cast<OGRSTSymbolParam>(eParam), pszValue);
2431
0
            break;
2432
0
        case OGRSTCLabel:
2433
0
            reinterpret_cast<OGRStyleLabel *>(hST)->SetParamStr(
2434
0
                static_cast<OGRSTLabelParam>(eParam), pszValue);
2435
0
            break;
2436
0
        default:
2437
0
            break;
2438
0
    }
2439
0
}
2440
2441
/************************************************************************/
2442
/*                           OGR_ST_SetParamNum()                       */
2443
/************************************************************************/
2444
/**
2445
 * \brief Set Style Tool parameter value from an integer
2446
 *
2447
 * Maps to the OGRStyleTool subclasses' SetParamNum() methods.
2448
 *
2449
 * @param hST handle to the style tool.
2450
 * @param eParam the parameter id from the enumeration corresponding to the
2451
 * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2452
 * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2453
 * @param nValue the new parameter value
2454
 *
2455
 */
2456
2457
void OGR_ST_SetParamNum(OGRStyleToolH hST, int eParam, int nValue)
2458
0
{
2459
0
    VALIDATE_POINTER0(hST, "OGR_ST_SetParamNum");
2460
2461
0
    switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2462
0
    {
2463
0
        case OGRSTCPen:
2464
0
            reinterpret_cast<OGRStylePen *>(hST)->SetParamNum(
2465
0
                static_cast<OGRSTPenParam>(eParam), nValue);
2466
0
            break;
2467
0
        case OGRSTCBrush:
2468
0
            reinterpret_cast<OGRStyleBrush *>(hST)->SetParamNum(
2469
0
                static_cast<OGRSTBrushParam>(eParam), nValue);
2470
0
            break;
2471
0
        case OGRSTCSymbol:
2472
0
            reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamNum(
2473
0
                static_cast<OGRSTSymbolParam>(eParam), nValue);
2474
0
            break;
2475
0
        case OGRSTCLabel:
2476
0
            reinterpret_cast<OGRStyleLabel *>(hST)->SetParamNum(
2477
0
                static_cast<OGRSTLabelParam>(eParam), nValue);
2478
0
            break;
2479
0
        default:
2480
0
            break;
2481
0
    }
2482
0
}
2483
2484
/************************************************************************/
2485
/*                           OGR_ST_SetParamDbl()                       */
2486
/************************************************************************/
2487
/**
2488
 * \brief Set Style Tool parameter value from a double
2489
 *
2490
 * Maps to the OGRStyleTool subclasses' SetParamDbl() methods.
2491
 *
2492
 * @param hST handle to the style tool.
2493
 * @param eParam the parameter id from the enumeration corresponding to the
2494
 * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2495
 * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2496
 * @param dfValue the new parameter value
2497
 *
2498
 */
2499
2500
void OGR_ST_SetParamDbl(OGRStyleToolH hST, int eParam, double dfValue)
2501
0
{
2502
0
    VALIDATE_POINTER0(hST, "OGR_ST_SetParamDbl");
2503
2504
0
    switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2505
0
    {
2506
0
        case OGRSTCPen:
2507
0
            reinterpret_cast<OGRStylePen *>(hST)->SetParamDbl(
2508
0
                static_cast<OGRSTPenParam>(eParam), dfValue);
2509
0
            break;
2510
0
        case OGRSTCBrush:
2511
0
            reinterpret_cast<OGRStyleBrush *>(hST)->SetParamDbl(
2512
0
                static_cast<OGRSTBrushParam>(eParam), dfValue);
2513
0
            break;
2514
0
        case OGRSTCSymbol:
2515
0
            reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamDbl(
2516
0
                static_cast<OGRSTSymbolParam>(eParam), dfValue);
2517
0
            break;
2518
0
        case OGRSTCLabel:
2519
0
            reinterpret_cast<OGRStyleLabel *>(hST)->SetParamDbl(
2520
0
                static_cast<OGRSTLabelParam>(eParam), dfValue);
2521
0
            break;
2522
0
        default:
2523
0
            break;
2524
0
    }
2525
0
}
2526
2527
/************************************************************************/
2528
/*                           OGR_ST_GetStyleString()                    */
2529
/************************************************************************/
2530
2531
/**
2532
 * \fn OGRStyleTool::GetStyleString()
2533
 * \brief Get the style string for this Style Tool
2534
 *
2535
 * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
2536
 *
2537
 * @return the style string for this style tool or "" if the hST is invalid.
2538
 */
2539
2540
/**
2541
 * \brief Get the style string for this Style Tool
2542
 *
2543
 * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
2544
 *
2545
 * @param hST handle to the style tool.
2546
 *
2547
 * @return the style string for this style tool or "" if the hST is invalid.
2548
 */
2549
2550
const char *OGR_ST_GetStyleString(OGRStyleToolH hST)
2551
0
{
2552
0
    const char *pszVal = "";
2553
2554
0
    VALIDATE_POINTER1(hST, "OGR_ST_GetStyleString", "");
2555
2556
0
    switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2557
0
    {
2558
0
        case OGRSTCPen:
2559
0
            pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetStyleString();
2560
0
            break;
2561
0
        case OGRSTCBrush:
2562
0
            pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetStyleString();
2563
0
            break;
2564
0
        case OGRSTCSymbol:
2565
0
            pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetStyleString();
2566
0
            break;
2567
0
        case OGRSTCLabel:
2568
0
            pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetStyleString();
2569
0
            break;
2570
0
        default:
2571
0
            break;
2572
0
    }
2573
2574
0
    return pszVal;
2575
0
}
2576
2577
/************************************************************************/
2578
/*                           OGR_ST_GetRGBFromString()                  */
2579
/************************************************************************/
2580
/**
2581
 * \brief Return the r,g,b,a components of a color encoded in \#RRGGBB[AA]
2582
 * format.
2583
 *
2584
 * Maps to OGRStyleTool::GetRGBFromString().
2585
 *
2586
 * @param hST handle to the style tool.
2587
 * @param pszColor the color to parse
2588
 * @param pnRed pointer to an int in which the red value will be returned
2589
 * @param pnGreen pointer to an int in which the green value will be returned
2590
 * @param pnBlue pointer to an int in which the blue value will be returned
2591
 * @param pnAlpha pointer to an int in which the (optional) alpha value will
2592
 * be returned
2593
 *
2594
 * @return TRUE if the color could be successfully parsed, or FALSE in case of
2595
 * errors.
2596
 */
2597
2598
int OGR_ST_GetRGBFromString(OGRStyleToolH hST, const char *pszColor, int *pnRed,
2599
                            int *pnGreen, int *pnBlue, int *pnAlpha)
2600
0
{
2601
2602
0
    VALIDATE_POINTER1(hST, "OGR_ST_GetRGBFromString", FALSE);
2603
0
    VALIDATE_POINTER1(pnRed, "OGR_ST_GetRGBFromString", FALSE);
2604
0
    VALIDATE_POINTER1(pnGreen, "OGR_ST_GetRGBFromString", FALSE);
2605
0
    VALIDATE_POINTER1(pnBlue, "OGR_ST_GetRGBFromString", FALSE);
2606
0
    VALIDATE_POINTER1(pnAlpha, "OGR_ST_GetRGBFromString", FALSE);
2607
2608
0
    return reinterpret_cast<OGRStyleTool *>(hST)->GetRGBFromString(
2609
0
        pszColor, *pnRed, *pnGreen, *pnBlue, *pnAlpha);
2610
0
}
2611
2612
//! @cond Doxygen_Suppress
2613
/* ======================================================================== */
2614
/*                OGRStylePen                                               */
2615
/*       Specific parameter (Set/Get) for the StylePen                      */
2616
/* ======================================================================== */
2617
2618
/****************************************************************************/
2619
/*                      OGRStylePen::OGRStylePen()                          */
2620
/*                                                                          */
2621
/****************************************************************************/
2622
OGRStylePen::OGRStylePen()
2623
0
    : OGRStyleTool(OGRSTCPen),
2624
0
      m_pasStyleValue(static_cast<OGRStyleValue *>(
2625
0
          CPLCalloc(OGRSTPenLast, sizeof(OGRStyleValue))))
2626
0
{
2627
0
}
2628
2629
/****************************************************************************/
2630
/*                      OGRStylePen::~OGRStylePen()                         */
2631
/*                                                                          */
2632
/****************************************************************************/
2633
OGRStylePen::~OGRStylePen()
2634
0
{
2635
0
    for (int i = 0; i < OGRSTPenLast; i++)
2636
0
    {
2637
0
        if (m_pasStyleValue[i].pszValue != nullptr)
2638
0
        {
2639
0
            CPLFree(m_pasStyleValue[i].pszValue);
2640
0
            m_pasStyleValue[i].pszValue = nullptr;
2641
0
        }
2642
0
    }
2643
2644
0
    CPLFree(m_pasStyleValue);
2645
0
}
2646
2647
/************************************************************************/
2648
/*                         OGRStylePen::Parse()                         */
2649
/************************************************************************/
2650
GBool OGRStylePen::Parse()
2651
2652
0
{
2653
0
    return OGRStyleTool::Parse(asStylePen, m_pasStyleValue,
2654
0
                               static_cast<int>(OGRSTPenLast));
2655
0
}
2656
2657
/************************************************************************/
2658
/*                            GetParamStr()                             */
2659
/************************************************************************/
2660
const char *OGRStylePen::GetParamStr(OGRSTPenParam eParam, GBool &bValueIsNull)
2661
0
{
2662
0
    return OGRStyleTool::GetParamStr(asStylePen[eParam],
2663
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2664
0
}
2665
2666
/************************************************************************/
2667
/*                            GetParamNum()                             */
2668
/************************************************************************/
2669
int OGRStylePen::GetParamNum(OGRSTPenParam eParam, GBool &bValueIsNull)
2670
0
{
2671
0
    return OGRStyleTool::GetParamNum(asStylePen[eParam],
2672
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2673
0
}
2674
2675
/************************************************************************/
2676
/*                            GetParamDbl()                             */
2677
/************************************************************************/
2678
double OGRStylePen::GetParamDbl(OGRSTPenParam eParam, GBool &bValueIsNull)
2679
0
{
2680
0
    return OGRStyleTool::GetParamDbl(asStylePen[eParam],
2681
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2682
0
}
2683
2684
/************************************************************************/
2685
/*                            SetParamStr()                             */
2686
/************************************************************************/
2687
2688
void OGRStylePen::SetParamStr(OGRSTPenParam eParam, const char *pszParamString)
2689
0
{
2690
0
    OGRStyleTool::SetParamStr(asStylePen[eParam], m_pasStyleValue[eParam],
2691
0
                              pszParamString);
2692
0
}
2693
2694
/************************************************************************/
2695
/*                            SetParamNum()                             */
2696
/************************************************************************/
2697
void OGRStylePen::SetParamNum(OGRSTPenParam eParam, int nParam)
2698
0
{
2699
0
    OGRStyleTool::SetParamNum(asStylePen[eParam], m_pasStyleValue[eParam],
2700
0
                              nParam);
2701
0
}
2702
2703
/************************************************************************/
2704
/*                            SetParamDbl()                             */
2705
/************************************************************************/
2706
void OGRStylePen::SetParamDbl(OGRSTPenParam eParam, double dfParam)
2707
0
{
2708
0
    OGRStyleTool::SetParamDbl(asStylePen[eParam], m_pasStyleValue[eParam],
2709
0
                              dfParam);
2710
0
}
2711
2712
/************************************************************************/
2713
/*                           GetStyleString()                           */
2714
/************************************************************************/
2715
const char *OGRStylePen::GetStyleString()
2716
0
{
2717
0
    return OGRStyleTool::GetStyleString(asStylePen, m_pasStyleValue,
2718
0
                                        static_cast<int>(OGRSTPenLast));
2719
0
}
2720
2721
/****************************************************************************/
2722
/*                      OGRStyleBrush::OGRStyleBrush()                      */
2723
/*                                                                          */
2724
/****************************************************************************/
2725
OGRStyleBrush::OGRStyleBrush()
2726
0
    : OGRStyleTool(OGRSTCBrush),
2727
0
      m_pasStyleValue(static_cast<OGRStyleValue *>(
2728
0
          CPLCalloc(OGRSTBrushLast, sizeof(OGRStyleValue))))
2729
0
{
2730
0
}
2731
2732
/****************************************************************************/
2733
/*                      OGRStyleBrush::~OGRStyleBrush()                     */
2734
/*                                                                          */
2735
/****************************************************************************/
2736
OGRStyleBrush::~OGRStyleBrush()
2737
0
{
2738
0
    for (int i = 0; i < OGRSTBrushLast; i++)
2739
0
    {
2740
0
        if (m_pasStyleValue[i].pszValue != nullptr)
2741
0
        {
2742
0
            CPLFree(m_pasStyleValue[i].pszValue);
2743
0
            m_pasStyleValue[i].pszValue = nullptr;
2744
0
        }
2745
0
    }
2746
2747
0
    CPLFree(m_pasStyleValue);
2748
0
}
2749
2750
/************************************************************************/
2751
/*                               Parse()                                */
2752
/************************************************************************/
2753
GBool OGRStyleBrush::Parse()
2754
0
{
2755
0
    return OGRStyleTool::Parse(asStyleBrush, m_pasStyleValue,
2756
0
                               static_cast<int>(OGRSTBrushLast));
2757
0
}
2758
2759
/************************************************************************/
2760
/*                            GetParamStr()                             */
2761
/************************************************************************/
2762
const char *OGRStyleBrush::GetParamStr(OGRSTBrushParam eParam,
2763
                                       GBool &bValueIsNull)
2764
0
{
2765
0
    return OGRStyleTool::GetParamStr(asStyleBrush[eParam],
2766
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2767
0
}
2768
2769
/************************************************************************/
2770
/*                            GetParamNum()                             */
2771
/************************************************************************/
2772
int OGRStyleBrush::GetParamNum(OGRSTBrushParam eParam, GBool &bValueIsNull)
2773
0
{
2774
0
    return OGRStyleTool::GetParamNum(asStyleBrush[eParam],
2775
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2776
0
}
2777
2778
/************************************************************************/
2779
/*                            GetParamDbl()                             */
2780
/************************************************************************/
2781
double OGRStyleBrush::GetParamDbl(OGRSTBrushParam eParam, GBool &bValueIsNull)
2782
0
{
2783
0
    return OGRStyleTool::GetParamDbl(asStyleBrush[eParam],
2784
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2785
0
}
2786
2787
/************************************************************************/
2788
/*                            SetParamStr()                             */
2789
/************************************************************************/
2790
void OGRStyleBrush::SetParamStr(OGRSTBrushParam eParam,
2791
                                const char *pszParamString)
2792
0
{
2793
0
    OGRStyleTool::SetParamStr(asStyleBrush[eParam], m_pasStyleValue[eParam],
2794
0
                              pszParamString);
2795
0
}
2796
2797
/************************************************************************/
2798
/*                            SetParamNum()                             */
2799
/************************************************************************/
2800
void OGRStyleBrush::SetParamNum(OGRSTBrushParam eParam, int nParam)
2801
0
{
2802
0
    OGRStyleTool::SetParamNum(asStyleBrush[eParam], m_pasStyleValue[eParam],
2803
0
                              nParam);
2804
0
}
2805
2806
/************************************************************************/
2807
/*                            SetParamDbl()                             */
2808
/************************************************************************/
2809
void OGRStyleBrush::SetParamDbl(OGRSTBrushParam eParam, double dfParam)
2810
0
{
2811
0
    OGRStyleTool::SetParamDbl(asStyleBrush[eParam], m_pasStyleValue[eParam],
2812
0
                              dfParam);
2813
0
}
2814
2815
/************************************************************************/
2816
/*                           GetStyleString()                           */
2817
/************************************************************************/
2818
const char *OGRStyleBrush::GetStyleString()
2819
0
{
2820
0
    return OGRStyleTool::GetStyleString(asStyleBrush, m_pasStyleValue,
2821
0
                                        static_cast<int>(OGRSTBrushLast));
2822
0
}
2823
2824
/****************************************************************************/
2825
/*                      OGRStyleSymbol::OGRStyleSymbol()                    */
2826
/****************************************************************************/
2827
OGRStyleSymbol::OGRStyleSymbol()
2828
0
    : OGRStyleTool(OGRSTCSymbol),
2829
0
      m_pasStyleValue(static_cast<OGRStyleValue *>(
2830
0
          CPLCalloc(OGRSTSymbolLast, sizeof(OGRStyleValue))))
2831
0
{
2832
0
}
2833
2834
/****************************************************************************/
2835
/*                      OGRStyleSymbol::~OGRStyleSymbol()                   */
2836
/*                                                                          */
2837
/****************************************************************************/
2838
OGRStyleSymbol::~OGRStyleSymbol()
2839
0
{
2840
0
    for (int i = 0; i < OGRSTSymbolLast; i++)
2841
0
    {
2842
0
        if (m_pasStyleValue[i].pszValue != nullptr)
2843
0
        {
2844
0
            CPLFree(m_pasStyleValue[i].pszValue);
2845
0
            m_pasStyleValue[i].pszValue = nullptr;
2846
0
        }
2847
0
    }
2848
2849
0
    CPLFree(m_pasStyleValue);
2850
0
}
2851
2852
/************************************************************************/
2853
/*                               Parse()                                */
2854
/************************************************************************/
2855
GBool OGRStyleSymbol::Parse()
2856
0
{
2857
0
    return OGRStyleTool::Parse(asStyleSymbol, m_pasStyleValue,
2858
0
                               static_cast<int>(OGRSTSymbolLast));
2859
0
}
2860
2861
/************************************************************************/
2862
/*                            GetParamStr()                             */
2863
/************************************************************************/
2864
const char *OGRStyleSymbol::GetParamStr(OGRSTSymbolParam eParam,
2865
                                        GBool &bValueIsNull)
2866
0
{
2867
0
    return OGRStyleTool::GetParamStr(asStyleSymbol[eParam],
2868
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2869
0
}
2870
2871
/************************************************************************/
2872
/*                            GetParamNum()                             */
2873
/************************************************************************/
2874
int OGRStyleSymbol::GetParamNum(OGRSTSymbolParam eParam, GBool &bValueIsNull)
2875
0
{
2876
0
    return OGRStyleTool::GetParamNum(asStyleSymbol[eParam],
2877
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2878
0
}
2879
2880
/************************************************************************/
2881
/*                            GetParamDbl()                             */
2882
/************************************************************************/
2883
double OGRStyleSymbol::GetParamDbl(OGRSTSymbolParam eParam, GBool &bValueIsNull)
2884
0
{
2885
0
    return OGRStyleTool::GetParamDbl(asStyleSymbol[eParam],
2886
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2887
0
}
2888
2889
/************************************************************************/
2890
/*                            SetParamStr()                             */
2891
/************************************************************************/
2892
void OGRStyleSymbol::SetParamStr(OGRSTSymbolParam eParam,
2893
                                 const char *pszParamString)
2894
0
{
2895
0
    OGRStyleTool::SetParamStr(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2896
0
                              pszParamString);
2897
0
}
2898
2899
/************************************************************************/
2900
/*                            SetParamNum()                             */
2901
/************************************************************************/
2902
void OGRStyleSymbol::SetParamNum(OGRSTSymbolParam eParam, int nParam)
2903
0
{
2904
0
    OGRStyleTool::SetParamNum(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2905
0
                              nParam);
2906
0
}
2907
2908
/************************************************************************/
2909
/*                            SetParamDbl()                             */
2910
/************************************************************************/
2911
void OGRStyleSymbol::SetParamDbl(OGRSTSymbolParam eParam, double dfParam)
2912
0
{
2913
0
    OGRStyleTool::SetParamDbl(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2914
0
                              dfParam);
2915
0
}
2916
2917
/************************************************************************/
2918
/*                           GetStyleString()                           */
2919
/************************************************************************/
2920
const char *OGRStyleSymbol::GetStyleString()
2921
0
{
2922
0
    return OGRStyleTool::GetStyleString(asStyleSymbol, m_pasStyleValue,
2923
0
                                        static_cast<int>(OGRSTSymbolLast));
2924
0
}
2925
2926
/****************************************************************************/
2927
/*                      OGRStyleLabel::OGRStyleLabel()                      */
2928
/*                                                                          */
2929
/****************************************************************************/
2930
OGRStyleLabel::OGRStyleLabel()
2931
0
    : OGRStyleTool(OGRSTCLabel),
2932
0
      m_pasStyleValue(static_cast<OGRStyleValue *>(
2933
0
          CPLCalloc(OGRSTLabelLast, sizeof(OGRStyleValue))))
2934
0
{
2935
0
}
2936
2937
/****************************************************************************/
2938
/*                      OGRStyleLabel::~OGRStyleLabel()                     */
2939
/*                                                                          */
2940
/****************************************************************************/
2941
OGRStyleLabel::~OGRStyleLabel()
2942
0
{
2943
0
    for (int i = 0; i < OGRSTLabelLast; i++)
2944
0
    {
2945
0
        if (m_pasStyleValue[i].pszValue != nullptr)
2946
0
        {
2947
0
            CPLFree(m_pasStyleValue[i].pszValue);
2948
0
            m_pasStyleValue[i].pszValue = nullptr;
2949
0
        }
2950
0
    }
2951
2952
0
    CPLFree(m_pasStyleValue);
2953
0
}
2954
2955
/************************************************************************/
2956
/*                               Parse()                                */
2957
/************************************************************************/
2958
GBool OGRStyleLabel::Parse()
2959
0
{
2960
0
    return OGRStyleTool::Parse(asStyleLabel, m_pasStyleValue,
2961
0
                               static_cast<int>(OGRSTLabelLast));
2962
0
}
2963
2964
/************************************************************************/
2965
/*                            GetParamStr()                             */
2966
/************************************************************************/
2967
const char *OGRStyleLabel::GetParamStr(OGRSTLabelParam eParam,
2968
                                       GBool &bValueIsNull)
2969
0
{
2970
0
    return OGRStyleTool::GetParamStr(asStyleLabel[eParam],
2971
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2972
0
}
2973
2974
/************************************************************************/
2975
/*                            GetParamNum()                             */
2976
/************************************************************************/
2977
int OGRStyleLabel::GetParamNum(OGRSTLabelParam eParam, GBool &bValueIsNull)
2978
0
{
2979
0
    return OGRStyleTool::GetParamNum(asStyleLabel[eParam],
2980
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2981
0
}
2982
2983
/************************************************************************/
2984
/*                            GetParamDbl()                             */
2985
/************************************************************************/
2986
double OGRStyleLabel::GetParamDbl(OGRSTLabelParam eParam, GBool &bValueIsNull)
2987
0
{
2988
0
    return OGRStyleTool::GetParamDbl(asStyleLabel[eParam],
2989
0
                                     m_pasStyleValue[eParam], bValueIsNull);
2990
0
}
2991
2992
/************************************************************************/
2993
/*                            SetParamStr()                             */
2994
/************************************************************************/
2995
void OGRStyleLabel::SetParamStr(OGRSTLabelParam eParam,
2996
                                const char *pszParamString)
2997
0
{
2998
0
    OGRStyleTool::SetParamStr(asStyleLabel[eParam], m_pasStyleValue[eParam],
2999
0
                              pszParamString);
3000
0
}
3001
3002
/************************************************************************/
3003
/*                            SetParamNum()                             */
3004
/************************************************************************/
3005
void OGRStyleLabel::SetParamNum(OGRSTLabelParam eParam, int nParam)
3006
0
{
3007
0
    OGRStyleTool::SetParamNum(asStyleLabel[eParam], m_pasStyleValue[eParam],
3008
0
                              nParam);
3009
0
}
3010
3011
/************************************************************************/
3012
/*                            SetParamDbl()                             */
3013
/************************************************************************/
3014
void OGRStyleLabel::SetParamDbl(OGRSTLabelParam eParam, double dfParam)
3015
0
{
3016
0
    OGRStyleTool::SetParamDbl(asStyleLabel[eParam], m_pasStyleValue[eParam],
3017
0
                              dfParam);
3018
0
}
3019
3020
/************************************************************************/
3021
/*                           GetStyleString()                           */
3022
/************************************************************************/
3023
const char *OGRStyleLabel::GetStyleString()
3024
0
{
3025
0
    return OGRStyleTool::GetStyleString(asStyleLabel, m_pasStyleValue,
3026
0
                                        static_cast<int>(OGRSTLabelLast));
3027
0
}
3028
3029
//! @endcond