Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / rendering / legend / VectorialUniqueValueLegend.java @ 28092

History | View | Annotate | Download (18.5 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 org.gvsig.fmap.mapcontext.rendering.legend;
42

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

    
50
import org.gvsig.fmap.dal.exception.DataException;
51
import org.gvsig.fmap.dal.feature.Feature;
52
import org.gvsig.fmap.dal.feature.FeatureStore;
53
import org.gvsig.fmap.dal.feature.FeatureType;
54
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
55
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
56
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
57
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbologyFactory;
58
import org.slf4j.Logger;
59
import org.slf4j.LoggerFactory;
60

    
61
import com.iver.utiles.StringUtilities;
62
import com.iver.utiles.XMLEntity;
63
import com.iver.utiles.XMLException;
64

    
65
/**
66
 * Vectorial legend for unique values
67
 *
68
 * @author   Vicente Caballero Navarro
69
 */
70
//public class VectorialUniqueValueLegend implements IVectorialUniqueValueLegend {
71
public class VectorialUniqueValueLegend extends AbstractClassifiedVectorLegend implements IVectorialUniqueValueLegend {
72
        final static private Logger logger = LoggerFactory.getLogger(VectorialUniqueValueLegend.class);
73
//        protected int fieldId;
74
//        protected DataSource dataSource;
75
        protected FeatureStore featureStore;
76
        private TreeMap symbols = new TreeMap( //<Object, ISymbol>
77
                        new Comparator() { //<Object>
78
                public int compare(Object o1, Object o2) {
79
                        if ((o1 != null) && (o2 != null)) {
80
                                Object v2 = o2;
81
                                Object v1 = o1;
82
                                Boolean boolVal;
83

    
84
                                // TODO estas dos comprobaciones son por evitar un bug en el gdbms, cuando se solucione se puede eliminar.
85
                                if (v1 == null && v2 == null) {
86
                                        return 0;
87
                                }
88

    
89
                                if (v1 instanceof NullUniqueValue) {
90
                                        return -1;
91
                                }
92

    
93
                                if (v2 instanceof NullUniqueValue) {
94
                                        return 1;
95
                                }
96

    
97
                                if (v1 instanceof Number && v2 instanceof Number){
98
                                        return((Number)v1).intValue()-((Number)v2).intValue();
99
                                }
100
                                if (v1 instanceof String && v2 instanceof String){
101
                                        return ((String)v1).compareTo(((String)v2));
102
                                }
103
                        }
104

    
105
                        return 0;
106
                }
107
        }); // Para poder ordenar
108
    private ArrayList keys = new ArrayList(); // En lugar de un HashSet, para tener acceso por ?ndice
109
    private String labelFieldName;
110
    private String labelFieldHeight;
111
    private String labelFieldRotation;
112
    private ISymbol defaultSymbol;
113
    private int shapeType;
114
    private String valueType = NullValue.class.getName();
115
    private boolean useDefaultSymbol = false;
116
    private Color[] selectedColors=null;
117
        /**
118
     * Constructor method
119
     */
120
    public VectorialUniqueValueLegend() {
121
    }
122

    
123
    /**
124
     * Constructor method
125
     *
126
     * @param shapeType Type of the shape.
127
     */
128
    public VectorialUniqueValueLegend(int shapeType) {
129
        setShapeType(shapeType);
130
    }
131

    
132
     public void setShapeType(int shapeType) {
133
            if (this.shapeType != shapeType) {
134
                    ISymbol old = defaultSymbol;
135
                    defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
136
                    fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
137
                    this.shapeType = shapeType;
138
            }
139
    }
140

    
141
    public void setValueSymbolByID(int id, ISymbol symbol) {
142
        ISymbol old = (ISymbol)symbols.put(keys.get(id), symbol);
143
        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(old, symbol));
144
    }
145

    
146
    /**
147
     * Used in the table that shows the legend
148
     *
149
     * @deprecated use setValueSymbolByID(int id, ISymbol symbol);
150
     * @param reference
151
     * @param symbol
152
     */
153
//    public void setValueSymbol(int id, ISymbol symbol) {
154
//            ISymbol old = symbols.put(keys.get(id), symbol);
155
//        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(old, symbol));
156
//    }
157

    
158
    public Object[] getValues() {
159
        return symbols.keySet().toArray(new Object[0]);
160
    }
161

    
162
    public void addSymbol(Object key, ISymbol symbol) {
163
        ISymbol resul;
164
        resul = (ISymbol)symbols.put(key, symbol);
165

    
166
        if (resul != null) {
167
                logger.error("Error: la clave " + key +
168
                " ya exist?a. Resul = " + resul);
169
            logger.warn("symbol nuevo:" + symbol.getDescription() +
170
                " Sviejo= " + resul.getDescription());
171
        } else {
172
            keys.add(key);
173

    
174
            if (!key.getClass().equals(NullValue.class)) {
175
                valueType = key.getClass().getName();
176
            }
177
        }
178

    
179
        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(resul, symbol));
180

    
181
    }
