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