Statistics
| Revision:

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

History | View | Annotate | Download (17.7 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.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
import org.gvsig.data.ReadException;
52
import org.gvsig.data.vectorial.Feature;
53
import org.gvsig.data.vectorial.FeatureStore;
54
import org.gvsig.data.vectorial.FeatureType;
55
import org.gvsig.fmap.mapcontext.layers.XMLException;
56
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
57
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
58
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
59
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
60
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbologyFactory;
61

    
62
import com.iver.utiles.XMLEntity;
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<Object, ISymbol> 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 = (Object) o2;
80
                                Object v1 = (Object) 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 == null) {
89
                                        return -1;
90
                                }
91

    
92
                                if (v2 == null) {
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
        /**
116
     * Constructor method
117
     */
118
    public VectorialUniqueValueLegend() {
119
    }
120

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

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

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

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

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

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

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

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

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

    
179
    }
180

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

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

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

    
195
        for (int i = 0; i < descriptions.length; i++)
196
            descriptions[i] = auxSym[i].getDescription();
197

    
198
        return descriptions;
199
    }
200

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

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

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

    
237
        if (theSymbol != null) {
238
                return theSymbol;
239

    
240
        }
241

    
242
               return getDefaultSymbol();
243
    }
244

    
245
    public ISymbol getDefaultSymbol() {
246

    
247
            NullUniqueValue nuv=new NullUniqueValue();
248
            if (symbols.containsKey(nuv))
249
                    return symbols.get(nuv);
250

    
251
            if(defaultSymbol==null) {
252
                    defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
253
                    fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, defaultSymbol));
254
            }
255
        return defaultSymbol;
256
    }
257

    
258

    
259
    public XMLEntity getXMLEntity() {
260
        XMLEntity xml = new XMLEntity();
261
        xml.putProperty("className", this.getClass().getName());
262
        xml.putProperty("fieldNames", getClassifyingFieldNames()[0]);
263

    
264
        ///////////////////////////////////////PEPE
265
        xml.putProperty("fieldTypes", getClassifyingFieldTypes()[0]);
266
        ///////////////////////////////////////PEPE
267

    
268
        xml.putProperty("labelfield", labelFieldName);
269
        xml.putProperty("labelFieldHeight", labelFieldHeight);
270
        xml.putProperty("labelFieldRotation", labelFieldRotation);
271

    
272
        xml.putProperty("useDefaultSymbol", useDefaultSymbol);
273
        xml.addChild(getDefaultSymbol().getXMLEntity());
274
        xml.putProperty("numKeys", keys.size());
275

    
276
        if (keys.size() > 0) {
277
            xml.putProperty("tipoValueKeys", valueType);
278

    
279
            String[] sk = new String[keys.size()];
280
            String[] sv = new String[keys.size()];
281
            int[] stk = new int[keys.size()];
282
            int[] stv = new int[keys.size()];
283
            ISymbol[] fsymbols = getSymbols();
284
            Object[] values = getValues();
285

    
286
            for (int i = 0; i < keys.size(); i++) {
287
                    if (keys.get(i).toString().equals("")) {
288
                            sk[i] =" ";
289
                    }else {
290
                            sk[i] = keys.get(i).toString();
291
                    }
292
                    if ((values[i]).toString().equals("")) {
293
                            sv[i] =" ";
294
                    }else {
295
                            sv[i] = (values[i]).toString();
296
                    }
297
                    stk[i]=getSQLType(keys.get(i));
298
                    stv[i]=getSQLType(values[i]);
299
//                    stk[i]= keys.get(i).getSQLType();
300
//                    stv[i]= (values[i]).getSQLType();
301
                xml.addChild(fsymbols[i].getXMLEntity());
302

    
303
                ///System.out.println("get-----------"+sk[i]+"--"+fsymbols[i].getDescription()+"---"+fsymbols[i].getColor());
304
            }
305

    
306
            xml.putProperty("keys", sk);
307
            xml.putProperty("values", sv);
308
            xml.putProperty("typeKeys",stk);
309
            xml.putProperty("typeValues",stv);
310
        }
311

    
312
        if (getZSort()!=null) {
313
                XMLEntity xmlZSort = getZSort().getXMLEntity();
314
                xmlZSort.putProperty("id", "zSort");
315
                xml.addChild(xmlZSort);
316
        }
317
        return xml;
318
    }