182

    
183
    public void clear() {
184
        keys.clear();
185
        ISymbol[] olds = (ISymbol[])symbols.values().toArray(new ISymbol[0]);
186
        symbols.clear();
187
        removeLegendListener(getZSort());
188
        setZSort(null);
189

    
190
        fireLegendClearEvent(new LegendClearEvent(olds));
191
    }
192

    
193
    public String[] getDescriptions() {
194
        String[] descriptions = new String[symbols.size()];
195
        ISymbol[] auxSym = getSymbols();
196

    
197
        for (int i = 0; i < descriptions.length; i++) {
198
                        descriptions[i] = auxSym[i].getDescription();
199
                }
200

    
201
        return descriptions;
202
    }
203

    
204
     public ISymbol[] getSymbols() {
205
        return (ISymbol[])symbols.values().toArray(new ISymbol[0]);
206
    }
207

    
208
    public void setClassifyingFieldNames(String[] fNames) {
209
             super.setClassifyingFieldNames(fNames);
210
//             try {
211
//                     fieldId = ((FeatureType)featureStore.getFeatureTypes().get(0)).getIndex(getClassifyingFieldNames()[0]);
212
//             } catch (NullPointerException e) {
213
//                     logger.warn("data source not set");
214
//             } catch (DataException e) {
215
//                     logger.warn("data source not set");
216
//                }
217
     }
218
    /*
219
     * @see com.iver.cit.gvsig.fmap.rendering.IVectorialLegend#getSymbol(int)
220
     */
221
//    public ISymbol getSymbol(int recordIndex) throws ReadException {
222
//                Object val = dataSource.getFieldValue(recordIndex, fieldId);
223
//                ISymbol theSymbol = getSymbolByValue(val);
224
//
225
//                return theSymbol;
226
//        }
227

    
228
    /**
229
         * Devuelve un s?mbolo a partir de una IFeature. OJO!! Cuando usamos un
230
         * feature iterator de base de datos el ?nico campo que vendr? rellenado es
231
         * el de fieldID. Los dem?s vendr?n a nulos para ahorra tiempo de creaci?n.
232
         *
233
         * @param feat
234
         *            IFeature
235
         *
236
         * @return S?mbolo.
237
         */
238
    public ISymbol getSymbolByFeature(Feature feat) {
239

    
240
            Object val = feat.get(getClassifyingFieldNames()[0]);
241
//        Object val = feat.get(fieldId);
242
        ISymbol theSymbol = getSymbolByValue(val);
243

    
244
        if (theSymbol != null) {
245
                return theSymbol;
246

    
247
        }
248

    
249
        if (isUseDefaultSymbol()) {
250
                        return defaultSymbol;
251
                }
252

    
253
        return null;
254
    }
255

    
256

    
257
    public ISymbol getDefaultSymbol() {
258

    
259
//          NullUniqueValue nuv=new NullUniqueValue();
260
//          if (symbols.containsKey(nuv))
261
//          return symbols.get(nuv);
262

    
263
            if(defaultSymbol==null) {
264
                    defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
265
                    fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, defaultSymbol));
266
            }
267
            return defaultSymbol;
268
    }
