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 |
} |