Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / rendering / legend / VectorialUniqueValueLegend.java @ 23303

History | View | Annotate | Download (18.4 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.apache.log4j.Logger;
51
import org.gvsig.fmap.data.ReadException;
52
import org.gvsig.fmap.data.feature.Feature;
53
import org.gvsig.fmap.data.feature.FeatureStore;
54
import org.gvsig.fmap.data.feature.FeatureType;
55
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
56
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
57
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
58
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbologyFactory;
59

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
180
    }
181

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

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

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

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

    
200
        return descriptions;
201
    }
202

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

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

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

    
239
        if (theSymbol != null) {
240
                return theSymbol;
241

    
242
        }
243

    
244
        if (isUseDefaultSymbol()) {
245
                        return defaultSymbol;
246
                }
247

    
248
        return null;
249
    }
250

    
251

    
252
    public ISymbol getDefaultSymbol() {
253

    
254
//          NullUniqueValue nuv=new NullUniqueValue();
255
//          if (symbols.containsKey(nuv))
256
//          return symbols.get(nuv);
257

    
258
            if(defaultSymbol==null) {
259
                    defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
260
                    fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, defaultSymbol));
261
            }
262
            return defaultSymbol;
263
    }
264

    
265
    public XMLEntity getXMLEntity() throws XMLException {
266
            XMLEntity xml = new XMLEntity();
267
        xml.putProperty("className", this.getClass().getName());
268
        xml.putProperty("fieldNames", getClassifyingFieldNames()[0]);
269

    
270

    
271
        xml.putProperty("fieldTypes", getClassifyingFieldTypes()[0]);
272

    
273
        if (selectedColors != null) {
274
                        String[] strColors = new String[selectedColors.length];
275
                        for (int i = 0; i < strColors.length; i++) {
276
                                strColors[i] = StringUtilities.color2String(selectedColors[i]);
277
                        }
278
                        xml.putProperty("colorScheme", strColors);
279
                }
280

    
281
        xml.putProperty("labelfield", labelFieldName);
282
        xml.putProperty("labelFieldHeight", labelFieldHeight);
283
        xml.putProperty("labelFieldRotation", labelFieldRotation);
284

    
285
        xml.putProperty("useDefaultSymbol", useDefaultSymbol);
286
        xml.addChild(getDefaultSymbol().getXMLEntity());
287
        xml.putProperty("numKeys", keys.size());
288

    
289
        if (keys.size() > 0) {
290
            xml.putProperty("tipoValueKeys", valueType);
291

    
292
            String[] sk = new String[keys.size()];
293
            String[] sv = new String[keys.size()];
294
            int[] stk = new int[keys.size()];
295
            int[] stv = new int[keys.size()];
296
            ISymbol[] fsymbols = getSymbols();
297
            Object[] values = getValues();
298

    
299
            for (int i = 0; i < keys.size(); i++) {
300
                    if (keys.get(i).toString().equals("")) {
301
                            sk[i] =" ";
302
                    }else {
303
                            sk[i] = keys.get(i).toString();
304
                    }
305
                    if ((values[i]).toString().equals("")) {
306
                            sv[i] =" ";
307
                    }else {
308
                            sv[i] = (values[i]).toString();
309
                    }
310
                    stk[i]=getSQLType(keys.get(i));
311
                    stv[i]=getSQLType(values[i]);
312
//                    stk[i]= keys.get(i).getSQLType();
313
//                    stv[i]= (values[i]).getSQLType();
314
                xml.addChild(fsymbols[i].getXMLEntity());
315

    
316
                ///System.out.println("get-----------"+sk[i]+"--"+fsymbols[i].getDescription()+"---"+fsymbols[i].getColor());
317
            }
318

    
319
            xml.putProperty("keys", sk);
320
            xml.putProperty("values", sv);
321
            xml.putProperty("typeKeys",stk);
322
            xml.putProperty("typeValues",stv);
323
        }
324

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

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

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

    
354
        if (xml.contains("fieldTypes")) {
355
                        setClassifyingFieldTypes(xml.getStringArrayProperty("fieldTypes"));
356
                }
357
        if (xml.contains("colorScheme")) {
358
                        String[] strColors = xml.getStringArrayProperty("colorScheme");
359

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

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

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

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

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

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

    
437
        public void setDefaultSymbol(ISymbol s) {
438
            ISymbol mySymbol = defaultSymbol;
439

    
440
            if (s == null) {
441
                        throw new NullPointerException("Default symbol cannot be null");
442
                }
443

    
444
            ISymbol old = mySymbol;
445
            defaultSymbol = s;
446
            fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, s));
447
    }
448

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

    
466
                return val;
467
            } catch (NumberFormatException e) {
468
            }
469

    
470
            try {
471
                val = new Long(s);//ValueFactory.createValueByType(s, Types.BIGINT);
472

    
473
                return val;
474
            } catch (NumberFormatException e) {
475
            }
476

    
477
            try {
478
                val = new Float(s);//ValueFactory.createValueByType(s, Types.FLOAT);
479

    
480
                return val;
481
            } catch (NumberFormatException e) {
482
            }
483

    
484
            try {
485
                val = new Double(s);//ValueFactory.createValueByType(s, Types.DOUBLE);
486

    
487
                return val;
488
            } catch (NumberFormatException e) {
489
            }
490

    
491
            val = s;//ValueFactory.createValueByType(s, Types.LONGVARCHAR);
492

    
493
//        } catch (ParseException e) {
494
//           log.warn("parse exception", e);
495
//        }
496

    
497
        return val;
498
    }
499

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

    
532
    public ILegend cloneLegend() throws XMLException {
533
        return LegendFactory.createFromXML(getXMLEntity());
534
    }
535

    
536

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

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

    
561
    }
562

    
563
    public int getShapeType() {
564
        return shapeType;
565
    }
566

    
567
    public void useDefaultSymbol(boolean b) {
568
        useDefaultSymbol = b;
569
    }
570

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

    
579
    public void delSymbol(Object key) {
580
        keys.remove(key);
581

    
582
        fireClassifiedSymbolChangeEvent(
583
                        new SymbolLegendEvent(
584
                                        (ISymbol)symbols.remove(key),
585
                                        null));
586
    }
587

    
588
        public String getClassName() {
589
                return getClass().getName();
590
        }
591

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

    
602
                        }
603
                }
604
        }
605
        public Color[] getColorScheme() {
606
                return selectedColors;
607
        }
608

    
609
        public void setColorScheme(Color[] cc) {
610
                 this.selectedColors = cc;
611
        }
612
}