Statistics
| Revision:

root / tags / v2_0_0_Build_2058 / libraries / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / legend / impl / AbstractIntervalLegend.java @ 39268

History | View | Annotate | Download (20.2 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22
package org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl;
23

    
24
import java.util.ArrayList;
25
import java.util.Comparator;
26
import java.util.Date;
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.Map;
30
import java.util.Map.Entry;
31
import java.util.TreeMap;
32

    
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureQuery;
36
import org.gvsig.fmap.dal.feature.FeatureReference;
37
import org.gvsig.fmap.dal.feature.FeatureSet;
38
import org.gvsig.fmap.dal.feature.FeatureStore;
39
import org.gvsig.fmap.mapcontext.MapContextException;
40
import org.gvsig.fmap.mapcontext.MapContextLocator;
41
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
42
import org.gvsig.fmap.mapcontext.rendering.legend.IInterval;
43
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialIntervalLegend;
44
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
45
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
46
import org.gvsig.tools.ToolsLocator;
47
import org.gvsig.tools.dispose.DisposableIterator;
48
import org.gvsig.tools.dynobject.DynStruct;
49
import org.gvsig.tools.persistence.PersistenceManager;
50
import org.gvsig.tools.persistence.PersistentState;
51
import org.gvsig.tools.persistence.exception.PersistenceException;
52
import org.gvsig.tools.util.Callable;
53
import org.slf4j.Logger;
54
import org.slf4j.LoggerFactory;
55

    
56
/**
57
 * @author 2005-2008 jaume dominguez faus - jaume.dominguez@iver.es
58
 * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
59
 */
60
public abstract class AbstractIntervalLegend extends
61
                AbstractClassifiedVectorLegend implements IVectorialIntervalLegend {
62

    
63
        public static final String INTERVAL_LEGEND_PERSISTENCE_DEFINITION_NAME = "IntervalLegend";
64

    
65
        private static final String FIELD_KEYS = "keys";
66
        private static final String FIELD_INTERVAL_TYPE = "intervalType";
67
        private static final String FIELD_USE_DEFAULT_SYMBOL = "useDefaultSymbol";
68
        private static final String FIELD_NULL_INTERVAL_SYMBOL =
69
                        "nullIntervalSymbol";
70
        private static final String FIELD_SYMBOLS = "symbols";
71
        
72
        protected List<Object> keys = new ArrayList<Object>(); // <Object>
73
        // protected int index = 0;
74
        // protected int fieldId;
75
        protected ISymbol defaultSymbol;
76
        // protected FeatureStore featureStore;
77
        protected int intervalType = NATURAL_INTERVALS;
78
        protected boolean useDefaultSymbol = false;
79

    
80
        private ISymbol nullIntervalSymbol = null;
81

    
82
        public static final int EQUAL_INTERVALS = 0;
83
        public static final int NATURAL_INTERVALS = 1;
84
        public static final int QUANTILE_INTERVALS = 2;
85
        protected Map<Object, ISymbol> symbols = createSymbolMap();
86
        final static private Logger logger = LoggerFactory.getLogger(AbstractIntervalLegend.class);
87
        
88
        public void addSymbol(Object key, ISymbol symbol) {
89
                if (key == null) {
90
                        nullIntervalSymbol = symbol;
91
                }
92
                else {
93
                        symbols.put(key, symbol);
94
                        keys.add(key);
95
                }
96
                fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(null, symbol));
97
        }
98

    
99
        /*
100
         * @see com.iver.cit.gvsig.fmap.rendering.IVectorialLegend#getSymbol(int)
101
         */
102
        public ISymbol getSymbol(FeatureReference featureID)
103
                        throws MapContextException, DataException {
104
                return getSymbolByFeature(featureID.getFeature());
105
                
106
//                Object val = featureStore.getFeatureByReference(featureID).get(getClassifyingFieldNames()[0]);
107
//                IInterval interval = getInterval(val);
108
//                ISymbol theSymbol = getSymbolByInterval(interval);
109
//
110
//                if (theSymbol != null) {
111
//                        return theSymbol;
112
//                } else if (useDefaultSymbol) {
113
//                        return getDefaultSymbol();
114
//                }
115
//                return null;
116

    
117
        }
118

    
119
        public ISymbol getSymbolByFeature(Feature feat) throws MapContextException {
120
                Object val = feat.get(getClassifyingFieldNames()[0]);
121
                IInterval interval = getInterval(val);
122
                ISymbol theSymbol = getSymbolByInterval(interval);
123

    
124
                if (theSymbol != null) {
125
                        return theSymbol;
126
                } else if (useDefaultSymbol) {
127
                        return getDefaultSymbol();
128
                }
129
                
130
                return null;
131
//                return theSymbol;
132
        }
133

    
134

    
135
        public IInterval[] calculateIntervals(FeatureStore featureStore,
136
                        String fieldName, int numIntervalos, int shapeType)
137
        throws DataException {
138
                logger.debug("elRs.start()");
139
//                recordSet.start();
140

    
141
//                int idField = -1;
142
                FeatureSet set = null;
143
                DisposableIterator iterator = null;
144
                try {
145

    
146
                setClassifyingFieldNames(new String[] {fieldName});
147

    
148
                String[] fieldNames = getClassifyingFieldNames();
149
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
150
                featureQuery.setAttributeNames(fieldNames);
151

    
152
                set = featureStore.getFeatureSet(featureQuery);
153
                iterator = set.fastIterator();
154

    
155

    
156
//                for (int i = 0; i < recordSet.getFieldCount(); i++) {
157
//                        String nomAux = recordSet.getFieldName(i).trim();
158
//
159
//                        if (fieldNames[0].compareToIgnoreCase(nomAux) == 0) {
160
//                                idField = i;
161
//
162
//                                break;
163
//                        }
164
//                }
165

    
166
//                if (idField == -1) {
167
//                        logger.error("Campo no reconocido " + fieldNames);
168
//
169
//                        return null;
170
//                }
171

    
172
                double minValue = Double.MAX_VALUE;
173
                double maxValue = Double.NEGATIVE_INFINITY;
174

    
175
                IVectorialIntervalLegend auxLegend = (IVectorialIntervalLegend) MapContextLocator
176
                                        .getMapContextManager().createLegend("VectorialInterval");
177
                auxLegend.setShapeType(shapeType);
178

    
179
                Object clave;
180

    
181
                while (iterator.hasNext()) {
182
                        Feature feature = (Feature) iterator.next();
183

    
184
//                for (int j = 0; j < recordSet.getRowCount(); j++) {
185
                        clave = feature.get(fieldName);
186

    
187
                        IInterval interval = auxLegend.getInterval(clave);
188

    
189
                        ////Comprobar que no esta repetido y no hace falta introducir en el hashtable el campo junto con el simbolo.
190
                        if (auxLegend.getSymbolByInterval(interval) == null) {
191
                                //si no esta creado el simbolo se crea
192
                                double valor = 0;
193

    
194

    
195
                                if (clave instanceof Number) {
196
                                        valor=((Number)clave).doubleValue();
197
                                }else if (clave instanceof Date) {
198
                                        //TODO POR IMPLEMENTAR
199
                                        ///valorDate = elRs.getFieldValueAsDate(idField);
200
                                        ///if (valorDate.before(minValueDate)) minValueDate = valorDate;
201
                                        ///if (valorDate.after(maxValueDate)) maxValueDate = valorDate;
202
//                                } else if (clave instanceof NullValue) {
203
//                                        continue;
204
                                }
205

    
206
                                if (valor < minValue) {
207
                                        minValue = valor;
208
                                }
209

    
210
                                if (valor > maxValue) {
211
                                        maxValue = valor;
212
                                }
213
                        }
214
                }
215

    
216
                        IInterval[] intervalArray = null;
217
                switch (getIntervalType()) {
218
                case VectorialIntervalLegend.EQUAL_INTERVALS:
219
                        intervalArray = calculateEqualIntervals(numIntervalos,
220
                                        minValue, maxValue, fieldName);
221

    
222
                        break;
223

    
224
                case VectorialIntervalLegend.NATURAL_INTERVALS:
225
                        intervalArray = calculateNaturalIntervals(featureStore, numIntervalos,
226
                                        minValue, maxValue, fieldName);
227

    
228
                        break;
229

    
230
                case VectorialIntervalLegend.QUANTILE_INTERVALS:
231
                        intervalArray = calculateQuantileIntervals(featureStore, numIntervalos,
232
                                        minValue, maxValue, fieldName);
233

    
234
                        break;
235
                }
236
//                recordSet.stop();
237
                return intervalArray;
238
                } finally {
239
                        if (iterator != null) {
240
                                iterator.dispose();
241
                        }
242
                        if (set != null) {
243
                                set.dispose();
244
                        }
245
                }
246
        }
247

    
248

    
249
    /**
250
     * EQUAL INTERVAL Devuelve un Array con el n?mero de intervalos que se
251
     * quieren crear. Los intervalos se crean con un tama?o igual entre ellos.
252
     * @param numIntervals n?mero de intervalos
253
     * @param minValue Valor m?nimo.
254
     * @param maxValue Valor m?ximo.
255
     * @param fieldName Nombre del campo
256
     *
257
     * @return Array con los intervalos.
258
     */
259
        private IInterval[] calculateEqualIntervals(int numIntervals,
260
                        double minValue,
261
        double maxValue, String fieldName) {
262
                IInterval[] theIntervalArray = new IInterval[numIntervals];
263
        double step = (maxValue - minValue) / numIntervals;
264

    
265
        if (numIntervals > 1) {
266
            theIntervalArray[0] = new FInterval(minValue, minValue + step);
267

    
268
            for (int i = 1; i < (numIntervals - 1); i++) {
269
                theIntervalArray[i] = new FInterval(minValue + (i * step) +
270
                        0.01, minValue + ((i + 1) * step));
271
            }
272

    
273
            theIntervalArray[numIntervals - 1] = new FInterval(minValue +
274
                    ((numIntervals - 1) * step) + 0.01, maxValue);
275
        } else {
276
            theIntervalArray[0] = new FInterval(minValue, maxValue);
277
        }
278

    
279
        return theIntervalArray;
280
    }
281

    
282
    /**
283
     * NATURAL INTERVAL Devuelve un Array con el n?mero de intervalos que se
284
     * quieren crear. Los intervalos se distribuyen de forma natural.
285
     *
286
     * @param numIntervals n?mero de intervalos
287
     * @param minValue Valor m?nimo.
288
     * @param maxValue Valor m?ximo.
289
     * @param fieldName Nombre del campo
290
     *
291
     * @return Array con los intervalos.
292
     * @throws DataException 
293
     * @throws LegendLayerException
294
     */
295
        private IInterval[] calculateNaturalIntervals(FeatureStore featureStore,
296
                        int numIntervals, double minValue,
297
        double maxValue, String fieldName) throws DataException {
298
        NaturalIntervalGenerator intervalGenerator = new NaturalIntervalGenerator(
299
                        featureStore, fieldName, numIntervals);
300

    
301
        intervalGenerator.generarIntervalos();
302

    
303
        int numIntervalsGen = intervalGenerator.getNumIntervals() - 1;
304

    
305
        if (numIntervalsGen == -1) {
306
            //TODO cuando no puede calcular los intervalos.
307
            numIntervalsGen = 1;
308
        }
309

    
310
        FInterval[] theIntervalArray = new FInterval[numIntervalsGen];
311

    
312
        if (numIntervalsGen > 1) {
313
            theIntervalArray[0] = new FInterval(minValue,
314
                    intervalGenerator.getValorRuptura(0));
315

    
316
            for (int i = 1; i < (numIntervalsGen - 1); i++) {
317
                theIntervalArray[i] = new FInterval(intervalGenerator.getValInit(i -
318
                            1), intervalGenerator.getValorRuptura(i));
319
            }
320

    
321
            theIntervalArray[numIntervalsGen - 1] = new FInterval(intervalGenerator.getValInit(numIntervalsGen -
322
                        2), maxValue);
323
        } else {
324
            theIntervalArray[numIntervalsGen - 1] = new FInterval(minValue,
325
                    maxValue);
326
        }
327

    
328
        return theIntervalArray;
329
    }
330

    
331
    /**
332
     * QUANTILE INTERVAL Devuelve un Array con el n?mero de intervalos que se
333
     * quieren crear. Los intervalos se distribuyen de forma quantile.
334
     * @param recordSet
335
     *
336
     * @param numIntervals n?mero de intervalos
337
     * @param minValue Valor m?nimo.
338
     * @param maxValue Valor m?ximo.
339
     * @param fieldName Nombre del campo
340
     *
341
     * @return Array con los intervalos.
342
     * @throws LegendLayerException
343
     */
344
        private IInterval[] calculateQuantileIntervals(FeatureStore featureStore,
345
                        int numIntervals, double minValue,
346
        double maxValue, String fieldName) throws DataException {
347
        QuantileIntervalGenerator intervalGenerator = new QuantileIntervalGenerator(
348
                        featureStore, fieldName, numIntervals);
349

    
350
        intervalGenerator.generarIntervalos();
351

    
352
        int numIntervalsGen = intervalGenerator.getNumIntervalGen();
353
        FInterval[] theIntervalArray = new FInterval[numIntervalsGen];
354

    
355
        if (intervalGenerator.getNumIntervalGen() > 1) {
356
            theIntervalArray[0] = new FInterval(minValue,
357
                    intervalGenerator.getValRuptura(0));
358

    
359
            for (int i = 1; i < (numIntervalsGen - 1); i++) {
360
                theIntervalArray[i] = new FInterval(intervalGenerator.getValInit(i -
361
                            1), intervalGenerator.getValRuptura(i));
362
            }
363

    
364
            theIntervalArray[numIntervalsGen - 1] = new FInterval(intervalGenerator.getValInit(numIntervalsGen -
365
                        2), maxValue);
366
        } else {
367
            theIntervalArray[numIntervalsGen - 1] = new FInterval(minValue,
368
                    maxValue);
369
        }
370

    
371
        return theIntervalArray;
372
    }
373

    
374
    public ISymbol getSymbolByInterval(IInterval key) {
375

    
376
                if (key == null){
377
                        if (nullIntervalSymbol != null) {
378
                                return nullIntervalSymbol;
379
                        }
380
                        else if (isUseDefaultSymbol()) {
381
                                return defaultSymbol;
382
                        }
383
                        return null;
384
                }
385
                if (symbols.containsKey(key)) {
386
                        return (ISymbol) symbols.get(key);
387
                }
388

    
389
                if (isUseDefaultSymbol()) {
390
                        return defaultSymbol;
391
                }
392

    
393
                return null;
394
        }
395

    
396

    
397
        public String[] getDescriptions() {
398
                String[] descriptions = new String[symbols.size()];
399
                ISymbol[] auxSym = getSymbols();
400

    
401
                for (int i = 0; i < descriptions.length; i++) {
402
                        descriptions[i] = auxSym[i].getDescription();
403
                }
404

    
405
                return descriptions;
406
        }
407

    
408

    
409
        public Object[] getValues() {
410
                return symbols.keySet().toArray();
411
        }
412

    
413
        public void clear() {
414
                // index = 0;
415
                keys.clear();
416
                symbols.clear();
417
        }
418

    
419
        public ISymbol[] getSymbols() {
420
                ISymbol[] symbolList;
421
                if (nullIntervalSymbol == null) {
422
                        symbolList = new ISymbol[symbols.size()];
423
                        return (ISymbol[]) symbols.values().toArray(symbolList);
424
                }
425
                else {
426
                        symbolList = new ISymbol[symbols.size() + 1];
427
                        symbolList[0] = nullIntervalSymbol;
428
                        int i = 1;
429
                        for (Iterator<ISymbol> iterator = symbols.values().iterator(); iterator.hasNext();) {
430
                                symbolList[i] = iterator.next();
431
                                i++;
432
                        }
433
                        return symbolList;
434
                }
435
        }
436

    
437
        public void setDefaultSymbol(ISymbol s) {
438
            ISymbol old = defaultSymbol;
439
                if (s == null) {
440
                        throw new NullPointerException("Default symbol cannot be null");
441
                }
442
                defaultSymbol = s;
443
                fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
444
        }
445

    
446
        public ISymbol getDefaultSymbol() {
447
//                NullIntervalValue niv=new NullIntervalValue();
448
//                if (symbols.containsKey(niv)) {
449
//                        return (ISymbol)symbols.get(niv);
450
//                }
451

    
452
                if(defaultSymbol==null) {
453
                        defaultSymbol = getSymbolManager().createSymbol(getShapeType());
454
                }
455
                return defaultSymbol;
456
        }
457

    
458

    
459

    
460
//    public void setFeatureStore(FeatureStore featureStore)
461
//        throws DataException {
462
//                    /*
463
//                     * when we move definitely to feature iterators this
464
//                     * method
465
//                     */
466
//                    this.featureStore = featureStore;
467
////                    fieldId = ((FeatureType)featureStore.getFeatureTypes().get(0)).getIndex(fieldNames[0]);
468
//    }
469

    
470

    
471
        public IInterval getInterval(Object v) {
472
                if (v != null ) {
473
                        for (int i = 0; i < keys.size(); i++) {
474
                                if (((IInterval) keys.get(i)).isInInterval(v)) {
475
                                        return (IInterval) keys.get(i);
476
                                }
477
                        }
478
                }
479

    
480
                return null;
481
        }
482

    
483
        public void setIntervalType(int intervalType) {
484
                this.intervalType = intervalType;
485
        }
486

    
487

    
488
        public int getIntervalType() {
489
                return intervalType;
490
        }
491

    
492
        public void useDefaultSymbol(boolean b) {
493
                useDefaultSymbol = b;
494
        }
495

    
496

    
497
        public boolean isUseDefaultSymbol() {
498
                return useDefaultSymbol;
499
        }
500

    
501

    
502
        public void delSymbol(Object obj) {
503
                keys.remove(obj);
504
                symbols.remove(obj);
505
                fireClassifiedSymbolChangeEvent(
506
                                new SymbolLegendEvent(
507
                                                (ISymbol)symbols.remove(obj),
508
                                                null));
509
        }
510

    
511

    
512
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
513
                if (symbols.containsValue(oldSymbol)) {
514
                        Iterator<Object> it = symbols.keySet().iterator();
515
                        while (it.hasNext()) {
516
                                Object key = it.next();
517
                                if (symbols.get(key).equals(oldSymbol)) {
518
                                        symbols.remove(key);
519
                                        symbols.put(key, newSymbol);
520
                                        fireClassifiedSymbolChangeEvent(
521
                                                        new SymbolLegendEvent(oldSymbol, newSymbol));
522
                                }
523
                        }
524
                }
525
        }
