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 971 : OGRStyleMgr::OGRStyleMgr(OGRStyleTable *poDataSetStyleTable)
112 971 : : m_poDataSetStyleTable(poDataSetStyleTable)
113 : {
114 971 : }
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 127 : OGRStyleMgrH OGR_SM_Create(OGRStyleTableH hStyleTable)
131 :
132 : {
133 : return reinterpret_cast<OGRStyleMgrH>(
134 127 : 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 1942 : OGRStyleMgr::~OGRStyleMgr()
147 : {
148 971 : CPLFree(m_pszStyleString);
149 971 : }
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 127 : void OGR_SM_Destroy(OGRStyleMgrH hSM)
163 :
164 : {
165 127 : delete reinterpret_cast<OGRStyleMgr *>(hSM);
166 127 : }
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 147 : const char *OGRStyleMgr::InitFromFeature(OGRFeature *poFeature)
226 : {
227 147 : CPLFree(m_pszStyleString);
228 147 : m_pszStyleString = nullptr;
229 :
230 147 : if (poFeature)
231 147 : InitStyleString(poFeature->GetStyleString());
232 : else
233 0 : m_pszStyleString = nullptr;
234 :
235 147 : 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 125 : const char *OGR_SM_InitFromFeature(OGRStyleMgrH hSM, OGRFeatureH hFeat)
256 :
257 : {
258 125 : VALIDATE_POINTER1(hSM, "OGR_SM_InitFromFeature", nullptr);
259 125 : VALIDATE_POINTER1(hFeat, "OGR_SM_InitFromFeature", nullptr);
260 :
261 125 : return reinterpret_cast<OGRStyleMgr *>(hSM)->InitFromFeature(
262 125 : 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 1076 : GBool OGRStyleMgr::InitStyleString(const char *pszStyleString)
284 : {
285 1076 : CPLFree(m_pszStyleString);
286 1076 : m_pszStyleString = nullptr;
287 :
288 1076 : 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 1074 : else if (pszStyleString)
296 608 : m_pszStyleString = CPLStrdup(pszStyleString);
297 :
298 1075 : 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 796 : int OGRStyleMgr::GetPartCount(const char *pszStyleString)
577 : {
578 796 : const char *pszString =
579 796 : pszStyleString != nullptr ? pszStyleString : m_pszStyleString;
580 :
581 796 : if (pszString == nullptr)
582 213 : return 0;
583 :
584 583 : int nPartCount = 1;
585 583 : const char *pszStrTmp = pszString;
586 : // Search for parts separated by semicolons not counting the possible
587 : // semicolon at the and of string.
588 583 : const char *pszPart = nullptr;
589 664 : while ((pszPart = strstr(pszStrTmp, ";")) != nullptr && pszPart[1] != '\0')
590 : {
591 81 : pszStrTmp = &pszPart[1];
592 81 : nPartCount++;
593 : }
594 583 : 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 127 : int OGR_SM_GetPartCount(OGRStyleMgrH hSM, const char *pszStyleString)
614 :
615 : {
616 127 : VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", FALSE);
617 :
618 127 : 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 497 : OGRStyleTool *OGRStyleMgr::GetPart(int nPartId, const char *pszStyleString)
644 : {
645 497 : const char *pszStyle = pszStyleString ? pszStyleString : m_pszStyleString;
646 :
647 497 : if (pszStyle == nullptr)
648 1 : return nullptr;
649 :
650 496 : char **papszStyleString = CSLTokenizeString2(
651 : pszStyle, ";",
652 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
653 :
654 496 : const char *pszString = CSLGetField(papszStyleString, nPartId);
655 :
656 496 : OGRStyleTool *poStyleTool = nullptr;
657 496 : if (strlen(pszString) > 0)
658 : {
659 495 : poStyleTool = CreateStyleToolFromStyleString(pszString);
660 495 : if (poStyleTool)
661 495 : poStyleTool->SetStyleString(pszString);
662 : }
663 :
664 496 : CSLDestroy(papszStyleString);
665 :
666 496 : 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 66 : OGRStyleToolH OGR_SM_GetPart(OGRStyleMgrH hSM, int nPartId,
690 : const char *pszStyleString)
691 :
692 : {
693 66 : VALIDATE_POINTER1(hSM, "OGR_SM_InitStyleString", nullptr);
694 :
695 : return reinterpret_cast<OGRStyleToolH>(
696 66 : 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 495 : OGRStyleMgr::CreateStyleToolFromStyleString(const char *pszStyleString)
709 : {
710 495 : char **papszToken = CSLTokenizeString2(
711 : pszStyleString, "();",
712 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
713 495 : OGRStyleTool *poStyleTool = nullptr;
714 :
715 495 : if (CSLCount(papszToken) < 2)
716 0 : poStyleTool = nullptr;
717 495 : else if (EQUAL(papszToken[0], "PEN"))
718 140 : poStyleTool = new OGRStylePen();
719 355 : else if (EQUAL(papszToken[0], "BRUSH"))
720 56 : poStyleTool = new OGRStyleBrush();
721 299 : else if (EQUAL(papszToken[0], "SYMBOL"))
722 280 : poStyleTool = new OGRStyleSymbol();
723 19 : else if (EQUAL(papszToken[0], "LABEL"))
724 19 : poStyleTool = new OGRStyleLabel();
725 : else
726 0 : poStyleTool = nullptr;
727 :
728 495 : CSLDestroy(papszToken);
729 :
730 495 : 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 68 : const char *OGRStyleTable::Find(const char *pszName)
1075 : {
1076 68 : const int nPos = IsExist(pszName);
1077 68 : if (nPos == -1)
1078 4 : return nullptr;
1079 :
1080 64 : const char *pszOutput = CSLGetField(m_papszStyleTable, nPos);
1081 :
1082 64 : const char *pszDash = strstr(pszOutput, ":");
1083 :
1084 64 : if (pszDash == nullptr)
1085 0 : return nullptr;
1086 :
1087 64 : 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 236 : int OGRStyleTable::IsExist(const char *pszName)
1151 : {
1152 236 : if (pszName == nullptr)
1153 0 : return -1;
1154 :
1155 236 : const int nCount = CSLCount(m_papszStyleTable);
1156 236 : const char *pszNewString = CPLSPrintf("%s:", pszName);
1157 :
1158 948 : for (int i = 0; i < nCount; i++)
1159 : {
1160 777 : if (strstr(m_papszStyleTable[i], pszNewString) != nullptr)
1161 : {
1162 65 : 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 748 : OGRStyleTool::OGRStyleTool(OGRSTClassId eClassId) : m_eClassId(eClassId)
1322 : {
1323 748 : }
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 1496 : OGRStyleTool::~OGRStyleTool()
1363 : {
1364 748 : CPLFree(m_pszStyleString);
1365 748 : }
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 65 : void OGR_ST_Destroy(OGRStyleToolH hST)
1377 :
1378 : {
1379 65 : delete reinterpret_cast<OGRStyleTool *>(hST);
1380 65 : }
1381 :
1382 : /****************************************************************************/
1383 : /* void OGRStyleTool::SetStyleString(const char *pszStyleString) */
1384 : /* */
1385 : /****************************************************************************/
1386 :
1387 : /** Undocumented
1388 : * @param pszStyleString undocumented.
1389 : */
1390 495 : void OGRStyleTool::SetStyleString(const char *pszStyleString)
1391 : {
1392 495 : m_pszStyleString = CPLStrdup(pszStyleString);
1393 495 : }
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 1573 : OGRSTClassId OGRStyleTool::GetType()
1597 : {
1598 1573 : 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 238 : OGRSTClassId OGR_ST_GetType(OGRStyleToolH hST)
1615 :
1616 : {
1617 238 : VALIDATE_POINTER1(hST, "OGR_ST_GetType", OGRSTCNone);
1618 238 : 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 655 : void OGRStyleTool::SetUnit(OGRSTUnitId eUnit, double dfGroundPaperScale)
1659 : {
1660 655 : m_eUnit = eUnit;
1661 655 : m_dfScale = dfGroundPaperScale;
1662 655 : }
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 65 : void OGR_ST_SetUnit(OGRStyleToolH hST, OGRSTUnitId eUnit,
1679 : double dfGroundPaperScale)
1680 :
1681 : {
1682 65 : VALIDATE_POINTER0(hST, "OGR_ST_SetUnit");
1683 65 : reinterpret_cast<OGRStyleTool *>(hST)->SetUnit(eUnit, dfGroundPaperScale);
1684 : }
1685 :
1686 : /************************************************************************/
1687 : /* Parse() */
1688 : /************************************************************************/
1689 :
1690 : //! @cond Doxygen_Suppress
1691 2801 : GBool OGRStyleTool::Parse(const OGRStyleParamId *pasStyle,
1692 : OGRStyleValue *pasValue, int nCount)
1693 : {
1694 2801 : if (IsStyleParsed())
1695 2182 : return TRUE;
1696 :
1697 619 : StyleParsed();
1698 :
1699 619 : 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 752 : char **papszToken = CSLTokenizeString2(
1706 376 : m_pszStyleString, "()",
1707 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
1708 :
1709 376 : 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 752 : char **papszToken2 = CSLTokenizeString2(
1720 376 : papszToken[1], ",",
1721 : CSLT_HONOURSTRINGS | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES);
1722 :
1723 : // Valid that we have the right StyleString for this feature type.
1724 376 : switch (GetType())
1725 : {
1726 45 : case OGRSTCPen:
1727 45 : 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 45 : break;
1738 35 : case OGRSTCBrush:
1739 35 : 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 35 : break;
1750 277 : case OGRSTCSymbol:
1751 277 : 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 277 : break;
1762 19 : case OGRSTCLabel:
1763 19 : 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 19 : 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 : }
1781 :
1782 : ////////////////////////////////////////////////////////////////////////
1783 : // Here we will loop on each element in the StyleString. If it is
1784 : // a valid element, we will add it in the StyleTool with
1785 : // SetParamStr().
1786 : //
1787 : // It is important to note that the SetInternalUnit...() is use to update
1788 : // the unit of the StyleTool param (m_eUnit).
1789 : // See OGRStyleTool::SetParamStr().
1790 : // There's a StyleTool unit (m_eUnit), which is the output unit, and each
1791 : // parameter of the style have its own unit value (the input unit). Here we
1792 : // set m_eUnit to the input unit and in SetParamStr(), we will use this
1793 : // value to set the input unit. Then after the loop we will reset m_eUnit
1794 : // to its original value. (Yes it is a side effect / black magic)
1795 : //
1796 : // The pasStyle variable is a global variable passed in argument to the
1797 : // function. See at the top of this file the four OGRStyleParamId
1798 : // variable. They are used to register the valid parameter of each
1799 : // StyleTool.
1800 : ////////////////////////////////////////////////////////////////////////
1801 :
1802 : // Save Scale and output Units because the parsing code will alter
1803 : // the values.
1804 376 : OGRSTUnitId eLastUnit = m_eUnit;
1805 376 : double dSavedScale = m_dfScale;
1806 376 : const int nElements = CSLCount(papszToken2);
1807 :
1808 1777 : for (int i = 0; i < nElements; i++)
1809 : {
1810 : char **papszStylePair =
1811 1401 : CSLTokenizeString2(papszToken2[i], ":",
1812 : CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES |
1813 : CSLT_STRIPENDSPACES | CSLT_ALLOWEMPTYTOKENS);
1814 :
1815 1401 : const int nTokens = CSLCount(papszStylePair);
1816 :
1817 1401 : if (nTokens < 1 || nTokens > 2)
1818 : {
1819 0 : CPLError(CE_Warning, CPLE_AppDefined,
1820 : "Error in the StyleTool String %s", m_pszStyleString);
1821 0 : CPLError(CE_Warning, CPLE_AppDefined,
1822 : "Malformed element #%d (\"%s\") skipped", i,
1823 0 : papszToken2[i]);
1824 0 : CSLDestroy(papszStylePair);
1825 0 : continue;
1826 : }
1827 :
1828 3980 : for (int j = 0; j < nCount; j++)
1829 : {
1830 3980 : if (pasStyle[j].pszToken &&
1831 3978 : EQUAL(pasStyle[j].pszToken, papszStylePair[0]))
1832 : {
1833 1401 : if (papszStylePair[1] != nullptr && pasStyle[j].bGeoref == TRUE)
1834 334 : SetInternalInputUnitFromParam(papszStylePair[1]);
1835 :
1836 : // Set either the actual value of style parameter or "1"
1837 : // for boolean parameters which do not have values (legacy
1838 : // behavior).
1839 1401 : OGRStyleTool::SetParamStr(
1840 1401 : pasStyle[j], pasValue[j],
1841 1401 : papszStylePair[1] != nullptr ? papszStylePair[1] : "1");
1842 :
1843 1401 : break;
1844 : }
1845 : }
1846 :
1847 1401 : CSLDestroy(papszStylePair);
1848 : }
1849 :
1850 376 : m_eUnit = eLastUnit;
1851 376 : m_dfScale = dSavedScale;
1852 :
1853 376 : CSLDestroy(papszToken2);
1854 376 : CSLDestroy(papszToken);
1855 :
1856 376 : return TRUE;
1857 : }
1858 :
1859 : //! @endcond
1860 :
1861 : /************************************************************************/
1862 : /* SetInternalInputUnitFromParam() */
1863 : /************************************************************************/
1864 :
1865 : //! @cond Doxygen_Suppress
1866 334 : void OGRStyleTool::SetInternalInputUnitFromParam(char *pszString)
1867 : {
1868 334 : if (pszString == nullptr)
1869 0 : return;
1870 :
1871 334 : char *pszUnit = strstr(pszString, "g");
1872 334 : if (pszUnit)
1873 : {
1874 8 : SetUnit(OGRSTUGround);
1875 8 : pszUnit[0] = '\0';
1876 8 : return;
1877 : }
1878 326 : pszUnit = strstr(pszString, "px");
1879 326 : if (pszUnit)
1880 : {
1881 36 : SetUnit(OGRSTUPixel);
1882 36 : pszUnit[0] = '\0';
1883 36 : return;
1884 : }
1885 290 : pszUnit = strstr(pszString, "pt");
1886 290 : if (pszUnit)
1887 : {
1888 232 : SetUnit(OGRSTUPoints);
1889 232 : pszUnit[0] = '\0';
1890 232 : return;
1891 : }
1892 58 : pszUnit = strstr(pszString, "mm");
1893 58 : if (pszUnit)
1894 : {
1895 1 : SetUnit(OGRSTUMM);
1896 1 : pszUnit[0] = '\0';
1897 1 : return;
1898 : }
1899 57 : pszUnit = strstr(pszString, "cm");
1900 57 : if (pszUnit)
1901 : {
1902 0 : SetUnit(OGRSTUCM);
1903 0 : pszUnit[0] = '\0';
1904 0 : return;
1905 : }
1906 57 : pszUnit = strstr(pszString, "in");
1907 57 : if (pszUnit)
1908 : {
1909 0 : SetUnit(OGRSTUInches);
1910 0 : pszUnit[0] = '\0';
1911 0 : return;
1912 : }
1913 :
1914 57 : SetUnit(OGRSTUMM);
1915 : }
1916 :
1917 : /************************************************************************/
1918 : /* ComputeWithUnit() */
1919 : /************************************************************************/
1920 255 : double OGRStyleTool::ComputeWithUnit(double dfValue, OGRSTUnitId eInputUnit)
1921 : {
1922 255 : OGRSTUnitId eOutputUnit = GetUnit();
1923 :
1924 255 : double dfNewValue = dfValue; // dfValue in meters;
1925 :
1926 255 : if (eOutputUnit == eInputUnit)
1927 174 : return dfValue;
1928 :
1929 81 : switch (eInputUnit)
1930 : {
1931 5 : case OGRSTUGround:
1932 5 : dfNewValue = dfValue / m_dfScale;
1933 5 : break;
1934 61 : case OGRSTUPixel:
1935 61 : dfNewValue = dfValue / (72.0 * 39.37);
1936 61 : break;
1937 14 : case OGRSTUPoints:
1938 14 : dfNewValue = dfValue / (72.0 * 39.37);
1939 14 : break;
1940 1 : case OGRSTUMM:
1941 1 : dfNewValue = 0.001 * dfValue;
1942 1 : break;
1943 0 : case OGRSTUCM:
1944 0 : dfNewValue = 0.01 * dfValue;
1945 0 : break;
1946 0 : case OGRSTUInches:
1947 0 : dfNewValue = dfValue / 39.37;
1948 0 : break;
1949 0 : default:
1950 0 : break; // imp.
1951 : }
1952 :
1953 81 : switch (eOutputUnit)
1954 : {
1955 2 : case OGRSTUGround:
1956 2 : dfNewValue *= m_dfScale;
1957 2 : break;
1958 0 : case OGRSTUPixel:
1959 0 : dfNewValue *= 72.0 * 39.37;
1960 0 : break;
1961 58 : case OGRSTUPoints:
1962 58 : dfNewValue *= 72.0 * 39.37;
1963 58 : break;
1964 21 : case OGRSTUMM:
1965 21 : dfNewValue *= 1000.0;
1966 21 : break;
1967 0 : case OGRSTUCM:
1968 0 : dfNewValue *= 100.0;
1969 0 : break;
1970 0 : case OGRSTUInches:
1971 0 : dfNewValue *= 39.37;
1972 0 : break;
1973 0 : default:
1974 0 : break; // imp.
1975 : }
1976 81 : return dfNewValue;
1977 : }
1978 :
1979 : /************************************************************************/
1980 : /* ComputeWithUnit() */
1981 : /************************************************************************/
1982 0 : int OGRStyleTool::ComputeWithUnit(int nValue, OGRSTUnitId eUnit)
1983 : {
1984 : return static_cast<int>(
1985 0 : ComputeWithUnit(static_cast<double>(nValue), eUnit));
1986 : }
1987 :
1988 : //! @endcond
1989 :
1990 : /************************************************************************/
1991 : /* GetParamStr() */
1992 : /************************************************************************/
1993 :
1994 : /** Undocumented
1995 : * @param sStyleParam undocumented.
1996 : * @param sStyleValue undocumented.
1997 : * @param bValueIsNull undocumented.
1998 : * @return Undocumented.
1999 : */
2000 687 : const char *OGRStyleTool::GetParamStr(const OGRStyleParamId &sStyleParam,
2001 : const OGRStyleValue &sStyleValue,
2002 : GBool &bValueIsNull)
2003 : {
2004 687 : if (!Parse())
2005 : {
2006 0 : bValueIsNull = TRUE;
2007 0 : return nullptr;
2008 : }
2009 :
2010 687 : bValueIsNull = !sStyleValue.bValid;
2011 :
2012 687 : if (bValueIsNull == TRUE)
2013 36 : return nullptr;
2014 :
2015 651 : switch (sStyleParam.eType)
2016 : {
2017 : // If sStyleParam.bGeoref == TRUE, need to convert to output value.
2018 651 : case OGRSTypeString:
2019 651 : return sStyleValue.pszValue;
2020 0 : case OGRSTypeDouble:
2021 0 : if (sStyleParam.bGeoref)
2022 0 : return CPLSPrintf("%f", ComputeWithUnit(sStyleValue.dfValue,
2023 0 : sStyleValue.eUnit));
2024 : else
2025 0 : return CPLSPrintf("%f", sStyleValue.dfValue);
2026 :
2027 0 : case OGRSTypeInteger:
2028 0 : if (sStyleParam.bGeoref)
2029 0 : return CPLSPrintf("%d", ComputeWithUnit(sStyleValue.nValue,
2030 0 : sStyleValue.eUnit));
2031 : else
2032 0 : return CPLSPrintf("%d", sStyleValue.nValue);
2033 0 : case OGRSTypeBoolean:
2034 0 : return CPLSPrintf("%d", sStyleValue.nValue != 0);
2035 0 : default:
2036 0 : bValueIsNull = TRUE;
2037 0 : return nullptr;
2038 : }
2039 : }
2040 :
2041 : /****************************************************************************/
2042 : /* int OGRStyleTool::GetParamNum(OGRStyleParamId sStyleParam , */
2043 : /* OGRStyleValue sStyleValue, */
2044 : /* GBool &bValueIsNull) */
2045 : /* */
2046 : /****************************************************************************/
2047 :
2048 : /** Undocumented
2049 : * @param sStyleParam undocumented.
2050 : * @param sStyleValue undocumented.
2051 : * @param bValueIsNull undocumented.
2052 : * @return Undocumented.
2053 : */
2054 49 : int OGRStyleTool::GetParamNum(const OGRStyleParamId &sStyleParam,
2055 : const OGRStyleValue &sStyleValue,
2056 : GBool &bValueIsNull)
2057 : {
2058 : return static_cast<int>(
2059 49 : GetParamDbl(sStyleParam, sStyleValue, bValueIsNull));
2060 : }
2061 :
2062 : /****************************************************************************/
2063 : /* double OGRStyleTool::GetParamDbl(OGRStyleParamId sStyleParam , */
2064 : /* OGRStyleValue sStyleValue, */
2065 : /* GBool &bValueIsNull) */
2066 : /* */
2067 : /****************************************************************************/
2068 :
2069 : /** Undocumented
2070 : * @param sStyleParam undocumented.
2071 : * @param sStyleValue undocumented.
2072 : * @param bValueIsNull undocumented.
2073 : * @return Undocumented.
2074 : */
2075 411 : double OGRStyleTool::GetParamDbl(const OGRStyleParamId &sStyleParam,
2076 : const OGRStyleValue &sStyleValue,
2077 : GBool &bValueIsNull)
2078 : {
2079 411 : if (!Parse())
2080 : {
2081 0 : bValueIsNull = TRUE;
2082 0 : return 0.0;
2083 : }
2084 :
2085 411 : bValueIsNull = !sStyleValue.bValid;
2086 :
2087 411 : if (bValueIsNull == TRUE)
2088 126 : return 0.0;
2089 :
2090 285 : switch (sStyleParam.eType)
2091 : {
2092 : // if sStyleParam.bGeoref == TRUE, need to convert to output value.
2093 0 : case OGRSTypeString:
2094 0 : if (sStyleParam.bGeoref)
2095 0 : return ComputeWithUnit(CPLAtof(sStyleValue.pszValue),
2096 0 : sStyleValue.eUnit);
2097 : else
2098 0 : return CPLAtof(sStyleValue.pszValue);
2099 272 : case OGRSTypeDouble:
2100 272 : if (sStyleParam.bGeoref)
2101 255 : return ComputeWithUnit(sStyleValue.dfValue, sStyleValue.eUnit);
2102 : else
2103 17 : return sStyleValue.dfValue;
2104 7 : case OGRSTypeInteger:
2105 7 : if (sStyleParam.bGeoref)
2106 : return static_cast<double>(
2107 0 : ComputeWithUnit(sStyleValue.nValue, sStyleValue.eUnit));
2108 : else
2109 7 : return static_cast<double>(sStyleValue.nValue);
2110 6 : case OGRSTypeBoolean:
2111 6 : return static_cast<double>(sStyleValue.nValue != 0);
2112 0 : default:
2113 0 : bValueIsNull = TRUE;
2114 0 : return 0.0;
2115 : }
2116 : }
2117 :
2118 : /****************************************************************************/
2119 : /* void OGRStyleTool::SetParamStr(OGRStyleParamId &sStyleParam , */
2120 : /* OGRStyleValue &sStyleValue, */
2121 : /* const char *pszParamString) */
2122 : /* */
2123 : /****************************************************************************/
2124 :
2125 : /** Undocumented
2126 : * @param sStyleParam undocumented.
2127 : * @param sStyleValue undocumented.
2128 : * @param pszParamString undocumented.
2129 : */
2130 1605 : void OGRStyleTool::SetParamStr(const OGRStyleParamId &sStyleParam,
2131 : OGRStyleValue &sStyleValue,
2132 : const char *pszParamString)
2133 : {
2134 1605 : Parse();
2135 1605 : StyleModified();
2136 1605 : sStyleValue.bValid = TRUE;
2137 1605 : sStyleValue.eUnit = GetUnit();
2138 1605 : switch (sStyleParam.eType)
2139 : {
2140 : // If sStyleParam.bGeoref == TRUE, need to convert to output value;
2141 1023 : case OGRSTypeString:
2142 1023 : sStyleValue.pszValue = CPLStrdup(pszParamString);
2143 1023 : break;
2144 569 : case OGRSTypeDouble:
2145 569 : sStyleValue.dfValue = CPLAtof(pszParamString);
2146 569 : break;
2147 7 : case OGRSTypeInteger:
2148 7 : sStyleValue.nValue = atoi(pszParamString);
2149 7 : break;
2150 6 : case OGRSTypeBoolean:
2151 6 : sStyleValue.nValue = atoi(pszParamString) != 0;
2152 6 : break;
2153 0 : default:
2154 0 : sStyleValue.bValid = FALSE;
2155 0 : break;
2156 : }
2157 1605 : }
2158 :
2159 : /****************************************************************************/
2160 : /* void OGRStyleTool::SetParamNum(OGRStyleParamId &sStyleParam , */
2161 : /* OGRStyleValue &sStyleValue, */
2162 : /* int nParam) */
2163 : /* */
2164 : /****************************************************************************/
2165 :
2166 : /** Undocumented
2167 : * @param sStyleParam undocumented.
2168 : * @param sStyleValue undocumented.
2169 : * @param nParam undocumented.
2170 : */
2171 0 : void OGRStyleTool::SetParamNum(const OGRStyleParamId &sStyleParam,
2172 : OGRStyleValue &sStyleValue, int nParam)
2173 : {
2174 0 : Parse();
2175 0 : StyleModified();
2176 0 : sStyleValue.bValid = TRUE;
2177 0 : sStyleValue.eUnit = GetUnit();
2178 0 : switch (sStyleParam.eType)
2179 : {
2180 :
2181 : // If sStyleParam.bGeoref == TRUE, need to convert to output value;
2182 0 : case OGRSTypeString:
2183 0 : sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%d", nParam));
2184 0 : break;
2185 0 : case OGRSTypeDouble:
2186 0 : sStyleValue.dfValue = static_cast<double>(nParam);
2187 0 : break;
2188 0 : case OGRSTypeInteger:
2189 0 : sStyleValue.nValue = nParam;
2190 0 : break;
2191 0 : case OGRSTypeBoolean:
2192 0 : sStyleValue.nValue = nParam != 0;
2193 0 : break;
2194 0 : default:
2195 0 : sStyleValue.bValid = FALSE;
2196 0 : break;
2197 : }
2198 0 : }
2199 :
2200 : /****************************************************************************/
2201 : /* void OGRStyleTool::SetParamDbl(OGRStyleParamId &sStyleParam , */
2202 : /* OGRStyleValue &sStyleValue, */
2203 : /* double dfParam) */
2204 : /* */
2205 : /****************************************************************************/
2206 :
2207 : /** Undocumented
2208 : * @param sStyleParam undocumented.
2209 : * @param sStyleValue undocumented.
2210 : * @param dfParam undocumented.
2211 : */
2212 98 : void OGRStyleTool::SetParamDbl(const OGRStyleParamId &sStyleParam,
2213 : OGRStyleValue &sStyleValue, double dfParam)
2214 : {
2215 98 : Parse();
2216 98 : StyleModified();
2217 98 : sStyleValue.bValid = TRUE;
2218 98 : sStyleValue.eUnit = GetUnit();
2219 98 : switch (sStyleParam.eType)
2220 : {
2221 : // If sStyleParam.bGeoref == TRUE, need to convert to output value;
2222 0 : case OGRSTypeString:
2223 0 : sStyleValue.pszValue = CPLStrdup(CPLString().Printf("%f", dfParam));
2224 0 : break;
2225 98 : case OGRSTypeDouble:
2226 98 : sStyleValue.dfValue = dfParam;
2227 98 : break;
2228 0 : case OGRSTypeInteger:
2229 0 : sStyleValue.nValue = static_cast<int>(dfParam);
2230 0 : break;
2231 0 : case OGRSTypeBoolean:
2232 0 : sStyleValue.nValue = static_cast<int>(dfParam) != 0;
2233 0 : break;
2234 0 : default:
2235 0 : sStyleValue.bValid = FALSE;
2236 0 : break;
2237 : }
2238 98 : }
2239 :
2240 : /************************************************************************/
2241 : /* OGR_ST_GetParamStr() */
2242 : /************************************************************************/
2243 : /**
2244 : * \brief Get Style Tool parameter value as string
2245 : *
2246 : * Maps to the OGRStyleTool subclasses' GetParamStr() methods.
2247 : *
2248 : * @param hST handle to the style tool.
2249 : * @param eParam the parameter id from the enumeration corresponding to the
2250 : * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2251 : * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2252 : * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
2253 : * to indicate whether the parameter value is NULL.
2254 : *
2255 : * @return the parameter value as string and sets bValueIsNull.
2256 : */
2257 :
2258 137 : const char *OGR_ST_GetParamStr(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2259 : {
2260 137 : VALIDATE_POINTER1(hST, "OGR_ST_GetParamStr", "");
2261 137 : VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamStr", "");
2262 :
2263 137 : GBool bIsNull = TRUE;
2264 137 : const char *pszVal = "";
2265 :
2266 137 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2267 : {
2268 4 : case OGRSTCPen:
2269 4 : pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamStr(
2270 : static_cast<OGRSTPenParam>(eParam), bIsNull);
2271 4 : break;
2272 1 : case OGRSTCBrush:
2273 1 : pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamStr(
2274 : static_cast<OGRSTBrushParam>(eParam), bIsNull);
2275 1 : break;
2276 102 : case OGRSTCSymbol:
2277 102 : pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamStr(
2278 : static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2279 102 : break;
2280 30 : case OGRSTCLabel:
2281 30 : pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamStr(
2282 : static_cast<OGRSTLabelParam>(eParam), bIsNull);
2283 30 : break;
2284 0 : default:
2285 0 : break;
2286 : }
2287 :
2288 137 : *bValueIsNull = bIsNull;
2289 137 : return pszVal;
2290 : }
2291 :
2292 : /************************************************************************/
2293 : /* OGR_ST_GetParamNum() */
2294 : /************************************************************************/
2295 : /**
2296 : * \brief Get Style Tool parameter value as an integer
2297 : *
2298 : * Maps to the OGRStyleTool subclasses' GetParamNum() methods.
2299 : *
2300 : * @param hST handle to the style tool.
2301 : * @param eParam the parameter id from the enumeration corresponding to the
2302 : * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2303 : * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2304 : * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
2305 : * to indicate whether the parameter value is NULL.
2306 : *
2307 : * @return the parameter value as integer and sets bValueIsNull.
2308 : */
2309 :
2310 30 : int OGR_ST_GetParamNum(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2311 : {
2312 30 : VALIDATE_POINTER1(hST, "OGR_ST_GetParamNum", 0);
2313 30 : VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamNum", 0);
2314 :
2315 30 : GBool bIsNull = TRUE;
2316 30 : int nVal = 0;
2317 :
2318 30 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2319 : {
2320 0 : case OGRSTCPen:
2321 0 : nVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamNum(
2322 : static_cast<OGRSTPenParam>(eParam), bIsNull);
2323 0 : break;
2324 0 : case OGRSTCBrush:
2325 0 : nVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamNum(
2326 : static_cast<OGRSTBrushParam>(eParam), bIsNull);
2327 0 : break;
2328 0 : case OGRSTCSymbol:
2329 0 : nVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamNum(
2330 : static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2331 0 : break;
2332 30 : case OGRSTCLabel:
2333 30 : nVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamNum(
2334 : static_cast<OGRSTLabelParam>(eParam), bIsNull);
2335 30 : break;
2336 0 : default:
2337 0 : break;
2338 : }
2339 :
2340 30 : *bValueIsNull = bIsNull;
2341 30 : return nVal;
2342 : }
2343 :
2344 : /************************************************************************/
2345 : /* OGR_ST_GetParamDbl() */
2346 : /************************************************************************/
2347 : /**
2348 : * \brief Get Style Tool parameter value as a double
2349 : *
2350 : * Maps to the OGRStyleTool subclasses' GetParamDbl() methods.
2351 : *
2352 : * @param hST handle to the style tool.
2353 : * @param eParam the parameter id from the enumeration corresponding to the
2354 : * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2355 : * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2356 : * @param bValueIsNull pointer to an integer that will be set to TRUE or FALSE
2357 : * to indicate whether the parameter value is NULL.
2358 : *
2359 : * @return the parameter value as double and sets bValueIsNull.
2360 : */
2361 :
2362 105 : double OGR_ST_GetParamDbl(OGRStyleToolH hST, int eParam, int *bValueIsNull)
2363 : {
2364 105 : VALIDATE_POINTER1(hST, "OGR_ST_GetParamDbl", 0.0);
2365 105 : VALIDATE_POINTER1(bValueIsNull, "OGR_ST_GetParamDbl", 0.0);
2366 :
2367 105 : GBool bIsNull = TRUE;
2368 105 : double dfVal = 0.0;
2369 :
2370 105 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2371 : {
2372 4 : case OGRSTCPen:
2373 4 : dfVal = reinterpret_cast<OGRStylePen *>(hST)->GetParamDbl(
2374 : static_cast<OGRSTPenParam>(eParam), bIsNull);
2375 4 : break;
2376 0 : case OGRSTCBrush:
2377 0 : dfVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetParamDbl(
2378 : static_cast<OGRSTBrushParam>(eParam), bIsNull);
2379 0 : break;
2380 51 : case OGRSTCSymbol:
2381 51 : dfVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetParamDbl(
2382 : static_cast<OGRSTSymbolParam>(eParam), bIsNull);
2383 51 : break;
2384 50 : case OGRSTCLabel:
2385 50 : dfVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetParamDbl(
2386 : static_cast<OGRSTLabelParam>(eParam), bIsNull);
2387 50 : break;
2388 0 : default:
2389 0 : break;
2390 : }
2391 :
2392 105 : *bValueIsNull = bIsNull;
2393 105 : return dfVal;
2394 : }
2395 :
2396 : /************************************************************************/
2397 : /* OGR_ST_SetParamStr() */
2398 : /************************************************************************/
2399 : /**
2400 : * \brief Set Style Tool parameter value from a string
2401 : *
2402 : * Maps to the OGRStyleTool subclasses' SetParamStr() methods.
2403 : *
2404 : * @param hST handle to the style tool.
2405 : * @param eParam the parameter id from the enumeration corresponding to the
2406 : * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2407 : * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2408 : * @param pszValue the new parameter value
2409 : *
2410 : */
2411 :
2412 0 : void OGR_ST_SetParamStr(OGRStyleToolH hST, int eParam, const char *pszValue)
2413 : {
2414 0 : VALIDATE_POINTER0(hST, "OGR_ST_SetParamStr");
2415 0 : VALIDATE_POINTER0(pszValue, "OGR_ST_SetParamStr");
2416 :
2417 0 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2418 : {
2419 0 : case OGRSTCPen:
2420 0 : reinterpret_cast<OGRStylePen *>(hST)->SetParamStr(
2421 : static_cast<OGRSTPenParam>(eParam), pszValue);
2422 0 : break;
2423 0 : case OGRSTCBrush:
2424 0 : reinterpret_cast<OGRStyleBrush *>(hST)->SetParamStr(
2425 : static_cast<OGRSTBrushParam>(eParam), pszValue);
2426 0 : break;
2427 0 : case OGRSTCSymbol:
2428 0 : reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamStr(
2429 : static_cast<OGRSTSymbolParam>(eParam), pszValue);
2430 0 : break;
2431 0 : case OGRSTCLabel:
2432 0 : reinterpret_cast<OGRStyleLabel *>(hST)->SetParamStr(
2433 : static_cast<OGRSTLabelParam>(eParam), pszValue);
2434 0 : break;
2435 0 : default:
2436 0 : break;
2437 : }
2438 : }
2439 :
2440 : /************************************************************************/
2441 : /* OGR_ST_SetParamNum() */
2442 : /************************************************************************/
2443 : /**
2444 : * \brief Set Style Tool parameter value from an integer
2445 : *
2446 : * Maps to the OGRStyleTool subclasses' SetParamNum() methods.
2447 : *
2448 : * @param hST handle to the style tool.
2449 : * @param eParam the parameter id from the enumeration corresponding to the
2450 : * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2451 : * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2452 : * @param nValue the new parameter value
2453 : *
2454 : */
2455 :
2456 0 : void OGR_ST_SetParamNum(OGRStyleToolH hST, int eParam, int nValue)
2457 : {
2458 0 : VALIDATE_POINTER0(hST, "OGR_ST_SetParamNum");
2459 :
2460 0 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2461 : {
2462 0 : case OGRSTCPen:
2463 0 : reinterpret_cast<OGRStylePen *>(hST)->SetParamNum(
2464 : static_cast<OGRSTPenParam>(eParam), nValue);
2465 0 : break;
2466 0 : case OGRSTCBrush:
2467 0 : reinterpret_cast<OGRStyleBrush *>(hST)->SetParamNum(
2468 : static_cast<OGRSTBrushParam>(eParam), nValue);
2469 0 : break;
2470 0 : case OGRSTCSymbol:
2471 0 : reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamNum(
2472 : static_cast<OGRSTSymbolParam>(eParam), nValue);
2473 0 : break;
2474 0 : case OGRSTCLabel:
2475 0 : reinterpret_cast<OGRStyleLabel *>(hST)->SetParamNum(
2476 : static_cast<OGRSTLabelParam>(eParam), nValue);
2477 0 : break;
2478 0 : default:
2479 0 : break;
2480 : }
2481 : }
2482 :
2483 : /************************************************************************/
2484 : /* OGR_ST_SetParamDbl() */
2485 : /************************************************************************/
2486 : /**
2487 : * \brief Set Style Tool parameter value from a double
2488 : *
2489 : * Maps to the OGRStyleTool subclasses' SetParamDbl() methods.
2490 : *
2491 : * @param hST handle to the style tool.
2492 : * @param eParam the parameter id from the enumeration corresponding to the
2493 : * type of this style tool (one of the OGRSTPenParam, OGRSTBrushParam,
2494 : * OGRSTSymbolParam or OGRSTLabelParam enumerations)
2495 : * @param dfValue the new parameter value
2496 : *
2497 : */
2498 :
2499 0 : void OGR_ST_SetParamDbl(OGRStyleToolH hST, int eParam, double dfValue)
2500 : {
2501 0 : VALIDATE_POINTER0(hST, "OGR_ST_SetParamDbl");
2502 :
2503 0 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2504 : {
2505 0 : case OGRSTCPen:
2506 0 : reinterpret_cast<OGRStylePen *>(hST)->SetParamDbl(
2507 : static_cast<OGRSTPenParam>(eParam), dfValue);
2508 0 : break;
2509 0 : case OGRSTCBrush:
2510 0 : reinterpret_cast<OGRStyleBrush *>(hST)->SetParamDbl(
2511 : static_cast<OGRSTBrushParam>(eParam), dfValue);
2512 0 : break;
2513 0 : case OGRSTCSymbol:
2514 0 : reinterpret_cast<OGRStyleSymbol *>(hST)->SetParamDbl(
2515 : static_cast<OGRSTSymbolParam>(eParam), dfValue);
2516 0 : break;
2517 0 : case OGRSTCLabel:
2518 0 : reinterpret_cast<OGRStyleLabel *>(hST)->SetParamDbl(
2519 : static_cast<OGRSTLabelParam>(eParam), dfValue);
2520 0 : break;
2521 0 : default:
2522 0 : break;
2523 : }
2524 : }
2525 :
2526 : /************************************************************************/
2527 : /* OGR_ST_GetStyleString() */
2528 : /************************************************************************/
2529 :
2530 : /**
2531 : * \fn OGRStyleTool::GetStyleString()
2532 : * \brief Get the style string for this Style Tool
2533 : *
2534 : * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
2535 : *
2536 : * @return the style string for this style tool or "" if the hST is invalid.
2537 : */
2538 :
2539 : /**
2540 : * \brief Get the style string for this Style Tool
2541 : *
2542 : * Maps to the OGRStyleTool subclasses' GetStyleString() methods.
2543 : *
2544 : * @param hST handle to the style tool.
2545 : *
2546 : * @return the style string for this style tool or "" if the hST is invalid.
2547 : */
2548 :
2549 0 : const char *OGR_ST_GetStyleString(OGRStyleToolH hST)
2550 : {
2551 0 : const char *pszVal = "";
2552 :
2553 0 : VALIDATE_POINTER1(hST, "OGR_ST_GetStyleString", "");
2554 :
2555 0 : switch (reinterpret_cast<OGRStyleTool *>(hST)->GetType())
2556 : {
2557 0 : case OGRSTCPen:
2558 0 : pszVal = reinterpret_cast<OGRStylePen *>(hST)->GetStyleString();
2559 0 : break;
2560 0 : case OGRSTCBrush:
2561 0 : pszVal = reinterpret_cast<OGRStyleBrush *>(hST)->GetStyleString();
2562 0 : break;
2563 0 : case OGRSTCSymbol:
2564 0 : pszVal = reinterpret_cast<OGRStyleSymbol *>(hST)->GetStyleString();
2565 0 : break;
2566 0 : case OGRSTCLabel:
2567 0 : pszVal = reinterpret_cast<OGRStyleLabel *>(hST)->GetStyleString();
2568 0 : break;
2569 0 : default:
2570 0 : break;
2571 : }
2572 :
2573 0 : return pszVal;
2574 : }
2575 :
2576 : /************************************************************************/
2577 : /* OGR_ST_GetRGBFromString() */
2578 : /************************************************************************/
2579 : /**
2580 : * \brief Return the r,g,b,a components of a color encoded in \#RRGGBB[AA]
2581 : * format.
2582 : *
2583 : * Maps to OGRStyleTool::GetRGBFromString().
2584 : *
2585 : * @param hST handle to the style tool.
2586 : * @param pszColor the color to parse
2587 : * @param pnRed pointer to an int in which the red value will be returned
2588 : * @param pnGreen pointer to an int in which the green value will be returned
2589 : * @param pnBlue pointer to an int in which the blue value will be returned
2590 : * @param pnAlpha pointer to an int in which the (optional) alpha value will
2591 : * be returned
2592 : *
2593 : * @return TRUE if the color could be successfully parsed, or FALSE in case of
2594 : * errors.
2595 : */
2596 :
2597 0 : int OGR_ST_GetRGBFromString(OGRStyleToolH hST, const char *pszColor, int *pnRed,
2598 : int *pnGreen, int *pnBlue, int *pnAlpha)
2599 : {
2600 :
2601 0 : VALIDATE_POINTER1(hST, "OGR_ST_GetRGBFromString", FALSE);
2602 0 : VALIDATE_POINTER1(pnRed, "OGR_ST_GetRGBFromString", FALSE);
2603 0 : VALIDATE_POINTER1(pnGreen, "OGR_ST_GetRGBFromString", FALSE);
2604 0 : VALIDATE_POINTER1(pnBlue, "OGR_ST_GetRGBFromString", FALSE);
2605 0 : VALIDATE_POINTER1(pnAlpha, "OGR_ST_GetRGBFromString", FALSE);
2606 :
2607 0 : return reinterpret_cast<OGRStyleTool *>(hST)->GetRGBFromString(
2608 0 : pszColor, *pnRed, *pnGreen, *pnBlue, *pnAlpha);
2609 : }
2610 :
2611 : //! @cond Doxygen_Suppress
2612 : /* ======================================================================== */
2613 : /* OGRStylePen */
2614 : /* Specific parameter (Set/Get) for the StylePen */
2615 : /* ======================================================================== */
2616 :
2617 : /****************************************************************************/
2618 : /* OGRStylePen::OGRStylePen() */
2619 : /* */
2620 : /****************************************************************************/
2621 253 : OGRStylePen::OGRStylePen()
2622 : : OGRStyleTool(OGRSTCPen),
2623 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2624 253 : CPLCalloc(OGRSTPenLast, sizeof(OGRStyleValue))))
2625 : {
2626 253 : }
2627 :
2628 : /****************************************************************************/
2629 : /* OGRStylePen::~OGRStylePen() */
2630 : /* */
2631 : /****************************************************************************/
2632 496 : OGRStylePen::~OGRStylePen()
2633 : {
2634 2277 : for (int i = 0; i < OGRSTPenLast; i++)
2635 : {
2636 2024 : if (m_pasStyleValue[i].pszValue != nullptr)
2637 : {
2638 192 : CPLFree(m_pasStyleValue[i].pszValue);
2639 192 : m_pasStyleValue[i].pszValue = nullptr;
2640 : }
2641 : }
2642 :
2643 253 : CPLFree(m_pasStyleValue);
2644 496 : }
2645 :
2646 : /************************************************************************/
2647 : /* OGRStylePen::Parse() */
2648 : /************************************************************************/
2649 472 : GBool OGRStylePen::Parse()
2650 :
2651 : {
2652 472 : return OGRStyleTool::Parse(asStylePen, m_pasStyleValue,
2653 472 : static_cast<int>(OGRSTPenLast));
2654 : }
2655 :
2656 : /************************************************************************/
2657 : /* GetParamStr() */
2658 : /************************************************************************/
2659 83 : const char *OGRStylePen::GetParamStr(OGRSTPenParam eParam, GBool &bValueIsNull)
2660 : {
2661 166 : return OGRStyleTool::GetParamStr(asStylePen[eParam],
2662 83 : m_pasStyleValue[eParam], bValueIsNull);
2663 : }
2664 :
2665 : /************************************************************************/
2666 : /* GetParamNum() */
2667 : /************************************************************************/
2668 0 : int OGRStylePen::GetParamNum(OGRSTPenParam eParam, GBool &bValueIsNull)
2669 : {
2670 0 : return OGRStyleTool::GetParamNum(asStylePen[eParam],
2671 0 : m_pasStyleValue[eParam], bValueIsNull);
2672 : }
2673 :
2674 : /************************************************************************/
2675 : /* GetParamDbl() */
2676 : /************************************************************************/
2677 73 : double OGRStylePen::GetParamDbl(OGRSTPenParam eParam, GBool &bValueIsNull)
2678 : {
2679 146 : return OGRStyleTool::GetParamDbl(asStylePen[eParam],
2680 73 : m_pasStyleValue[eParam], bValueIsNull);
2681 : }
2682 :
2683 : /************************************************************************/
2684 : /* SetParamStr() */
2685 : /************************************************************************/
2686 :
2687 53 : void OGRStylePen::SetParamStr(OGRSTPenParam eParam, const char *pszParamString)
2688 : {
2689 53 : OGRStyleTool::SetParamStr(asStylePen[eParam], m_pasStyleValue[eParam],
2690 : pszParamString);
2691 53 : }
2692 :
2693 : /************************************************************************/
2694 : /* SetParamNum() */
2695 : /************************************************************************/
2696 0 : void OGRStylePen::SetParamNum(OGRSTPenParam eParam, int nParam)
2697 : {
2698 0 : OGRStyleTool::SetParamNum(asStylePen[eParam], m_pasStyleValue[eParam],
2699 : nParam);
2700 0 : }
2701 :
2702 : /************************************************************************/
2703 : /* SetParamDbl() */
2704 : /************************************************************************/
2705 83 : void OGRStylePen::SetParamDbl(OGRSTPenParam eParam, double dfParam)
2706 : {
2707 83 : OGRStyleTool::SetParamDbl(asStylePen[eParam], m_pasStyleValue[eParam],
2708 : dfParam);
2709 83 : }
2710 :
2711 : /************************************************************************/
2712 : /* GetStyleString() */
2713 : /************************************************************************/
2714 396 : const char *OGRStylePen::GetStyleString()
2715 : {
2716 396 : return OGRStyleTool::GetStyleString(asStylePen, m_pasStyleValue,
2717 396 : static_cast<int>(OGRSTPenLast));
2718 : }
2719 :
2720 : /****************************************************************************/
2721 : /* OGRStyleBrush::OGRStyleBrush() */
2722 : /* */
2723 : /****************************************************************************/
2724 139 : OGRStyleBrush::OGRStyleBrush()
2725 : : OGRStyleTool(OGRSTCBrush),
2726 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2727 139 : CPLCalloc(OGRSTBrushLast, sizeof(OGRStyleValue))))
2728 : {
2729 139 : }
2730 :
2731 : /****************************************************************************/
2732 : /* OGRStyleBrush::~OGRStyleBrush() */
2733 : /* */
2734 : /****************************************************************************/
2735 278 : OGRStyleBrush::~OGRStyleBrush()
2736 : {
2737 1251 : for (int i = 0; i < OGRSTBrushLast; i++)
2738 : {
2739 1112 : if (m_pasStyleValue[i].pszValue != nullptr)
2740 : {
2741 170 : CPLFree(m_pasStyleValue[i].pszValue);
2742 170 : m_pasStyleValue[i].pszValue = nullptr;
2743 : }
2744 : }
2745 :
2746 139 : CPLFree(m_pasStyleValue);
2747 278 : }
2748 :
2749 : /************************************************************************/
2750 : /* Parse() */
2751 : /************************************************************************/
2752 283 : GBool OGRStyleBrush::Parse()
2753 : {
2754 283 : return OGRStyleTool::Parse(asStyleBrush, m_pasStyleValue,
2755 283 : static_cast<int>(OGRSTBrushLast));
2756 : }
2757 :
2758 : /************************************************************************/
2759 : /* GetParamStr() */
2760 : /************************************************************************/
2761 91 : const char *OGRStyleBrush::GetParamStr(OGRSTBrushParam eParam,
2762 : GBool &bValueIsNull)
2763 : {
2764 182 : return OGRStyleTool::GetParamStr(asStyleBrush[eParam],
2765 91 : m_pasStyleValue[eParam], bValueIsNull);
2766 : }
2767 :
2768 : /************************************************************************/
2769 : /* GetParamNum() */
2770 : /************************************************************************/
2771 0 : int OGRStyleBrush::GetParamNum(OGRSTBrushParam eParam, GBool &bValueIsNull)
2772 : {
2773 0 : return OGRStyleTool::GetParamNum(asStyleBrush[eParam],
2774 0 : m_pasStyleValue[eParam], bValueIsNull);
2775 : }
2776 :
2777 : /************************************************************************/
2778 : /* GetParamDbl() */
2779 : /************************************************************************/
2780 20 : double OGRStyleBrush::GetParamDbl(OGRSTBrushParam eParam, GBool &bValueIsNull)
2781 : {
2782 40 : return OGRStyleTool::GetParamDbl(asStyleBrush[eParam],
2783 20 : m_pasStyleValue[eParam], bValueIsNull);
2784 : }
2785 :
2786 : /************************************************************************/
2787 : /* SetParamStr() */
2788 : /************************************************************************/
2789 83 : void OGRStyleBrush::SetParamStr(OGRSTBrushParam eParam,
2790 : const char *pszParamString)
2791 : {
2792 83 : OGRStyleTool::SetParamStr(asStyleBrush[eParam], m_pasStyleValue[eParam],
2793 : pszParamString);
2794 83 : }
2795 :
2796 : /************************************************************************/
2797 : /* SetParamNum() */
2798 : /************************************************************************/
2799 0 : void OGRStyleBrush::SetParamNum(OGRSTBrushParam eParam, int nParam)
2800 : {
2801 0 : OGRStyleTool::SetParamNum(asStyleBrush[eParam], m_pasStyleValue[eParam],
2802 : nParam);
2803 0 : }
2804 :
2805 : /************************************************************************/
2806 : /* SetParamDbl() */
2807 : /************************************************************************/
2808 0 : void OGRStyleBrush::SetParamDbl(OGRSTBrushParam eParam, double dfParam)
2809 : {
2810 0 : OGRStyleTool::SetParamDbl(asStyleBrush[eParam], m_pasStyleValue[eParam],
2811 : dfParam);
2812 0 : }
2813 :
2814 : /************************************************************************/
2815 : /* GetStyleString() */
2816 : /************************************************************************/
2817 170 : const char *OGRStyleBrush::GetStyleString()
2818 : {
2819 170 : return OGRStyleTool::GetStyleString(asStyleBrush, m_pasStyleValue,
2820 170 : static_cast<int>(OGRSTBrushLast));
2821 : }
2822 :
2823 : /****************************************************************************/
2824 : /* OGRStyleSymbol::OGRStyleSymbol() */
2825 : /****************************************************************************/
2826 332 : OGRStyleSymbol::OGRStyleSymbol()
2827 : : OGRStyleTool(OGRSTCSymbol),
2828 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2829 332 : CPLCalloc(OGRSTSymbolLast, sizeof(OGRStyleValue))))
2830 : {
2831 332 : }
2832 :
2833 : /****************************************************************************/
2834 : /* OGRStyleSymbol::~OGRStyleSymbol() */
2835 : /* */
2836 : /****************************************************************************/
2837 664 : OGRStyleSymbol::~OGRStyleSymbol()
2838 : {
2839 4316 : for (int i = 0; i < OGRSTSymbolLast; i++)
2840 : {
2841 3984 : if (m_pasStyleValue[i].pszValue != nullptr)
2842 : {
2843 619 : CPLFree(m_pasStyleValue[i].pszValue);
2844 619 : m_pasStyleValue[i].pszValue = nullptr;
2845 : }
2846 : }
2847 :
2848 332 : CPLFree(m_pasStyleValue);
2849 664 : }
2850 :
2851 : /************************************************************************/
2852 : /* Parse() */
2853 : /************************************************************************/
2854 1765 : GBool OGRStyleSymbol::Parse()
2855 : {
2856 1765 : return OGRStyleTool::Parse(asStyleSymbol, m_pasStyleValue,
2857 1765 : static_cast<int>(OGRSTSymbolLast));
2858 : }
2859 :
2860 : /************************************************************************/
2861 : /* GetParamStr() */
2862 : /************************************************************************/
2863 451 : const char *OGRStyleSymbol::GetParamStr(OGRSTSymbolParam eParam,
2864 : GBool &bValueIsNull)
2865 : {
2866 902 : return OGRStyleTool::GetParamStr(asStyleSymbol[eParam],
2867 451 : m_pasStyleValue[eParam], bValueIsNull);
2868 : }
2869 :
2870 : /************************************************************************/
2871 : /* GetParamNum() */
2872 : /************************************************************************/
2873 0 : int OGRStyleSymbol::GetParamNum(OGRSTSymbolParam eParam, GBool &bValueIsNull)
2874 : {
2875 0 : return OGRStyleTool::GetParamNum(asStyleSymbol[eParam],
2876 0 : m_pasStyleValue[eParam], bValueIsNull);
2877 : }
2878 :
2879 : /************************************************************************/
2880 : /* GetParamDbl() */
2881 : /************************************************************************/
2882 192 : double OGRStyleSymbol::GetParamDbl(OGRSTSymbolParam eParam, GBool &bValueIsNull)
2883 : {
2884 384 : return OGRStyleTool::GetParamDbl(asStyleSymbol[eParam],
2885 192 : m_pasStyleValue[eParam], bValueIsNull);
2886 : }
2887 :
2888 : /************************************************************************/
2889 : /* SetParamStr() */
2890 : /************************************************************************/
2891 63 : void OGRStyleSymbol::SetParamStr(OGRSTSymbolParam eParam,
2892 : const char *pszParamString)
2893 : {
2894 63 : OGRStyleTool::SetParamStr(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2895 : pszParamString);
2896 63 : }
2897 :
2898 : /************************************************************************/
2899 : /* SetParamNum() */
2900 : /************************************************************************/
2901 0 : void OGRStyleSymbol::SetParamNum(OGRSTSymbolParam eParam, int nParam)
2902 : {
2903 0 : OGRStyleTool::SetParamNum(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2904 : nParam);
2905 0 : }
2906 :
2907 : /************************************************************************/
2908 : /* SetParamDbl() */
2909 : /************************************************************************/
2910 10 : void OGRStyleSymbol::SetParamDbl(OGRSTSymbolParam eParam, double dfParam)
2911 : {
2912 10 : OGRStyleTool::SetParamDbl(asStyleSymbol[eParam], m_pasStyleValue[eParam],
2913 : dfParam);
2914 10 : }
2915 :
2916 : /************************************************************************/
2917 : /* GetStyleString() */
2918 : /************************************************************************/
2919 110 : const char *OGRStyleSymbol::GetStyleString()
2920 : {
2921 110 : return OGRStyleTool::GetStyleString(asStyleSymbol, m_pasStyleValue,
2922 110 : static_cast<int>(OGRSTSymbolLast));
2923 : }
2924 :
2925 : /****************************************************************************/
2926 : /* OGRStyleLabel::OGRStyleLabel() */
2927 : /* */
2928 : /****************************************************************************/
2929 24 : OGRStyleLabel::OGRStyleLabel()
2930 : : OGRStyleTool(OGRSTCLabel),
2931 : m_pasStyleValue(static_cast<OGRStyleValue *>(
2932 24 : CPLCalloc(OGRSTLabelLast, sizeof(OGRStyleValue))))
2933 : {
2934 24 : }
2935 :
2936 : /****************************************************************************/
2937 : /* OGRStyleLabel::~OGRStyleLabel() */
2938 : /* */
2939 : /****************************************************************************/
2940 48 : OGRStyleLabel::~OGRStyleLabel()
2941 : {
2942 528 : for (int i = 0; i < OGRSTLabelLast; i++)
2943 : {
2944 504 : if (m_pasStyleValue[i].pszValue != nullptr)
2945 : {
2946 42 : CPLFree(m_pasStyleValue[i].pszValue);
2947 42 : m_pasStyleValue[i].pszValue = nullptr;
2948 : }
2949 : }
2950 :
2951 24 : CPLFree(m_pasStyleValue);
2952 48 : }
2953 :
2954 : /************************************************************************/
2955 : /* Parse() */
2956 : /************************************************************************/
2957 281 : GBool OGRStyleLabel::Parse()
2958 : {
2959 281 : return OGRStyleTool::Parse(asStyleLabel, m_pasStyleValue,
2960 281 : static_cast<int>(OGRSTLabelLast));
2961 : }
2962 :
2963 : /************************************************************************/
2964 : /* GetParamStr() */
2965 : /************************************************************************/
2966 62 : const char *OGRStyleLabel::GetParamStr(OGRSTLabelParam eParam,
2967 : GBool &bValueIsNull)
2968 : {
2969 124 : return OGRStyleTool::GetParamStr(asStyleLabel[eParam],
2970 62 : m_pasStyleValue[eParam], bValueIsNull);
2971 : }
2972 :
2973 : /************************************************************************/
2974 : /* GetParamNum() */
2975 : /************************************************************************/
2976 49 : int OGRStyleLabel::GetParamNum(OGRSTLabelParam eParam, GBool &bValueIsNull)
2977 : {
2978 98 : return OGRStyleTool::GetParamNum(asStyleLabel[eParam],
2979 49 : m_pasStyleValue[eParam], bValueIsNull);
2980 : }
2981 :
2982 : /************************************************************************/
2983 : /* GetParamDbl() */
2984 : /************************************************************************/
2985 77 : double OGRStyleLabel::GetParamDbl(OGRSTLabelParam eParam, GBool &bValueIsNull)
2986 : {
2987 154 : return OGRStyleTool::GetParamDbl(asStyleLabel[eParam],
2988 77 : m_pasStyleValue[eParam], bValueIsNull);
2989 : }
2990 :
2991 : /************************************************************************/
2992 : /* SetParamStr() */
2993 : /************************************************************************/
2994 5 : void OGRStyleLabel::SetParamStr(OGRSTLabelParam eParam,
2995 : const char *pszParamString)
2996 : {
2997 5 : OGRStyleTool::SetParamStr(asStyleLabel[eParam], m_pasStyleValue[eParam],
2998 : pszParamString);
2999 5 : }
3000 :
3001 : /************************************************************************/
3002 : /* SetParamNum() */
3003 : /************************************************************************/
3004 0 : void OGRStyleLabel::SetParamNum(OGRSTLabelParam eParam, int nParam)
3005 : {
3006 0 : OGRStyleTool::SetParamNum(asStyleLabel[eParam], m_pasStyleValue[eParam],
3007 : nParam);
3008 0 : }
3009 :
3010 : /************************************************************************/
3011 : /* SetParamDbl() */
3012 : /************************************************************************/
3013 5 : void OGRStyleLabel::SetParamDbl(OGRSTLabelParam eParam, double dfParam)
3014 : {
3015 5 : OGRStyleTool::SetParamDbl(asStyleLabel[eParam], m_pasStyleValue[eParam],
3016 : dfParam);
3017 5 : }
3018 :
3019 : /************************************************************************/
3020 : /* GetStyleString() */
3021 : /************************************************************************/
3022 10 : const char *OGRStyleLabel::GetStyleString()
3023 : {
3024 10 : return OGRStyleTool::GetStyleString(asStyleLabel, m_pasStyleValue,
3025 10 : static_cast<int>(OGRSTLabelLast));
3026 : }
3027 :
3028 : //! @endcond
|