Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / VectorialUniqueValueLegend.java @ 22465

History | View | Annotate | Download (19 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.rendering;
42

    
43
import java.sql.Types;
44
import java.text.ParseException;
45
import java.util.ArrayList;
46
import java.util.Comparator;
47
import java.util.Iterator;
48
import java.util.TreeMap;
49

    
50
import org.apache.log4j.Logger;
51

    
52
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
53
import com.hardcode.gdbms.engine.data.DataSource;
54
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
55
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException;
56
import com.hardcode.gdbms.engine.instruction.SemanticException;
57
import com.hardcode.gdbms.engine.values.BooleanValue;
58
import com.hardcode.gdbms.engine.values.NullValue;
59
import com.hardcode.gdbms.engine.values.StringValue;
60
import com.hardcode.gdbms.engine.values.Value;
61
import com.hardcode.gdbms.engine.values.ValueFactory;
62
import com.iver.cit.gvsig.fmap.core.IFeature;
63
import com.iver.cit.gvsig.fmap.core.ISLDCompatible;
64
import com.iver.cit.gvsig.fmap.core.SLDTags;
65
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
66
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
67
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
68
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
69
import com.iver.cit.gvsig.fmap.layers.XMLException;
70
import com.iver.utiles.XMLEntity;
71

    
72
/**
73
 * Vectorial legend for unique values
74
 * 
75
 * @author   Vicente Caballero Navarro
76
 */
77
//public class VectorialUniqueValueLegend implements IVectorialUniqueValueLegend {
78
public class VectorialUniqueValueLegend extends AbstractClassifiedVectorLegend implements IVectorialUniqueValueLegend {
79
        private static final Logger log = Logger.getLogger(VectorialUniqueValueLegend.class);
80
        protected int fieldId;
81
        protected DataSource dataSource;
82

    
83
        private TreeMap<Value, ISymbol> symbols = new TreeMap<Value, ISymbol>(
84
                        new Comparator<Object>() {
85
                public int compare(Object o1, Object o2) {
86
                        if ((o1 != null) && (o2 != null)) {
87
                                Value v2 = (Value) o2;
88
                                Value v1 = (Value) o1;
89
                                BooleanValue boolVal;
90

    
91
                                // TODO estas dos comprobaciones son por evitar un bug en el gdbms, cuando se solucione se puede eliminar.
92
                                if (v1 instanceof NullValue && v2 instanceof NullValue) {
93
                                        return 0;
94
                                }
95

    
96
                                if (v1 instanceof NullValue) {
97
                                        return -1;
98
                                }
99

    
100
                                if (v2 instanceof NullValue) {
101
                                        return 1;
102
                                }
103

    
104
                                try {
105
                                        boolVal = (BooleanValue) (v1.greater(v2));
106

    
107
                                        if (boolVal.getValue()) {
108
                                                return 1;
109
                                        }
110

    
111
                                        boolVal = (BooleanValue) (v1.less(v2));
112

    
113
                                        if (boolVal.getValue()) {
114
                                                return -1;
115
                                        }
116
                                } catch (IncompatibleTypesException e) {
117
                                        // TODO Auto-generated catch block
118
                                        //e.printStackTrace();
119
                                }
120

    
121
                                try {
122
                                        if (((BooleanValue) v1.equals(v2)).getValue()) {
123
                                                return 0;
124
                                        }
125
                                } catch (IncompatibleTypesException e) {
126
                                        // TODO Auto-generated catch block
127
                                        //e.printStackTrace();
128
                                }
129

    
130
                                if (v1 instanceof StringValue) {
131
                                        return -1;
132
                                }
133

    
134
                                if (v2 instanceof StringValue) {
135
                                        return 1;
136
                                }
137
                        }
138

    
139
                        return 0;
140
                }
141
        }); // Para poder ordenar
142
    private ArrayList<Value> keys = new ArrayList<Value>(); // En lugar de un HashSet, para tener acceso por ?ndice
143
    private String labelFieldName;
144
    private String labelFieldHeight;
145
    private String labelFieldRotation;
146
    private ISymbol defaultSymbol;
147
    private int shapeType;
148
    private String valueType = NullValue.class.getName();
149
    private boolean useDefaultSymbol = false;
150
        /**
151
     * Constructor method
152
     */
153
    public VectorialUniqueValueLegend() {
154
    }
155

    
156
    /**
157
     * Constructor method 
158
     *
159
     * @param shapeType Type of the shape.
160
     */
161
    public VectorialUniqueValueLegend(int shapeType) {
162
        setShapeType(shapeType);
163
    }
164

    
165
     public void setShapeType(int shapeType) {
166
            if (this.shapeType != shapeType) {
167
                    ISymbol old = defaultSymbol;
168
                    defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
169
                    fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
170
                    this.shapeType = shapeType;
171
            }
172
    }
173

    
174
    public void setValueSymbolByID(int id, ISymbol symbol) {
175
        ISymbol old = symbols.put(keys.get(id), symbol);
176
        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(old, symbol));
177
    }
178

    
179
    /**
180
     * Used in the table that shows the legend
181
     * 
182
     * @deprecated use setValueSymbolByID(int id, ISymbol symbol);
183
     * @param id
184
     * @param symbol
185
     */
186
    public void setValueSymbol(int id, ISymbol symbol) {
187
            ISymbol old = symbols.put(keys.get(id), symbol);
188
        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(old, symbol));
189
    }