269

    
270
    public XMLEntity getXMLEntity() throws XMLException {
271
            XMLEntity xml = new XMLEntity();
272
        xml.putProperty("className", this.getClass().getName());
273
        xml.putProperty("fieldNames", getClassifyingFieldNames()[0]);
274

    
275
        if (getClassifyingFieldTypes()!=null)
276
                xml.putProperty("fieldTypes", getClassifyingFieldTypes()[0]);
277

    
278
        if (selectedColors != null) {
279
                        String[] strColors = new String[selectedColors.length];
280
                        for (int i = 0; i < strColors.length; i++) {
281
                                strColors[i] = StringUtilities.color2String(selectedColors[i]);
282
                        }
283
                        xml.putProperty("colorScheme", strColors);
284
                }
285

    
286
        xml.putProperty("labelfield", labelFieldName);
287
        xml.putProperty("labelFieldHeight", labelFieldHeight);
288
        xml.putProperty("labelFieldRotation", labelFieldRotation);
289

    
290
        xml.putProperty("useDefaultSymbol", useDefaultSymbol);
291
        xml.addChild(getDefaultSymbol().getXMLEntity());
292
        xml.putProperty("numKeys", keys.size());
293

    
294
        if (keys.size() > 0) {
295
            xml.putProperty("tipoValueKeys", valueType);
296

    
297
            String[] sk = new String[keys.size()];
298
            String[] sv = new String[keys.size()];
299
            int[] stk = new int[keys.size()];
300
            int[] stv = new int[keys.size()];
301
            ISymbol[] fsymbols = getSymbols();
302
            Object[] values = getValues();
303

    
304
            for (int i = 0; i < keys.size(); i++) {
305
                    sk[i] = keys.get(i).toString();
306
                    sv[i] = (values[i]).toString();
307
                    stk[i]=getSQLType(keys.get(i));
308
                    stv[i]=getSQLType(values[i]);
309
//                  stk[i]= keys.get(i).getSQLType();
310
//                  stv[i]= (values[i]).getSQLType();
311
                    xml.addChild(fsymbols[i].getXMLEntity());
312

    
313
                    ///System.out.println("get-----------"+sk[i]+"--"+fsymbols[i].getDescription()+"---"+fsymbols[i].getColor());
314
            }
315

    
316
            xml.putProperty("keys", sk);
317
            xml.putProperty("values", sv);
318
            xml.putProperty("typeKeys",stk);
319
            xml.putProperty("typeValues",stv);
320
        }
321

    
322
        if (getZSort()!=null) {
323
                XMLEntity xmlZSort = getZSort().getXMLEntity();
324
                xmlZSort.putProperty("id", "zSort");
325
                xml.addChild(xmlZSort);
326
        }
327
        return xml;
328
    }
329

    
330
    private int getSQLType(Object object) {
331
                if (object instanceof Integer){
332
                        return Types.INTEGER;
333
                }else if (object instanceof Long){
334
                        return Types.BIGINT;
335
                }else if (object instanceof Float){
336
                        return Types.FLOAT;
337
                }else if (object instanceof Double){
338
                        return Types.DOUBLE;
339
                }
340
            return Types.LONGVARCHAR;
341
        }
