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 <ogrsf_frmts.h>
30 : #include <ogr_featurestyle.h>
31 : #include <string>
32 : using namespace std;
33 :
34 : #include <kml/dom.h>
35 :
36 : using kmldom::KmlFactory;;
37 : using kmldom::IconStylePtr;
38 : using kmldom::PolyStylePtr;
39 : using kmldom::LineStylePtr;
40 : using kmldom::LabelStylePtr;
41 : using kmldom::StylePtr;
42 : using kmldom::Style;
43 : using kmldom::StyleMapPtr;
44 : using kmldom::StyleSelectorPtr;
45 :
46 :
47 : #include "ogrlibkmlfeaturestyle.h"
48 : #include "ogrlibkmlstyle.h"
49 :
50 : /******************************************************************************
51 : function to write out a features style to kml
52 :
53 : args:
54 : poOgrLayer the layer the feature is in
55 : poOgrFeat the feature
56 : poKmlFactory the kml dom factory
57 : poKmlPlacemark the placemark to add it to
58 :
59 : returns:
60 : nothing
61 : ******************************************************************************/
62 :
63 : void featurestyle2kml (
64 : OGRLIBKMLDataSource * poOgrDS,
65 : OGRLayer * poOgrLayer,
66 : OGRFeature * poOgrFeat,
67 : KmlFactory * poKmlFactory,
68 9 : PlacemarkPtr poKmlPlacemark )
69 : {
70 :
71 : /***** get the style table *****/
72 :
73 : OGRStyleTable *poOgrSTBL;
74 :
75 9 : const char *pszStyleString = poOgrFeat->GetStyleString ( );
76 :
77 : /***** does the feature have style? *****/
78 :
79 9 : if ( pszStyleString ) {
80 :
81 : /***** does it ref a style table? *****/
82 :
83 0 : if ( *pszStyleString == '@' ) {
84 :
85 : /***** is the name in the layer style table *****/
86 :
87 : OGRStyleTable *hSTBLLayer;
88 0 : const char *pszTest = NULL;
89 :
90 0 : if ( ( hSTBLLayer = poOgrLayer->GetStyleTable ( ) ) )
91 0 : pszTest = hSTBLLayer->Find ( pszStyleString );
92 :
93 0 : if ( pszTest ) {
94 0 : string oTmp = "#";
95 :
96 0 : oTmp.append ( pszStyleString + 1 );
97 :
98 0 : poKmlPlacemark->set_styleurl ( oTmp );
99 : }
100 :
101 :
102 : /***** assume its a dataset style, mayby the user will add it later *****/
103 :
104 : else {
105 0 : string oTmp;
106 :
107 0 : if ( poOgrDS->GetStylePath ( ) )
108 0 : oTmp.append ( poOgrDS->GetStylePath ( ) );
109 0 : oTmp.append ( "#" );
110 0 : oTmp.append ( pszStyleString + 1 );
111 :
112 0 : poKmlPlacemark->set_styleurl ( oTmp );
113 : }
114 : }
115 :
116 : /***** no style table ref *****/
117 :
118 : else {
119 0 : StylePtr poKmlStyle = poKmlFactory->CreateStyle ( );
120 :
121 : /***** parse the style string *****/
122 :
123 : addstylestring2kml ( pszStyleString, poKmlStyle, poKmlFactory,
124 0 : poKmlPlacemark, poOgrFeat );
125 :
126 : /***** add the style to the placemark *****/
127 :
128 0 : poKmlPlacemark->set_styleselector ( poKmlStyle );
129 :
130 : }
131 : }
132 :
133 : /***** get the style table *****/
134 :
135 9 : else if ( ( poOgrSTBL = poOgrFeat->GetStyleTable ( ) ) ) {
136 :
137 :
138 0 : StylePtr poKmlStyle = poKmlFactory->CreateStyle ( );
139 :
140 : /***** parse the style table *****/
141 :
142 0 : poOgrSTBL->ResetStyleStringReading ( );
143 : const char *pszStyleString;
144 :
145 0 : while ( ( pszStyleString = poOgrSTBL->GetNextStyle ( ) ) ) {
146 :
147 0 : if ( *pszStyleString == '@' ) {
148 :
149 : /***** is the name in the layer style table *****/
150 :
151 : OGRStyleTable *poOgrSTBLLayer;
152 0 : const char *pszTest = NULL;
153 :
154 0 : if ( ( poOgrSTBLLayer = poOgrLayer->GetStyleTable ( ) ) )
155 0 : poOgrSTBLLayer->Find ( pszStyleString );
156 :
157 0 : if ( pszTest ) {
158 0 : string oTmp = "#";
159 :
160 0 : oTmp.append ( pszStyleString + 1 );
161 :
162 0 : poKmlPlacemark->set_styleurl ( oTmp );
163 : }
164 :
165 : /***** assume its a dataset style, *****/
166 : /***** mayby the user will add it later *****/
167 :
168 : else {
169 0 : string oTmp;
170 :
171 0 : if ( poOgrDS->GetStylePath ( ) )
172 0 : oTmp.append ( poOgrDS->GetStylePath ( ) );
173 0 : oTmp.append ( "#" );
174 0 : oTmp.append ( pszStyleString + 1 );
175 :
176 0 : poKmlPlacemark->set_styleurl ( oTmp );
177 : }
178 : }
179 :
180 : else {
181 :
182 : /***** parse the style string *****/
183 :
184 : addstylestring2kml ( pszStyleString, poKmlStyle,
185 0 : poKmlFactory, poKmlPlacemark, poOgrFeat );
186 :
187 : /***** add the style to the placemark *****/
188 :
189 0 : poKmlPlacemark->set_styleselector ( poKmlStyle );
190 :
191 : }
192 0 : }
193 : }
194 9 : }
195 :
196 : /******************************************************************************
197 : function to read a kml style into ogr's featurestyle
198 : ******************************************************************************/
199 :
200 : void kml2featurestyle (
201 : PlacemarkPtr poKmlPlacemark,
202 : OGRLIBKMLDataSource * poOgrDS,
203 : OGRLayer * poOgrLayer,
204 54 : OGRFeature * poOgrFeat )
205 : {
206 :
207 : /***** does the placemark have a styleselector and a style url? *****/
208 :
209 54 : if ( poKmlPlacemark->has_styleselector ( )
210 : && poKmlPlacemark->has_styleurl ( ) ) {
211 :
212 : /* todo do the style and styleurl part */
213 :
214 : }
215 :
216 : /***** is the style a style url *****/
217 :
218 54 : else if ( poKmlPlacemark->has_styleurl ( ) ) {
219 :
220 15 : const string poKmlStyleUrl = poKmlPlacemark->get_styleurl ( );
221 :
222 : /***** is the name in the layer style table *****/
223 :
224 15 : char *pszTmp = CPLStrdup ( poKmlStyleUrl.c_str ( ) );
225 :
226 : OGRStyleTable *poOgrSTBLLayer;
227 15 : const char *pszTest = NULL;
228 :
229 15 : if ( *pszTmp == '#'
230 : && ( poOgrSTBLLayer = poOgrLayer->GetStyleTable ( ) ) )
231 1 : pszTest = poOgrSTBLLayer->Find ( pszTmp + 1 );
232 :
233 15 : if ( pszTest ) {
234 :
235 : /***** should we resolve the style *****/
236 :
237 0 : const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" );
238 :
239 0 : if (EQUAL(pszResolve, "yes")) {
240 0 : poOgrFeat->SetStyleString ( pszTest );
241 : }
242 :
243 : else {
244 0 : *pszTmp = '@';
245 :
246 0 : poOgrFeat->SetStyleStringDirectly ( pszTmp );
247 :
248 : }
249 :
250 : }
251 :
252 : /***** not a layer style *****/
253 :
254 :
255 : else {
256 :
257 : /***** is it a dataset style? *****/
258 :
259 15 : int nPathLen = strlen ( poOgrDS->GetStylePath ( ) );
260 :
261 15 : if ( !strncmp ( pszTmp, poOgrDS->GetStylePath ( ), nPathLen )) {
262 :
263 :
264 : /***** should we resolve the style *****/
265 :
266 15 : const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" );
267 :
268 15 : if ( EQUAL(pszResolve, "yes") &&
269 : ( poOgrSTBLLayer = poOgrDS->GetStyleTable ( ) ) &&
270 : ( pszTest = poOgrSTBLLayer->Find ( pszTmp + nPathLen + 1) )
271 : ) {
272 :
273 0 : poOgrFeat->SetStyleString ( pszTest );
274 : }
275 :
276 : else {
277 :
278 15 : pszTmp[nPathLen] = '@';
279 15 : poOgrFeat->SetStyleString ( pszTmp + nPathLen );
280 : }
281 :
282 15 : CPLFree ( pszTmp );
283 : }
284 :
285 : /**** its someplace else *****/
286 :
287 : else {
288 :
289 : //todo Handle out of DS style tables
290 :
291 : }
292 15 : }
293 :
294 : }
295 :
296 : /***** does the placemark have a style selector *****/
297 :
298 39 : else if ( poKmlPlacemark->has_styleselector ( ) ) {
299 :
300 : StyleSelectorPtr poKmlStyleSelector =
301 0 : poKmlPlacemark->get_styleselector ( );
302 :
303 : /***** is the style a style? *****/
304 :
305 0 : if ( poKmlStyleSelector->IsA ( kmldom::Type_Style ) ) {
306 0 : StylePtr poKmlStyle = AsStyle ( poKmlStyleSelector );
307 :
308 0 : OGRStyleMgr *poOgrSM = new OGRStyleMgr;
309 :
310 0 : poOgrSM->InitStyleString ( NULL );
311 :
312 : /***** read the style *****/
313 :
314 0 : kml2stylestring ( poKmlStyle, poOgrSM );
315 :
316 : /***** add the style to the feature *****/
317 :
318 0 : poOgrSM->SetFeatureStyleString ( poOgrFeat );
319 :
320 0 : delete poOgrSM;
321 : }
322 :
323 : /***** is the style a stylemap? *****/
324 :
325 0 : else if ( poKmlStyleSelector->IsA ( kmldom::Type_StyleMap ) ) {
326 : /* todo need to figure out what to do with a style map */
327 0 : }
328 :
329 :
330 : }
331 54 : }
|