526

    
527
        public Object clone() throws CloneNotSupportedException {
528
                AbstractIntervalLegend clone = (AbstractIntervalLegend) super.clone();
529

    
530
                // Clone null interval symbol
531
                if (nullIntervalSymbol != null) {
532
                        clone.nullIntervalSymbol = (ISymbol) nullIntervalSymbol.clone();
533
                }
534
                
535
                // Clone default symbol
536
                if (defaultSymbol != null) {
537
                        clone.defaultSymbol = (ISymbol) defaultSymbol.clone();
538
                }
539
                // Clone keys
540
                clone.keys = new ArrayList<Object>();
541
                
542
                // Clone symbols
543
                if (symbols != null) {
544
                        clone.symbols = createSymbolMap();
545
                        for (Iterator<Entry<Object, ISymbol>> iterator =
546
                                        symbols.entrySet().iterator(); iterator.hasNext();) {
547
                                Entry<Object, ISymbol> entry = iterator.next();
548
                                IInterval intervalClone =
549
                                                (IInterval) ((IInterval) entry.getKey()).clone();
550
                                ISymbol symbolClone =
551
                                                (ISymbol) ((ISymbol) entry.getValue()).clone();
552
                                clone.addSymbol(intervalClone, symbolClone);
553
                        }
554
                }
555
                
556
                clone.setIntervalType(this.getIntervalType());
557

    
558
                return clone;
559
        }