342

    
343
        public void setXMLEntity(XMLEntity xml) {
344
        clear();
345
        if (xml.contains("fieldName")) {
346
                        setClassifyingFieldNames(new String[] {xml.getStringProperty("fieldName")});
347
                } else {
348
                        setClassifyingFieldNames(xml.getStringArrayProperty("fieldNames"));
349
                }
350

    
351
        if (xml.contains("fieldTypes")) {
352
                        setClassifyingFieldTypes(xml.getIntArrayProperty("fieldTypes"));
353
                }
354
        if (xml.contains("colorScheme")) {
355
                        String[] strColors = xml.getStringArrayProperty("colorScheme");
356

    
357
                Color[] cc = new Color[strColors.length];
358
                        for (int i = 0; i < cc.length; i++) {
359
                                cc[i] = StringUtilities.string2Color(strColors[i]);
360
                        }
361
                        setColorScheme(cc);
362
                }
363
        useDefaultSymbol = xml.getBooleanProperty("useDefaultSymbol");
364
        setDefaultSymbol(SymbologyFactory.createSymbolFromXML(xml.getChild(0), null));
365

    
366
        int numKeys = xml.getIntProperty("numKeys");
367

    
368
        if (numKeys > 0) {
369
            String className = xml.getStringProperty("tipoValueKeys");
370
            String[] sk = xml.getStringArrayProperty("keys");
371
            String[] sv = xml.getStringArrayProperty("values");
372
            Object auxValue = null;
373
            Object auxValue2 = null;
374
            int[] stk=null;
375
            if (xml.contains("typeKeys")) {
376
                                stk = xml.getIntArrayProperty("typeKeys");
377
                                int[] stv = xml.getIntArrayProperty("typeValues");
378
                                for (int i = 0; i < numKeys; i++) {
379
                                        boolean isDefault = false;
380
                                        if (getValue(sk[i], stk[i]) == null) {
381
                                                isDefault = true;
382
                                        }
383

    
384
                                        if (className
385
                                                        .equals("com.hardcode.gdbms.engine.values.NullUniqueValue")
386
                                                        || isDefault) {
387
                                                auxValue = new NullUniqueValue();
388
                                                auxValue2 = new NullValue();
389
                                        } else {
390
                                                auxValue = getValue(sk[i], stk[i]); // ValueFactory.createValue(sk[i],
391
                                                                                                                        // className);
392
                                                auxValue2 = getValue(sv[i], stv[i]); // ValueFactory.createValue(sv[i],
393
                                                                                                                                // className);
394
                                        }
395

    
396
                                        // (substituir la de baix per esta) ISymbol sym = SymbolFactory.createFromXML(xml.getChild(i + 1), null);
397
                                        ISymbol sym = SymbologyFactory.createSymbolFromXML(xml.getChild(i + 1), null);
398
                                        symbols.put(auxValue2, sym);
399
                                        keys.add(auxValue);
400
                                }
401
                        } else {
402
                                for (int i = 0; i < numKeys; i++) {
403
                                        boolean isDefault = false;
404
                                        if (getValue(sk[i]) == null) {
405
                                                isDefault = true;
406
                                        }
407
                                        if (className
408
                                                        .equals("com.hardcode.gdbms.engine.values.NullUniqueValue")
409
                                                        || isDefault) {
410
                                                auxValue = new NullUniqueValue();
411
                                                auxValue2 = new NullValue();
412
                                        } else {
413
                                                auxValue = getValue(sk[i]); // ValueFactory.createValue(sk[i],
414
                                                                                                        // className);
415
                                                auxValue2 = getValue(sv[i]); // ValueFactory.createValue(sv[i],
416
                                                                                                                // className);
417
                                        }
418
                                        ISymbol sym = FSymbol.createFromXML(xml.getChild(i + 1));
419
                                        symbols.put(auxValue2, sym);
420
                                        keys.add(auxValue);
421
                                }
422
                        }
423
        }
424

    
425
        XMLEntity zSortXML = xml.firstChild("id", "zSort");
426
                if (zSortXML != null) {
427
                        ZSort zSort = new ZSort(this);
428
                        zSort.setXMLEntity(zSortXML);
429
                        addLegendListener(zSort);
430
                        setZSort(zSort);
431
                }
432
    }
433

    
434
        public void setDefaultSymbol(ISymbol s) {
435
            ISymbol mySymbol = defaultSymbol;
436

    
437
            if (s == null) {
438
                        throw new NullPointerException("Default symbol cannot be null");
439
                }
440

    
441
            ISymbol old = mySymbol;
442
            defaultSymbol = s;
443
            fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, s));
444
    }
445

    
446
    /**
447
     * Returns the value using the its value in a string.
448
         *
449
         *
450
         * @param s String with the value.
451
         * @deprecated Method used until 1.0 alpha 855 You should use getValue(String s,int type);
452
         * @return Value.
453
         */