190

    
191
    public Object[] getValues() {
192
        return symbols.keySet().toArray(new Object[0]);
193
    }
194

    
195
    public void addSymbol(Object key, ISymbol symbol) {
196
        ISymbol resul;
197
        resul = symbols.put((Value) key, symbol);
198

    
199
        if (resul != null) {
200
                log.error("Error: la clave " + key +
201
                " ya exist?a. Resul = " + resul);
202
            log.warn("symbol nuevo:" + symbol.getDescription() +
203
                " Sviejo= " + resul.getDescription());
204
        } else { 
205
            keys.add((Value) key);
206

    
207
            if (!key.getClass().equals(NullValue.class)) {
208
                valueType = key.getClass().getName();
209
            }
210
        }
211
        
212
        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(resul, symbol));
213
       
214
    }
215

    
216
    public void clear() {
217
        keys.clear();
218
        ISymbol[] olds = symbols.values().toArray(new ISymbol[0]);
219
        symbols.clear();
220
        removeLegendListener(getZSort());
221
        setZSort(null);
222
        
223
        fireLegendClearEvent(new LegendClearEvent(olds));
224
    }
225

    
226
    public String[] getDescriptions() {
227
        String[] descriptions = new String[symbols.size()];
228
        ISymbol[] auxSym = getSymbols();
229

    
230
        for (int i = 0; i < descriptions.length; i++)
231
            descriptions[i] = auxSym[i].getDescription();
232

    
233
        return descriptions;
234
    }
235

    
236
     public ISymbol[] getSymbols() {
237
        return symbols.values().toArray(new ISymbol[0]);
238
    }
239

    
240
     @Override
241
     public void setClassifyingFieldNames(String[] fNames) {
242
             super.setClassifyingFieldNames(fNames);
243
             try {
244
                     fieldId = dataSource.getFieldIndexByName(getClassifyingFieldNames()[0]);
245
             } catch (NullPointerException e) {
246
                     log.warn("data source not set");
247
             } catch (ReadDriverException e) {
248
                     log.warn("failed setting field id");
249
             }
250
     }
251
    /*
252
     * @see com.iver.cit.gvsig.fmap.rendering.IVectorialLegend#getSymbol(int)
253
     */
254
    public ISymbol getSymbol(int recordIndex) throws ReadDriverException {
255
                Value val = dataSource.getFieldValue(recordIndex, fieldId);
256
                ISymbol theSymbol = getSymbolByValue(val);
257

    
258
                return theSymbol;
259
        }
260

    
261
    /**
262
         * Devuelve un s?mbolo a partir de una IFeature. OJO!! Cuando usamos un
263
         * feature iterator de base de datos el ?nico campo que vendr? rellenado es
264
         * el de fieldID. Los dem?s vendr?n a nulos para ahorra tiempo de creaci?n.
265
         *
266
         * @param feat
267
         *            IFeature
268
         *
269
         * @return S?mbolo.
270
         */
271
    public ISymbol getSymbolByFeature(IFeature feat) {
272
        Value val = feat.getAttribute(FLyrVect.forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD
273
                        ? 0 :fieldId);
274
        ISymbol theSymbol = getSymbolByValue(val);
275

    
276
        if (theSymbol != null) {
277
                return theSymbol;
278

    
279
        } 
280

    
281
               return getDefaultSymbol();
282
    }