560

    
561
        @SuppressWarnings("unchecked")
562
        public void loadFromState(PersistentState state)
563
                        throws PersistenceException {
564
                // Set parent properties
565
                super.loadFromState(state);
566
                // Set own properties
567
                setIntervalType(state.getInt(FIELD_INTERVAL_TYPE));
568
                keys = new ArrayList<Object>(state.getList(FIELD_KEYS));
569
                nullIntervalSymbol = (ISymbol) state.get(FIELD_NULL_INTERVAL_SYMBOL);
570
                useDefaultSymbol(state.getBoolean(FIELD_USE_DEFAULT_SYMBOL));
571
                Map persistedSymbolMap = (Map) state.get(FIELD_SYMBOLS);
572
                if (persistedSymbolMap != null) {
573
                        symbols.putAll(persistedSymbolMap);
574
                }
575
        }
576

    
577
        public void saveToState(PersistentState state) throws PersistenceException {
578
                // Save parent properties
579
                super.saveToState(state);
580
                // Save own properties
581
                state.set(FIELD_INTERVAL_TYPE, getIntervalType());
582
                state.set(FIELD_KEYS, keys);
583
                state.set(FIELD_NULL_INTERVAL_SYMBOL, nullIntervalSymbol);
584
                state.set(FIELD_USE_DEFAULT_SYMBOL, isUseDefaultSymbol());
585
                state.set(FIELD_SYMBOLS, symbols);
586
        }
