1 : /******************************************************************************
2 : *
3 : * Project: KML Translator
4 : * Purpose: Implements OGRLIBKMLDriver
5 : * Author: Brian Case, rush at winkey dot org
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2010, Brian Case
9 : *
10 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : *****************************************************************************/
28 :
29 : #include <ogr_featurestyle.h>
30 :
31 : #include <kml/dom.h>
32 : #include <kml/base/color32.h>
33 :
34 : using kmldom::KmlFactory;;
35 : using kmldom::ElementPtr;
36 : using kmldom::ObjectPtr;
37 : using kmldom::FeaturePtr;
38 : using kmldom::StylePtr;
39 : using kmldom::StyleSelectorPtr;
40 : using kmldom::LineStylePtr;
41 : using kmldom::PolyStylePtr;
42 : using kmldom::IconStylePtr;
43 : using kmldom::IconStyleIconPtr;
44 : using kmldom::LabelStylePtr;
45 : using kmldom::HotSpotPtr;
46 : using kmlbase::Color32;
47 :
48 : #include "ogrlibkmlstyle.h"
49 :
50 : /******************************************************************************
51 : generic function to parse a stylestring and add to a kml style
52 :
53 : args:
54 : pszStyleString the stylestring to parse
55 : poKmlStyle the kml style to add to
56 : poKmlFactory the kml dom factory
57 :
58 : returns:
59 : nothing
60 :
61 : ******************************************************************************/
62 :
63 0 : void addstylestring2kml (
64 : const char *pszStyleString,
65 : StylePtr poKmlStyle,
66 : KmlFactory * poKmlFactory,
67 : PlacemarkPtr poKmlPlacemark,
68 : OGRFeature * poOgrFeat )
69 : {
70 :
71 0 : LineStylePtr poKmlLineStyle = NULL;
72 0 : PolyStylePtr poKmlPolyStyle = NULL;
73 0 : IconStylePtr poKmlIconStyle = NULL;
74 0 : LabelStylePtr poKmlLabelStyle = NULL;
75 :
76 : /***** just bail now if stylestring is empty *****/
77 :
78 0 : if ( !pszStyleString || !*pszStyleString ) {
79 : return;
80 : }
81 :
82 : /***** create and init a style mamager with the style string *****/
83 :
84 0 : OGRStyleMgr *poOgrSM = new OGRStyleMgr;
85 :
86 0 : poOgrSM->InitStyleString ( pszStyleString );
87 :
88 : /***** loop though the style parts *****/
89 :
90 : int i;
91 :
92 0 : for ( i = 0; i < poOgrSM->GetPartCount ( NULL ); i++ ) {
93 0 : OGRStyleTool *poOgrST = poOgrSM->GetPart ( i, NULL );
94 :
95 0 : if ( !poOgrST ) {
96 0 : continue;
97 : }
98 :
99 0 : switch ( poOgrST->GetType ( ) ) {
100 : case OGRSTCPen:
101 : {
102 : GBool nullcheck;
103 :
104 0 : poKmlLineStyle = poKmlFactory->CreateLineStyle ( );
105 :
106 0 : OGRStylePen *poStylePen = ( OGRStylePen * ) poOgrST;
107 :
108 : /***** pen color *****/
109 :
110 : int nR,
111 : nG,
112 : nB,
113 : nA;
114 :
115 0 : const char *pszcolor = poStylePen->Color ( nullcheck );
116 :
117 0 : if ( !nullcheck
118 : && poStylePen->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
119 0 : poKmlLineStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
120 : }
121 0 : double dfWidth = poStylePen->Width ( nullcheck );
122 :
123 0 : if ( nullcheck )
124 0 : dfWidth = 1.0;
125 :
126 0 : poKmlLineStyle->set_width ( dfWidth );
127 :
128 0 : break;
129 : }
130 : case OGRSTCBrush:
131 : {
132 : GBool nullcheck;
133 :
134 0 : poKmlPolyStyle = poKmlFactory->CreatePolyStyle ( );
135 :
136 0 : OGRStyleBrush *poStyleBrush = ( OGRStyleBrush * ) poOgrST;
137 :
138 : /***** brush color *****/
139 :
140 : int nR,
141 : nG,
142 : nB,
143 : nA;
144 :
145 0 : const char *pszcolor = poStyleBrush->ForeColor ( nullcheck );
146 :
147 0 : if ( !nullcheck
148 : && poStyleBrush->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
149 0 : poKmlPolyStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
150 : }
151 :
152 :
153 0 : break;
154 : }
155 : case OGRSTCSymbol:
156 : {
157 : GBool nullcheck;
158 : GBool nullcheck2;
159 :
160 0 : OGRStyleSymbol *poStyleSymbol = ( OGRStyleSymbol * ) poOgrST;
161 :
162 : /***** id (kml icon) *****/
163 :
164 0 : const char *pszId = poStyleSymbol->Id ( nullcheck );
165 :
166 0 : if ( !nullcheck ) {
167 0 : if ( !poKmlIconStyle)
168 0 : poKmlIconStyle = poKmlFactory->CreateIconStyle ( );
169 :
170 : /***** split it at the ,'s *****/
171 :
172 : char **papszTokens =
173 : CSLTokenizeString2 ( pszId, ",",
174 : CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES |
175 0 : CSLT_STRIPENDSPACES );
176 :
177 0 : if ( papszTokens ) {
178 :
179 : /***** for lack of a better solution just take the first one *****/
180 : //todo come up with a better idea
181 :
182 0 : if ( papszTokens[0] ) {
183 : IconStyleIconPtr poKmlIcon =
184 0 : poKmlFactory->CreateIconStyleIcon ( );
185 0 : poKmlIcon->set_href ( papszTokens[0] );
186 0 : poKmlIconStyle->set_icon ( poKmlIcon );
187 : }
188 :
189 0 : CSLDestroy ( papszTokens );
190 :
191 : }
192 :
193 :
194 : }
195 :
196 : /***** heading *****/
197 :
198 0 : double heading = poStyleSymbol->Angle ( nullcheck );
199 :
200 0 : if ( !nullcheck ) {
201 0 : if ( !poKmlIconStyle)
202 0 : poKmlIconStyle = poKmlFactory->CreateIconStyle ( );
203 0 : poKmlIconStyle->set_heading ( heading );
204 : }
205 :
206 : /***** scale *****/
207 :
208 0 : double dfScale = poStyleSymbol->Size ( nullcheck );
209 :
210 0 : if ( !nullcheck ) {
211 0 : if ( !poKmlIconStyle)
212 0 : poKmlIconStyle = poKmlFactory->CreateIconStyle ( );
213 :
214 0 : poKmlIconStyle->set_scale ( dfScale );
215 : }
216 :
217 : /***** color *****/
218 :
219 : int nR,
220 : nG,
221 : nB,
222 : nA;
223 :
224 0 : const char *pszcolor = poStyleSymbol->Color ( nullcheck );
225 :
226 0 : if ( !nullcheck && poOgrST->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
227 0 : poKmlIconStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
228 : }
229 :
230 : /***** hotspot *****/
231 :
232 0 : double dfDx = poStyleSymbol->SpacingX ( nullcheck );
233 0 : double dfDy = poStyleSymbol->SpacingY ( nullcheck2 );
234 :
235 0 : if ( !nullcheck && !nullcheck2 ) {
236 0 : if ( !poKmlIconStyle)
237 0 : poKmlIconStyle = poKmlFactory->CreateIconStyle ( );
238 :
239 0 : HotSpotPtr poKmlHotSpot = poKmlFactory->CreateHotSpot ( );
240 :
241 0 : poKmlHotSpot->set_x ( dfDx );
242 0 : poKmlHotSpot->set_y ( dfDy );
243 :
244 0 : poKmlIconStyle->set_hotspot ( poKmlHotSpot );
245 : }
246 :
247 0 : break;
248 : }
249 : case OGRSTCLabel:
250 : {
251 : GBool nullcheck;
252 : GBool nullcheck2;
253 :
254 0 : poKmlLabelStyle = poKmlFactory->CreateLabelStyle ( );
255 :
256 0 : OGRStyleLabel *poStyleLabel = ( OGRStyleLabel * ) poOgrST;
257 :
258 : /***** color *****/
259 :
260 : int nR,
261 : nG,
262 : nB,
263 : nA;
264 :
265 0 : const char *pszcolor = poStyleLabel->ForeColor ( nullcheck );
266 :
267 0 : if ( !nullcheck
268 : && poStyleLabel->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
269 0 : poKmlLabelStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
270 : }
271 :
272 : /***** scale *****/
273 :
274 0 : double dfScale = poStyleLabel->Stretch ( nullcheck );
275 :
276 0 : if ( !nullcheck ) {
277 0 : dfScale /= 100.0;
278 0 : poKmlLabelStyle->set_scale ( dfScale );
279 : }
280 :
281 : /***** heading *****/
282 :
283 0 : double heading = poStyleLabel->Angle ( nullcheck );
284 :
285 0 : if ( !nullcheck ) {
286 0 : if ( !poKmlIconStyle) {
287 0 : poKmlIconStyle = poKmlFactory->CreateIconStyle ( );
288 0 : IconStyleIconPtr poKmlIcon = poKmlFactory->CreateIconStyleIcon ( );
289 0 : poKmlIconStyle->set_icon ( poKmlIcon );
290 : }
291 :
292 0 : poKmlIconStyle->set_heading ( heading );
293 : }
294 :
295 : /***** hotspot *****/
296 :
297 0 : double dfDx = poStyleLabel->SpacingX ( nullcheck );
298 0 : double dfDy = poStyleLabel->SpacingY ( nullcheck2 );
299 :
300 0 : if ( !nullcheck && !nullcheck2 ) {
301 0 : if ( !poKmlIconStyle) {
302 0 : poKmlIconStyle = poKmlFactory->CreateIconStyle ( );
303 0 : IconStyleIconPtr poKmlIcon = poKmlFactory->CreateIconStyleIcon ( );
304 0 : poKmlIconStyle->set_icon ( poKmlIcon );
305 : }
306 :
307 0 : HotSpotPtr poKmlHotSpot = poKmlFactory->CreateHotSpot ( );
308 :
309 0 : poKmlHotSpot->set_x ( dfDx );
310 0 : poKmlHotSpot->set_y ( dfDy );
311 :
312 0 : poKmlIconStyle->set_hotspot ( poKmlHotSpot );
313 : }
314 :
315 : /***** label text *****/
316 :
317 0 : const char *pszText = poStyleLabel->TextString ( nullcheck );
318 :
319 0 : if ( !nullcheck ) {
320 0 : if ( poKmlPlacemark ) {
321 :
322 0 : poKmlPlacemark->set_name( pszText );
323 : }
324 : }
325 :
326 : break;
327 : }
328 : case OGRSTCNone:
329 : default:
330 : break;
331 : }
332 :
333 0 : delete poOgrST;
334 : }
335 :
336 0 : if ( poKmlLineStyle )
337 0 : poKmlStyle->set_linestyle ( poKmlLineStyle );
338 :
339 0 : if ( poKmlPolyStyle )
340 0 : poKmlStyle->set_polystyle ( poKmlPolyStyle );
341 :
342 0 : if ( poKmlIconStyle )
343 0 : poKmlStyle->set_iconstyle ( poKmlIconStyle );
344 :
345 0 : if ( poKmlLabelStyle )
346 0 : poKmlStyle->set_labelstyle ( poKmlLabelStyle );
347 :
348 0 : delete poOgrSM;
349 : }
350 :
351 : /******************************************************************************
352 : kml2pen
353 : ******************************************************************************/
354 :
355 : OGRStylePen *kml2pen (
356 : LineStylePtr poKmlLineStyle,
357 : OGRStylePen *poOgrStylePen);
358 :
359 : /******************************************************************************
360 : kml2brush
361 : ******************************************************************************/
362 :
363 : OGRStyleBrush *kml2brush (
364 : PolyStylePtr poKmlPolyStyle,
365 : OGRStyleBrush *poOgrStyleBrush);
366 :
367 : /******************************************************************************
368 : kml2symbol
369 : ******************************************************************************/
370 :
371 : OGRStyleSymbol *kml2symbol (
372 : IconStylePtr poKmlIconStyle,
373 : OGRStyleSymbol *poOgrStyleSymbol);
374 :
375 : /******************************************************************************
376 : kml2label
377 : ******************************************************************************/
378 :
379 : OGRStyleLabel *kml2label (
380 : LabelStylePtr poKmlLabelStyle,
381 : OGRStyleLabel *poOgrStyleLabel);
382 :
383 : /******************************************************************************
384 : kml2stylemgr
385 : ******************************************************************************/
386 :
387 42 : void kml2stylestring (
388 : StylePtr poKmlStyle,
389 : OGRStyleMgr * poOgrSM )
390 :
391 : {
392 :
393 : OGRStyleMgr * poOgrNewSM ;
394 42 : OGRStyleTool *poOgrST = NULL;
395 42 : OGRStyleTool *poOgrTmpST = NULL;
396 : int i;
397 :
398 42 : poOgrNewSM = new OGRStyleMgr( NULL );
399 :
400 : /***** linestyle / pen *****/
401 :
402 42 : if ( poKmlStyle->has_linestyle ( ) ) {
403 :
404 30 : poOgrNewSM->InitStyleString ( NULL );
405 :
406 30 : LineStylePtr poKmlLineStyle = poKmlStyle->get_linestyle ( );
407 :
408 30 : poOgrTmpST = NULL;
409 30 : for ( i = 0; i < poOgrSM->GetPartCount ( NULL ); i++ ) {
410 0 : poOgrST = poOgrSM->GetPart ( i, NULL );
411 :
412 0 : if ( !poOgrST )
413 0 : continue;
414 :
415 0 : if ( poOgrST->GetType ( ) == OGRSTCPen ) {
416 0 : poOgrTmpST = poOgrST;
417 : }
418 : else {
419 0 : poOgrNewSM->AddPart ( poOgrST );
420 0 : delete poOgrST;
421 : }
422 : }
423 :
424 : OGRStylePen *poOgrStylePen = kml2pen ( poKmlLineStyle,
425 30 : ( OGRStylePen *) poOgrTmpST);
426 :
427 30 : poOgrNewSM->AddPart ( poOgrStylePen );
428 :
429 30 : delete poOgrStylePen;
430 30 : poOgrSM->InitStyleString ( poOgrNewSM->GetStyleString(NULL) );
431 :
432 : }
433 :
434 : /***** polystyle / brush *****/
435 :
436 42 : if ( poKmlStyle->has_polystyle ( ) ) {
437 :
438 24 : poOgrNewSM->InitStyleString ( NULL );
439 :
440 24 : PolyStylePtr poKmlPolyStyle = poKmlStyle->get_polystyle ( );
441 :
442 24 : poOgrTmpST = NULL;
443 48 : for ( i = 0; i < poOgrSM->GetPartCount ( NULL ); i++ ) {
444 24 : poOgrST = poOgrSM->GetPart ( i, NULL );
445 :
446 24 : if ( !poOgrST )
447 0 : continue;
448 :
449 24 : if ( poOgrST->GetType ( ) == OGRSTCBrush ) {
450 0 : poOgrTmpST = poOgrST;
451 : }
452 : else {
453 24 : poOgrNewSM->AddPart ( poOgrST );
454 24 : delete poOgrST;
455 : }
456 : }
457 :
458 : OGRStyleBrush *poOgrStyleBrush = kml2brush ( poKmlPolyStyle,
459 24 : ( OGRStyleBrush *) poOgrTmpST );
460 :
461 24 : poOgrNewSM->AddPart ( poOgrStyleBrush );
462 :
463 24 : delete poOgrStyleBrush;
464 24 : poOgrSM->InitStyleString ( poOgrNewSM->GetStyleString(NULL) );
465 :
466 : }
467 :
468 : /***** iconstyle / symbol *****/
469 :
470 42 : if ( poKmlStyle->has_iconstyle ( ) ) {
471 :
472 12 : poOgrNewSM->InitStyleString ( NULL );
473 :
474 12 : IconStylePtr poKmlIconStyle = poKmlStyle->get_iconstyle ( );
475 :
476 12 : poOgrTmpST = NULL;
477 15 : for ( i = 0; i < poOgrSM->GetPartCount ( NULL ); i++ ) {
478 3 : poOgrST = poOgrSM->GetPart ( i, NULL );
479 :
480 3 : if ( !poOgrST )
481 0 : continue;
482 :
483 3 : if ( poOgrST->GetType ( ) == OGRSTCSymbol ) {
484 0 : poOgrTmpST = poOgrST;
485 : }
486 : else {
487 3 : poOgrNewSM->AddPart ( poOgrST );
488 3 : delete poOgrST;
489 : }
490 : }
491 :
492 : OGRStyleSymbol *poOgrStyleSymbol = kml2symbol ( poKmlIconStyle,
493 12 : ( OGRStyleSymbol *) poOgrTmpST );
494 :
495 12 : poOgrNewSM->AddPart ( poOgrStyleSymbol );
496 :
497 12 : delete poOgrStyleSymbol;
498 12 : poOgrSM->InitStyleString ( poOgrNewSM->GetStyleString(NULL) );
499 :
500 : }
501 :
502 : /***** labelstyle / label *****/
503 :
504 42 : if ( poKmlStyle->has_labelstyle ( ) ) {
505 :
506 0 : poOgrNewSM->InitStyleString ( NULL );
507 :
508 0 : LabelStylePtr poKmlLabelStyle = poKmlStyle->get_labelstyle ( );
509 :
510 0 : poOgrTmpST = NULL;
511 0 : for ( i = 0; i < poOgrSM->GetPartCount ( NULL ); i++ ) {
512 0 : poOgrST = poOgrSM->GetPart ( i, NULL );
513 :
514 0 : if ( !poOgrST )
515 0 : continue;
516 :
517 0 : if ( poOgrST->GetType ( ) == OGRSTCLabel ) {
518 0 : poOgrTmpST = poOgrST;
519 : }
520 : else {
521 0 : poOgrNewSM->AddPart ( poOgrST );
522 0 : delete poOgrST;
523 : }
524 : }
525 :
526 : OGRStyleLabel *poOgrStyleLabel = kml2label ( poKmlLabelStyle,
527 0 : ( OGRStyleLabel *) poOgrTmpST );
528 :
529 0 : poOgrNewSM->AddPart ( poOgrStyleLabel );
530 :
531 0 : delete poOgrStyleLabel;
532 0 : poOgrSM->InitStyleString ( poOgrNewSM->GetStyleString(NULL) );
533 :
534 : }
535 :
536 42 : delete poOgrNewSM;
537 :
538 42 : }
539 :
540 :
541 :
542 : /******************************************************************************
543 : kml2pen
544 : ******************************************************************************/
545 :
546 30 : OGRStylePen *kml2pen (
547 : LineStylePtr poKmlLineStyle,
548 : OGRStylePen *poOgrStylePen)
549 : {
550 :
551 30 : if (!poOgrStylePen)
552 30 : poOgrStylePen = new OGRStylePen ( );
553 :
554 : /***** <LineStyle> should always have a width in pixels *****/
555 :
556 30 : poOgrStylePen->SetUnit(OGRSTUPixel);
557 :
558 : /***** width *****/
559 :
560 30 : if ( poKmlLineStyle->has_width ( ) )
561 24 : poOgrStylePen->SetWidth ( poKmlLineStyle->get_width ( ) );
562 :
563 : /***** color *****/
564 :
565 30 : if ( poKmlLineStyle->has_color ( ) ) {
566 15 : Color32 poKmlColor = poKmlLineStyle->get_color ( );
567 15 : char szColor[10] = { };
568 : snprintf ( szColor, sizeof ( szColor ), "#%02X%02X%02X%02X",
569 : poKmlColor.get_red ( ),
570 : poKmlColor.get_green ( ),
571 15 : poKmlColor.get_blue ( ), poKmlColor.get_alpha ( ) );
572 15 : poOgrStylePen->SetColor ( szColor );
573 : }
574 :
575 30 : return poOgrStylePen;
576 : }
577 :
578 : /******************************************************************************
579 : kml2brush
580 : ******************************************************************************/
581 :
582 24 : OGRStyleBrush *kml2brush (
583 : PolyStylePtr poKmlPolyStyle,
584 : OGRStyleBrush *poOgrStyleBrush)
585 : {
586 :
587 24 : if (!poOgrStyleBrush)
588 24 : poOgrStyleBrush = new OGRStyleBrush ( );
589 :
590 : /***** color *****/
591 :
592 24 : if ( poKmlPolyStyle->has_color ( ) ) {
593 24 : Color32 poKmlColor = poKmlPolyStyle->get_color ( );
594 24 : char szColor[10] = { };
595 : snprintf ( szColor, sizeof ( szColor ), "#%02X%02X%02X%02X",
596 : poKmlColor.get_red ( ),
597 : poKmlColor.get_green ( ),
598 24 : poKmlColor.get_blue ( ), poKmlColor.get_alpha ( ) );
599 24 : poOgrStyleBrush->SetForeColor ( szColor );
600 : }
601 :
602 24 : return poOgrStyleBrush;
603 : }
604 :
605 : /******************************************************************************
606 : kml2symbol
607 : ******************************************************************************/
608 :
609 12 : OGRStyleSymbol *kml2symbol (
610 : IconStylePtr poKmlIconStyle,
611 : OGRStyleSymbol *poOgrStyleSymbol)
612 : {
613 :
614 12 : if (!poOgrStyleSymbol)
615 12 : poOgrStyleSymbol = new OGRStyleSymbol ( );
616 :
617 : /***** id (kml icon) *****/
618 :
619 12 : if ( poKmlIconStyle->has_icon ( ) ) {
620 12 : IconStyleIconPtr poKmlIcon = poKmlIconStyle->get_icon ( );
621 :
622 12 : if ( poKmlIcon->has_href ( ) ) {
623 12 : std::string oIcon = "\"";
624 24 : oIcon.append ( poKmlIcon->get_href ( ).c_str ( ) );
625 12 : oIcon.append ( "\"" );
626 12 : poOgrStyleSymbol->SetId ( oIcon.c_str ( ) );
627 :
628 12 : }
629 : }
630 :
631 : /***** heading *****/
632 :
633 12 : if ( poKmlIconStyle->has_heading ( ) )
634 0 : poOgrStyleSymbol->SetAngle ( poKmlIconStyle->get_heading ( ) );
635 :
636 : /***** scale *****/
637 :
638 12 : if ( poKmlIconStyle->has_scale ( ) )
639 0 : poOgrStyleSymbol->SetSize ( poKmlIconStyle->get_scale ( ) );
640 :
641 : /***** color *****/
642 :
643 12 : if ( poKmlIconStyle->has_color ( ) ) {
644 0 : Color32 poKmlColor = poKmlIconStyle->get_color ( );
645 0 : char szColor[10] = { };
646 : snprintf ( szColor, sizeof ( szColor ), "#%02X%02X%02X%02X",
647 : poKmlColor.get_red ( ),
648 : poKmlColor.get_green ( ),
649 0 : poKmlColor.get_blue ( ), poKmlColor.get_alpha ( ) );
650 0 : poOgrStyleSymbol->SetColor ( szColor );
651 : }
652 :
653 : /***** hotspot *****/
654 :
655 12 : if ( poKmlIconStyle->has_hotspot ( ) ) {
656 0 : HotSpotPtr poKmlHotSpot = poKmlIconStyle->get_hotspot ( );
657 :
658 0 : if ( poKmlHotSpot->has_x ( ) )
659 0 : poOgrStyleSymbol->SetSpacingX ( poKmlHotSpot->get_x ( ) );
660 0 : if ( poKmlHotSpot->has_y ( ) )
661 0 : poOgrStyleSymbol->SetSpacingY ( poKmlHotSpot->get_y ( ) );
662 :
663 : }
664 :
665 12 : return poOgrStyleSymbol;
666 : }
667 :
668 : /******************************************************************************
669 : kml2label
670 : ******************************************************************************/
671 :
672 0 : OGRStyleLabel *kml2label (
673 : LabelStylePtr poKmlLabelStyle,
674 : OGRStyleLabel *poOgrStyleLabel)
675 : {
676 :
677 0 : if (!poOgrStyleLabel)
678 0 : poOgrStyleLabel = new OGRStyleLabel ( );
679 :
680 : /***** color *****/
681 :
682 0 : if ( poKmlLabelStyle->has_color ( ) ) {
683 0 : Color32 poKmlColor = poKmlLabelStyle->get_color ( );
684 0 : char szColor[10] = { };
685 : snprintf ( szColor, sizeof ( szColor ), "#%02X%02X%02X%02X",
686 : poKmlColor.get_red ( ),
687 : poKmlColor.get_green ( ),
688 0 : poKmlColor.get_blue ( ), poKmlColor.get_alpha ( ) );
689 0 : poOgrStyleLabel->SetForColor ( szColor );
690 : }
691 :
692 0 : if ( poKmlLabelStyle->has_scale ( ) ) {
693 0 : double dfScale = poKmlLabelStyle->get_scale ( );
694 0 : dfScale *= 100.0;
695 :
696 0 : poOgrStyleLabel->SetStretch(dfScale);
697 : }
698 :
699 0 : return poOgrStyleLabel;
700 : }
701 :
702 : /******************************************************************************
703 : function to add a kml style to a style table
704 : ******************************************************************************/
705 :
706 42 : void kml2styletable (
707 : OGRStyleTable * poOgrStyleTable,
708 : StylePtr poKmlStyle )
709 : {
710 :
711 :
712 : /***** no reason to add it if it don't have an id *****/
713 :
714 42 : if ( poKmlStyle->has_id ( ) ) {
715 :
716 42 : OGRStyleMgr *poOgrSM = new OGRStyleMgr ( poOgrStyleTable );
717 :
718 42 : poOgrSM->InitStyleString ( NULL );
719 :
720 : /***** read the style *****/
721 :
722 84 : kml2stylestring ( poKmlStyle, poOgrSM );
723 :
724 : /***** add the style to the style table *****/
725 :
726 42 : const std::string oName = poKmlStyle->get_id ( );
727 :
728 :
729 : poOgrSM->AddStyle ( CPLString ( ).Printf ( "@%s",
730 84 : oName.c_str ( ) ), NULL );
731 :
732 : /***** cleanup the style manager *****/
733 :
734 42 : delete poOgrSM;
735 : }
736 :
737 : else {
738 : CPLError ( CE_Failure, CPLE_AppDefined,
739 0 : "ERROR Parseing kml Style: No id" );
740 : }
741 :
742 : return;
743 : }
744 :
745 : /******************************************************************************
746 : function to parse a style table out of a document
747 : ******************************************************************************/
748 :
749 19 : void ParseStyles (
750 : DocumentPtr poKmlDocument,
751 : OGRStyleTable ** poStyleTable )
752 : {
753 :
754 : /***** if document is null just bail now *****/
755 :
756 19 : if ( !poKmlDocument )
757 0 : return;
758 :
759 : /***** loop over the Styles *****/
760 :
761 19 : size_t nKmlStyles = poKmlDocument->get_styleselector_array_size ( );
762 : size_t iKmlStyle;
763 :
764 61 : for ( iKmlStyle = 0; iKmlStyle < nKmlStyles; iKmlStyle++ ) {
765 :
766 : StyleSelectorPtr poKmlStyle =
767 45 : poKmlDocument->get_styleselector_array_at ( iKmlStyle );
768 :
769 45 : if ( !poKmlStyle->IsA ( kmldom::Type_Style ) )
770 3 : continue;
771 :
772 42 : if ( !*poStyleTable )
773 6 : *poStyleTable = new OGRStyleTable ( );
774 :
775 42 : ElementPtr poKmlElement = AsElement ( poKmlStyle );
776 :
777 42 : kml2styletable ( *poStyleTable, AsStyle ( poKmlElement ) );
778 : }
779 :
780 19 : return;
781 : }
782 :
783 : /******************************************************************************
784 : function to add a style table to a kml container
785 : ******************************************************************************/
786 :
787 0 : void styletable2kml (
788 : OGRStyleTable * poOgrStyleTable,
789 : KmlFactory * poKmlFactory,
790 : ContainerPtr poKmlContainer )
791 : {
792 :
793 : /***** just return if the styletable is null *****/
794 :
795 0 : if ( !poOgrStyleTable )
796 0 : return;
797 :
798 : /***** parse the style table *****/
799 :
800 0 : poOgrStyleTable->ResetStyleStringReading ( );
801 : const char *pszStyleString;
802 :
803 0 : while ( ( pszStyleString = poOgrStyleTable->GetNextStyle ( ) ) ) {
804 0 : const char *pszStyleName = poOgrStyleTable->GetLastStyleName ( );
805 :
806 : /***** add the style header to the kml *****/
807 :
808 0 : StylePtr poKmlStyle = poKmlFactory->CreateStyle ( );
809 :
810 0 : poKmlStyle->set_id ( pszStyleName + 1 );
811 :
812 : /***** parse the style string *****/
813 :
814 0 : addstylestring2kml ( pszStyleString, poKmlStyle, poKmlFactory, NULL, NULL );
815 :
816 : /***** add the style to the container *****/
817 :
818 0 : DocumentPtr poKmlDocument = AsDocument ( poKmlContainer );
819 :
820 : //ObjectPtr pokmlObject = boost::static_pointer_cast <kmldom::Object> () ;
821 : //poKmlContainer->add_feature ( AsFeature( poKmlStyle) );
822 0 : poKmlDocument->add_styleselector ( poKmlStyle );
823 :
824 : }
825 :
826 0 : return;
827 : }
|