283

    
284
    public ISymbol getDefaultSymbol() {
285

    
286
//          NullUniqueValue nuv=new NullUniqueValue();
287
//          if (symbols.containsKey(nuv))
288
//          return symbols.get(nuv);
289

    
290
            if(defaultSymbol==null) {
291
                    defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
292
                    fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, defaultSymbol));
293
            }
294
            return defaultSymbol;
295
    }
296

    
297
    public XMLEntity getXMLEntity() {
298
        XMLEntity xml = new XMLEntity();
299
        xml.putProperty("className", this.getClass().getName());
300
        xml.putProperty("fieldNames", getClassifyingFieldNames()[0]);
301
        
302
        ///////////////////////////////////////PEPE
303
        xml.putProperty("fieldTypes", getClassifyingFieldTypes()[0]);
304
        ///////////////////////////////////////PEPE
305
        
306
        xml.putProperty("labelfield", labelFieldName);
307
        xml.putProperty("labelFieldHeight", labelFieldHeight);
308
        xml.putProperty("labelFieldRotation", labelFieldRotation);
309

    
310
        xml.putProperty("useDefaultSymbol", useDefaultSymbol);
311
        xml.addChild(getDefaultSymbol().getXMLEntity());
312
        xml.putProperty("numKeys", keys.size());
313

    
314
        if (keys.size() > 0) {
315
            xml.putProperty("tipoValueKeys", valueType);
316

    
317
            String[] sk = new String[keys.size()];
318
            String[] sv = new String[keys.size()];
319
            int[] stk = new int[keys.size()];
320
            int[] stv = new int[keys.size()];
321
            ISymbol[] fsymbols = getSymbols();
322
            Object[] values = getValues();
323

    
324
            for (int i = 0; i < keys.size(); i++) {
325
                    if (keys.get(i).toString().equals("")) {
326
                            sk[i] =" ";
327
                    }else {
328
                            sk[i] = keys.get(i).toString();
329
                    }
330
                    if (((Value) values[i]).toString().equals("")) {
331
                            sv[i] =" ";
332
                    }else {
333
                            sv[i] = ((Value) values[i]).toString();
334
                    }
335
                    stk[i]= keys.get(i).getSQLType();
336
                    stv[i]= ((Value)values[i]).getSQLType();
337
                xml.addChild(fsymbols[i].getXMLEntity());
338

    
339
                ///System.out.println("get-----------"+sk[i]+"--"+fsymbols[i].getDescription()+"---"+fsymbols[i].getColor());
340
            }
341

    
342
            xml.putProperty("keys", sk);
343
            xml.putProperty("values", sv);
344
            xml.putProperty("typeKeys",stk);
345
            xml.putProperty("typeValues",stv);
346
        }
347
        
348
        if (getZSort()!=null) {
349
                XMLEntity xmlZSort = getZSort().getXMLEntity();
350
                xmlZSort.putProperty("id", "zSort");
351
                xml.addChild(xmlZSort);
352
        }
353
        return xml;
354
    }
355

    
356
    public void setXMLEntity03(XMLEntity xml) {
357
        clear();
358
        setClassifyingFieldNames(new String[] {xml.getStringProperty("fieldName")});
359

    
360
        int useDefaultSymbol = xml.getIntProperty("useDefaultSymbol");
361

    
362
        if (useDefaultSymbol == 1) {
363
            setDefaultSymbol(FSymbol.createFromXML03(xml.getChild(0)));
364
        } else {
365
            setDefaultSymbol(null);
366
        }
367

    
368
        int numKeys = xml.getIntProperty("numKeys");
369

    
370
        if (numKeys > 0) {
371
            String className = xml.getStringProperty("tipoValueKeys");
372
            String[] sk = xml.getStringArrayProperty("keys");
373
            String[] sv = xml.getStringArrayProperty("values");
374
            Value auxValue;
375
            Value auxValue2;
376

    
377
            for (int i = 0; i < numKeys; i++) {
378
                try {
379
                    auxValue = ValueFactory.createValue(sk[i], className);
380
                    auxValue2 = ValueFactory.createValue(sv[i], className);
381

    
382
                    ISymbol sym = FSymbol.createFromXML03(xml.getChild(i +
383
                                useDefaultSymbol));
384

    
385
                    symbols.put(auxValue2, sym);
386
                    keys.add(auxValue);
387

    
388
                } catch (SemanticException e) {
389
                        log.error("Exception", e);
390
                    e.printStackTrace();
391
                }
392
            }
393
        }
394
    }