319

    
320
    private int getSQLType(Object object) {
321
                if (object instanceof Integer){
322
                        return Types.INTEGER;
323
                }else if (object instanceof Long){
324
                        return Types.BIGINT;
325
                }else if (object instanceof Float){
326
                        return Types.FLOAT;
327
                }else if (object instanceof Double){
328
                        return Types.DOUBLE;
329
                }
330
            return Types.LONGVARCHAR;
331
        }
332

    
333
        public void setXMLEntity(XMLEntity xml) {
334
        clear();
335
        if (xml.contains("fieldName"))
336
                setClassifyingFieldNames(new String[] {xml.getStringProperty("fieldName")});
337
        else
338
                setClassifyingFieldNames(xml.getStringArrayProperty("fieldNames"));
339

    
340
        //TODO Falta ver de recuperar los tipos que ahroa son String
341
//        if (xml.contains("fieldTypes"))
342
//                setClassifyingFieldTypes(new int[] {xml.getIntProperty("fieldTypes")});
343

    
344
        useDefaultSymbol = xml.getBooleanProperty("useDefaultSymbol");
345
        setDefaultSymbol(SymbologyFactory.createSymbolFromXML(xml.getChild(0), null));
346

    
347
        int numKeys = xml.getIntProperty("numKeys");
348

    
349
        if (numKeys > 0) {
350
            String className = xml.getStringProperty("tipoValueKeys");
351
            String[] sk = xml.getStringArrayProperty("keys");
352
            String[] sv = xml.getStringArrayProperty("values");
353
            Object auxValue = null;
354
            Object auxValue2 = null;
355
            int[] stk=null;
356
            if (xml.contains("typeKeys")) {
357
                                stk = xml.getIntArrayProperty("typeKeys");
358
                                int[] stv = xml.getIntArrayProperty("typeValues");
359
                                for (int i = 0; i < numKeys; i++) {
360
                                        boolean isDefault = false;
361
                                        if (getValue(sk[i], stk[i]) == null) {
362
                                                isDefault = true;
363
                                        }
364

    
365
                                        if (className
366
                                                        .equals("com.hardcode.gdbms.engine.values.NullUniqueValue")
367
                                                        || isDefault) {
368
                                                auxValue = new NullUniqueValue();
369
                                                auxValue2 = new NullValue();
370
                                        } else {
371
                                                auxValue = getValue(sk[i], stk[i]); // ValueFactory.createValue(sk[i],
372
                                                                                                                        // className);
373
                                                auxValue2 = getValue(sv[i], stv[i]); // ValueFactory.createValue(sv[i],
374
                                                                                                                                // className);
375
                                        }
376

    
377
                                        // (substituir la de baix per esta) ISymbol sym = SymbolFactory.createFromXML(xml.getChild(i + 1), null);
378
                                        ISymbol sym = SymbologyFactory.createSymbolFromXML(xml.getChild(i + 1), null);
379
                                        symbols.put(auxValue2, sym);
380
                                        keys.add(auxValue);
381
                                }
382
                        } else {
383
                                for (int i = 0; i < numKeys; i++) {
384
                                        boolean isDefault = false;
385
                                        if (getValue(sk[i]) == null) {
386
                                                isDefault = true;
387
                                        }
388
                                        if (className
389
                                                        .equals("com.hardcode.gdbms.engine.values.NullUniqueValue")
390
                                                        || isDefault) {
391
                                                auxValue = new NullUniqueValue();
392
                                                auxValue2 = new NullValue();
393
                                        } else {
394
                                                auxValue = getValue(sk[i]); // ValueFactory.createValue(sk[i],
395
                                                                                                        // className);
396
                                                auxValue2 = getValue(sv[i]); // ValueFactory.createValue(sv[i],
397
                                                                                                                // className);
398
                                        }
399
                                        ISymbol sym = FSymbol.createFromXML(xml.getChild(i + 1));
400
                                        symbols.put(auxValue2, sym);
401
                                        keys.add(auxValue);
402
                                }
403
                        }
404
        }
405

    
406
        XMLEntity zSortXML = xml.firstChild("id", "zSort");
407
                if (zSortXML != null) {
408
                        ZSort zSort = new ZSort(this);
409
                        zSort.setXMLEntity(zSortXML);
410
                        addLegendListener(zSort);
411
                        setZSort(zSort);
412
                }
413
    }
414

    
415
    public void setDefaultSymbol(ISymbol s) {
416
            if (s == null) throw new NullPointerException("Default symbol cannot be null");
417
            ISymbol old = defaultSymbol;
418
        defaultSymbol = s;
419
                fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
420

    
421

    
422
    }
423
    /**
424
     * Returns the value using the its value in a string.
425
         *
426
         *
427
         * @param s String with the value.
428
         * @deprecated Method used until 1.0 alpha 855 You should use getValue(String s,int type);
429
         * @return Value.
430
         */