587

    
588
        public static class RegisterPersistence implements Callable {
589

    
590
                public Object call() throws Exception {
591
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
592
                        if( manager.getDefinition(INTERVAL_LEGEND_PERSISTENCE_DEFINITION_NAME)==null ) {
593
                                DynStruct definition = manager.addDefinition(
594
                                                AbstractIntervalLegend.class,
595
                                                INTERVAL_LEGEND_PERSISTENCE_DEFINITION_NAME,
596
                                                INTERVAL_LEGEND_PERSISTENCE_DEFINITION_NAME+" Persistence definition (FIXME check keys type)",
597
                                                null, 
598
                                                null
599
                                );
600
                                
601
                                // Extend the Classified Vector Legend base definition
602
                                definition.extend(manager.getDefinition(CLASSIFIED_VECTOR_LEGEND_PERSISTENCE_DEFINITION_NAME));
603

    
604
                                // Interval type
605
                                definition.addDynFieldInt(FIELD_INTERVAL_TYPE).setMandatory(true);
606
                                // Keys
607
                                definition.addDynFieldList(FIELD_KEYS)
608
                                        .setClassOfItems(int.class);
609
                                // Null interval symbol
610
                                definition.addDynFieldObject(FIELD_NULL_INTERVAL_SYMBOL)
611
                                        .setClassOfValue(ISymbol.class)
612
                                        .setMandatory(false);
613
                                // Use default symbol?
614
                                definition.addDynFieldBoolean(FIELD_USE_DEFAULT_SYMBOL);
615
                                // Symbols
616
                                definition.addDynFieldMap(FIELD_SYMBOLS).setClassOfItems(ISymbol.class);
617
                        }
618
                        return Boolean.TRUE;
619
                }
620
                
621
        }