395

    
396
    public void setXMLEntity(XMLEntity xml) {
397
        clear();
398
        if (xml.contains("fieldName"))
399
                setClassifyingFieldNames(new String[] {xml.getStringProperty("fieldName")});
400
        else
401
                setClassifyingFieldNames(xml.getStringArrayProperty("fieldNames"));
402

    
403
        if (xml.contains("fieldTypes"))
404
                setClassifyingFieldTypes(new int[] {xml.getIntProperty("fieldTypes")});
405

    
406
        useDefaultSymbol = xml.getBooleanProperty("useDefaultSymbol");
407
        setDefaultSymbol(SymbologyFactory.createSymbolFromXML(xml.getChild(0), null));
408

    
409
        int numKeys = xml.getIntProperty("numKeys");
410

    
411
        if (numKeys > 0) {
412
            String className = xml.getStringProperty("tipoValueKeys");
413
            String[] sk = xml.getStringArrayProperty("keys");
414
            String[] sv = xml.getStringArrayProperty("values");
415
            Value auxValue = null;
416
            Value auxValue2 = null;
417
            int[] stk=null;
418
            if (xml.contains("typeKeys")) {
419
                                stk = xml.getIntArrayProperty("typeKeys");
420
                                int[] stv = xml.getIntArrayProperty("typeValues");
421
                                for (int i = 0; i < numKeys; i++) {
422
                                        boolean isDefault = false;
423
                                        if (getValue(sk[i], stk[i]) == null) {
424
                                                isDefault = true;
425
                                        }
426

    
427
                                        if (className
428
                                                        .equals("com.hardcode.gdbms.engine.values.NullUniqueValue")
429
                                                        || isDefault) {
430
                                                auxValue = new NullUniqueValue();
431
                                                auxValue2 = ValueFactory.createNullValue();
432
                                        } else {
433
                                                auxValue = getValue(sk[i], stk[i]); // ValueFactory.createValue(sk[i],
434
                                                                                                                        // className);
435
                                                auxValue2 = getValue(sv[i], stv[i]); // ValueFactory.createValue(sv[i],
436
                                                                                                                                // className);
437
                                        }
438

    
439
                                        // (substituir la de baix per esta) ISymbol sym = SymbolFactory.createFromXML(xml.getChild(i + 1), null);
440
                                        ISymbol sym = SymbologyFactory.createSymbolFromXML(xml.getChild(i + 1), null);
441
                                        symbols.put(auxValue2, sym);
442
                                        keys.add(auxValue);
443
                                }
444
                        } else {
445
                                for (int i = 0; i < numKeys; i++) {
446
                                        boolean isDefault = false;
447
                                        if (getValue(sk[i]) == null) {
448
                                                isDefault = true;
449
                                        }
450
                                        if (className
451
                                                        .equals("com.hardcode.gdbms.engine.values.NullUniqueValue")
452
                                                        || isDefault) {
453
                                                auxValue = new NullUniqueValue();
454
                                                auxValue2 = ValueFactory.createNullValue();
455
                                        } else {
456
                                                auxValue = getValue(sk[i]); // ValueFactory.createValue(sk[i],
457
                                                                                                        // className);
458
                                                auxValue2 = getValue(sv[i]); // ValueFactory.createValue(sv[i],
459
                                                                                                                // className);
460
                                        }
461
                                        ISymbol sym = FSymbol.createFromXML(xml.getChild(i + 1));
462
                                        symbols.put(auxValue2, sym);
463
                                        keys.add(auxValue);
464
                                }
465
                        }
466
        }
467
        
468
        XMLEntity zSortXML = xml.firstChild("id", "zSort");
469
                if (zSortXML != null) {
470
                        ZSort zSort = new ZSort(this);
471
                        zSort.setXMLEntity(zSortXML);
472
                        addLegendListener(zSort);
473
                        setZSort(zSort);
474
                }
475
    }
476

    
477
    public void setDefaultSymbol(ISymbol s) {
478
            ISymbol mySymbol = defaultSymbol;
479
            
480
            if (s == null) 
481
                    throw new NullPointerException("Default symbol cannot be null");
482
            
483
            ISymbol old = mySymbol;
484
            defaultSymbol = s;
485
            fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, s));
486
    }
