Statistics
| Revision:

svn-gvsig-desktop / branches / v02_desarrollo / libraries / sld / temp / org.gvsig.sldconverter / org.gvsig.sldconverter.lib / org.gvsig.sldconverter.lib.impl / src / main / java / org / gvsig / sldconverter / impl / util / BasicUtils.java @ 40862

History | View | Annotate | Download (50.3 KB)

1
package org.gvsig.sldconverter.impl.util;
2

    
3
import java.awt.Color;
4
import java.io.File;
5
import java.io.IOException;
6
import java.net.URL;
7
import java.text.DecimalFormat;
8
import java.text.DecimalFormatSymbols;
9
import java.util.ArrayList;
10
import java.util.HashMap;
11
import java.util.Iterator;
12
import java.util.List;
13
import java.util.Map;
14

    
15
import org.gvsig.fmap.dal.DALLocator;
16
import org.gvsig.fmap.dal.DataManager;
17
import org.gvsig.fmap.dal.DataTypes;
18
import org.gvsig.fmap.geom.Geometry;
19
import org.gvsig.fmap.mapcontext.MapContextLocator;
20
import org.gvsig.fmap.mapcontext.MapContextManager;
21
import org.gvsig.fmap.mapcontext.rendering.legend.IInterval;
22
import org.gvsig.fmap.mapcontext.rendering.legend.ISingleSymbolLegend;
23
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialIntervalLegend;
24
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialUniqueValueLegend;
25
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
26
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
27
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
28
import org.gvsig.sldconverter.SLDConverterLocator;
29
import org.gvsig.sldconverter.SLDConverterManager;
30
import org.gvsig.sldconverter.exception.UnsupportedLegendException;
31
import org.gvsig.sldconverter.exception.UnsupportedSymbolException;
32
import org.gvsig.sldsupport.SLDSupportLocator;
33
import org.gvsig.sldsupport.SLDSupportManager;
34
import org.gvsig.sldsupport.exception.UnsupportedSLDObjectException;
35
import org.gvsig.sldsupport.sld.SLDTags;
36
import org.gvsig.sldsupport.sld.filter.FilterTags;
37
import org.gvsig.sldsupport.sld.filter.SLDFilter;
38
import org.gvsig.sldsupport.sld.filter.SLDFilterOperator;
39
import org.gvsig.sldsupport.sld.filter.expression.SLDExpression;
40
import org.gvsig.sldsupport.sld.filter.expression.operator.SLDLiteral;
41
import org.gvsig.sldsupport.sld.filter.expression.operator.SLDPropertyName;
42
import org.gvsig.sldsupport.sld.filter.operator.SLDComparisonOperator;
43
import org.gvsig.sldsupport.sld.filter.operator.comparison.SLDBinaryComparisonOperator;
44
import org.gvsig.sldsupport.sld.filter.operator.comparison.SLDIsBetweenOperator;
45
import org.gvsig.sldsupport.sld.graphic.SLDExternalGraphic;
46
import org.gvsig.sldsupport.sld.graphic.SLDGraphic;
47
import org.gvsig.sldsupport.sld.graphic.SLDGraphicStackElement;
48
import org.gvsig.sldsupport.sld.graphic.SLDMark;
49
import org.gvsig.sldsupport.sld.layer.SLDLayer;
50
import org.gvsig.sldsupport.sld.layer.SLDNamedLayer;
51
import org.gvsig.sldsupport.sld.layer.SLDUserLayer;
52
import org.gvsig.sldsupport.sld.rule.SLDRule;
53
import org.gvsig.sldsupport.sld.style.SLDFeatureStyle;
54
import org.gvsig.sldsupport.sld.style.layer.SLDLayerStyle;
55
import org.gvsig.sldsupport.sld.style.layer.SLDUserStyle;
56
import org.gvsig.sldsupport.sld.symbol.SLDLineSymbol;
57
import org.gvsig.sldsupport.sld.symbol.SLDPointSymbol;
58
import org.gvsig.sldsupport.sld.symbol.SLDPolygonSymbol;
59
import org.gvsig.sldsupport.sld.symbol.SLDSymbol;
60
import org.gvsig.sldsupport.sld.symbol.misc.SLDFill;
61
import org.gvsig.sldsupport.sld.symbol.misc.SLDParameterValue;
62
import org.gvsig.sldsupport.sld.symbol.misc.SLDStroke;
63
import org.gvsig.symbology.SymbologyLocator;
64
import org.gvsig.symbology.SymbologyManager;
65
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
66
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IMultiLayerFillSymbol;
67
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IPictureFillSymbol;
68
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.ISimpleFillSymbol;
69
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
70
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.IMultiLayerLineSymbol;
71
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
72
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMultiLayerMarkerSymbol;
73
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IPictureMarkerSymbol;
74
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.ISimpleMarkerSymbol;
75
import org.gvsig.tools.ToolsLocator;
76
import org.gvsig.tools.dataTypes.CoercionException;
77
import org.gvsig.tools.dataTypes.DataType;
78
import org.gvsig.tools.dataTypes.DataTypesManager;
79
import org.slf4j.Logger;
80
import org.slf4j.LoggerFactory;
81

    
82
public class BasicUtils {
83
        
84
        private static Logger logger = LoggerFactory.getLogger(BasicUtils.class);
85
        
86
        public static DecimalFormat df = null;
87
        static {
88
                DecimalFormatSymbols dformater_rules = new DecimalFormatSymbols();
89
                dformater_rules.setDecimalSeparator ('.');
90
                df = new DecimalFormat("##########.0##########", dformater_rules);
91
        }
92
        
93
        public static SLDConverterManager sldMan() {
94
                return SLDConverterLocator.getInstance().getSLDConverterManager();
95
        }
96
        
97
        public static SLDSupportManager supMan() {
98
                return SLDSupportLocator.getInstance().getSLDSupportManager();
99
        }
100
        
101
        public static SymbologyManager symMan() {
102
                return SymbologyLocator.getSymbologyManager();
103
        }
104
        
105
        public static SymbolManager syMan() {
106
                return MapContextLocator.getSymbolManager();
107
        }
108
        
109
        public static MapContextManager mapMan() {
110
                return MapContextLocator.getMapContextManager();
111
        }
112
        
113
        public static DataTypesManager datMan() {
114
                return ToolsLocator.getDataTypesManager();
115
        }
116
        
117
        public static int canConvertUserLayer(SLDUserLayer layer) {
118
                List<SLDUserStyle> stys = layer.getStyles();
119
                if (stys.size() == 0) {
120
                        return SLDConverterManager.CAN_NOT_CONVERT;
121
                } else {
122
                        if (stys.size() == 1) {
123
                                return canConvertUserStyle(
124
                                                stys.get(0),
125
                                                SLDConverterManager.CAN_CONVERT_PARTIALLY);
126
                        } else {
127
                                return canConvertUserStyle(
128
                                                stys.get(0),
129
                                                /*result devaluated*/
130
                                                SLDConverterManager.CAN_CONVERT_PARTIALLY);
131
                        }
132
                }
133
        }
134

    
135

    
136
        public static int canConvertNamedLayer(SLDNamedLayer layer) {
137
                
138
                List<SLDLayerStyle> stys = layer.getStyles();
139
                if (stys.size() == 0) {
140
                        return SLDConverterManager.CAN_NOT_CONVERT;
141
                } else {
142
                        if (stys.size() == 1 && stys.get(0) instanceof SLDUserStyle) {
143
                                return canConvertUserStyle(
144
                                                (SLDUserStyle) stys.get(0),
145
                                                SLDConverterManager.CAN_CONVERT_PARTIALLY);
146
                        } else {
147
                                for (int i=0; i<stys.size(); i++) {
148
                                        if (stys.get(i) instanceof SLDUserStyle) {
149
                                                /*
150
                                                 * Get first USerStyle and devaluate result
151
                                                 */
152
                                                return canConvertUserStyle(
153
                                                                (SLDUserStyle) stys.get(0),
154
                                                                /*result devaluated*/
155
                                                                SLDConverterManager.CAN_CONVERT_PARTIALLY);
156
                                        }
157
                                }
158
                                // No user style found:
159
                                return SLDConverterManager.CAN_NOT_CONVERT;
160
                        }
161
                }
162
        }
163
        
164
        public static int canConvertUserStyle(SLDUserStyle style, int max) {
165
                
166
                List<SLDFeatureStyle> fstys = style.getFeatureStyles();
167
                if (fstys.size() == 0) {
168
                        return SLDConverterManager.CAN_NOT_CONVERT;
169
                } else {
170
                        if (fstys.size() == 1) {
171
                                return canConvertFeatureStyle(fstys.get(0), max);
172
                        } else {
173
                                return canConvertFeatureStyle(fstys.get(0), max / 2);
174
                        }
175
                }
176
        }
177
        
178
        public static int canConvertFeatureStyle(SLDFeatureStyle sldFeatureStyle, int max) {
179
                
180
                List<SLDRule> rules = sldFeatureStyle.getRules();
181
                if (rules == null || rules.size() == 0) {
182
                        return SLDConverterManager.CAN_NOT_CONVERT;
183
                }
184
                
185
                if (areRulesOfSingleSymbol(rules)) {
186
                        return max;
187
                } else {
188
                        if (areRulesOfUniqueSymbol(rules)) {
189
                                return max;
190
                        } else {
191
                                if (areRulesOfIntervals(rules)) {
192
                                        return max;
193
                                } else {
194
                                        return SLDConverterManager.CAN_NOT_CONVERT;
195
                                }
196
                        }
197
                }
198
        }
199

    
200
        
201
        public static boolean areRulesOfIntervals(List<SLDRule> rules) {
202

    
203
                if (rules == null || rules.size() == 0) {
204
                        return false;
205
                }
206
                
207
                SLDRule rule = null;
208
                String fieldName = null;
209
                for (int i=0; i<rules.size(); i++) {
210
                        rule = rules.get(i);
211
                        fieldName = getComparisonToNumericLiteralFieldName(rule);
212
                        if (fieldName != null) {
213
                                break;
214
                        }
215
                }
216
                
217
                if (fieldName == null) {
218
                        // The filter of first rule is not of type "field name equals literal"
219
                        return false;
220
                }
221
                int elsecount = 0;
222
                for (int i=1; i<rules.size(); i++) {
223
                        rule = rules.get(i);
224
                        if (!isElse(rule)) {
225
                                String fname = getComparisonToNumericLiteralFieldName(rule);
226
                                if (fname == null || fname.compareTo(fieldName) != 0) {
227
                                        // Not a equals operation based on the same field
228
                                        return false;
229
                                }
230
                        } else {
231
                                elsecount++;
232
                        }
233
                                
234
                }
235
                // Found no reason to deny it's a interval legend
236
                // (if number of else filters is 0 or 1)
237
                return elsecount < 2;
238
        }
239
        
240
        
241
        
242
        
243
        
244
        public static String getFirstPropertyName(List<SLDRule> rules) {
245
                if (rules == null || rules.size() == 0) {
246
                        return null;
247
                }
248
                
249
                SLDRule rule = null;
250
                String fieldName = null;
251
                for (int i=0; i<rules.size(); i++) {
252
                        rule = rules.get(i);
253
                        fieldName = getFirstPropertyName(rule);
254
                        if (fieldName != null) {
255
                                return fieldName;
256
                        }
257
                }
258
                return null;
259
        }
260
        
261
        /**
262
         * Gets data type from literals.
263
         * Possible responses:
264
         * 
265
         * - DataTypes.DOUBLE
266
         * - DataTypes.INTEGER
267
         * - DataTypes.STRING
268
         * 
269
         * @param lits
270
         * @return
271
         */
272
        public static DataType guessDataType(List<SLDLiteral> lits) {
273
                
274
                boolean isDouble = true;
275
                boolean isInt = true;
276
                Iterator<SLDLiteral> iter = lits.iterator();
277
                SLDLiteral lit = null;
278
                
279
                while (iter.hasNext()) {
280
                        lit = iter.next();
281
                        try { Double.parseDouble(lit.getValue()); } catch (Exception exc) {
282
                                isDouble = false;
283
                                break;
284
                        }
285
                }
286
                if (isDouble) {
287
                        return datMan().get(DataTypes.DOUBLE);
288
                }
289
                // =======================================
290
                iter = lits.iterator();
291
                isInt = true;
292
                while (iter.hasNext()) {
293
                        lit = iter.next();
294
                        try { Integer.parseInt(lit.getValue()); } catch (Exception exc) {
295
                                isInt = false;
296
                                break;
297
                        }
298
                }
299
                if (isInt) {
300
                        return datMan().get(DataTypes.INT);
301
                } else {
302
                        return datMan().get(DataTypes.STRING);
303
                }
304
        }
305
        
306
        /**
307
         * Coerces literal value using the dataType
308
         * Returns null if coercion was not possible
309
         * @param lit
310
         * @param dt
311
         * @return
312
         */
313
        public static Object getValue(SLDLiteral lit, DataType dt) {
314
                
315
                if (lit == null) {
316
                        return null;
317
                }
318
                try {
319
                        return dt.coerce(lit.getValue());
320
                } catch (CoercionException e) {
321
                        logger.info("While coercing literal: " + lit.getValue(), e);
322
                        return null;
323
                }
324
        }
325
        
326
        public static List<SLDLiteral> getComparisonLiterals(List<SLDRule> rules) {
327
                List<SLDLiteral> resp = new ArrayList<SLDLiteral>();
328
                SLDRule rule = null;
329
                SLDComparisonOperator item = null;
330
                for (int i=0; i<rules.size(); i++) {
331
                        rule = rules.get(i);
332
                        SLDFilter filt = rule.getFilter();
333
                        if (filt != null && !filt.isElse()) {
334
                                SLDFilterOperator oper = filt.getFilterOperator();
335
                                if (oper instanceof SLDComparisonOperator) {
336
                                        item = (SLDComparisonOperator) oper;
337
                                        List<SLDExpression> list = item.getExpressions();
338
                                        for (int j=0; j<list.size(); j++) {
339
                                                if (list.get(j) instanceof SLDLiteral) {
340
                                                        resp.add((SLDLiteral) list.get(j));
341
                                                }
342
                                        }
343
                                }
344
                        }
345
                }
346
                return resp;
347
        }
348
        
349

    
350
        public static boolean areRulesOfUniqueSymbol(List<SLDRule> rules) {
351
                
352
                if (rules == null || rules.size() == 0) {
353
                        return false;
354
                }
355
                
356
                SLDRule rule = null;
357
                String fieldName = null;
358
                for (int i=0; i<rules.size(); i++) {
359
                        rule = rules.get(i);
360
                        fieldName = getEqualsLiteralFieldName(rule);
361
                        if (fieldName != null) {
362
                                break;
363
                        }
364
                }
365
                
366
                if (fieldName == null) {
367
                        // The filter of first rule is not of type "field name equals literal"
368
                        return false;
369
                }
370
                int elsecount = 0;
371
                for (int i=1; i<rules.size(); i++) {
372
                        rule = rules.get(i);
373
                        if (!isElse(rule)) {
374
                                String fname = getEqualsLiteralFieldName(rule);
375
                                if (fname == null || fname.compareTo(fieldName) != 0) {
376
                                        // Not a equals operation based on the same field
377
                                        return false;
378
                                }
379
                        } else {
380
                                elsecount++;
381
                        }
382
                                
383
                }
384
                // Found no reason to deny it's a unique symbol legend
385
                // (if number of else filters is 0 or 1)
386
                return elsecount < 2;
387
        }
388

    
389
        private static boolean isElse(SLDRule rule) {
390
                SLDFilter filt = rule.getFilter();
391
                return filt != null && filt.isElse();
392
        }
393

    
394
        
395
        private static String getFirstPropertyName(SLDRule rule) {
396
                SLDFilter filt = rule.getFilter();
397
                if (filt == null) {
398
                        return null;
399
                }
400
                SLDFilterOperator oper = filt.getFilterOperator();
401
                if (oper instanceof SLDComparisonOperator) {
402
                        
403
                        SLDComparisonOperator cop = (SLDComparisonOperator) oper;
404
                        List<SLDExpression> list = cop.getExpressions();
405
                        for (int i=0; i<list.size(); i++) {
406
                                if (list.get(i) instanceof SLDPropertyName) {
407
                                        return ((SLDPropertyName) list.get(i)).getPropertyName();
408
                                }
409
                        }
410
                        return null;
411
                } else {
412
                        return null;
413
                }
414
                
415
        }
416

    
417
        /**
418
         * Returns the name of the field name on which the rule
419
         * is based if the rule has a equals operation and the
420
         * operand is a literal. Otherwise returns null.
421
         *    
422
         * @param rule
423
         * @return
424
         */
425
        private static String getEqualsLiteralFieldName(SLDRule rule) {
426
                
427
                SLDFilter filt = rule.getFilter();
428
                if (filt == null) {
429
                        return null;
430
                }
431
                SLDFilterOperator oper = filt.getFilterOperator();
432
                if (!(oper instanceof SLDBinaryComparisonOperator)) {
433
                        // not binary
434
                        return null;
435
                }
436
                SLDBinaryComparisonOperator bop = (SLDBinaryComparisonOperator) oper;
437
                if (bop.getComparisonOperator().compareToIgnoreCase(
438
                                FilterTags.PROPERTYISEQUALTO) != 0) {
439
                        // not "equals" operand
440
                        return null;
441
                }
442
                SLDPropertyName pname = null;
443
                if (bop.getFirstExpression() instanceof SLDLiteral &&
444
                                bop.getSecondExpression() instanceof SLDPropertyName) {
445
                        pname = (SLDPropertyName) bop.getSecondExpression();
446
                        return pname.getPropertyName();
447

    
448
                } else {
449
                        if (bop.getSecondExpression() instanceof SLDLiteral &&
450
                                        bop.getFirstExpression() instanceof SLDPropertyName) {
451
                                pname = (SLDPropertyName) bop.getFirstExpression(); 
452
                                return pname.getPropertyName();
453
                        } else {
454
                                // not a couple "property name + literal"
455
                                return null;
456
                        }
457
                }
458
        }
459

    
460
        
461
        /**
462
         * Returns the name of the field name on which the rule
463
         * is based if the rule is a interval comparison and the
464
         * operand is a literal. Otherwise returns null.
465
         *    
466
         * @param rule
467
         * @return
468
         */
469
        private static String getComparisonToNumericLiteralFieldName(SLDRule rule) {
470
                
471
                SLDFilter filt = rule.getFilter();
472
                if (filt == null) {
473
                        return null;
474
                }
475
                SLDFilterOperator oper = filt.getFilterOperator();
476
                if (!(oper instanceof SLDComparisonOperator)) {
477
                        // interval has to be SLDComparisonOperator
478
                        return null;
479
                }
480
                SLDComparisonOperator cop = (SLDComparisonOperator) oper;
481
                SLDPropertyName pname = null;
482
                if (cop instanceof SLDBinaryComparisonOperator) {
483
                        SLDBinaryComparisonOperator bco = (SLDBinaryComparisonOperator) cop;
484
                        String opname = bco.getComparisonOperator();
485
                        if (opname.compareTo(FilterTags.PROPERTYISGREATEROREQUALTHAN) == 0
486
                                        || opname.compareTo(FilterTags.PROPERTYISGREATERTHAN) == 0
487
                                        || opname.compareTo(FilterTags.PROPERTYISLESSOREQUALTHAN) == 0
488
                                        || opname.compareTo(FilterTags.PROPERTYISLESSTHAN) == 0) {
489

    
490
                                if (bco.getFirstExpression() instanceof SLDLiteral &&
491
                                                bco.getSecondExpression() instanceof SLDPropertyName) {
492
                                        
493
                                        pname = (SLDPropertyName) bco.getSecondExpression(); 
494
                                        if (isNumeric((SLDLiteral) bco.getFirstExpression())) {
495
                                                return pname.getPropertyName();
496
                                        } else {
497
                                                return null;
498
                                        }
499
                                        
500
                                }
501
                                if (bco.getFirstExpression() instanceof SLDPropertyName &&
502
                                                bco.getSecondExpression() instanceof SLDLiteral) {
503
                                        
504
                                        pname = (SLDPropertyName) bco.getFirstExpression(); 
505
                                        if (isNumeric((SLDLiteral) bco.getSecondExpression())) {
506
                                                return pname.getPropertyName();
507
                                        } else {
508
                                                return null;
509
                                        }
510
                                }
511
                        }
512
                } else {
513
                        if (cop instanceof SLDIsBetweenOperator) {
514
                                
515
                                SLDIsBetweenOperator beop = (SLDIsBetweenOperator) cop;
516
                                if (beop.getExpression() instanceof SLDPropertyName
517
                                                // Limits must be literals
518
                                                && beop.getLowerBoundary() instanceof SLDLiteral
519
                                                && beop.getUpperBoundary() instanceof SLDLiteral) {
520
                                        
521
                                        pname = (SLDPropertyName) beop.getExpression();
522
                                        if (isNumeric((SLDLiteral) beop.getLowerBoundary())
523
                                                        && isNumeric((SLDLiteral) beop.getUpperBoundary())) {
524
                                                return pname.getPropertyName();
525
                                        } else {
526
                                                return null;
527
                                        }
528
                                }
529
                        }
530
                }
531
                // Not the type we are looking for
532
                return null;
533
        }        
534
        
535
        
536
        public static boolean isNumeric(SLDLiteral lit) {
537
                try {
538
                        Double.parseDouble(lit.getValue());
539
                        return true;
540
                } catch (Exception exc) {
541
                        return false;
542
                }
543
        }
544
        
545
        
546
        public static boolean areRulesOfSingleSymbol(List<SLDRule> rules) {
547
                
548
                if (rules.size() != 1) {
549
                        return false;
550
                }
551
                
552
                SLDRule rule = rules.get(0);
553
                /*
554
                 * Check there is NOT a filter
555
                 */
556
                return rule.getFilter() == null;
557
        }
558

    
559

    
560
        public static SLDUserStyle getFirstUserStyle(SLDLayer layer) {
561
                
562
                if (layer instanceof SLDNamedLayer) {
563
                        SLDNamedLayer nl = (SLDNamedLayer) layer;
564
                        for (int i=0; i<nl.getStyles().size(); i++) {
565
                                if (nl.getStyles().get(i) instanceof SLDUserStyle) {
566
                                        // return first found
567
                                        return (SLDUserStyle) nl.getStyles().get(i); 
568
                                }
569
                        }
570
                        return null;
571
                } else {
572
                        if (layer instanceof SLDUserLayer) {
573
                                SLDUserLayer ul = (SLDUserLayer) layer;
574
                                if (ul.getStyles().size() == 1) {
575
                                        return ul.getStyles().get(0);
576
                                } else {
577
                                        return null;
578
                                }
579
                        } else {
580
                                return null;
581
                        }
582
                }
583
        }
584
        
585
        /**
586
         *
587
         * Geometry.TYPES.POINT
588
         * Geometry.TYPES.CURVE
589
         * Geometry.TYPES.SURFACE
590
         * or
591
         * Geometry.TYPES.NULL if there is not consistency in the list
592
         * 
593
         * @return
594
         */
595
        public static int getGeometryTypeForSymbols(List<SLDSymbol> list) {
596
                
597
                if (list == null || list.size() == 0) {
598
                        return Geometry.TYPES.NULL;
599
                }
600
                
601
                SLDSymbol ss = list.get(0);
602
                if (ss instanceof SLDPointSymbol) {
603
                        if (allItemsOfClass(list, SLDPointSymbol.class)) {
604
                                return Geometry.TYPES.POINT;
605
                        }
606
                } else {
607
                        if (ss instanceof SLDLineSymbol) {
608
                                if (allItemsOfClass(list, SLDLineSymbol.class)) {
609
                                        return Geometry.TYPES.CURVE;
610
                                }
611
                        } else {
612
                                if (ss instanceof SLDPolygonSymbol) {
613
                                        if (allItemsOfClass(list, SLDPolygonSymbol.class)) {
614
                                                return Geometry.TYPES.SURFACE;
615
                                        }
616
                                } else {
617
                                        // Unknown
618
                                        return Geometry.TYPES.NULL;
619
                                }
620
                        }
621
                }
622
                // Inconsistent list
623
                return Geometry.TYPES.NULL;
624
        }
625
        
626
        
627

    
628
        private static boolean allItemsOfClass(List<SLDSymbol> list, Class clazz) {
629
                for (int i=0; i<list.size(); i++) {
630
                        if (list.get(i).getClass() != clazz) {
631
                                return false;
632
                        }
633
                }
634
                return true;
635
        }
636

    
637
        public static ISymbol combineSymbols(List<ISymbol> gsyms, int geotype) {
638
                
639
                if (gsyms.size() == 1) {
640
                        return gsyms.get(0);
641
                }
642
                
643
                IMultiLayerSymbol resp = syMan().createMultiLayerSymbol(geotype);
644
                for (int i=0; i<gsyms.size(); i++) {
645
                        resp.addLayer(gsyms.get(i));
646
                }
647
                return resp;
648
        }
649

    
650
        // ==========================================================
651
        // ==========================================================
652
        // ==========================================================
653
        /*
654
         * Symbol utilities...
655
         */
656
        
657
        public static ISymbol toMarkerSymbol(SLDPointSymbol sym)
658
                        throws UnsupportedSLDObjectException {
659
                
660
                SLDGraphic gra = sym.getGraphic();
661
                List<SLDGraphicStackElement> list = gra.getElementStack();
662
                if (list.size() == 1) {
663
                        
664
                        Integer alpha = getAlphaValue(gra.getOpacity());
665
                        Double sz = getDouble(gra.getSize());
666
                        IMarkerSymbol msym = toMarkerSymbol(list.get(0));
667
                        if (alpha != null) {
668
                                msym.setAlpha(alpha.intValue());
669
                        }
670
                        if (sz != null) {
671
                                msym.setSize(sz.doubleValue());
672
                        }
673
                        return msym;
674
                } else {
675

    
676
                        IMultiLayerSymbol resp = syMan().createMultiLayerSymbol(
677
                                        Geometry.TYPES.POINT);
678
                        for (int i=0; i<list.size(); i++) {
679
                                resp.addLayer(toMarkerSymbol(list.get(i)));
680
                        }
681
                        return resp;
682
                }
683
        }
684
        
685
        private static IMarkerSymbol toMarkerSymbol(SLDExternalGraphic extgra)
686
                        throws UnsupportedSLDObjectException {
687

    
688
                if (extgra.isOnlineResource()) {
689
                        URL u = null;
690
                        IPictureMarkerSymbol pms = null;
691
                        try {
692
                                u = new URL(extgra.getOnlineResource()); 
693
                                pms = symMan().createPictureMarkerSymbol(u,u);
694
                        } catch (Exception exc) {
695
                                throw new UnsupportedSLDObjectException(exc,
696
                                                "SLDExternalGraphic", "Creating picture marker symbol from URL");
697
                        }
698
                        return pms;
699
                } else {
700
                        // TODO Not supported yet
701
                        throw new UnsupportedSLDObjectException(
702
                                        "SLDExternalGraphic",
703
                                        "Inline content not supported.");
704
                }
705
        }
706

    
707
        private static IMarkerSymbol toMarkerSymbol(SLDGraphicStackElement elem)
708
                        throws UnsupportedSLDObjectException {
709
                
710
                if (elem == null) {
711
                        throw new UnsupportedSLDObjectException("SLDGraphicStackElement", "Null");
712
                }
713
                
714
                if (elem instanceof SLDExternalGraphic) {
715
                        return toMarkerSymbol((SLDExternalGraphic) elem);
716
                } else {
717
                        if (elem instanceof SLDMark) {
718
                                return toMarkerSymbol((SLDMark) elem);
719
                        } else {
720
                                throw new UnsupportedSLDObjectException(
721
                                                "SLDGraphicStackElement",
722
                                                "Unexpected class: " + elem.getClass().getName());
723
                        }
724
                }
725
        }
726
        
727
        
728
        private static IMarkerSymbol toMarkerSymbol(SLDMark mk)
729
                        throws UnsupportedSLDObjectException {
730

    
731
                switch (mk.getMarkType()) {
732
                case SLDMark.MARK_TYPE_INLINE_CONTENT:
733
                        throw new UnsupportedSLDObjectException(
734
                                        "SLDMark",
735
                                        "Inline content not supported.");
736
                        // ============================================
737
                case SLDMark.MARK_TYPE_ONLINE_RESOURCE:
738
                        URL u = null;
739
                        IPictureMarkerSymbol pms = null;
740
                        try {
741
                                u = new URL(mk.getOnlineResource()); 
742
                                pms = symMan().createPictureMarkerSymbol(u,u);
743
                        } catch (Exception exc) {
744
                                throw new UnsupportedSLDObjectException(exc, "SLDMark",
745
                                                "Creating picture marker symbol from URL");
746
                        }
747
                        return pms;                        
748
                        // ============================================
749
                case SLDMark.MARK_TYPE_WELL_KNOWN_NAME:
750
                        String wkn = mk.getWellKnownName();
751
                        int t = getMarkerSymbolType(wkn);
752
                        ISimpleMarkerSymbol resp = symMan().createSimpleMarkerSymbol();
753
                        resp.setStyle(t);
754
                        
755
                        SLDFill fill = mk.getFill();
756
                        Color co = null;
757
                        Double dob = null;
758
                        if (fill != null) {
759
                                co = toColor(fill.getFillColor());
760
                                if (co != null) {
761
                                        resp.setColor(co);
762
                                }
763
                        }
764
                        SLDStroke stro = mk.getStroke();
765
                        if (stro != null) {
766
                                co = toColor(stro.getColor());
767
                                if (co != null) {
768
                                        resp.setOutlineColor(co);
769
                                }
770
                                dob = toDouble(stro.getWidth());
771
                                if (dob != null) {
772
                                        resp.setOutlineSize(dob.doubleValue());
773
                                }
774
                        }
775
                        return resp;
776
                        // ============================================
777
                default:
778
                        IMarkerSymbol ms = symMan().createSimpleMarkerSymbol();
779
                        SLDStroke str = mk.getStroke();
780
                        Color col = getColor(str.getColor());
781
                        if (col != null) {
782
                                ms.setColor(col);
783
                        }
784
                        Double sz = toDouble(str.getWidth());
785
                        if (sz != null) {
786
                                ms.setSize(sz.doubleValue());
787
                        }
788
                        return ms;
789
                }
790

    
791
        }
792
        
793
        private static int getMarkerSymbolType(String wkn) {
794
                
795
                if (wkn.compareToIgnoreCase("circle") == 0)
796
                        return IMarkerSymbol.CIRCLE_STYLE;
797
                else if (wkn.compareToIgnoreCase("x") == 0)
798
                        return IMarkerSymbol.X_STYLE;
799
                else if (wkn.compareToIgnoreCase("cross") == 0)
800
                        return IMarkerSymbol.CROSS_STYLE;
801
                else if (wkn.compareToIgnoreCase("triangle") == 0)
802
                        return IMarkerSymbol.TRIANGLE_STYLE;
803
                else if (wkn.compareToIgnoreCase("star") == 0)
804
                        return IMarkerSymbol.STAR_STYLE;
805
                return IMarkerSymbol.SQUARE_STYLE;
806
        }
807

    
808
        private static ISymbol toMarkerSymbol(SLDGraphic gra) 
809
                        throws UnsupportedSLDObjectException {
810
                
811
                IMarkerSymbol resp = null;
812
                List<SLDGraphicStackElement> list = gra.getElementStack();
813
                
814
                Integer alpha = getAlphaValue(gra.getOpacity());
815
                Double sz = getDouble(gra.getSize());
816

    
817
                if (list.size() == 0) {
818
                        // Get data from css/svg params
819
                        ISimpleMarkerSymbol sms = symMan().createSimpleMarkerSymbol();
820
                        if (alpha != null) {
821
                                sms.setAlpha(alpha.intValue());
822
                        }
823
                        if (sz != null) {
824
                                sms.setSize(sz.doubleValue());
825
                        }
826
                        // color? default?
827
                        return sms;
828

    
829
                } else {
830
                        
831
                        if (list.size() == 1) {
832
                                IMarkerSymbol msym = toMarkerSymbol(list.get(0));
833
                                if (alpha != null) {
834
                                        msym.setAlpha(alpha.intValue());
835
                                }
836
                                if (sz != null) {
837
                                        msym.setSize(sz.doubleValue());
838
                                }
839
                                return msym;
840
                        } else {
841
                                
842
                                IMultiLayerSymbol mls = syMan().createMultiLayerSymbol(Geometry.TYPES.POINT);
843
                                for (int i=0; i<list.size(); i++) {
844
                                        mls.addLayer(toMarkerSymbol(list.get(i)));
845
                                }
846
                                return mls;
847
                        }
848
                }
849
        }
850

    
851
        // ==========================================================
852
        // ==========================================================
853
        
854
        public static ISymbol toLineSymbol(SLDLineSymbol sym) 
855
                        throws UnsupportedSLDObjectException {
856
                
857
                ILineSymbol resp = symMan().createSimpleLineSymbol();
858
                SLDStroke stro = sym.getStroke();
859
                
860
                Color col = BasicUtils.toColor(stro.getColor());
861
                if (col != null) {
862
                        resp.setColor(col);
863
                }
864
                Double wi = BasicUtils.toDouble(stro.getWidth());
865
                if (wi != null) {
866
                        resp.setLineWidth(wi);
867
                }
868
                return resp;
869
        }
870

    
871
        private static Double toDouble(SLDExpression width)
872
                        throws UnsupportedSLDObjectException {
873
                
874
                if (width instanceof SLDLiteral) {
875
                        
876
                        SLDLiteral lit = (SLDLiteral) width;
877
                        try {
878
                                double resp = Double.parseDouble(lit.getValue());
879
                                return new Double(resp);
880
                        } catch (Exception exc) {
881
                                logger.info("Non parseable double: " + exc.getMessage());
882
                                return null;
883
                        }
884
                        
885
                } else {
886
                        throw new UnsupportedSLDObjectException(
887
                                        "SLDExpression",
888
                                        "Not supported as Double: " + width.getClass().getName());
889
                }
890
        }
891
        
892
        private static Integer toInteger(SLDExpression width) {
893
                
894
                if (width instanceof SLDLiteral) {
895
                        
896
                        SLDLiteral lit = (SLDLiteral) width;
897
                        try {
898
                                int resp = Integer.parseInt(lit.getValue());
899
                                return new Integer(resp);
900
                        } catch (Exception exc) {
901
                                logger.info("Non parseable integer: " + exc.getMessage());
902
                                return null;
903
                        }
904
                        
905
                } else {
906
                        // TODO parse integer expression
907
                        return null;
908
                }
909
        }
910
        
911
        /**
912
         * 
913
         * Input must be like "#fa5e02", "0x000", etc
914
         * 
915
         * @param hex
916
         * @return Null if not parseable
917
         */
918
        public static Color parseColor(String colorStr) {
919
                Color co = null;
920
                try {
921
                        co = Color.decode(colorStr.trim());
922
                } catch (Exception exc) {
923
                        logger.info("Non parseable color: " + exc.getMessage());
924
                }
925
                return co;
926
        }
927
        
928
        /**
929
         * Examples:
930
         * #ff0000
931
         * 0x000000cd9983
932
         * 
933
         * Returns null is color is null
934
         * 
935
         * @param co
936
         * @param length
937
         * @param prefix
938
         * @return
939
         */
940
        public static String toHexadecimal(Color co, int length, String prefix) {
941
                
942
                if (co == null) {
943
                        return null;
944
                }
945
                
946
                int v = (co.getRed() << 16) + (co.getGreen() << 8) + co.getBlue();
947
                String resp = Integer.toHexString(v);
948
                int len = resp.length();
949
                for (int i=0; i<(length-len); i++) {
950
                        resp = "0" + resp;
951
                }
952
                resp = resp.substring(resp.length() - length);
953
                if (prefix != null) {
954
                        resp = prefix + resp;
955
                }
956
                return resp;
957
        }
958
        
959
        
960
        /**
961
         * Returns null if no data found
962
         * @param valu
963
         * @return
964
         * @throws UnsupportedSLDObjectException
965
         */
966
        public static Color getColor(SLDParameterValue valu) {
967
                List<SLDExpression> list = valu.getExpressionList();
968
                if (list == null || list.size() == 0) {
969
                        return null;
970
                }
971
                SLDExpression expr = list.get(0);
972
                if (expr instanceof SLDLiteral) {
973
                        SLDLiteral lit = (SLDLiteral) expr;
974
                        return parseColor(lit.getValue());
975
                } else {
976
                        // TODO Use expression to get color (?)
977
                        return null;
978
                }
979
        }
980
        
981
        public static Color getColor(SLDExpression valu) {
982

    
983
                if (valu instanceof SLDLiteral) {
984
                        SLDLiteral lit = (SLDLiteral) valu;
985
                        return parseColor(lit.getValue());
986
                } else {
987
                        // TODO Use expression to get color (?)
988
                        return null;
989
                }
990
        }
991
        
992
        /**
993
         * Returns null if no data found
994
         * @param valu
995
         * @return
996
         * @throws UnsupportedSLDObjectException 
997
         */
998
        public static Double getDouble(SLDParameterValue valu)
999
                        throws UnsupportedSLDObjectException {
1000
                
1001
                List<SLDExpression> list = valu.getExpressionList();
1002
                if (list == null || list.size() == 0) {
1003
                        return null;
1004
                }
1005
                return toDouble(list.get(0));
1006
        }
1007
        
1008
        /**
1009
         * Returns null if no data found
1010
         * @param valu
1011
         * @return
1012
         * @throws UnsupportedSLDObjectException 
1013
         */
1014
        public static Integer getAlphaValue(SLDParameterValue valu)
1015
                        throws UnsupportedSLDObjectException {
1016
                
1017
                List<SLDExpression> list = valu.getExpressionList();
1018
                if (list == null || list.size() == 0) {
1019
                        return null;
1020
                }
1021
                Double d = toDouble(list.get(0));
1022
                if (d == null) {
1023
                        return null;
1024
                } else {
1025
                        if (d.doubleValue() <= 0) {
1026
                                return new Integer(0);
1027
                        } else {
1028
                                if (d.doubleValue() >= 1.0) {
1029
                                        return new Integer(255);
1030
                                } else {
1031
                                        return new Integer((int) Math.round(255*d.doubleValue()));
1032
                                }
1033
                        }
1034
                }
1035
        }
1036

    
1037
        private static Color toColor(SLDExpression color) 
1038
                        throws UnsupportedSLDObjectException {
1039

    
1040
                if (color instanceof SLDLiteral) {
1041
                        
1042
                        SLDLiteral lit = (SLDLiteral) color;
1043
                        Color resp = null;
1044
                        resp = parseColor(lit.getValue());
1045
                        return resp;
1046
                        
1047
                } else {
1048
                        throw new UnsupportedSLDObjectException(
1049
                                        "SLDExpression",
1050
                                        "Not supported as Color: " + color.getClass().getName());
1051
                }
1052
                
1053
                
1054
        }
1055

    
1056
        // ==========================================================
1057
        // ==========================================================
1058
        
1059
        public static ISymbol toFillSymbol(SLDPolygonSymbol sym) 
1060
                        throws UnsupportedSLDObjectException {
1061

    
1062
                ISimpleFillSymbol resp = symMan().createSimpleFillSymbol();
1063
                SLDFill fill = sym.getFill();
1064
                SLDGraphic gra = fill.getFillGraphic();
1065
                SLDStroke stro = sym.getStroke();
1066
                
1067
                Color borderColor = null;
1068
                Double borderWidth = null;
1069

    
1070
                if (gra == null) {
1071
                        // Solid fill
1072
                        Color aux_co = toColor(fill.getFillColor());
1073
                        if (aux_co != null) {
1074
                                resp.setFillColor(aux_co);
1075
                        }
1076
                        borderColor = toColor(stro.getColor());
1077
                        if (borderColor != null) {
1078
                                resp.getOutline().setColor(borderColor);
1079
                        }
1080
                        borderWidth = toDouble(stro.getWidth());
1081
                        if (borderWidth != null) {
1082
                                resp.getOutline().setLineWidth(borderWidth.doubleValue());
1083
                        }
1084
                        return resp;
1085
                        
1086
                } else {
1087
                        
1088
                        ISymbol aux = toMarkerSymbol(gra);
1089
                        if (aux instanceof IPictureMarkerSymbol) {
1090
                                IPictureMarkerSymbol pms = (IPictureMarkerSymbol) aux;
1091
                                IPictureFillSymbol pfs = null;
1092
                                try {
1093
                                        pfs = symMan().createPictureFillSymbol(
1094
                                                        pms.getSource(), pms.getSelectedSource());
1095
                                } catch (Exception exc) {
1096
                                        throw new UnsupportedSLDObjectException(
1097
                                                        exc,
1098
                                                        "SLDPolygonSymbol",
1099
                                                        "This type of grachic not supported as fill graphic: "
1100
                                                        + aux.getClass().getName());
1101
                                }
1102
                                return pfs;
1103
                        } else {
1104
                                throw new UnsupportedSLDObjectException(
1105
                                                "SLDPolygonSymbol",
1106
                                                "This type of grachic not supported as fill graphic: "
1107
                                                + aux.getClass().getName());
1108
                        }
1109
                }
1110
        }
1111
        
1112
        // ===============================================================
1113
        // ===============================================================
1114
        
1115
        public static List<SLDSymbol> toSLDSymbol(ISymbol sym)
1116
        throws UnsupportedSymbolException {
1117
                
1118
                List<SLDSymbol> resp = new ArrayList<SLDSymbol>();
1119
                if (sym instanceof IMultiLayerFillSymbol) {
1120
                        IMultiLayerFillSymbol aux = (IMultiLayerFillSymbol) sym;
1121
                        for (int i=0; i<aux.getLayerCount(); i++) {
1122
                                resp.addAll(toSLDSymbol(aux.getLayer(i)));
1123
                        }
1124
                        return resp;
1125
                }
1126
                if (sym instanceof IMultiLayerLineSymbol) {
1127
                        IMultiLayerLineSymbol aux = (IMultiLayerLineSymbol) sym;
1128
                        for (int i=0; i<aux.getLayerCount(); i++) {
1129
                                resp.addAll(toSLDSymbol(aux.getLayer(i)));
1130
                        }
1131
                        return resp;
1132
                }
1133
                if (sym instanceof IMultiLayerMarkerSymbol) {
1134
                        IMultiLayerMarkerSymbol aux = (IMultiLayerMarkerSymbol) sym;
1135
                        for (int i=0; i<aux.getLayerCount(); i++) {
1136
                                resp.addAll(toSLDSymbol(aux.getLayer(i)));
1137
                        }
1138
                        return resp;
1139
                }
1140
                // ====================================================
1141
                if (sym instanceof IFillSymbol) {
1142
                        resp.add(toSLDPolygonSymbol((IFillSymbol) sym));
1143
                        return resp;
1144
                }
1145
                if (sym instanceof ILineSymbol) {
1146
                        resp.add(toSLDLineSymbol((ILineSymbol) sym));
1147
                        return resp;
1148
                }
1149
                if (sym instanceof IMarkerSymbol) {
1150
                        resp.add(toSLDPointSymbol((IMarkerSymbol) sym));
1151
                        return resp;
1152
                }
1153
                // ====================
1154
                throw new UnsupportedSymbolException(
1155
                                sym == null ? "Null" : sym.getClass().getName(),
1156
                                "Unsupported symbol");
1157
        }
1158
        
1159
        // =================================
1160
        // =================================
1161

    
1162
        private static SLDPointSymbol toSLDPointSymbol(IMarkerSymbol sym)
1163
                        throws UnsupportedSymbolException {
1164
                
1165
                if (sym instanceof IPictureMarkerSymbol) {
1166
                        
1167
                        IPictureMarkerSymbol aux = (IPictureMarkerSymbol) sym;
1168
                        SLDExternalGraphic egra = new SLDExternalGraphic();
1169
                        egra.setIsOnline(true);
1170
                        egra.setOnlineResource(aux.getSource().toString());
1171
                        egra.setFormat(BasicUtils.getFormat(aux.getSource()));
1172
                        SLDGraphic gra = new SLDGraphic();
1173
                        gra.getElementStack().add(egra);
1174
                        SLDPointSymbol resp = new SLDPointSymbol();
1175
                        resp.setGraphic(gra);
1176
                        return resp;
1177
                        
1178
                } else {
1179
                        if (sym instanceof ISimpleMarkerSymbol) {
1180
                                
1181
                                ISimpleMarkerSymbol aux = (ISimpleMarkerSymbol) sym;
1182
                                
1183
                                SLDMark mark = new SLDMark();
1184
                                mark.setMarkType(SLDMark.MARK_TYPE_WELL_KNOWN_NAME);
1185
                                String wkn = getMarkWellKnownName(aux.getStyle());
1186
                                mark.setWellKnownName(wkn);
1187
                                
1188
                                Color fillColor = aux.getColor();
1189
                                Color borderColor = aux.getOutlineColor();
1190
                                double size = aux.getSize();
1191
                                double borderw = aux.getOutlineSize();
1192
                                double rot = aux.getRotation();
1193
                                // from (radians,anticlockwise) to (degrees,clockwise) 
1194
                                rot = -rot * 180.0 / Math.PI;
1195
                                // ===============
1196
                                SLDFill fill = new SLDFill();
1197
                                String colhex = toHexadecimal(fillColor, 6, "#");
1198
                                if (colhex == null) {
1199
                                        colhex = SLDFill.DEFAULT_FILL_COLOR;
1200
                                }
1201

    
1202
                                fill.setFillColor(new SLDLiteral(colhex));
1203
                                mark.setFill(fill);
1204
                                // ===
1205
                                SLDStroke stro = new SLDStroke();
1206
                                colhex = toHexadecimal(borderColor, 6, "#");
1207
                                if (colhex != null) {
1208
                                        stro.setColor(new SLDLiteral(colhex));
1209
                                }
1210
                                
1211
                                stro.setWidth(new SLDLiteral(df.format(borderw)));
1212
                                mark.setStroke(stro);
1213
                                // ===============
1214
                                SLDGraphic gra = new SLDGraphic();
1215
                                // ===============
1216
                                SLDParameterValue pv = new SLDParameterValue();
1217
                                pv.getExpressionList().add(new SLDLiteral(df.format(size)));
1218
                                gra.setSize(pv);
1219
                                // ===
1220
                                pv = new SLDParameterValue();
1221
                                pv.getExpressionList().add(new SLDLiteral(df.format(rot)));
1222
                                gra.setRotation(pv);
1223
                                // ===============
1224
                                gra.getElementStack().add(mark);
1225
                                SLDPointSymbol resp = new SLDPointSymbol();
1226
                                resp.setGraphic(gra);
1227
                                return resp;
1228
                                
1229
                        } else {
1230
                                throw new UnsupportedSymbolException(
1231
                                                sym.getClass().getName(),
1232
                                                "Unsupported class for conversion to SLD");
1233
                        }
1234
                }
1235
        }
1236

    
1237
        // =================================
1238
        
1239
        private static SLDLineSymbol toSLDLineSymbol(ILineSymbol sym)
1240
                        throws UnsupportedSymbolException {
1241
                
1242
                Color bcolor = sym.getColor();
1243
                double bw = sym.getLineWidth();
1244
                
1245
                SLDStroke stro = new SLDStroke();
1246
                String colhex = toHexadecimal(bcolor, 6, "#");
1247
                if (colhex != null) {
1248
                        stro.setColor(new SLDLiteral(colhex));
1249
                }
1250
                stro.setWidth(new SLDLiteral(df.format(bw)));
1251
                
1252
                SLDLineSymbol resp = new SLDLineSymbol();
1253
                resp.setStroke(stro);
1254
                return resp;
1255
        }
1256
        
1257
        // =================================
1258

    
1259
        private static SLDPolygonSymbol toSLDPolygonSymbol(IFillSymbol sym)
1260
                        throws UnsupportedSymbolException {
1261
                
1262
                Color color = sym.getOutline().getColor();
1263
                double w = sym.getOutline().getLineWidth();
1264
                SLDStroke stro = new SLDStroke();
1265
                String colhex = toHexadecimal(color, 6, "#");
1266
                if (colhex != null) {
1267
                        stro.setColor(new SLDLiteral(colhex));
1268
                }
1269
                stro.setWidth(new SLDLiteral(df.format(w)));
1270
                // =================
1271
                color = sym.getColor();
1272
                colhex = toHexadecimal(color, 6, "#");
1273
                SLDFill fill = new SLDFill();
1274
                if (colhex != null) {
1275
                        fill.setFillColor(new SLDLiteral(colhex));
1276
                }
1277
                // =================
1278
                SLDPolygonSymbol resp = new SLDPolygonSymbol();
1279
                resp.setFill(fill);
1280
                resp.setStroke(stro);
1281
                return resp;
1282
        }
1283
        
1284
        private static String getFormat(URL u) {
1285
                
1286
                if (u == null) {
1287
                        return "";
1288
                } else {
1289
                        String str = u.toString();
1290
                        int lastp = str.lastIndexOf(".");
1291
                        if (lastp == -1) {
1292
                                return ""; 
1293
                        } else {
1294
                                str = str.substring(lastp + 1);
1295
                                return "image/" + str;
1296
                        }
1297
                }
1298
        }
1299
        
1300
        public static String getMarkWellKnownName(int style) {
1301
                
1302
                if (style == IMarkerSymbol.CIRCLE_STYLE)
1303
                        return "circle";
1304
                else if (style == IMarkerSymbol.CROSS_STYLE)
1305
                        return "cross";
1306
                else if (style == IMarkerSymbol.SQUARE_STYLE)
1307
                        return "square";
1308
                else if (style == IMarkerSymbol.TRIANGLE_STYLE)
1309
                        return "triangle";
1310
                else if (style == IMarkerSymbol.STAR_STYLE)
1311
                        return "star";
1312
                else if (style == IMarkerSymbol.X_STYLE)
1313
                        return "x";
1314
                
1315
                return "square";        
1316
        }
1317

    
1318
        public static SLDLayer toSLDLayer(ISingleSymbolLegend legend)
1319
        throws UnsupportedLegendException, UnsupportedSymbolException {
1320
                
1321
                ISymbol sym = legend.getDefaultSymbol();
1322
                SLDSymbol sldsym = sldMan().toSLDSymbol(sym);
1323
                
1324
                SLDRule rule = new SLDRule();
1325
                rule.getSymbols().add(sldsym);
1326
                SLDFeatureStyle fstyle = new SLDFeatureStyle();
1327
                fstyle.getRules().add(rule);
1328
                
1329
                SLDUserStyle usty = new SLDUserStyle();
1330
                usty.getFeatureStyles().add(fstyle);
1331
                
1332
                SLDNamedLayer nlayer = new SLDNamedLayer();
1333
                nlayer.setName("Name");
1334
                nlayer.getStyles().add(usty);
1335
                return nlayer;
1336
        }
1337
        
1338

    
1339
        public static ISymbol getElseSymbol(List<SLDRule> rules)
1340
                        throws UnsupportedSLDObjectException {
1341
                
1342
                if (rules == null || rules.size() == 0) {
1343
                        return null;
1344
                }
1345
                
1346
                SLDFilter filt = null;
1347
                List<SLDSymbol> symList = null;
1348
                for (int i=0; i<rules.size(); i++) {
1349
                        filt = rules.get(i).getFilter();
1350
                        if (filt != null && filt.isElse()) {
1351
                                symList = rules.get(i).getSymbols();
1352
                                if (symList != null && symList.size() > 0) {
1353
                                        /*
1354
                                         * Using first symbol only
1355
                                         */
1356
                                        return sldMan().toSymbol(symList.get(0));
1357
                                }
1358
                        }
1359
                }
1360
                // not found
1361
                return null;
1362
        }
1363

    
1364
        
1365
        private static boolean isEqualsTo(SLDFilterOperator oper) {
1366
                if (oper instanceof SLDBinaryComparisonOperator) {
1367
                        SLDBinaryComparisonOperator binoper = (SLDBinaryComparisonOperator) oper;
1368
                        return binoper.getComparisonOperator().compareToIgnoreCase(
1369
                                        FilterTags.PROPERTYISEQUALTO) == 0;
1370
                }
1371
                return false;
1372
        }
1373
        
1374
        /**
1375
         * Translates rules to a value-symbol correspondence.
1376
         * In the filters, only the simple "is equal to" operators
1377
         * will be used only when the expression is a SLDLiteral
1378
         * 
1379
         * @param rules
1380
         * @param dt
1381
         * @return
1382
         * @throws UnsupportedSLDObjectException 
1383
         * @throws CoercionException 
1384
         */
1385
        public static Map<Object, ISymbol> getValueToSymbol(
1386
                        List<SLDRule> rules, DataType dt, String pname)
1387
                                        throws UnsupportedSLDObjectException {
1388
                
1389
                Map<Object, ISymbol> resp = new HashMap<Object, ISymbol>();
1390
                if (rules == null || rules.size() == 0) {
1391
                        return resp;
1392
                }
1393
                SLDFilter filt = null;
1394
                List<SLDSymbol> symList = null;
1395
                SLDFilterOperator oper = null;
1396
                SLDBinaryComparisonOperator binoper = null;
1397
                ISymbol sym = null;
1398
                SLDPropertyName sldpname = null;
1399
                SLDLiteral sldlit = null;
1400
                Object val = null;
1401
                for (int i=0; i<rules.size(); i++) {
1402
                        symList = rules.get(i).getSymbols();
1403
                        if (symList == null || symList.size() == 0) {
1404
                                /*
1405
                                 * No symbols found
1406
                                 */
1407
                                continue;
1408
                        }
1409
                        filt = rules.get(i).getFilter();
1410
                        if (filt != null && !filt.isElse()) {
1411
                                oper = filt.getFilterOperator();
1412
                                if (oper instanceof SLDBinaryComparisonOperator && isEqualsTo(oper)) {
1413
                                        /*
1414
                                         * Must be binary comparison operator "equals to"
1415
                                         */
1416
                                        binoper = (SLDBinaryComparisonOperator) oper;
1417
                                        /*
1418
                                         * Must be using property name and literal
1419
                                         */
1420
                                        if (binoper.getFirstExpression() instanceof SLDLiteral
1421
                                                        && binoper.getSecondExpression() instanceof SLDPropertyName) {
1422
                                                
1423
                                                sldpname = (SLDPropertyName) binoper.getSecondExpression(); 
1424
                                                if (sldpname.getPropertyName().compareTo(pname) == 0) {
1425
                                                        sldlit = (SLDLiteral) binoper.getFirstExpression();
1426
                                                        val = BasicUtils.getValue(sldlit, dt);
1427
                                                        sym = sldMan().toSymbol(symList.get(0));
1428
                                                        if (val != null && sym != null) {
1429
                                                                sym.setDescription(sldlit.getValue());
1430
                                                                resp.put(val, sym);
1431
                                                        }
1432
                                                }
1433
                                        }
1434
                                        // =======================================
1435
                                        /*
1436
                                         * Must be  using property  name and literal
1437
                                         * (reversed)
1438
                                         */
1439
                                        if (binoper.getFirstExpression() instanceof SLDPropertyName
1440
                                                        && binoper.getSecondExpression() instanceof SLDLiteral) {
1441
                                                
1442
                                                sldpname = (SLDPropertyName) binoper.getFirstExpression(); 
1443
                                                if (sldpname.getPropertyName().compareTo(pname) == 0) {
1444
                                                        sldlit = (SLDLiteral) binoper.getSecondExpression();
1445
                                                        val = BasicUtils.getValue(sldlit, dt);
1446
                                                        sym = sldMan().toSymbol(symList.get(0));
1447
                                                        if (val != null && sym != null) {
1448
                                                                resp.put(val, sym);
1449
                                                        }
1450
                                                }
1451
                                        }
1452
                                        // =======================================
1453
                                }
1454
                        }
1455
                }
1456
                return resp;
1457
        }
1458
        
1459
        
1460
        /**
1461
         * Translates rules to a interval-symbol correspondence.
1462
         * 
1463
         * @param rules
1464
         * @param dt
1465
         * @return
1466
         * @throws UnsupportedSLDObjectException 
1467
         * @throws CoercionException 
1468
         */
1469
        public static Map<IInterval, ISymbol> getIntervalToSymbol(
1470
                        List<SLDRule> rules, DataType dt, String pname)
1471
                                        throws UnsupportedSLDObjectException {
1472
                
1473
                Map<IInterval, ISymbol> resp = new HashMap<IInterval, ISymbol>();
1474
                if (rules == null || rules.size() == 0) {
1475
                        return resp;
1476
                }
1477
                SLDFilter filt = null;
1478
                List<SLDSymbol> symList = null;
1479
                SLDFilterOperator oper = null;
1480
                SLDBinaryComparisonOperator binoper = null;
1481
                ISymbol sym = null;
1482
                SLDPropertyName sldpname = null;
1483
                SLDLiteral sldlit = null;
1484
                Object val = null;
1485
                for (int i=0; i<rules.size(); i++) {
1486
                        symList = rules.get(i).getSymbols();
1487
                        if (symList == null || symList.size() == 0) {
1488
                                /*
1489
                                 * No symbols found
1490
                                 */
1491
                                continue;
1492
                        }
1493
                        filt = rules.get(i).getFilter();
1494
                        if (filt == null) {
1495
                                continue;
1496
                        }
1497
                        if (!filt.isElse()) {
1498
                                oper = filt.getFilterOperator();
1499
                                if (oper instanceof SLDComparisonOperator) {
1500
                                        sym = sldMan().toSymbol(symList.get(0));
1501
                                        if (sym != null) {
1502
                                                IInterval ival = getIntervalForSymbol(
1503
                                                                (SLDComparisonOperator) oper, pname, sym);
1504
                                                if (ival != null) {
1505
                                                        resp.put(ival, sym);
1506
                                                }
1507
                                        }
1508
                                }
1509
                        } else {
1510
                                // filter is else
1511
                        }
1512
                }
1513
                return resp;
1514
        }
1515
        
1516
        private static IInterval getIntervalForSymbol(
1517
                        SLDComparisonOperator oper, String pname, ISymbol sym) {
1518
                
1519
                double min = 0;
1520
                double max = 0;
1521
                SLDBinaryComparisonOperator bc = null;
1522
                SLDIsBetweenOperator bw = null;
1523
                SLDLiteral lit = null;
1524
                if (oper instanceof SLDBinaryComparisonOperator) {
1525
                        bc = (SLDBinaryComparisonOperator) oper;
1526
                        if (isGreaterComparison(bc)) {
1527
                                lit = getLiteral(bc.getExpressions());
1528
                                try {
1529
                                        min = Double.parseDouble(lit.getValue());
1530
                                        max = Double.MAX_VALUE;
1531
                                        sym.setDescription("> " + lit.getValue());
1532
                                } catch (Exception exc) {
1533
                                        return null;
1534
                                }
1535
                                
1536
                        } else {
1537
                                if (isLessThanComparison(bc)) {
1538
                                        lit = getLiteral(bc.getExpressions());
1539
                                        try {
1540
                                                max = Double.parseDouble(lit.getValue());
1541
                                                min = -Double.MAX_VALUE;
1542
                                                sym.setDescription("< " + lit.getValue());
1543
                                        } catch (Exception exc) {
1544
                                                return null;
1545
                                        }
1546
                                } else {
1547
                                        return null;
1548
                                }
1549
                        }
1550
                } else {
1551
                        if (oper instanceof SLDIsBetweenOperator) {
1552
                                bw = (SLDIsBetweenOperator) oper;
1553
                                SLDExpression lower = bw.getLowerBoundary();
1554
                                SLDExpression upper = bw.getUpperBoundary();
1555
                                if (lower instanceof SLDLiteral && upper instanceof SLDLiteral) {
1556
                                        String lowerstr = ((SLDLiteral) lower).getValue();
1557
                                        String upperstr = ((SLDLiteral) upper).getValue();
1558
                                        try {
1559
                                                min = Double.parseDouble(lowerstr);
1560
                                                max = Double.parseDouble(upperstr);
1561
                                                sym.setDescription(lowerstr + " - " + upperstr);
1562
                                        } catch (Exception exc) {
1563
                                                return null;
1564
                                        }
1565
                                } else {
1566
                                        return null;
1567
                                }
1568
                                
1569
                        } else {
1570
                                return null;
1571
                        }
1572
                }
1573
                return symMan().createInterval(min, max);
1574
        }
1575

    
1576
        private static SLDLiteral getLiteral(List<SLDExpression> exps) {
1577
                
1578
                for (int i=0; i<exps.size(); i++) {
1579
                        if (exps.get(i) instanceof SLDLiteral) {
1580
                                return (SLDLiteral) exps.get(i); 
1581
                        }
1582
                }
1583
                return null;
1584
        }
1585

    
1586
        private static boolean isLessThanComparison(SLDBinaryComparisonOperator bc) {
1587
                if (bc == null) {
1588
                        return false;
1589
                } else {
1590
                        String comp = bc.getComparisonOperator();
1591
                        return comp != null &&
1592
                                        (comp.compareTo(FilterTags.PROPERTYISLESSOREQUALTHAN) == 0
1593
                                        || comp.compareTo(FilterTags.PROPERTYISLESSTHAN) == 0);
1594
                }
1595
        }
1596

    
1597
        private static boolean isGreaterComparison(SLDBinaryComparisonOperator bc) {
1598
                if (bc == null) {
1599
                        return false;
1600
                } else {
1601
                        String comp = bc.getComparisonOperator();
1602
                        return comp != null &&
1603
                                        (comp.compareTo(FilterTags.PROPERTYISGREATEROREQUALTHAN) == 0
1604
                                        || comp.compareTo(FilterTags.PROPERTYISGREATERTHAN) == 0);
1605
                }
1606
        }
1607

    
1608
        // ======================================
1609
        
1610
        public static SLDLayer toSLDLayer(IVectorialUniqueValueLegend legend)
1611
                        throws UnsupportedSymbolException {
1612
                
1613
                String fname = legend.getClassifyingFieldNames()[0];
1614
                SLDSymbol sldsym = null;
1615
                SLDRule rule = null;
1616
                SLDFeatureStyle fstyle = new SLDFeatureStyle();
1617
                
1618
                Object val = null;
1619
                String valstr = null;
1620
                Object[] vals = legend.getValues();
1621
                ISymbol[] syms = legend.getSymbols();
1622
                int n = Math.min(vals.length, syms.length);
1623
                SLDFilter filt = null;
1624
                SLDBinaryComparisonOperator oper = null;
1625
                for (int i=0; i<n; i++) {
1626
                        rule = new SLDRule();
1627
                        // =====================
1628
                        sldsym = sldMan().toSLDSymbol(syms[i]);
1629
                        rule.getSymbols().add(sldsym);
1630
                        // =====================
1631
                        filt = supMan().createFilter();
1632
                        filt.setIsElse(false);
1633
                        oper = new SLDBinaryComparisonOperator();
1634
                        oper.setComparisonOperator(FilterTags.PROPERTYISEQUALTO);
1635
                        oper.setFirstExpression(new SLDPropertyName(fname));
1636
                        // ======= Value (Object) to String
1637
                        val = vals[i];
1638
                        valstr = valueToString(val);
1639
                        oper.setSecondExpression(new SLDLiteral(valstr));
1640
                        filt.setFilterOperator(oper);
1641
                        // =====================
1642
                        rule.setFilter(filt);
1643
                        // ======================
1644
                        fstyle.getRules().add(rule);
1645
                }
1646
                // ================ Default symbol
1647
                ISymbol sym = legend.getDefaultSymbol();
1648
                if (sym != null) {
1649
                        rule = new SLDRule();
1650
                        sldsym = sldMan().toSLDSymbol(sym);
1651
                        rule.getSymbols().add(sldsym);
1652
                        filt = supMan().createFilter();
1653
                        filt.setIsElse(true);
1654
                        rule.setFilter(filt);
1655
                        fstyle.getRules().add(rule);
1656
                }
1657
                // ======================
1658
                SLDUserStyle usty = new SLDUserStyle();
1659
                usty.getFeatureStyles().add(fstyle);
1660
                
1661
                SLDNamedLayer nlayer = new SLDNamedLayer();
1662
                nlayer.setName("Name");
1663
                nlayer.getStyles().add(usty);
1664
                return nlayer;                
1665
        }
1666
        
1667
        
1668
        
1669

    
1670
        private static String valueToString(Object val) {
1671
                
1672
                if (val instanceof Double) {
1673
                        return BasicUtils.df.format(((Double) val).doubleValue());
1674
                } else {
1675
                        if (val instanceof Float) {
1676
                                return BasicUtils.df.format(((Float) val).doubleValue());
1677
                        } else {
1678
                                return val == null ? "" : val.toString();
1679
                        }
1680
                }
1681
        }
1682

    
1683
        
1684
        
1685
        public static SLDLayer toSLDLayer(IVectorialIntervalLegend legend)
1686
                        throws UnsupportedSymbolException {
1687
                
1688
                String fname = legend.getClassifyingFieldNames()[0];
1689
                SLDSymbol sldsym = null;
1690
                SLDRule rule = null;
1691
                SLDFeatureStyle fstyle = new SLDFeatureStyle();
1692
                
1693
                IInterval iival = null;
1694
                String valstr = null;
1695
                Object[] vals = legend.getValues();
1696
                ISymbol[] syms = legend.getSymbols();
1697
                int n = Math.min(vals.length, syms.length);
1698
                SLDFilter filt = null;
1699
                SLDComparisonOperator oper = null;
1700
                ISymbol elsesym = null; 
1701

    
1702
                for (int i=0; i<n; i++) {
1703
                        rule = new SLDRule();
1704
                        // =====================
1705
                        sldsym = sldMan().toSLDSymbol(syms[i]);
1706
                        rule.getSymbols().add(sldsym);
1707
                        // =====================
1708
                        if (vals[i] instanceof IInterval) {
1709
                                filt = supMan().createFilter();
1710
                                filt.setIsElse(false);
1711
                                iival = (IInterval) vals[i];
1712
                                oper = intervalToComparisonOperator(iival, fname);
1713
                                filt.setFilterOperator(oper);
1714
                                // =====================
1715
                                rule.setFilter(filt);
1716
                                // ======================
1717
                                fstyle.getRules().add(rule);
1718
                        } else {
1719
                                // assuming "Default"
1720
                                elsesym = syms[i]; 
1721
                        }
1722
                }
1723
                // ================ Default symbol
1724
                
1725
                // No "Default" value was found in intervals
1726
                // but default sym is enabled
1727
                if (elsesym == null && legend.isUseDefaultSymbol()) {
1728
                        elsesym = legend.getDefaultSymbol();
1729
                }
1730

    
1731
                if (elsesym != null) {
1732
                        rule = new SLDRule();
1733
                        sldsym = sldMan().toSLDSymbol(elsesym);
1734
                        rule.getSymbols().add(sldsym);
1735
                        filt = supMan().createFilter();
1736
                        filt.setIsElse(true);
1737
                        rule.setFilter(filt);
1738
                        fstyle.getRules().add(rule);
1739
                }
1740
                // ======================
1741
                SLDUserStyle usty = new SLDUserStyle();
1742
                usty.getFeatureStyles().add(fstyle);
1743
                
1744
                SLDNamedLayer nlayer = new SLDNamedLayer();
1745
                nlayer.setName("Name");
1746
                nlayer.getStyles().add(usty);
1747
                return nlayer;        
1748
                
1749
        }
1750

    
1751
        private static SLDComparisonOperator intervalToComparisonOperator(
1752
                        IInterval iival, String fieldName) {
1753
                
1754
                double max = iival.getMax();
1755
                double min = iival.getMin();
1756
                if (max == Double.MAX_VALUE && min != -Double.MAX_VALUE) {
1757
                        // greater than min
1758
                        SLDBinaryComparisonOperator resp = new SLDBinaryComparisonOperator();
1759
                        resp.setComparisonOperator(FilterTags.PROPERTYISGREATEROREQUALTHAN);
1760
                        resp.setFirstExpression(new SLDPropertyName(fieldName));
1761
                        resp.setSecondExpression(new SLDLiteral(Double.toString(min)));
1762
                        return resp;
1763
                        
1764
                } else {
1765
                        if (min == -Double.MAX_VALUE && max != Double.MAX_VALUE) {
1766
                                // less than max
1767
                                SLDBinaryComparisonOperator resp = new SLDBinaryComparisonOperator();
1768
                                resp.setComparisonOperator(FilterTags.PROPERTYISLESSOREQUALTHAN);
1769
                                resp.setFirstExpression(new SLDPropertyName(fieldName));
1770
                                resp.setSecondExpression(new SLDLiteral(Double.toString(max)));
1771
                                return resp;
1772
                                
1773
                        } else {
1774
                                // normal (between)
1775
                                SLDIsBetweenOperator resp = new SLDIsBetweenOperator();
1776
                                resp.setExpression(new SLDPropertyName(fieldName));
1777
                                resp.setLowerBoundary(new SLDLiteral(Double.toString(min)));
1778
                                resp.setUpperBoundary(new SLDLiteral(Double.toString(max)));
1779
                                return resp;
1780
                        }
1781
                }
1782
        }
1783

    
1784

    
1785
}