454
    private Object getValue(String s) {
455
        Object val = new NullUniqueValue();
456
        if (s.equals("Resto de Valores")) {
457
                        return val;
458
                }
459
//        try {
460
            try {
461
                val = new Integer(s);//(s, Types.INTEGER);
462

    
463
                return val;
464
            } catch (NumberFormatException e) {
465
            }
466

    
467
            try {
468
                val = new Long(s);//ValueFactory.createValueByType(s, Types.BIGINT);
469

    
470
                return val;
471
            } catch (NumberFormatException e) {
472
            }
473

    
474
            try {
475
                val = new Float(s);//ValueFactory.createValueByType(s, Types.FLOAT);
476

    
477
                return val;
478
            } catch (NumberFormatException e) {
479
            }
480

    
481
            try {
482
                val = new Double(s);//ValueFactory.createValueByType(s, Types.DOUBLE);
483

    
484
                return val;
485
            } catch (NumberFormatException e) {
486
            }
487

    
488
            val = s;//ValueFactory.createValueByType(s, Types.LONGVARCHAR);
489

    
490
//        } catch (ParseException e) {
491
//           log.warn("parse exception", e);
492
//        }
493

    
494
        return val;
495
    }
496

    
497
    /**
498
     * Devuelve el valor a partir de su valor en un string.
499
     *
500
     * @param s String con el valor.
501
     *
502
     * @return Value.
503
     */
504
    private Object getValue(String s,int type) {
505
            Object val = new NullUniqueValue();
506
            if (type==Types.OTHER) {
507
                        return val;
508
                }
509
            switch (type) {
510
            case Types.INTEGER:
511
                    val = new Integer(s);
512
                    break;
513
            case Types.BIGINT:
514
                    val = new Long(s);
515
                    break;
516
            case Types.FLOAT:
517
                    val = new Float(s);
518
                    break;
519
            case Types.DOUBLE:
520
                    val = new Double(s);
521
                    break;
522
            default:
523
                    val=s;
524
            break;
525
            }
526
            return val;
527
    }
528

    
529
    public ILegend cloneLegend() throws XMLException {
530
        return LegendFactory.createFromXML(getXMLEntity());
531
    }
532

    
533

    
534
    /* (non-Javadoc)
535
     * @see com.iver.cit.gvsig.fmap.rendering.VectorialLegend#setDataSource(com.hardcode.gdbms.engine.data.DataSource)
536
     */
537
    public void setFeatureStore(FeatureStore fs) throws        DataException {
538
                featureStore = fs;
539
//                if (getClassifyingFieldNames()!=null) {
540
//                        fieldId = ((FeatureType)fs.getFeatureTypes().get(0)).getIndex(getClassifyingFieldNames()[0]);
541
//                }
542
        }
543

    
544
    /*
545
     * (non-Javadoc)
546
     *
547
     * @see com.iver.cit.gvsig.fmap.rendering.UniqueValueLegend#getSymbolByValue(com.hardcode.gdbms.engine.values.Value)
548
     */
549
    public ISymbol getSymbolByValue(Object key) {
550
            ISymbol symbol = (ISymbol)symbols.get(key);
551
            if (symbol!=null) {
552
                    return symbol;
553
            } else if (useDefaultSymbol) {
554
                    return getDefaultSymbol();
555
            }
556
            return null;
557

    
558
    }
559

    
560
    public int getShapeType() {
561
        return shapeType;
562
    }
563

    
564
    public void useDefaultSymbol(boolean b) {
565
        useDefaultSymbol = b;
566
    }
567

    
568
    /**
569
         * Devuelve si se utiliza o no el resto de valores para representarse.
570
         * @return  True si se utiliza el resto de valores.
571
         */
572
    public boolean isUseDefaultSymbol() {
573
        return useDefaultSymbol;
574
    }
575

    
576
    public void delSymbol(Object key) {
577
        keys.remove(key);
578

    
579
                ISymbol removedSymbol = (ISymbol) symbols.remove(key);
580
                if (removedSymbol != null){
581
                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(removedSymbol, null));
582
                }
583
    }
584

    
585
        public String getClassName() {
586
                return getClass().getName();
587
        }
588

    
589
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
590
                if (symbols.containsValue(oldSymbol)) {
591
                        Iterator it = symbols.keySet().iterator();
592
                        while (it.hasNext()) {
593
                                Object key = it.next();
594
                                if (symbols.get(key).equals(oldSymbol)) {
595
                                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(
596
                                                        (ISymbol)symbols.put(key, newSymbol), newSymbol));
597
                                }
598

    
599
                        }
600
                }
601
        }
602
        public Color[] getColorScheme() {
603
                return selectedColors;
604
        }
605

    
606
        public void setColorScheme(Color[] cc) {
607
                 this.selectedColors = cc;
608
        }
609
}