487

    
488
    /**
489
     * Returns the value using the its value in a string.
490
         * 
491
         *
492
         * @param s String with the value.
493
         * @deprecated Method used until 1.0 alpha 855 You should use getValue(String s,int type);
494
         * @return Value.
495
         */
496
    private Value getValue(String s) {
497
        Value val = new NullUniqueValue();
498
        if (s.equals("Resto de Valores"))return val;
499
        try {
500
            try {
501
                val = ValueFactory.createValueByType(s, Types.INTEGER);
502

    
503
                return val;
504
            } catch (NumberFormatException e) {
505
            }
506

    
507
            try {
508
                val = ValueFactory.createValueByType(s, Types.BIGINT);
509

    
510
                return val;
511
            } catch (NumberFormatException e) {
512
            }
513

    
514
            try {
515
                val = ValueFactory.createValueByType(s, Types.FLOAT);
516

    
517
                return val;
518
            } catch (NumberFormatException e) {
519
            }
520

    
521
            try {
522
                val = ValueFactory.createValueByType(s, Types.DOUBLE);
523

    
524
                return val;
525
            } catch (NumberFormatException e) {
526
            }
527

    
528
            val = ValueFactory.createValueByType(s, Types.LONGVARCHAR);
529

    
530
        } catch (ParseException e) {
531
           log.warn("parse exception", e);
532
        }
533

    
534
        return val;
535
    }
536

    
537
    /**
538
     * Devuelve el valor a partir de su valor en un string.
539
     *
540
     * @param s String con el valor.
541
     *
542
     * @return Value.
543
     */
544
    private Value getValue(String s,int type) {
545
        Value val = new NullUniqueValue();
546
        if (type==Types.OTHER)
547
                return val;
548
        try {
549
                val = ValueFactory.createValueByType(s, type);
550
        } catch (ParseException e) {
551
            e.printStackTrace();
552
        }
553
        return val;
554
    }
555

    
556
    public ILegend cloneLegend() throws XMLException {
557
        return LegendFactory.createFromXML(getXMLEntity());
558
    }
559

    
560

    
561
    /* (non-Javadoc)
562
     * @see com.iver.cit.gvsig.fmap.rendering.VectorialLegend#setDataSource(com.hardcode.gdbms.engine.data.DataSource)
563
     */
564
    public void setDataSource(DataSource ds) throws FieldNotFoundException,
565
                        ReadDriverException {
566
                dataSource = ds;
567
                ds.start();
568
                if (getClassifyingFieldNames()!=null)
569
                        fieldId = ds.getFieldIndexByName(getClassifyingFieldNames()[0]);
570
                ds.stop();
571
        }
572

    
573
    /*
574
     * (non-Javadoc)
575
     *
576
     * @see com.iver.cit.gvsig.fmap.rendering.UniqueValueLegend#getSymbolByValue(com.hardcode.gdbms.engine.values.Value)
577
     */
578
    public ISymbol getSymbolByValue(Value key) {
579
            ISymbol symbol = symbols.get(key);
580
            if (symbol!=null) {
581
                    return symbol;
582
            } else if (useDefaultSymbol) {
583
                    return getDefaultSymbol();
584
            }
585
            return null;
586

    
587
    }
588

    
589
    public int getShapeType() {
590
        return shapeType;
591
    }
592

    
593
    public void useDefaultSymbol(boolean b) {
594
        useDefaultSymbol = b;
595
    }
596

    
597
    /**
598
         * Devuelve si se utiliza o no el resto de valores para representarse.
599
         * @return  True si se utiliza el resto de valores.
600
         */
601
    public boolean isUseDefaultSymbol() {
602
        return useDefaultSymbol;
603
    }
604

    
605
    public void delSymbol(Object key) {
606
        keys.remove(key);
607
        
608
        fireClassifiedSymbolChangeEvent(
609
                        new SymbolLegendEvent(
610
                                        symbols.remove(key),
611
                                        null));
612
    }
613

    
614
        public String getClassName() {
615
                return getClass().getName();
616
        }
617
        
618
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
619
                if (symbols.containsValue(oldSymbol)) {
620
                        Iterator<Value> it = symbols.keySet().iterator();
621
                        while (it.hasNext()) {
622
                                Value key = it.next();
623
                                if (symbols.get(key).equals(oldSymbol)) {
624
                                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(
625
                                                        symbols.put(key, newSymbol), newSymbol));
626
                                }
627

    
628
                        }
629
                }
630
        }
631
}