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 / legend / IntervalsLegendUtils.java @ 40864

History | View | Annotate | Download (13.6 KB)

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

    
3
import java.util.HashMap;
4
import java.util.Iterator;
5
import java.util.List;
6
import java.util.Map;
7

    
8
import org.gvsig.fmap.mapcontext.rendering.legend.IInterval;
9
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialIntervalLegend;
10
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
11
import org.gvsig.sldconverter.exception.UnsupportedSymbolException;
12
import org.gvsig.sldconverter.impl.util.BasicUtils;
13
import org.gvsig.sldsupport.exception.UnsupportedSLDObjectException;
14
import org.gvsig.sldsupport.sld.filter.FilterTags;
15
import org.gvsig.sldsupport.sld.filter.SLDFilter;
16
import org.gvsig.sldsupport.sld.filter.SLDFilterOperator;
17
import org.gvsig.sldsupport.sld.filter.expression.SLDExpression;
18
import org.gvsig.sldsupport.sld.filter.expression.operator.SLDLiteral;
19
import org.gvsig.sldsupport.sld.filter.expression.operator.SLDPropertyName;
20
import org.gvsig.sldsupport.sld.filter.operator.SLDComparisonOperator;
21
import org.gvsig.sldsupport.sld.filter.operator.comparison.SLDBinaryComparisonOperator;
22
import org.gvsig.sldsupport.sld.filter.operator.comparison.SLDIsBetweenOperator;
23
import org.gvsig.sldsupport.sld.layer.SLDLayer;
24
import org.gvsig.sldsupport.sld.layer.SLDNamedLayer;
25
import org.gvsig.sldsupport.sld.rule.SLDRule;
26
import org.gvsig.sldsupport.sld.style.SLDFeatureStyle;
27
import org.gvsig.sldsupport.sld.style.layer.SLDUserStyle;
28
import org.gvsig.sldsupport.sld.symbol.SLDSymbol;
29
import org.gvsig.tools.dataTypes.CoercionException;
30
import org.gvsig.tools.dataTypes.DataType;
31

    
32
public class IntervalsLegendUtils {
33
        
34
        
35
        public static IVectorialIntervalLegend toIntervalsLegend(List<SLDRule> rules)
36
                        throws UnsupportedSLDObjectException {
37
                
38
                IVectorialIntervalLegend intleg = (IVectorialIntervalLegend) 
39
                                BasicUtils.mapMan().createLegend(
40
                                                IVectorialIntervalLegend.LEGEND_NAME);
41
                
42
                String pname = BasicUtils.getFirstPropertyName(rules);
43
                if (pname == null || pname.length() == 0) {
44
                        throw new UnsupportedSLDObjectException(
45
                                        "SLDFeatureStyle", "Cannot interpret rules (no property name)");
46
                }
47
                List<SLDLiteral> lits = BasicUtils.getComparisonLiterals(rules);
48
                if (lits == null || lits.size() == 0) {
49
                        throw new UnsupportedSLDObjectException(
50
                                        "SLDFeatureStyle", "Cannot interpret rules (no literals)");
51
                }
52
                DataType dt = BasicUtils.guessDataType(lits);
53
                ISymbol sym = BasicUtils.getElseSymbol(rules);
54
                // sym can be null
55
                Map<IInterval, ISymbol> map =
56
                                IntervalsLegendUtils.getIntervalToSymbol(rules, dt, pname);
57
                Iterator iter = map.keySet().iterator();
58
                Object k = null;
59
                while (iter.hasNext()) {
60
                        k = iter.next();
61
                        intleg.addSymbol(k, map.get(k));
62
                }
63
                // Setting Default symbol
64
                if (sym != null) {
65
                        sym.setDescription("Default");
66
                        intleg.setDefaultSymbol(sym);
67
                        intleg.useDefaultSymbol(true);
68
                        // String among the intervals
69
                        intleg.addSymbol(sym.getDescription(), sym);
70
                } else {
71
                        intleg.useDefaultSymbol(false);
72
                }
73
                
74
                String[] atts = new String[1];
75
                atts[0] = pname;
76
                intleg.setClassifyingFieldNames(atts);
77
                int[] typs = new int[1];
78
                typs[0] = dt.getType();
79
                intleg.setClassifyingFieldTypes(typs);
80
                return intleg;        
81
        
82
        }
83
        
84
        
85
        public static boolean areRulesOfIntervals(List<SLDRule> rules) {
86

    
87
                if (rules == null || rules.size() == 0) {
88
                        return false;
89
                }
90
                
91
                SLDRule rule = null;
92
                String fieldName = null;
93
                for (int i=0; i<rules.size(); i++) {
94
                        rule = rules.get(i);
95
                        fieldName = getComparisonToNumericLiteralFieldName(rule);
96
                        if (fieldName != null) {
97
                                break;
98
                        }
99
                }
100
                
101
                if (fieldName == null) {
102
                        // The filter of first rule is not of type "field name equals literal"
103
                        return false;
104
                }
105
                int elsecount = 0;
106
                for (int i=1; i<rules.size(); i++) {
107
                        rule = rules.get(i);
108
                        if (!BasicUtils.isElse(rule)) {
109
                                String fname = getComparisonToNumericLiteralFieldName(rule);
110
                                if (fname == null || fname.compareTo(fieldName) != 0) {
111
                                        // Not a equals operation based on the same field
112
                                        return false;
113
                                }
114
                        } else {
115
                                elsecount++;
116
                        }
117
                                
118
                }
119
                // Found no reason to deny it's a interval legend
120
                // (if number of else filters is 0 or 1)
121
                return elsecount < 2;
122
        }
123
        
124
        
125
        /**
126
         * Returns the name of the field name on which the rule
127
         * is based if the rule is a interval comparison and the
128
         * operand is a literal. Otherwise returns null.
129
         *    
130
         * @param rule
131
         * @return
132
         */
133
        private static String getComparisonToNumericLiteralFieldName(SLDRule rule) {
134
                
135
                SLDFilter filt = rule.getFilter();
136
                if (filt == null) {
137
                        return null;
138
                }
139
                SLDFilterOperator oper = filt.getFilterOperator();
140
                if (!(oper instanceof SLDComparisonOperator)) {
141
                        // interval has to be SLDComparisonOperator
142
                        return null;
143
                }
144
                SLDComparisonOperator cop = (SLDComparisonOperator) oper;
145
                SLDPropertyName pname = null;
146
                if (cop instanceof SLDBinaryComparisonOperator) {
147
                        SLDBinaryComparisonOperator bco = (SLDBinaryComparisonOperator) cop;
148
                        String opname = bco.getComparisonOperator();
149
                        if (opname.compareTo(FilterTags.PROPERTYISGREATEROREQUALTHAN) == 0
150
                                        || opname.compareTo(FilterTags.PROPERTYISGREATERTHAN) == 0
151
                                        || opname.compareTo(FilterTags.PROPERTYISLESSOREQUALTHAN) == 0
152
                                        || opname.compareTo(FilterTags.PROPERTYISLESSTHAN) == 0) {
153

    
154
                                if (bco.getFirstExpression() instanceof SLDLiteral &&
155
                                                bco.getSecondExpression() instanceof SLDPropertyName) {
156
                                        
157
                                        pname = (SLDPropertyName) bco.getSecondExpression(); 
158
                                        if (BasicUtils.isNumeric((SLDLiteral) bco.getFirstExpression())) {
159
                                                return pname.getPropertyName();
160
                                        } else {
161
                                                return null;
162
                                        }
163
                                        
164
                                }
165
                                if (bco.getFirstExpression() instanceof SLDPropertyName &&
166
                                                bco.getSecondExpression() instanceof SLDLiteral) {
167
                                        
168
                                        pname = (SLDPropertyName) bco.getFirstExpression(); 
169
                                        if (BasicUtils.isNumeric((SLDLiteral) bco.getSecondExpression())) {
170
                                                return pname.getPropertyName();
171
                                        } else {
172
                                                return null;
173
                                        }
174
                                }
175
                        }
176
                } else {
177
                        if (cop instanceof SLDIsBetweenOperator) {
178
                                
179
                                SLDIsBetweenOperator beop = (SLDIsBetweenOperator) cop;
180
                                if (beop.getExpression() instanceof SLDPropertyName
181
                                                // Limits must be literals
182
                                                && beop.getLowerBoundary() instanceof SLDLiteral
183
                                                && beop.getUpperBoundary() instanceof SLDLiteral) {
184
                                        
185
                                        pname = (SLDPropertyName) beop.getExpression();
186
                                        if (BasicUtils.isNumeric((SLDLiteral) beop.getLowerBoundary())
187
                                                        && BasicUtils.isNumeric((SLDLiteral) beop.getUpperBoundary())) {
188
                                                return pname.getPropertyName();
189
                                        } else {
190
                                                return null;
191
                                        }
192
                                }
193
                        }
194
                }
195
                // Not the type we are looking for
196
                return null;
197
        }                
198
        
199
        
200
        public static SLDLayer toSLDLayer(IVectorialIntervalLegend legend)
201
                        throws UnsupportedSymbolException {
202
                
203
                String fname = legend.getClassifyingFieldNames()[0];
204
                SLDSymbol sldsym = null;
205
                SLDRule rule = null;
206
                SLDFeatureStyle fstyle = new SLDFeatureStyle();
207
                
208
                IInterval iival = null;
209
                String valstr = null;
210
                Object[] vals = legend.getValues();
211
                ISymbol[] syms = legend.getSymbols();
212
                int n = Math.min(vals.length, syms.length);
213
                SLDFilter filt = null;
214
                SLDComparisonOperator oper = null;
215
                ISymbol elsesym = null; 
216

    
217
                for (int i=0; i<n; i++) {
218
                        rule = new SLDRule();
219
                        // =====================
220
                        sldsym = BasicUtils.sldMan().toSLDSymbol(syms[i]);
221
                        rule.getSymbols().add(sldsym);
222
                        // =====================
223
                        if (vals[i] instanceof IInterval) {
224
                                filt = BasicUtils.supMan().createFilter();
225
                                filt.setIsElse(false);
226
                                iival = (IInterval) vals[i];
227
                                oper = intervalToComparisonOperator(iival, fname);
228
                                filt.setFilterOperator(oper);
229
                                // =====================
230
                                rule.setFilter(filt);
231
                                // ======================
232
                                fstyle.getRules().add(rule);
233
                        } else {
234
                                // assuming "Default"
235
                                elsesym = syms[i]; 
236
                        }
237
                }
238
                // ================ Default symbol
239
                
240
                // No "Default" value was found in intervals
241
                // but default sym is enabled
242
                if (elsesym == null && legend.isUseDefaultSymbol()) {
243
                        elsesym = legend.getDefaultSymbol();
244
                }
245

    
246
                if (elsesym != null) {
247
                        rule = new SLDRule();
248
                        sldsym = BasicUtils.sldMan().toSLDSymbol(elsesym);
249
                        rule.getSymbols().add(sldsym);
250
                        filt = BasicUtils.supMan().createFilter();
251
                        filt.setIsElse(true);
252
                        rule.setFilter(filt);
253
                        fstyle.getRules().add(rule);
254
                }
255
                // ======================
256
                SLDUserStyle usty = new SLDUserStyle();
257
                usty.getFeatureStyles().add(fstyle);
258
                
259
                SLDNamedLayer nlayer = new SLDNamedLayer();
260
                nlayer.setName("Name");
261
                nlayer.getStyles().add(usty);
262
                return nlayer;        
263
                
264
        }
265
        
266
        
267
        private static SLDComparisonOperator intervalToComparisonOperator(
268
                        IInterval iival, String fieldName) {
269
                
270
                double max = iival.getMax();
271
                double min = iival.getMin();
272
                if (max == Double.MAX_VALUE && min != -Double.MAX_VALUE) {
273
                        // greater than min
274
                        SLDBinaryComparisonOperator resp = new SLDBinaryComparisonOperator();
275
                        resp.setComparisonOperator(FilterTags.PROPERTYISGREATEROREQUALTHAN);
276
                        resp.setFirstExpression(new SLDPropertyName(fieldName));
277
                        
278
                        resp.setSecondExpression(new SLDLiteral(BasicUtils.df.format(min)));
279
                        return resp;
280
                        
281
                } else {
282
                        if (min == -Double.MAX_VALUE && max != Double.MAX_VALUE) {
283
                                // less than max
284
                                SLDBinaryComparisonOperator resp = new SLDBinaryComparisonOperator();
285
                                resp.setComparisonOperator(FilterTags.PROPERTYISLESSOREQUALTHAN);
286
                                resp.setFirstExpression(new SLDPropertyName(fieldName));
287
                                resp.setSecondExpression(new SLDLiteral(BasicUtils.df.format(max)));
288
                                return resp;
289
                                
290
                        } else {
291
                                // normal (between)
292
                                SLDIsBetweenOperator resp = new SLDIsBetweenOperator();
293
                                resp.setExpression(new SLDPropertyName(fieldName));
294
                                resp.setLowerBoundary(new SLDLiteral(BasicUtils.df.format(min)));
295
                                resp.setUpperBoundary(new SLDLiteral(BasicUtils.df.format(max)));
296
                                return resp;
297
                        }
298
                }
299
        }        
300
        
301
        
302
        
303
        /**
304
         * Translates rules to a interval-symbol correspondence.
305
         * 
306
         * @param rules
307
         * @param dt
308
         * @return
309
         * @throws UnsupportedSLDObjectException 
310
         * @throws CoercionException 
311
         */
312
        public static Map<IInterval, ISymbol> getIntervalToSymbol(
313
                        List<SLDRule> rules, DataType dt, String pname)
314
                                        throws UnsupportedSLDObjectException {
315
                
316
                Map<IInterval, ISymbol> resp = new HashMap<IInterval, ISymbol>();
317
                if (rules == null || rules.size() == 0) {
318
                        return resp;
319
                }
320
                SLDFilter filt = null;
321
                List<SLDSymbol> symList = null;
322
                SLDFilterOperator oper = null;
323
                SLDBinaryComparisonOperator binoper = null;
324
                ISymbol sym = null;
325
                SLDPropertyName sldpname = null;
326
                SLDLiteral sldlit = null;
327
                Object val = null;
328
                for (int i=0; i<rules.size(); i++) {
329
                        symList = rules.get(i).getSymbols();
330
                        if (symList == null || symList.size() == 0) {
331
                                /*
332
                                 * No symbols found
333
                                 */
334
                                continue;
335
                        }
336
                        filt = rules.get(i).getFilter();
337
                        if (filt == null) {
338
                                continue;
339
                        }
340
                        if (!filt.isElse()) {
341
                                oper = filt.getFilterOperator();
342
                                if (oper instanceof SLDComparisonOperator) {
343
                                        sym = BasicUtils.sldMan().toSymbol(symList.get(0));
344
                                        if (sym != null) {
345
                                                IInterval ival = getIntervalForSymbol(
346
                                                                (SLDComparisonOperator) oper, pname, sym);
347
                                                if (ival != null) {
348
                                                        resp.put(ival, sym);
349
                                                }
350
                                        }
351
                                }
352
                        } else {
353
                                // filter is else
354
                        }
355
                }
356
                return resp;
357
        }
358
        
359
        private static IInterval getIntervalForSymbol(
360
                        SLDComparisonOperator oper, String pname, ISymbol sym) {
361
                
362
                double min = 0;
363
                double max = 0;
364
                SLDBinaryComparisonOperator bc = null;
365
                SLDIsBetweenOperator bw = null;
366
                SLDLiteral lit = null;
367
                if (oper instanceof SLDBinaryComparisonOperator) {
368
                        bc = (SLDBinaryComparisonOperator) oper;
369
                        if (isGreaterComparison(bc)) {
370
                                lit = BasicUtils.getLiteral(bc.getExpressions());
371
                                try {
372
                                        min = Double.parseDouble(lit.getValue());
373
                                        max = Double.MAX_VALUE;
374
                                        sym.setDescription("> " + lit.getValue());
375
                                } catch (Exception exc) {
376
                                        return null;
377
                                }
378
                                
379
                        } else {
380
                                if (isLessThanComparison(bc)) {
381
                                        lit = BasicUtils.getLiteral(bc.getExpressions());
382
                                        try {
383
                                                max = Double.parseDouble(lit.getValue());
384
                                                min = -Double.MAX_VALUE;
385
                                                sym.setDescription("< " + lit.getValue());
386
                                        } catch (Exception exc) {
387
                                                return null;
388
                                        }
389
                                } else {
390
                                        return null;
391
                                }
392
                        }
393
                } else {
394
                        if (oper instanceof SLDIsBetweenOperator) {
395
                                bw = (SLDIsBetweenOperator) oper;
396
                                SLDExpression lower = bw.getLowerBoundary();
397
                                SLDExpression upper = bw.getUpperBoundary();
398
                                if (lower instanceof SLDLiteral && upper instanceof SLDLiteral) {
399
                                        String lowerstr = ((SLDLiteral) lower).getValue();
400
                                        String upperstr = ((SLDLiteral) upper).getValue();
401
                                        try {
402
                                                min = Double.parseDouble(lowerstr);
403
                                                max = Double.parseDouble(upperstr);
404
                                                sym.setDescription(lowerstr + " - " + upperstr);
405
                                        } catch (Exception exc) {
406
                                                return null;
407
                                        }
408
                                } else {
409
                                        return null;
410
                                }
411
                                
412
                        } else {
413
                                return null;
414
                        }
415
                }
416
                return BasicUtils.symMan().createInterval(min, max);
417
        }
418
        
419
        
420
        private static boolean isLessThanComparison(SLDBinaryComparisonOperator bc) {
421
                if (bc == null) {
422
                        return false;
423
                } else {
424
                        String comp = bc.getComparisonOperator();
425
                        return comp != null &&
426
                                        (comp.compareTo(FilterTags.PROPERTYISLESSOREQUALTHAN) == 0
427
                                        || comp.compareTo(FilterTags.PROPERTYISLESSTHAN) == 0);
428
                }
429
        }
430

    
431
        private static boolean isGreaterComparison(SLDBinaryComparisonOperator bc) {
432
                if (bc == null) {
433
                        return false;
434
                } else {
435
                        String comp = bc.getComparisonOperator();
436
                        return comp != null &&
437
                                        (comp.compareTo(FilterTags.PROPERTYISGREATEROREQUALTHAN) == 0
438
                                        || comp.compareTo(FilterTags.PROPERTYISGREATERTHAN) == 0);
439
                }
440
        }        
441
        
442
}