Line data Source code
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 993 : OGRStyleMgr::OGRStyleMgr(OGRStyleTable *poDataSetStyleTable)
112 993 : : m_poDataSetStyleTable(poDataSetStyleTable)
113 : {
114 993 : }
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 165 : OGRStyleMgrH OGR_SM_Create(OGRStyleTableH hStyleTable)
131 :
132 : {
133 : return reinterpret_cast<OGRStyleMgrH>(
134 165 : new OGRStyleMgr(reinterpret_cast<OGRStyleTable *>(hStyleTable)));
135 : }
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 1986 : OGRStyleMgr::~OGRStyleMgr()
147 : {
148 993 : CPLFree(m_pszStyleString);
149 993 : }
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 165 : void OGR_SM_Destroy(OGRStyleMgrH hSM)
163 :
164 : {
165 165 : delete reinterpret_cast<OGRStyleMgr *>(hSM);
166 165 : }
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 0 : GBool OGRStyleMgr::SetFeatureStyleString(OGRFeature *poFeature,
189 : const char *pszStyleString,
190 : GBool bNoMatching)
191 : {
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 : else
204 0 : poFeature->SetStyleString(pszStyleString);
205 :
206 0 : return TRUE;
207 : }
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 175 : const char *OGRStyleMgr::InitFromFeature(OGRFeature *poFeature)
226 : {
227 175 : CPLFree(m_pszStyleString);
228 175 : m_pszStyleString = nullptr;
229 :
230 175 : if (poFeature)
231 175 : InitStyleString(poFeature->GetStyleString());
232 : else
233 0 : m_pszStyleString = nullptr;
234 :
235 175 : return m_pszStyleString;
236 : }
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 163 : const char *OGR_SM_InitFromFeature(OGRStyleMgrH hSM, OGRFeatureH hFeat)
256 :
257 : {
258 163 : VALIDATE_POINTER1(hSM, "OGR_SM_InitFromFeature", nullptr);
259 163 : VALIDATE_POINTER1(hFeat, "OGR_SM_InitFromFeature", nullptr);
260 :
261 163 : return reinterpret_cast<OGRStyleMgr *>(hSM)->InitFromFeature(
262 163 : reinterpret_cast<OGRFeature *>(hFeat));
263 : }
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 1104 : GBool OGRStyleMgr::InitStyleString(const char *pszStyleString)
284 : {
285 1104 : CPLFree(m_pszStyleString);
286 1104 : m_pszStyleString = nullptr;
287 :
288 1104 : if (pszStyleString && pszStyleString[0] == '@')
289 : {
290 2 : const char *pszStyleStringFromName = GetStyleByName(pszStyleString + 1);
291 2 : if (pszStyleStringFromName == nullptr)
292 1 : return FALSE;
293 1 : m_pszStyleString = CPLStrdup(pszStyleStringFromName);
294 : }
295 1102 : else if (pszStyleString)
296 625 : m_pszStyleString = CPLStrdup(pszStyleString);
297 :
298 1103 : return TRUE;
299 : }
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 3 : int OGR_SM_InitStyleString(OGRStyleMgrH hSM, const char *pszStyleString)
321 :
322 : {
323 3 : VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
324 :
325 3 : return reinterpret_cast<OGRStyleMgr *>(hSM)->InitStyleString(
326 3 : pszStyleString);
327 : }
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 0 : const char *OGRStyleMgr::GetStyleName(const char *pszStyleString)
343 : {
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 : {
351 0 : if (m_poDataSetStyleTable)
352 0 : return m_poDataSetStyleTable->GetStyleName(pszStyle);
353 : }
354 0 : return nullptr;
355 : }
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 2 : const char *OGRStyleMgr::GetStyleByName(const char *pszStyleName)
371 : {
372 2 : if (m_poDataSetStyleTable)
373 : {
374 2 : return m_poDataSetStyleTable->Find(pszStyleName);
375 : }
376 0 : return nullptr;
377 : }
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 155 : GBool OGRStyleMgr::AddStyle(const char *pszStyleName,
398 : const char *pszStyleString)
399 : {
400 155 : const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
401 :
402 155 : if (m_poDataSetStyleTable)
403 : {
404 155 : return m_poDataSetStyleTable->AddStyle(pszStyleName, pszStyle);
405 : }
406 0 : return FALSE;
407 : }
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 0 : int OGR_SM_AddStyle(OGRStyleMgrH hSM, const char *pszStyleName,
427 : const char *pszStyleString)
428 : {
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 : }
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 244 : const char *OGRStyleMgr::GetStyleString(OGRFeature *poFeature)
455 : {
456 244 : if (poFeature == nullptr)
457 244 : return m_pszStyleString;
458 :
459 0 : return InitFromFeature(poFeature);
460 : }
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 0 : GBool OGRStyleMgr::AddPart(const char *pszPart)
476 : {
477 0 : if (pszPart == nullptr)
478 0 : return FALSE;
479 :
480 0 : if (m_pszStyleString)
481 : {
482 : char *pszTmp =
483 0 : CPLStrdup(CPLString().Printf("%s;%s", m_pszStyleString, pszPart));
484 0 : CPLFree(m_pszStyleString);
485 0 : m_pszStyleString = pszTmp;
486 : }
487 : else
488 : {
489 0 : char *pszTmp = CPLStrdup(CPLString().Printf("%s", pszPart));
490 0 : CPLFree(m_pszStyleString);
491 0 : m_pszStyleString = pszTmp;
492 : }
493 0 : return TRUE;
494 : }
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 343 : GBool OGRStyleMgr::AddPart(OGRStyleTool *poStyleTool)
512 : {
513 343 : if (poStyleTool == nullptr || !poStyleTool->GetStyleString())
514 0 : return FALSE;
515 :
516 343 : if (m_pszStyleString)
517 : {
518 200 : char *pszTmp = CPLStrdup(CPLString().Printf(
519 100 : "%s;%s", m_pszStyleString, poStyleTool->GetStyleString()));
520 100 : CPLFree(m_pszStyleString);
521 100 : m_pszStyleString = pszTmp;
522 : }
523 : else
524 : {
525 : char *pszTmp =
526 243 : CPLStrdup(CPLString().Printf("%s", poStyleTool->GetStyleString()));
527 243 : CPLFree(m_pszStyleString);
528 243 : m_pszStyleString = pszTmp;
529 : }
530 343 : return TRUE;
531 : }
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 0 : int OGR_SM_AddPart(OGRStyleMgrH hSM, OGRStyleToolH hST)
549 :
550 : {
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 : }
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 824 : int OGRStyleMgr::GetPartCount(const char *pszStyleString)
577 : {
578 824 : const char *pszString =
579 824 : pszStyleString != nullptr ? pszStyleString : m_pszStyleString;
580 :
581 824 : if (pszString == nullptr)
582 224 : return 0;
583 :
584 600 : int nPartCount = 1;
585 600 : const char *pszStrTmp = pszString;
586 : // Search for parts separated by semicolons not counting the possible
587 : // semicolon at the and of string.
588 600 : const char *pszPart = nullptr;
589 683 : while ((pszPart = strstr(pszStrTmp, ";")) != nullptr && pszPart[1] != '\0')
590 : {
591 83 : pszStrTmp = &pszPart[1];
592 83 : nPartCount++;
593 : }
594 600 : return nPartCount;
595 : }
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 165 : int OGR_SM_GetPartCount(OGRStyleMgrH hSM, const char *pszStyleString)
614 :
615 : {
616 165 : VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
617 :
618 165 : return reinterpret_cast<OGRStyleMgr *>(hSM)->GetPartCount(pszStyleString);
619 : }
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 516 : OGRStyleTool *OGRStyleMgr::GetPart(int nPartId, const char *pszStyleString)
644 : {
645 516 : const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
646 :
647 516 : if (pszStyle == nullptr)
648 1 : return nullptr;
649 :
650 515 : char **papszStyleString = CSLTokenizeString2(
651 : pszStyle, ";",
652 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
653 :
654 515 : const char *pszString = CSLGetField(papszStyleString, nPartId);
655 :
656 515 : OGRStyleTool *poStyleTool = nullptr;
657 515 : if (strlen(pszString) > 0)
658 : {
659 513 : poStyleTool = CreateStyleToolFromStyleString(pszString);
660 513 : if (poStyleTool)
661 513 : poStyleTool->SetStyleString(pszString);
662 : }
663 :
664 515 : CSLDestroy(papszStyleString);
665 :
666 515 : return poStyleTool;
667 : }
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 95 : OGRStyleToolH OGR_SM_GetPart(OGRStyleMgrH hSM, int nPartId,
690 : const char *pszStyleString)
691 :
692 : {
693 95 : VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", nullptr);
694 :
695 : return reinterpret_cast<OGRStyleToolH>(
696 95 : reinterpret_cast<OGRStyleMgr *>(hSM)->GetPart(nPartId, pszStyleString));
697 : }
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 513 : OGRStyleMgr::CreateStyleToolFromStyleString(const char *pszStyleString)
709 : {
710 513 : char **papszToken = CSLTokenizeString2(
711 : pszStyleString, "();",
712 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
713 513 : OGRStyleTool *poStyleTool = nullptr;
714 :
715 513 : if (CSLCount(papszToken) < 2)
716 0 : poStyleTool = nullptr;
717 513 : else if (EQUAL(papszToken[0], "PEN"))
718 141 : poStyleTool = new OGRStylePen();
719 372 : else if (EQUAL(papszToken[0], "BRUSH"))
720 48 : poStyleTool = new OGRStyleBrush();
721 324 : else if (EQUAL(papszToken[0], "SYMBOL"))
722 302 : poStyleTool = new OGRStyleSymbol();
723 22 : else if (EQUAL(papszToken[0], "LABEL"))
724 22 : poStyleTool = new OGRStyleLabel();
725 : else
726 0 : poStyleTool = nullptr;
727 :
728 513 : CSLDestroy(papszToken);
729 :
730 513 : return poStyleTool;
731 : }
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 39 : OGRStyleTable::OGRStyleTable()
745 : {
746 39 : m_papszStyleTable = nullptr;
747 39 : iNextStyle = 0;
748 39 : }
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 5 : OGRStyleTableH OGR_STBL_Create(void)
763 :
764 : {
765 5 : return reinterpret_cast<OGRStyleTableH>(new OGRStyleTable());
766 : }
767 :
768 : /****************************************************************************/
769 : /* void OGRStyleTable::Clear() */
770 : /* */
771 : /****************************************************************************/
772 :
773 : /**
774 : * \brief Clear a style table.
775 : *
776 : */
777 :
778 39 : void OGRStyleTable::Clear()
779 : {
780 39 : if (m_papszStyleTable)
781 39 : CSLDestroy(m_papszStyleTable);
782 39 : m_papszStyleTable = nullptr;
783 39 : }
784 :
785 : /****************************************************************************/
786 : /* OGRStyleTable::~OGRStyleTable() */
787 : /* */
788 : /****************************************************************************/
789 39 : OGRStyleTable::~OGRStyleTable()
790 : {
791 39 : Clear();
792 39 : }
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 5 : void OGR_STBL_Destroy(OGRStyleTableH hSTBL)
804 :
805 : {
806 5 : delete reinterpret_cast<OGRStyleTable *>(hSTBL);
807 5 : }
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 0 : const char *OGRStyleTable::GetStyleName(const char *pszStyleString)
824 : {
825 0 : for (int i = 0; i < CSLCount(m_papszStyleTable); i++)
826 : {
827 0 : const char *pszStyleStringBegin = strstr(m_papszStyleTable[i], ":");
828 :
829 0 : if (pszStyleStringBegin &&
830 0 : EQUAL(&pszStyleStringBegin[1], pszStyleString))
831 : {
832 0 : osLastRequestedStyleName = m_papszStyleTable[i];
833 0 : const size_t nColon = osLastRequestedStyleName.find(':');
834 0 : if (nColon != std::string::npos)
835 : osLastRequestedStyleName =
836 0 : osLastRequestedStyleName.substr(0, nColon);
837 :
838 0 : return osLastRequestedStyleName;
839 : }
840 : }
841 :
842 0 : return nullptr;
843 : }
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 177 : GBool OGRStyleTable::AddStyle(const char *pszName, const char *pszStyleString)
865 : {
866 177 : if (pszName == nullptr || pszStyleString == nullptr)
867 10 : return FALSE;
868 :
869 167 : const int nPos = IsExist(pszName);
870 167 : if (nPos != -1)
871 0 : return FALSE;
872 :
873 167 : m_papszStyleTable =
874 167 : CSLAddString(m_papszStyleTable,
875 334 : CPLString().Printf("%s:%s", pszName, pszStyleString));
876 167 : return TRUE;
877 : }
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 6 : int OGR_STBL_AddStyle(OGRStyleTableH hStyleTable, const char *pszName,
897 : const char *pszStyleString)
898 : {
899 6 : VALIDATE_POINTER1(hStyleTable, "OGR_STBL_AddStyle", FALSE);
900 :
901 : return reinterpret_cast<OGRStyleTable *>(hStyleTable)
902 6 : ->AddStyle(pszName, pszStyleString);
903 : }
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 1 : GBool OGRStyleTable::RemoveStyle(const char *pszName)
921 : {
922 1 : const int nPos = IsExist(pszName);
923 1 : if (nPos == -1)
924 0 : return FALSE;
925 :
926 1 : m_papszStyleTable = CSLRemoveStrings(m_papszStyleTable, nPos, 1, nullptr);
927 1 : return TRUE;
928 : }
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 0 : GBool OGRStyleTable::ModifyStyle(const char *pszName,
949 : const char *pszStyleString)
950 : {
951 0 : if (pszName == nullptr || pszStyleString == nullptr)
952 0 : return FALSE;
953 :
954 0 : RemoveStyle(pszName);
955 0 : return AddStyle(pszName, pszStyleString);
956 : }
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 2 : GBool OGRStyleTable::SaveStyleTable(const char *pszFilename)
974 : {
975 2 : if (pszFilename == nullptr)
976 0 : return FALSE;
977 :
978 2 : if (CSLSave(m_papszStyleTable, pszFilename) == 0)
979 1 : return FALSE;
980 :
981 1 : return TRUE;
982 : }
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 2 : int OGR_STBL_SaveStyleTable(OGRStyleTableH hStyleTable, const char *pszFilename)
1000 : {
1001 2 : VALIDATE_POINTER1(hStyleTable, "OGR_STBL_SaveStyleTable", FALSE);
1002 2 : VALIDATE_POINTER1(pszFilename, "OGR_STBL_SaveStyleTable", FALSE);
1003 :
1004 : return reinterpret_cast<OGRStyleTable *>(hStyleTable)
1005 2 : ->SaveStyleTable(pszFilename);
1006 : }
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 2 : GBool OGRStyleTable::LoadStyleTable(const char *pszFilename)
1024 : {
1025 2 : if (pszFilename == nullptr)
1026 0 : return FALSE;
1027 :
1028 2 : CSLDestroy(m_papszStyleTable);
1029 :
1030 2 : m_papszStyleTable = CSLLoad(pszFilename);
1031 :
1032 2 : return m_papszStyleTable != nullptr;
1033 : }
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 2 : int OGR_STBL_LoadStyleTable(OGRStyleTableH hStyleTable, const char *pszFilename)
1051 : {
1052 2 : VALIDATE_POINTER1(hStyleTable, "OGR_STBL_LoadStyleTable", FALSE);
1053 2 : VALIDATE_POINTER1(pszFilename, "OGR_STBL_LoadStyleTable", FALSE);
1054 :
1055 : return reinterpret_cast<OGRStyleTable *>(hStyleTable)
1056 2 : ->LoadStyleTable(pszFilename);
1057 : }
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 66 : const char *OGRStyleTable::Find(const char *pszName)
1075 : {
1076 66 : const int nPos = IsExist(pszName);
1077 66 : if (nPos == -1)
1078 4 : return nullptr;
1079 :
1080 62 : const char *pszOutput = CSLGetField(m_papszStyleTable, nPos);
1081 :
1082 62 : const char *pszDash = strstr(pszOutput, ":");
1083 :
1084 62 : if (pszDash == nullptr)
1085 0 : return nullptr;
1086 :
1087 62 : return &pszDash[1];
1088 : }
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 2 : const char *OGR_STBL_Find(OGRStyleTableH hStyleTable, const char *pszName)
1106 : {
1107 2 : VALIDATE_POINTER1(hStyleTable, "OGR_STBL_Find", nullptr);
1108 2 : VALIDATE_POINTER1(pszName, "OGR_STBL_Find", nullptr);
1109 :
1110 2 : return reinterpret_cast<OGRStyleTable *>(hStyleTable)->Find(pszName);
1111 : }
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 0 : void OGRStyleTable::Print(FILE *fpOut)
1126 : {
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 : {
1132 0 : CSLPrint(m_papszStyleTable, fpOut);
1133 : }
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 234 : int OGRStyleTable::IsExist(const char *pszName)
1151 : {
1152 234 : if (pszName == nullptr)
1153 0 : return -1;
1154 :
1155 234 : const int nCount = CSLCount(m_papszStyleTable);
1156 234 : const char *pszNewString = CPLSPrintf("%s:", pszName);
1157 :
1158 942 : for (int i = 0; i < nCount; i++)
1159 : {
1160 771 : if (strstr(m_papszStyleTable[i], pszNewString) != nullptr)
1161 : {
1162 63 : return i;
1163 : }
1164 : }
1165 :
1166 171 : return -1;
1167 : }
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 6 : OGRStyleTable *OGRStyleTable::Clone()
1183 :
1184 : {
1185 6 : OGRStyleTable *poNew = new OGRStyleTable();
1186 :
1187 6 : poNew->m_papszStyleTable = CSLDuplicate(m_papszStyleTable);
1188 :
1189 6 : return poNew;
1190 : }
1191 :
1192 : /************************************************************************/
1193 : /* ResetStyleStringReading() */
1194 : /************************************************************************/
1195 :
1196 : /** Reset the next style pointer to 0 */
1197 9 : void OGRStyleTable::ResetStyleStringReading()
1198 :
1199 : {
1200 9 : iNextStyle = 0;
1201 9 : }
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 1 : void OGR_STBL_ResetStyleStringReading(OGRStyleTableH hStyleTable)
1218 : {
1219 1 : VALIDATE_POINTER0(hStyleTable, "OGR_STBL_ResetStyleStringReading");
1220 :
1221 1 : reinterpret_cast<OGRStyleTable *>(hStyleTable)->ResetStyleStringReading();
1222 : }
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 33 : const char *OGRStyleTable::GetNextStyle()
1235 : {
1236 33 : while (iNextStyle < CSLCount(m_papszStyleTable))
1237 : {
1238 24 : const char *pszOutput = CSLGetField(m_papszStyleTable, iNextStyle++);
1239 24 : if (pszOutput == nullptr)
1240 0 : continue;
1241 :
1242 24 : const char *pszDash = strstr(pszOutput, ":");
1243 :
1244 24 : osLastRequestedStyleName = pszOutput;
1245 24 : const size_t nColon = osLastRequestedStyleName.find(':');
1246 24 : if (nColon != std::string::npos)
1247 : osLastRequestedStyleName =
1248 24 : osLastRequestedStyleName.substr(0, nColon);
1249 :
1250 24 : if (pszDash)
1251 24 : return pszDash + 1;
1252 : }
1253 9 : return nullptr;
1254 : }
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 5 : const char *OGR_STBL_GetNextStyle(OGRStyleTableH hStyleTable)
1271 : {
1272 5 : VALIDATE_POINTER1(hStyleTable, "OGR_STBL_GetNextStyle", nullptr);
1273 :
1274 5 : return reinterpret_cast<OGRStyleTable *>(hStyleTable)->GetNextStyle();
1275 : }
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 21 : const char *OGRStyleTable::GetLastStyleName()
1289 : {
1290 21 : return osLastRequestedStyleName;
1291 : }
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 1 : const char *OGR_STBL_GetLastStyleName(OGRStyleTableH hStyleTable)
1309 : {
1310 1 : VALIDATE_POINTER1(hStyleTable, "OGR_STBL_GetLastStyleName", nullptr);
1311 :
1312 1 : return reinterpret_cast<OGRStyleTable *>(hStyleTable)->GetLastStyleName();
1313 : }
1314 :
1315 : /****************************************************************************/
1316 : /* OGRStyleTool::OGRStyleTool() */
1317 : /* */
1318 : /****************************************************************************/
1319 :
1320 : /** Constructor */
1321 766 : OGRStyleTool::OGRStyleTool(OGRSTClassId eClassId) : m_eClassId(eClassId)
1322 : {
1323 766 : }
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 0 : OGRStyleToolH OGR_ST_Create(OGRSTClassId eClassId)
1341 :
1342 : {
1343 0 : switch (eClassId)
1344 : {
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 : }
1356 : }
1357 :
1358 : /****************************************************************************/
1359 : /* OGRStyleTool::~OGRStyleTool() */
1360 : /* */
1361 : /****************************************************************************/
1362 1532 : OGRStyleTool::~OGRStyleTool()
1363 : {
1364 766 : CPLFree(m_pszStyleString);
1365 766 : }
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 93 : void OGR_ST_Destroy(OGRStyleToolH hST)
1377 :
1378 : {
1379 93 : delete reinterpret_cast<OGRStyleTool *>(hST);
1380 93 : }
1381 :
1382 : /****************************************************************************/
1383 : /* void OGRStyleTool::SetStyleString(const char *pszStyleString) */
1384 : /* */
1385 : /****************************************************************************/
1386 :
1387 : /** Undocumented
1388 : * @param pszStyleString undocumented.
1389 : */
1390 513 : void OGRStyleTool::SetStyleString(const char *pszStyleString)
1391 : {
1392 513 : m_pszStyleString = CPLStrdup(pszStyleString);
1393 513 : }
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 686 : const char *OGRStyleTool::GetStyleString(const OGRStyleParamId *pasStyleParam,
1408 : OGRStyleValue *pasStyleValue,
1409 : int nSize)
1410 : {
1411 686 : if (IsStyleModified())
1412 : {
1413 243 : CPLFree(m_pszStyleString);
1414 :
1415 243 : const char *pszClass = nullptr;
1416 243 : switch (GetType())
1417 : {
1418 103 : case OGRSTCPen:
1419 103 : pszClass = "PEN(";
1420 103 : break;
1421 83 : case OGRSTCBrush:
1422 83 : pszClass = "BRUSH(";
1423 83 : break;
1424 52 : case OGRSTCSymbol:
1425 52 : pszClass = "SYMBOL(";
1426 52 : break;
1427 5 : case OGRSTCLabel:
1428 5 : pszClass = "LABEL(";
1429 5 : break;
1430 0 : default:
1431 0 : pszClass = "UNKNOWN(";
1432 : }
1433 :
1434 243 : CPLString osCurrent = pszClass;
1435 :
1436 243 : bool bFound = false;
1437 2460 : for (int i = 0; i < nSize; i++)
1438 : {
1439 2217 : if (!pasStyleValue[i].bValid ||
1440 302 : pasStyleParam[i].eType == OGRSTypeUnused)
1441 : {
1442 1915 : continue;
1443 : }
1444 :
1445 302 : if (bFound)
1446 59 : osCurrent += ",";
1447 302 : bFound = true;
1448 :
1449 302 : osCurrent += pasStyleParam[i].pszToken;
1450 302 : switch (pasStyleParam[i].eType)
1451 : {
1452 204 : case OGRSTypeString:
1453 204 : osCurrent += ":";
1454 204 : osCurrent += pasStyleValue[i].pszValue;
1455 204 : break;
1456 98 : case OGRSTypeDouble:
1457 : osCurrent +=
1458 98 : CPLString().Printf(":%f", pasStyleValue[i].dfValue);
1459 98 : break;
1460 0 : case OGRSTypeInteger:
1461 : osCurrent +=
1462 0 : CPLString().Printf(":%d", pasStyleValue[i].nValue);
1463 0 : break;
1464 0 : case OGRSTypeBoolean:
1465 : osCurrent +=
1466 0 : CPLString().Printf(":%d", pasStyleValue[i].nValue != 0);
1467 0 : break;
1468 0 : default:
1469 0 : break;
1470 : }
1471 302 : if (pasStyleParam[i].bGeoref)
1472 90 : switch (pasStyleValue[i].eUnit)
1473 : {
1474 0 : case OGRSTUGround:
1475 0 : osCurrent += "g";
1476 0 : break;
1477 83 : case OGRSTUPixel:
1478 83 : osCurrent += "px";
1479 83 : 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 7 : case OGRSTUMM:
1490 : // osCurrent += "mm";
1491 : default:
1492 7 : break; // imp
1493 : }
1494 : }
1495 243 : osCurrent += ")";
1496 :
1497 243 : m_pszStyleString = CPLStrdup(osCurrent);
1498 :
1499 243 : m_bModified = FALSE;
1500 : }
1501 :
1502 686 : return m_pszStyleString;
1503 : }
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 23 : GBool OGRStyleTool::GetRGBFromString(const char *pszColor, int &nRed,
1525 : int &nGreen, int &nBlue,
1526 : int &nTransparance)
1527 : {
1528 23 : int nCount = 0;
1529 :
1530 23 : nTransparance = 255;
1531 :
1532 : // FIXME: should we really use sscanf here?
1533 23 : unsigned int unRed = 0;
1534 23 : unsigned int unGreen = 0;
1535 23 : unsigned int unBlue = 0;
1536 23 : unsigned int unTransparance = 0;
1537 23 : if (pszColor)
1538 23 : nCount = sscanf(pszColor, "#%2x%2x%2x%2x", &unRed, &unGreen, &unBlue,
1539 : &unTransparance);
1540 23 : nRed = static_cast<int>(unRed);
1541 23 : nGreen = static_cast<int>(unGreen);
1542 23 : nBlue = static_cast<int>(unBlue);
1543 23 : if (nCount == 4)
1544 18 : nTransparance = static_cast<int>(unTransparance);
1545 23 : return nCount >= 3;
1546 : }
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 0 : int OGRStyleTool::GetSpecificId(const char *pszId, const char *pszWanted)
1562 : {
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 : {
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 : }
1581 :
1582 0 : return nValue;
1583 : }
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 1780 : OGRSTClassId OGRStyleTool::GetType()
1597 : {
1598 1780 : return m_eClassId;
1599 : }
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 339 : OGRSTClassId OGR_ST_GetType(OGRStyleToolH hST)
1615 :
1616 : {
1617 339 : VALIDATE_POINTER1(hST, "OGR_ST_GetType", OGRSTCNone);
1618 339 : return reinterpret_cast<OGRStyleTool *>(hST)->GetType();
1619 : }
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 2 : OGRSTUnitId OGR_ST_GetUnit(OGRStyleToolH hST)
1641 :
1642 : {
1643 2 : VALIDATE_POINTER1(hST, "OGR_ST_GetUnit", OGRSTUGround);
1644 2 : return reinterpret_cast<OGRStyleTool *>(hST)->GetUnit();
1645 : }
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 708 : void OGRStyleTool::SetUnit(OGRSTUnitId eUnit, double dfGroundPaperScale)
1659 : {
1660 708 : m_eUnit = eUnit;
1661 708 : m_dfScale = dfGroundPaperScale;
1662 708 : }
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 93 : void OGR_ST_SetUnit(OGRStyleToolH hST, OGRSTUnitId eUnit,
1679 : double dfGroundPaperScale)
1680 :
1681 : {
1682 93 : VALIDATE_POINTER0(hST, "OGR_ST_SetUnit");
1683 93 : reinterpret_cast<OGRStyleTool *>(hST)->SetUnit(eUnit, dfGroundPaperScale);
1684 : }
1685 :
1686 : /************************************************************************/
1687 : /* Parse() */
1688 : /************************************************************************/
1689 :
1690 : //! @cond Doxygen_Suppress
1691 2920 : GBool OGRStyleTool::Parse(const OGRStyleParamId *pasStyle,
1692 : OGRStyleValue *pasValue, int nCount)
1693 : {
1694 2920 : if (IsStyleParsed())
1695 2283 : return TRUE;
1696 :
1697 637 : StyleParsed();
1698 :
1699 637 : if (m_pszStyleString == nullptr)
1700 243 : 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 788 : char **papszToken = CSLTokenizeString2(
1706 394 : m_pszStyleString, "()",
1707 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
1708 :
1709 394 : if (CSLCount(papszToken) > 2 || CSLCount(papszToken) == 0)
1710 : {
1711 0 : CSLDestroy(papszToken);
1712 0 : CPLError(CE_Failure, CPLE_AppDefined,
1713 : "Error in the format of the StyleTool %s", m_pszStyleString);
1714 0 : return FALSE;
1715 : }
1716 :
1717 : // Token that will contains StyleString elements.
1718 : // Tokenize the content of the StyleString to get paired components in it.
1719 788 : char **papszToken2 = CSLTokenizeString2(
1720 394 : papszToken[1], ",",
1721 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
1722 :
1723 : // Valid that we have the right StyleString for this feature type.
1724 394 : switch (GetType())
1725 : {
1726 46 : case OGRSTCPen:
1727 46 : if (!EQUAL(papszToken[0], "PEN"))
1728 : {
1729 0 : CPLError(
1730 : CE_Failure, CPLE_AppDefined,
1731 : "Error in the Type of StyleTool %s should be a PEN Type",
1732 : papszToken[0]);
1733 0 : CSLDestroy(papszToken);
1734 0 : CSLDestroy(papszToken2);
1735 0 : return FALSE;
1736 : }
1737 46 : break;
1738 27 : case OGRSTCBrush:
1739 27 : if (!EQUAL(papszToken[0], "BRUSH"))
1740 : {
1741 0 : CPLError(
1742 : CE_Failure, CPLE_AppDefined,
1743 : "Error in the Type of StyleTool %s should be a BRUSH Type",
1744 : papszToken[0]);
1745 0 : CSLDestroy(papszToken);
1746 0 : CSLDestroy(papszToken2);
1747 0 : return FALSE;
1748 : }
1749 27 : break;
1750 299 : case OGRSTCSymbol:
1751 299 : if (!EQUAL(papszToken[0], "SYMBOL"))
1752 : {
1753 0 : CPLError(CE_Failure, CPLE_AppDefined,
1754 : "Error in the Type of StyleTool %s should be "
1755 : "a SYMBOL Type",
1756 : papszToken[0]);
1757 0 : CSLDestroy(papszToken);
1758 0 : CSLDestroy(papszToken2);
1759 0 : return FALSE;
1760 : }
1761 299 : break;
1762 22 : case OGRSTCLabel:
1763 22 : if (!EQUAL(papszToken[0], "LABEL"))
1764 : {
1765 0 : CPLError(
1766 : CE_Failure, CPLE_AppDefined,
1767 : "Error in the Type of StyleTool %s should be a LABEL Type",
1768 : papszToken[0]);
1769 0 : CSLDestroy(papszToken);
1770 0 : CSLDestroy(papszToken2);
1771 0 : return FALSE;
1772 : }
1773 22 : break;
1774 0 : default:
1775 0 : CPLError(CE_Failure, CPLE_AppDefined,
1776 : "Error in the Type of StyleTool, Type undetermined");
1777 0 : CSLDestroy(papszToken);
1778 0 : CSLDestroy(papszToken2);
1779 0 : return FALSE;
1780 : break;
1781 : }
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 394 : OGRSTUnitId eLastUnit = m_eUnit;
1806 394 : double dSavedScale = m_dfScale;
1807 394 : const int nElements = CSLCount(papszToken2);
1808 :
1809 1851 : for (int i = 0; i < nElements; i++)
1810 : {
1811 : char **papszStylePair =
1812 1457 : CSLTokenizeString2(papszToken2[i], ":",
1813 : CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES |
1814 : CSLT_STRIPENDSPACES | CSLT_ALLOWEMPTYTOKENS);
1815 :
1816 1457 : const int nTokens = CSLCount(papszStylePair);
1817 :
1818 1457 : if (nTokens < 1 || nTokens > 2)
1819 : {
1820 0 : CPLError(CE_Warning, CPLE_AppDefined,
1821 : "Error in the StyleTool String %s", m_pszStyleString);
1822 0 : CPLError(CE_Warning, CPLE_AppDefined,
1823 : "Malformed element #%d (\"%s\") skipped", i,
1824 0 : papszToken2[i]);
1825 0 : CSLDestroy(papszStylePair);
1826 0 : continue;
1827 : }
1828 :
1829 4179 : for (int j = 0; j < nCount; j++)
1830 : {
1831 4179 : if (pasStyle[j].pszToken &&
1832 4177 : EQUAL(pasStyle[j].pszToken, papszStylePair[0]))
1833 : {
1834 1457 : if (papszStylePair[1] != nullptr && pasStyle[j].bGeoref == TRUE)
1835 360 : 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 1457 : OGRStyleTool::SetParamStr(
1841 1457 : pasStyle[j], pasValue[j],
1842 1457 : papszStylePair[1] != nullptr ? papszStylePair[1] : "1");
1843 :
1844 1457 : break;
1845 : }
1846 : }
1847 :
1848 1457 : CSLDestroy(papszStylePair);
1849 : }
1850 :
1851 394 : m_eUnit = eLastUnit;
1852 394 : m_dfScale = dSavedScale;
1853 :
1854 394 : CSLDestroy(papszToken2);
1855 394 : CSLDestroy(papszToken);
1856 :
1857 394 : return TRUE;
1858 : }
1859 :
1860 : //! @endcond
1861 :
1862 : /************************************************************************/
1863 : /* SetInternalInputUnitFromParam() */
1864 : /************************************************************************/
1865 :
1866 : //! @cond Doxygen_Suppress
1867 360 : void OGRStyleTool::SetInternalInputUnitFromParam(char *pszString)
1868 : {
1869 360 : if (pszString == nullptr)
1870 0 : return;
1871 :
1872 360 : char *pszUnit = strstr(pszString, "g");
1873 360 : if (pszUnit)
1874 : {
1875 8 : SetUnit(OGRSTUGround);
1876 8 : pszUnit[0] = '\0';
1877 8 : return;
1878 : }
1879 352 : pszUnit = strstr(pszString, "px");
1880 352 : if (pszUnit)
1881 : {
1882 37 : SetUnit(OGRSTUPixel);
1883 37 : pszUnit[0] = '\0';
1884 37 : return;
1885 : }
1886 315 : pszUnit = strstr(pszString, "pt");
1887 315 : if (pszUnit)
1888 : {
1889 234 : SetUnit(OGRSTUPoints);
1890 234 : pszUnit[0] = '\0';
1891 234 : return;
1892 : }
1893 81 : pszUnit = strstr(pszString, "mm");
1894 81 : if (pszUnit)
1895 : {
1896 1 : SetUnit(OGRSTUMM);
1897 1 : pszUnit[0] = '\0';
1898 1 : return;
1899 : }
1900 80 : pszUnit = strstr(pszString, "cm");
1901 80 : if (pszUnit)
1902 : {
1903 0 : SetUnit(OGRSTUCM);
1904 0 : pszUnit[0] = '\0';
1905 0 : return;
1906 : }
1907 80 : pszUnit = strstr(pszString, "in");
1908 80 : if (pszUnit)
1909 : {
1910 0 : SetUnit(OGRSTUInches);
1911 0 : pszUnit[0] = '\0';
1912 0 : return;
1913 : }
1914 :
1915 80 : SetUnit(OGRSTUMM);
1916 : }
1917 :
1918 : /************************************************************************/
1919 : /* ComputeWithUnit() */
1920 : /************************************************************************/
1921 281 : double OGRStyleTool::ComputeWithUnit(double dfValue, OGRSTUnitId eInputUnit)
1922 : {
1923 281 : OGRSTUnitId eOutputUnit = GetUnit();
1924 :
1925 281 : double dfNewValue = dfValue; // dfValue in meters;
1926 :
1927 281 : if (eOutputUnit == eInputUnit)
1928 197 : return dfValue;
1929 :
1930 84 : switch (eInputUnit)
1931 : {
1932 5 : case OGRSTUGround:
1933 5 : dfNewValue = dfValue / m_dfScale;
1934 5 : break;
1935 62 : case OGRSTUPixel:
1936 62 : dfNewValue = dfValue / (72.0 * 39.37);
1937 62 : break;
1938 16 : case OGRSTUPoints:
1939 16 : dfNewValue = dfValue / (72.0 * 39.37);
1940 16 : break;
1941 1 : case OGRSTUMM:
1942 1 : dfNewValue = 0.001 * dfValue;
1943 1 : 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 : }
1953 :
1954 84 : switch (eOutputUnit)
1955 : {
1956 2 : case OGRSTUGround:
1957 2 : dfNewValue *= m_dfScale;
1958 2 : break;
1959 0 : case OGRSTUPixel:
1960 0 : dfNewValue *= 72.0 * 39.37;
1961 0 : break;
1962 58 : case OGRSTUPoints:
1963 58 : dfNewValue *= 72.0 * 39.37;
1964 58 : break;
1965 24 : case OGRSTUMM:
1966 24 : dfNewValue *= 1000.0;
1967 24 : 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 : }
1977 84 : return dfNewValue;
1978 : }
1979 :
1980 : /************************************************************************/
1981 : /* ComputeWithUnit() */
1982 : /************************************************************************/
1983 0 : int OGRStyleTool::ComputeWithUnit(int nValue, OGRSTUnitId eUnit)
1984 : {
1985 : return static_cast<int>(
1986 0 : ComputeWithUnit(static_cast<double>(nValue), eUnit));
1987 : }
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 723 : const char *OGRStyleTool::GetParamStr(const OGRStyleParamId &sStyleParam,
2002 : const OGRStyleValue &sStyleValue,
2003 : GBool &bValueIsNull)
2004 : {
2005 723 : if (!Parse())
2006 : {
2007 0 : bValueIsNull = TRUE;
2008 0 : return nullptr;
2009 : }
2010 :
2011 723 : bValueIsNull = !sStyleValue.bValid;
2012 :
2013 723 : if (bValueIsNull == TRUE)
2014 38 : return nullptr;
2015 :
2016 685 : switch (sStyleParam.eType)
2017 : {
2018 : // If sStyleParam.bGeoref == TRUE, need to convert to output value.
2019 685 : case OGRSTypeString:
2020 685 : 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 : 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 : 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 : }
2040 : }
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 58 : int OGRStyleTool::GetParamNum(const OGRStyleParamId &sStyleParam,
2056 : const OGRStyleValue &sStyleValue,
2057 : GBool &bValueIsNull)
2058 : {
2059 : return static_cast<int>(
2060 58 : GetParamDbl(sStyleParam, sStyleValue, bValueIsNull));
2061 : }
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 438 : double OGRStyleTool::GetParamDbl(const OGRStyleParamId &sStyleParam,
2077 : const OGRStyleValue &sStyleValue,
2078 : GBool &bValueIsNull)
2079 : {
2080 438 : if (!Parse())
2081 : {
2082 0 : bValueIsNull = TRUE;
2083 0 : return 0.0;
2084 : }
2085 :
2086 438 : bValueIsNull = !sStyleValue.bValid;
2087 :
2088 438 : if (bValueIsNull == TRUE)
2089 123 : return 0.0;
2090 :
2091 315 : switch (sStyleParam.eType)
2092 : {
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 : else
2099 0 : return CPLAtof(sStyleValue.pszValue);
2100 300 : case OGRSTypeDouble:
2101 300 : if (sStyleParam.bGeoref)
2102 281 : return ComputeWithUnit(sStyleValue.dfValue, sStyleValue.eUnit);
2103 : else
2104 19 : return sStyleValue.dfValue;
2105 9 : case OGRSTypeInteger:
2106 9 : if (sStyleParam.bGeoref)
2107 : return static_cast<double>(
2108 0 : ComputeWithUnit(sStyleValue.nValue, sStyleValue.eUnit));
2109 : else
2110 9 : return static_cast<double>(sStyleValue.nValue);
2111 6 : case OGRSTypeBoolean:
2112 6 : return static_cast<double>(sStyleValue.nValue != 0);
2113 0 : default:
2114 0 : bValueIsNull = TRUE;
2115 0 : return 0.0;
2116 : }
2117 : }
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 1661 : void OGRStyleTool::SetParamStr(const OGRStyleParamId &sStyleParam,
2132 : OGRStyleValue &sStyleValue,
2133 : const char *pszParamString)
2134 : {
2135 1661 : Parse();
2136 1661 : StyleModified();
2137 1661 : sStyleValue.bValid = TRUE;
2138 1661 : sStyleValue.eUnit = GetUnit();
2139 1661 : switch (sStyleParam.eType)
2140 : {
2141 : // If sStyleParam.bGeoref == TRUE, need to convert to output value;
2142 1049 : case OGRSTypeString:
2143 1049 : sStyleValue.pszValue = CPLStrdup(pszParamString);
2144 1049 : break;
2145 597 : case OGRSTypeDouble:
2146 597 : sStyleValue.dfValue = CPLAtof(pszParamString);
2147 597 : break;
2148 9 : case OGRSTypeInteger:
2149 9 : sStyleValue.nValue = atoi(pszParamString);
2150 9 : break;
2151 6 : case OGRSTypeBoolean:
2152 6 : sStyleValue.nValue = atoi(pszParamString) != 0;
2153 6 : break;
2154 0 : default:
2155 0 : sStyleValue.bValid = FALSE;
2156 0 : break;
2157 : }
2158 1661 : }
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 0 : void OGRStyleTool::SetParamNum(const OGRStyleParamId &sStyleParam,
2173 : OGRStyleValue &sStyleValue, int nParam)
2174 : {
2175 0 : Parse();
2176 0 : StyleModified();
2177 0 : sStyleValue.bValid = TRUE;
2178 0 : sStyleValue.eUnit = GetUnit();
2179 0 : switch (sStyleParam.eType)
2180 : {
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 : }
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 98 : void OGRStyleTool::SetParamDbl(const OGRStyleParamId &sStyleParam,
2214 : OGRStyleValue &sStyleValue, double dfParam)
2215 : {
2216 98 : Parse();
2217 98 : StyleModified();
2218 98 : sStyleValue.bValid = TRUE;
2219 98 : sStyleValue.eUnit = GetUnit();
2220 98 : switch (sStyleParam.eType)
2221 : {
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 98 : case OGRSTypeDouble:
2227 98 : sStyleValue.dfValue = dfParam;
2228 98 : 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 : }
2239 98 : }
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 195 : const char *OGR_ST_GetParamStr(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2260 : {
2261 195 : VALIDATE_POINTER1(hST, "OGR_ST_GetParamStr", "");
2262 195 : VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamStr", "");
2263 :
2264 195 : GBool bIsNull = TRUE;
2265 195 : const char *pszVal = "";
2266 :
2267 195 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2268 : {
2269 8 : case OGRSTCPen:
2270 8 : pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamStr(
2271 : static_cast<OGRSTPenParam>(eParam), bIsNull);
2272 8 : break;
2273 2 : case OGRSTCBrush:
2274 2 : pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamStr(
2275 : static_cast<OGRSTBrushParam>(eParam), bIsNull);
2276 2 : break;
2277 146 : case OGRSTCSymbol:
2278 146 : pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamStr(
2279 : static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2280 146 : break;
2281 39 : case OGRSTCLabel:
2282 39 : pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamStr(
2283 : static_cast<OGRSTLabelParam>(eParam), bIsNull);
2284 39 : break;
2285 0 : default:
2286 0 : break;
2287 : }
2288 :
2289 195 : *bValueIsNull = bIsNull;
2290 195 : return pszVal;
2291 : }
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 39 : int OGR_ST_GetParamNum(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2312 : {
2313 39 : VALIDATE_POINTER1(hST, "OGR_ST_GetParamNum", 0);
2314 39 : VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamNum", 0);
2315 :
2316 39 : GBool bIsNull = TRUE;
2317 39 : int nVal = 0;
2318 :
2319 39 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2320 : {
2321 0 : case OGRSTCPen:
2322 0 : nVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamNum(
2323 : static_cast<OGRSTPenParam>(eParam), bIsNull);
2324 0 : break;
2325 0 : case OGRSTCBrush:
2326 0 : nVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamNum(
2327 : static_cast<OGRSTBrushParam>(eParam), bIsNull);
2328 0 : break;
2329 0 : case OGRSTCSymbol:
2330 0 : nVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamNum(
2331 : static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2332 0 : break;
2333 39 : case OGRSTCLabel:
2334 39 : nVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamNum(
2335 : static_cast<OGRSTLabelParam>(eParam), bIsNull);
2336 39 : break;
2337 0 : default:
2338 0 : break;
2339 : }
2340 :
2341 39 : *bValueIsNull = bIsNull;
2342 39 : return nVal;
2343 : }
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 144 : double OGR_ST_GetParamDbl(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2364 : {
2365 144 : VALIDATE_POINTER1(hST, "OGR_ST_GetParamDbl", 0.0);
2366 144 : VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamDbl", 0.0);
2367 :
2368 144 : GBool bIsNull = TRUE;
2369 144 : double dfVal = 0.0;
2370 :
2371 144 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2372 : {
2373 6 : case OGRSTCPen:
2374 6 : dfVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamDbl(
2375 : static_cast<OGRSTPenParam>(eParam), bIsNull);
2376 6 : break;
2377 0 : case OGRSTCBrush:
2378 0 : dfVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamDbl(
2379 : static_cast<OGRSTBrushParam>(eParam), bIsNull);
2380 0 : break;
2381 73 : case OGRSTCSymbol:
2382 73 : dfVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamDbl(
2383 : static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2384 73 : break;
2385 65 : case OGRSTCLabel:
2386 65 : dfVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamDbl(
2387 : static_cast<OGRSTLabelParam>(eParam), bIsNull);
2388 65 : break;
2389 0 : default:
2390 0 : break;
2391 : }
2392 :
2393 144 : *bValueIsNull = bIsNull;
2394 144 : return dfVal;
2395 : }
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 0 : void OGR_ST_SetParamStr(OGRStyleToolH hST, int eParam, const char *pszValue)
2414 : {
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 : {
2420 0 : case OGRSTCPen:
2421 0 : reinterpret_cast<OGRStylePen *>(hST)->SetParamStr(
2422 : static_cast<OGRSTPenParam>(eParam), pszValue);
2423 0 : break;
2424 0 : case OGRSTCBrush:
2425 0 : reinterpret_cast<OGRStyleBrush *>(hST)->SetParamStr(
2426 : static_cast<OGRSTBrushParam>(eParam), pszValue);
2427 0 : break;
2428 0 : case OGRSTCSymbol:
2429 0 : reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamStr(
2430 : static_cast<OGRSTSymbolParam>(eParam), pszValue);
2431 0 : break;
2432 0 : case OGRSTCLabel:
2433 0 : reinterpret_cast<OGRStyleLabel *>(hST)->SetParamStr(
2434 : static_cast<OGRSTLabelParam>(eParam), pszValue);
2435 0 : break;
2436 0 : default:
2437 0 : break;
2438 : }
2439 : }
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 0 : void OGR_ST_SetParamNum(OGRStyleToolH hST, int eParam, int nValue)
2458 : {
2459 0 : VALIDATE_POINTER0(hST, "OGR_ST_SetParamNum");
2460 :
2461 0 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2462 : {
2463 0 : case OGRSTCPen:
2464 0 : reinterpret_cast<OGRStylePen *>(hST)->SetParamNum(
2465 : static_cast<OGRSTPenParam>(eParam), nValue);
2466 0 : break;
2467 0 : case OGRSTCBrush:
2468 0 : reinterpret_cast<OGRStyleBrush *>(hST)->SetParamNum(
2469 : static_cast<OGRSTBrushParam>(eParam), nValue);
2470 0 : break;
2471 0 : case OGRSTCSymbol:
2472 0 : reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamNum(
2473 : static_cast<OGRSTSymbolParam>(eParam), nValue);
2474 0 : break;
2475 0 : case OGRSTCLabel:
2476 0 : reinterpret_cast<OGRStyleLabel *>(hST)->SetParamNum(
2477 : static_cast<OGRSTLabelParam>(eParam), nValue);
2478 0 : break;
2479 0 : default:
2480 0 : break;
2481 : }
2482 : }
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 0 : void OGR_ST_SetParamDbl(OGRStyleToolH hST, int eParam, double dfValue)
2501 : {
2502 0 : VALIDATE_POINTER0(hST, "OGR_ST_SetParamDbl");
2503 :
2504 0 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2505 : {
2506 0 : case OGRSTCPen:
2507 0 : reinterpret_cast<OGRStylePen *>(hST)->SetParamDbl(
2508 : static_cast<OGRSTPenParam>(eParam), dfValue);
2509 0 : break;
2510 0 : case OGRSTCBrush:
2511 0 : reinterpret_cast<OGRStyleBrush *>(hST)->SetParamDbl(
2512 : static_cast<OGRSTBrushParam>(eParam), dfValue);
2513 0 : break;
2514 0 : case OGRSTCSymbol:
2515 0 : reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamDbl(
2516 : static_cast<OGRSTSymbolParam>(eParam), dfValue);
2517 0 : break;
2518 0 : case OGRSTCLabel:
2519 0 : reinterpret_cast<OGRStyleLabel *>(hST)->SetParamDbl(
2520 : static_cast<OGRSTLabelParam>(eParam), dfValue);
2521 0 : break;
2522 0 : default:
2523 0 : break;
2524 : }
2525 : }
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 0 : const char *OGR_ST_GetStyleString(OGRStyleToolH hST)
2551 : {
2552 0 : const char *pszVal = "";
2553 :
2554 0 : VALIDATE_POINTER1(hST, "OGR_ST_GetStyleString", "");
2555 :
2556 0 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2557 : {
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 : }
2573 :
2574 0 : return pszVal;
2575 : }
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 0 : int OGR_ST_GetRGBFromString(OGRStyleToolH hST, const char *pszColor, int *pnRed,
2599 : int *pnGreen, int *pnBlue, int *pnAlpha)
2600 : {
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 : }
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 254 : OGRStylePen::OGRStylePen()
2623 : : OGRStyleTool(OGRSTCPen),
2624 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2625 254 : CPLCalloc(OGRSTPenLast, sizeof(OGRStyleValue))))
2626 : {
2627 254 : }
2628 :
2629 : /****************************************************************************/
2630 : /* OGRStylePen::~OGRStylePen() */
2631 : /* */
2632 : /****************************************************************************/
2633 498 : OGRStylePen::~OGRStylePen()
2634 : {
2635 2286 : for (int i = 0; i < OGRSTPenLast; i++)
2636 : {
2637 2032 : if (m_pasStyleValue[i].pszValue != nullptr)
2638 : {
2639 194 : CPLFree(m_pasStyleValue[i].pszValue);
2640 194 : m_pasStyleValue[i].pszValue = nullptr;
2641 : }
2642 : }
2643 :
2644 254 : CPLFree(m_pasStyleValue);
2645 498 : }
2646 :
2647 : /************************************************************************/
2648 : /* OGRStylePen::Parse() */
2649 : /************************************************************************/
2650 484 : GBool OGRStylePen::Parse()
2651 :
2652 : {
2653 484 : return OGRStyleTool::Parse(asStylePen, m_pasStyleValue,
2654 484 : static_cast<int>(OGRSTPenLast));
2655 : }
2656 :
2657 : /************************************************************************/
2658 : /* GetParamStr() */
2659 : /************************************************************************/
2660 90 : const char *OGRStylePen::GetParamStr(OGRSTPenParam eParam, GBool &bValueIsNull)
2661 : {
2662 180 : return OGRStyleTool::GetParamStr(asStylePen[eParam],
2663 90 : m_pasStyleValue[eParam], bValueIsNull);
2664 : }
2665 :
2666 : /************************************************************************/
2667 : /* GetParamNum() */
2668 : /************************************************************************/
2669 0 : int OGRStylePen::GetParamNum(OGRSTPenParam eParam, GBool &bValueIsNull)
2670 : {
2671 0 : return OGRStyleTool::GetParamNum(asStylePen[eParam],
2672 0 : m_pasStyleValue[eParam], bValueIsNull);
2673 : }
2674 :
2675 : /************************************************************************/
2676 : /* GetParamDbl() */
2677 : /************************************************************************/
2678 74 : double OGRStylePen::GetParamDbl(OGRSTPenParam eParam, GBool &bValueIsNull)
2679 : {
2680 148 : return OGRStyleTool::GetParamDbl(asStylePen[eParam],
2681 74 : m_pasStyleValue[eParam], bValueIsNull);
2682 : }
2683 :
2684 : /************************************************************************/
2685 : /* SetParamStr() */
2686 : /************************************************************************/
2687 :
2688 53 : void OGRStylePen::SetParamStr(OGRSTPenParam eParam, const char *pszParamString)
2689 : {
2690 53 : OGRStyleTool::SetParamStr(asStylePen[eParam], m_pasStyleValue[eParam],
2691 : pszParamString);
2692 53 : }
2693 :
2694 : /************************************************************************/
2695 : /* SetParamNum() */
2696 : /************************************************************************/
2697 0 : void OGRStylePen::SetParamNum(OGRSTPenParam eParam, int nParam)
2698 : {
2699 0 : OGRStyleTool::SetParamNum(asStylePen[eParam], m_pasStyleValue[eParam],
2700 : nParam);
2701 0 : }
2702 :
2703 : /************************************************************************/
2704 : /* SetParamDbl() */
2705 : /************************************************************************/
2706 83 : void OGRStylePen::SetParamDbl(OGRSTPenParam eParam, double dfParam)
2707 : {
2708 83 : OGRStyleTool::SetParamDbl(asStylePen[eParam], m_pasStyleValue[eParam],
2709 : dfParam);
2710 83 : }
2711 :
2712 : /************************************************************************/
2713 : /* GetStyleString() */
2714 : /************************************************************************/
2715 396 : const char *OGRStylePen::GetStyleString()
2716 : {
2717 396 : return OGRStyleTool::GetStyleString(asStylePen, m_pasStyleValue,
2718 396 : static_cast<int>(OGRSTPenLast));
2719 : }
2720 :
2721 : /****************************************************************************/
2722 : /* OGRStyleBrush::OGRStyleBrush() */
2723 : /* */
2724 : /****************************************************************************/
2725 131 : OGRStyleBrush::OGRStyleBrush()
2726 : : OGRStyleTool(OGRSTCBrush),
2727 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2728 131 : CPLCalloc(OGRSTBrushLast, sizeof(OGRStyleValue))))
2729 : {
2730 131 : }
2731 :
2732 : /****************************************************************************/
2733 : /* OGRStyleBrush::~OGRStyleBrush() */
2734 : /* */
2735 : /****************************************************************************/
2736 262 : OGRStyleBrush::~OGRStyleBrush()
2737 : {
2738 1179 : for (int i = 0; i < OGRSTBrushLast; i++)
2739 : {
2740 1048 : if (m_pasStyleValue[i].pszValue != nullptr)
2741 : {
2742 145 : CPLFree(m_pasStyleValue[i].pszValue);
2743 145 : m_pasStyleValue[i].pszValue = nullptr;
2744 : }
2745 : }
2746 :
2747 131 : CPLFree(m_pasStyleValue);
2748 262 : }
2749 :
2750 : /************************************************************************/
2751 : /* Parse() */
2752 : /************************************************************************/
2753 211 : GBool OGRStyleBrush::Parse()
2754 : {
2755 211 : return OGRStyleTool::Parse(asStyleBrush, m_pasStyleValue,
2756 211 : static_cast<int>(OGRSTBrushLast));
2757 : }
2758 :
2759 : /************************************************************************/
2760 : /* GetParamStr() */
2761 : /************************************************************************/
2762 66 : const char *OGRStyleBrush::GetParamStr(OGRSTBrushParam eParam,
2763 : GBool &bValueIsNull)
2764 : {
2765 132 : return OGRStyleTool::GetParamStr(asStyleBrush[eParam],
2766 66 : m_pasStyleValue[eParam], bValueIsNull);
2767 : }
2768 :
2769 : /************************************************************************/
2770 : /* GetParamNum() */
2771 : /************************************************************************/
2772 0 : int OGRStyleBrush::GetParamNum(OGRSTBrushParam eParam, GBool &bValueIsNull)
2773 : {
2774 0 : return OGRStyleTool::GetParamNum(asStyleBrush[eParam],
2775 0 : m_pasStyleValue[eParam], bValueIsNull);
2776 : }
2777 :
2778 : /************************************************************************/
2779 : /* GetParamDbl() */
2780 : /************************************************************************/
2781 0 : double OGRStyleBrush::GetParamDbl(OGRSTBrushParam eParam, GBool &bValueIsNull)
2782 : {
2783 0 : return OGRStyleTool::GetParamDbl(asStyleBrush[eParam],
2784 0 : m_pasStyleValue[eParam], bValueIsNull);
2785 : }
2786 :
2787 : /************************************************************************/
2788 : /* SetParamStr() */
2789 : /************************************************************************/
2790 83 : void OGRStyleBrush::SetParamStr(OGRSTBrushParam eParam,
2791 : const char *pszParamString)
2792 : {
2793 83 : OGRStyleTool::SetParamStr(asStyleBrush[eParam], m_pasStyleValue[eParam],
2794 : pszParamString);
2795 83 : }
2796 :
2797 : /************************************************************************/
2798 : /* SetParamNum() */
2799 : /************************************************************************/
2800 0 : void OGRStyleBrush::SetParamNum(OGRSTBrushParam eParam, int nParam)
2801 : {
2802 0 : OGRStyleTool::SetParamNum(asStyleBrush[eParam], m_pasStyleValue[eParam],
2803 : nParam);
2804 0 : }
2805 :
2806 : /************************************************************************/
2807 : /* SetParamDbl() */
2808 : /************************************************************************/
2809 0 : void OGRStyleBrush::SetParamDbl(OGRSTBrushParam eParam, double dfParam)
2810 : {
2811 0 : OGRStyleTool::SetParamDbl(asStyleBrush[eParam], m_pasStyleValue[eParam],
2812 : dfParam);
2813 0 : }
2814 :
2815 : /************************************************************************/
2816 : /* GetStyleString() */
2817 : /************************************************************************/
2818 170 : const char *OGRStyleBrush::GetStyleString()
2819 : {
2820 170 : return OGRStyleTool::GetStyleString(asStyleBrush, m_pasStyleValue,
2821 170 : static_cast<int>(OGRSTBrushLast));
2822 : }
2823 :
2824 : /****************************************************************************/
2825 : /* OGRStyleSymbol::OGRStyleSymbol() */
2826 : /****************************************************************************/
2827 354 : OGRStyleSymbol::OGRStyleSymbol()
2828 : : OGRStyleTool(OGRSTCSymbol),
2829 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2830 354 : CPLCalloc(OGRSTSymbolLast, sizeof(OGRStyleValue))))
2831 : {
2832 354 : }
2833 :
2834 : /****************************************************************************/
2835 : /* OGRStyleSymbol::~OGRStyleSymbol() */
2836 : /* */
2837 : /****************************************************************************/
2838 708 : OGRStyleSymbol::~OGRStyleSymbol()
2839 : {
2840 4602 : for (int i = 0; i < OGRSTSymbolLast; i++)
2841 : {
2842 4248 : if (m_pasStyleValue[i].pszValue != nullptr)
2843 : {
2844 663 : CPLFree(m_pasStyleValue[i].pszValue);
2845 663 : m_pasStyleValue[i].pszValue = nullptr;
2846 : }
2847 : }
2848 :
2849 354 : CPLFree(m_pasStyleValue);
2850 708 : }
2851 :
2852 : /************************************************************************/
2853 : /* Parse() */
2854 : /************************************************************************/
2855 1895 : GBool OGRStyleSymbol::Parse()
2856 : {
2857 1895 : return OGRStyleTool::Parse(asStyleSymbol, m_pasStyleValue,
2858 1895 : static_cast<int>(OGRSTSymbolLast));
2859 : }
2860 :
2861 : /************************************************************************/
2862 : /* GetParamStr() */
2863 : /************************************************************************/
2864 495 : const char *OGRStyleSymbol::GetParamStr(OGRSTSymbolParam eParam,
2865 : GBool &bValueIsNull)
2866 : {
2867 990 : return OGRStyleTool::GetParamStr(asStyleSymbol[eParam],
2868 495 : m_pasStyleValue[eParam], bValueIsNull);
2869 : }
2870 :
2871 : /************************************************************************/
2872 : /* GetParamNum() */
2873 : /************************************************************************/
2874 0 : int OGRStyleSymbol::GetParamNum(OGRSTSymbolParam eParam, GBool &bValueIsNull)
2875 : {
2876 0 : return OGRStyleTool::GetParamNum(asStyleSymbol[eParam],
2877 0 : m_pasStyleValue[eParam], bValueIsNull);
2878 : }
2879 :
2880 : /************************************************************************/
2881 : /* GetParamDbl() */
2882 : /************************************************************************/
2883 214 : double OGRStyleSymbol::GetParamDbl(OGRSTSymbolParam eParam, GBool &bValueIsNull)
2884 : {
2885 428 : return OGRStyleTool::GetParamDbl(asStyleSymbol[eParam],
2886 214 : m_pasStyleValue[eParam], bValueIsNull);
2887 : }
2888 :
2889 : /************************************************************************/
2890 : /* SetParamStr() */
2891 : /************************************************************************/
2892 63 : void OGRStyleSymbol::SetParamStr(OGRSTSymbolParam eParam,
2893 : const char *pszParamString)
2894 : {
2895 63 : OGRStyleTool::SetParamStr(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2896 : pszParamString);
2897 63 : }
2898 :
2899 : /************************************************************************/
2900 : /* SetParamNum() */
2901 : /************************************************************************/
2902 0 : void OGRStyleSymbol::SetParamNum(OGRSTSymbolParam eParam, int nParam)
2903 : {
2904 0 : OGRStyleTool::SetParamNum(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2905 : nParam);
2906 0 : }
2907 :
2908 : /************************************************************************/
2909 : /* SetParamDbl() */
2910 : /************************************************************************/
2911 10 : void OGRStyleSymbol::SetParamDbl(OGRSTSymbolParam eParam, double dfParam)
2912 : {
2913 10 : OGRStyleTool::SetParamDbl(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2914 : dfParam);
2915 10 : }
2916 :
2917 : /************************************************************************/
2918 : /* GetStyleString() */
2919 : /************************************************************************/
2920 110 : const char *OGRStyleSymbol::GetStyleString()
2921 : {
2922 110 : return OGRStyleTool::GetStyleString(asStyleSymbol, m_pasStyleValue,
2923 110 : static_cast<int>(OGRSTSymbolLast));
2924 : }
2925 :
2926 : /****************************************************************************/
2927 : /* OGRStyleLabel::OGRStyleLabel() */
2928 : /* */
2929 : /****************************************************************************/
2930 27 : OGRStyleLabel::OGRStyleLabel()
2931 : : OGRStyleTool(OGRSTCLabel),
2932 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2933 27 : CPLCalloc(OGRSTLabelLast, sizeof(OGRStyleValue))))
2934 : {
2935 27 : }
2936 :
2937 : /****************************************************************************/
2938 : /* OGRStyleLabel::~OGRStyleLabel() */
2939 : /* */
2940 : /****************************************************************************/
2941 54 : OGRStyleLabel::~OGRStyleLabel()
2942 : {
2943 594 : for (int i = 0; i < OGRSTLabelLast; i++)
2944 : {
2945 567 : if (m_pasStyleValue[i].pszValue != nullptr)
2946 : {
2947 47 : CPLFree(m_pasStyleValue[i].pszValue);
2948 47 : m_pasStyleValue[i].pszValue = nullptr;
2949 : }
2950 : }
2951 :
2952 27 : CPLFree(m_pasStyleValue);
2953 54 : }
2954 :
2955 : /************************************************************************/
2956 : /* Parse() */
2957 : /************************************************************************/
2958 330 : GBool OGRStyleLabel::Parse()
2959 : {
2960 330 : return OGRStyleTool::Parse(asStyleLabel, m_pasStyleValue,
2961 330 : static_cast<int>(OGRSTLabelLast));
2962 : }
2963 :
2964 : /************************************************************************/
2965 : /* GetParamStr() */
2966 : /************************************************************************/
2967 72 : const char *OGRStyleLabel::GetParamStr(OGRSTLabelParam eParam,
2968 : GBool &bValueIsNull)
2969 : {
2970 144 : return OGRStyleTool::GetParamStr(asStyleLabel[eParam],
2971 72 : m_pasStyleValue[eParam], bValueIsNull);
2972 : }
2973 :
2974 : /************************************************************************/
2975 : /* GetParamNum() */
2976 : /************************************************************************/
2977 58 : int OGRStyleLabel::GetParamNum(OGRSTLabelParam eParam, GBool &bValueIsNull)
2978 : {
2979 116 : return OGRStyleTool::GetParamNum(asStyleLabel[eParam],
2980 58 : m_pasStyleValue[eParam], bValueIsNull);
2981 : }
2982 :
2983 : /************************************************************************/
2984 : /* GetParamDbl() */
2985 : /************************************************************************/
2986 92 : double OGRStyleLabel::GetParamDbl(OGRSTLabelParam eParam, GBool &bValueIsNull)
2987 : {
2988 184 : return OGRStyleTool::GetParamDbl(asStyleLabel[eParam],
2989 92 : m_pasStyleValue[eParam], bValueIsNull);
2990 : }
2991 :
2992 : /************************************************************************/
2993 : /* SetParamStr() */
2994 : /************************************************************************/
2995 5 : void OGRStyleLabel::SetParamStr(OGRSTLabelParam eParam,
2996 : const char *pszParamString)
2997 : {
2998 5 : OGRStyleTool::SetParamStr(asStyleLabel[eParam], m_pasStyleValue[eParam],
2999 : pszParamString);
3000 5 : }
3001 :
3002 : /************************************************************************/
3003 : /* SetParamNum() */
3004 : /************************************************************************/
3005 0 : void OGRStyleLabel::SetParamNum(OGRSTLabelParam eParam, int nParam)
3006 : {
3007 0 : OGRStyleTool::SetParamNum(asStyleLabel[eParam], m_pasStyleValue[eParam],
3008 : nParam);
3009 0 : }
3010 :
3011 : /************************************************************************/
3012 : /* SetParamDbl() */
3013 : /************************************************************************/
3014 5 : void OGRStyleLabel::SetParamDbl(OGRSTLabelParam eParam, double dfParam)
3015 : {
3016 5 : OGRStyleTool::SetParamDbl(asStyleLabel[eParam], m_pasStyleValue[eParam],
3017 : dfParam);
3018 5 : }
3019 :
3020 : /************************************************************************/
3021 : /* GetStyleString() */
3022 : /************************************************************************/
3023 10 : const char *OGRStyleLabel::GetStyleString()
3024 : {
3025 10 : return OGRStyleTool::GetStyleString(asStyleLabel, m_pasStyleValue,
3026 10 : static_cast<int>(OGRSTLabelLast));
3027 : }
3028 :
3029 : //! @endcond
|