Statistics
| Revision:

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

History | View | Annotate | Download (18.6 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
                        if(sk.length == 0){
372
                                sk = new String[]{""};
373
                        }
374
            String[] sv = xml.getStringArrayProperty("values");
375
                        if(sv.length == 0){
376
                                sv = new String[]{""};
377
                        }
378
            Object auxValue = null;
379
            Object auxValue2 = null;
380
            int[] stk=null;
381
            if (xml.contains("typeKeys")) {
382
                                stk = xml.getIntArrayProperty("typeKeys");
383
                                int[] stv = xml.getIntArrayProperty("typeValues");
384
                                for (int i = 0; i < numKeys; i++) {
385
                                        boolean isDefault = false;
386
                                        if (getValue(sk[i], stk[i]) == null) {
387
                                                isDefault = true;
388
                                        }
389

    
390
                                        if (className
391
                                                        .equals("com.hardcode.gdbms.engine.values.NullUniqueValue")
392
                                                        || isDefault) {
393
                                                auxValue = new NullUniqueValue();
394
                                                auxValue2 = new NullValue();
395
                                        } else {
396
                                                auxValue = getValue(sk[i], stk[i]); // ValueFactory.createValue(sk[i],
397
                                                                                                                        // className);
398
                                                auxValue2 = getValue(sv[i], stv[i]); // ValueFactory.createValue(sv[i],
399
                                                                                                                                // className);
400
                                        }
401

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

    
431
        XMLEntity zSortXML = xml.firstChild("id", "zSort");
432
                if (zSortXML != null) {
433
                        ZSort zSort = new ZSort(this);
434
                        zSort.setXMLEntity(zSortXML);
435
                        addLegendListener(zSort);
436
                        setZSort(zSort);
437
                }
438
    }
439

    
440
        public void setDefaultSymbol(ISymbol s) {
441
            ISymbol mySymbol = defaultSymbol;
442

    
443
            if (s == null) {
444
                        throw new NullPointerException("Default symbol cannot be null");
445
                }
446

    
447
            ISymbol old = mySymbol;
448
            defaultSymbol = s;
449
            fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, s));
450
    }
451

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

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

    
473
            try {
474
                val = new Long(s);//ValueFactory.createValueByType(s, Types.BIGINT);
475

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

    
480
            try {
481
                val = new Float(s);//ValueFactory.createValueByType(s, Types.FLOAT);
482

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

    
487
            try {
488
                val = new Double(s);//ValueFactory.createValueByType(s, Types.DOUBLE);
489

    
490
                return val;
491
            } catch (NumberFormatException e) {
492
            }
493

    
494
            val = s;//ValueFactory.createValueByType(s, Types.LONGVARCHAR);
495

    
496
//        } catch (ParseException e) {
497
//           log.warn("parse exception", e);
498
//        }
499

    
500
        return val;
501
    }
502

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

    
535
    public ILegend cloneLegend() throws XMLException {
536
        return LegendFactory.createFromXML(getXMLEntity());
537
    }
538

    
539

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

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

    
564
    }
565

    
566
    public int getShapeType() {
567
        return shapeType;
568
    }
569

    
570
    public void useDefaultSymbol(boolean b) {
571
        useDefaultSymbol = b;
572
    }
573

    
574
    /**
575
         * Devuelve si se utiliza o no el resto de valores para representarse.
576
         * @return  True si se utiliza el resto de valores.
577
         */
578
    public boolean isUseDefaultSymbol() {
579
        return useDefaultSymbol;
580
    }
581

    
582
    public void delSymbol(Object key) {
583
        keys.remove(key);
584

    
585
                ISymbol removedSymbol = (ISymbol) symbols.remove(key);
586
                if (removedSymbol != null){
587
                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(removedSymbol, null));
588
                }
589
    }
590

    
591
        public String getClassName() {
592
                return getClass().getName();
593
        }
594

    
595
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
596
                if (symbols.containsValue(oldSymbol)) {
597
                        Iterator it = symbols.keySet().iterator();
598
                        while (it.hasNext()) {
599
                                Object key = it.next();
600
                                if (symbols.get(key).equals(oldSymbol)) {
601
                                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(
602
                                                        (ISymbol)symbols.put(key, newSymbol), newSymbol));
603
                                }
604

    
605
                        }
606
                }
607
        }
608
        public Color[] getColorScheme() {
609
                return selectedColors;
610
        }
611

    
612
        public void setColorScheme(Color[] cc) {
613
                 this.selectedColors = cc;
614
        }
615
}