622
        
623

    
624
        
625
        
626
        private Map<Object, ISymbol> createSymbolMap() {
627
                return new TreeMap<Object, ISymbol>
628
                (new Comparator<Object>() { 
629
                                        public int compare(Object o1, Object o2) {
630
                                                if ((o1 != null) && (o2 != null)) {
631
                                                        // if (o1 instanceof NullIntervalValue &&
632
                                                        // o2 instanceof NullIntervalValue) {
633
                                                        // return 0;
634
                                                        // }
635
                                                        //
636
                                                        // if (o2 instanceof NullIntervalValue) {
637
                                                        // return 1;
638
                                                        // }
639
                                                        //
640
                                                        // if (o1 instanceof NullIntervalValue) {
641
                                                        // return -1;
642
                                                        // }
643

    
644
                                                        FInterval i2 = (FInterval) o2;
645
                                                        FInterval i1 = (FInterval) o1;
646

    
647
                                                        if (i1.getMin() > i2.getMin()) {
648
                                                                return 1;
649
                                                        }
650

    
651
                                                        if (i1.getMin() < i2.getMin()) {
652
                                                                return -1;
653
                                                        }
654
                                                        if (i1.getMax() < i2.getMax()) {
655
                                                                return -1;
656
                                                        }
657
                                                        if (i1.getMax() > i2.getMax()) {
658
                                                                return 1;
659
                                                        }
660
                                                }
661

    
662
                                                return 0;
663
                                        }
664
                                });
665
        }
666
}