431
    private Object getValue(String s) {
432
        Object val = new NullUniqueValue();
433
        if (s.equals("Resto de Valores"))return val;
434
//        try {
435
            try {
436
                val = new Integer(s);//(s, Types.INTEGER);
437

    
438
                return val;
439
            } catch (NumberFormatException e) {
440
            }
441

    
442
            try {
443
                val = new Long(s);//ValueFactory.createValueByType(s, Types.BIGINT);
444

    
445
                return val;
446
            } catch (NumberFormatException e) {
447
            }
448

    
449
            try {
450
                val = new Float(s);//ValueFactory.createValueByType(s, Types.FLOAT);
451

    
452
                return val;
453
            } catch (NumberFormatException e) {
454
            }
455

    
456
            try {
457
                val = new Double(s);//ValueFactory.createValueByType(s, Types.DOUBLE);
458

    
459
                return val;
460
            } catch (NumberFormatException e) {
461
            }
462

    
463
            val = s;//ValueFactory.createValueByType(s, Types.LONGVARCHAR);
464

    
465
//        } catch (ParseException e) {
466
//           log.warn("parse exception", e);
467
//        }
468

    
469
        return val;
470
    }
471

    
472
    /**
473
     * Devuelve el valor a partir de su valor en un string.
474
     *
475
     * @param s String con el valor.
476
     *
477
     * @return Value.
478
     */
479
    private Object getValue(String s,int type) {
480
            Object val = new NullUniqueValue();
481
            if (type==Types.OTHER)
482
                    return val;
483
            switch (type) {
484
            case Types.INTEGER:
485
                    val = new Integer(s);
486
                    break;
487
            case Types.BIGINT:
488
                    val = new Long(s);
489
                    break;
490
            case Types.FLOAT:
491
                    val = new Float(s);
492
                    break;
493
            case Types.DOUBLE:
494
                    val = new Double(s);
495
                    break;
496
            default:
497
                    val=s;
498
            break;
499
            }
500
            return val;
501
    }
502

    
503
    public ILegend cloneLegend() throws XMLException {
504
        return LegendFactory.createFromXML(getXMLEntity());
505
    }
506

    
507

    
508
    /* (non-Javadoc)
509
     * @see com.iver.cit.gvsig.fmap.rendering.VectorialLegend#setDataSource(com.hardcode.gdbms.engine.data.DataSource)
510
     */
511
    public void setFeatureStore(FeatureStore fs) throws        ReadException {
512
                featureStore = fs;
513
                fieldId = ((FeatureType)fs.getFeatureTypes().get(0)).getFieldIndex(getClassifyingFieldNames()[0]);
514
        }
515

    
516
    /*
517
     * (non-Javadoc)
518
     *
519
     * @see com.iver.cit.gvsig.fmap.rendering.UniqueValueLegend#getSymbolByValue(com.hardcode.gdbms.engine.values.Value)
520
     */
521
    public ISymbol getSymbolByValue(Object key) {
522
            ISymbol symbol = symbols.get(key);
523
            if (symbol!=null) {
524
                    return symbol;
525
            } else if (useDefaultSymbol) {
526
                    return getDefaultSymbol();
527
            }
528
            return null;
529

    
530
    }
531

    
532
    public int getShapeType() {
533
        return shapeType;
534
    }
535

    
536
    public void useDefaultSymbol(boolean b) {
537
        useDefaultSymbol = b;
538
    }
539

    
540
    /**
541
         * Devuelve si se utiliza o no el resto de valores para representarse.
542
         * @return  True si se utiliza el resto de valores.
543
         */
544
    public boolean isUseDefaultSymbol() {
545
        return useDefaultSymbol;
546
    }
547

    
548
    public void delSymbol(Object key) {
549
        keys.remove(key);
550

    
551
        fireClassifiedSymbolChangeEvent(
552
                        new SymbolLegendEvent(
553
                                        symbols.remove(key),
554
                                        null));
555
    }
556

    
557
        public String getClassName() {
558
                return getClass().getName();
559
        }
560

    
561
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
562
                if (symbols.containsValue(oldSymbol)) {
563
                        Iterator it = symbols.keySet().iterator();
564
                        while (it.hasNext()) {
565
                                Object key = it.next();
566
                                if (symbols.get(key).equals(oldSymbol)) {
567
                                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(
568
                                                        symbols.put(key, newSymbol), newSymbol));
569
                                }
570

    
571
                        }
572
                }
573
        }
574
}