Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / 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 @ 40560

History | View | Annotate | Download (20.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl;
25

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

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

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

    
65
        public static final String INTERVAL_LEGEND_PERSISTENCE_DEFINITION_NAME = "IntervalLegend";
66

    
67
        private static final String FIELD_KEYS = "keys";
68
        private static final String FIELD_INTERVAL_TYPE = "intervalType";
69
        private static final String FIELD_USE_DEFAULT_SYMBOL = "useDefaultSymbol";
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
                    // why did we use this?
91
                        // nullIntervalSymbol = symbol;
92
                    logger.info(
93
                        "Warning: tried to add symbol with null key.",
94
                        new Exception("Key is NULL"));
95
                } else {
96
                        symbols.put(key, symbol);
97
                        keys.add(key);
98
                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(null, symbol));
99
                }
100
        }
101

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

    
120
        }
121

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

    
127
                if (theSymbol != null) {
128
                        return theSymbol;
129
                } else if (useDefaultSymbol) {
130
                        return getDefaultSymbol();
131
                }
132
                
133
                return null;
134
//                return theSymbol;
135
        }
136

    
137

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

    
144
//                int idField = -1;
145
                FeatureSet set = null;
146
                DisposableIterator iterator = null;
147
                try {
148

    
149
                setClassifyingFieldNames(new String[] {fieldName});
150

    
151
                String[] fieldNames = getClassifyingFieldNames();
152
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
153
                featureQuery.setAttributeNames(fieldNames);
154

    
155
                set = featureStore.getFeatureSet(featureQuery);
156
                iterator = set.fastIterator();
157

    
158

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

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

    
175
                double minValue = Double.MAX_VALUE;
176
                double maxValue = Double.NEGATIVE_INFINITY;
177

    
178
                IVectorialIntervalLegend auxLegend = (IVectorialIntervalLegend) MapContextLocator
179
                                        .getMapContextManager().createLegend("VectorialInterval");
180
                auxLegend.setShapeType(shapeType);
181

    
182
                Object clave;
183

    
184
                while (iterator.hasNext()) {
185
                        Feature feature = (Feature) iterator.next();
186

    
187
//                for (int j = 0; j < recordSet.getRowCount(); j++) {
188
                        clave = feature.get(fieldName);
189

    
190
                        IInterval interval = auxLegend.getInterval(clave);
191

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

    
197

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

    
209
                                if (valor < minValue) {
210
                                        minValue = valor;
211
                                }
212

    
213
                                if (valor > maxValue) {
214
                                        maxValue = valor;
215
                                }
216
                        }
217
                }
218

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

    
225
                        break;
226

    
227
                case VectorialIntervalLegend.NATURAL_INTERVALS:
228
                        intervalArray = calculateNaturalIntervals(featureStore, numIntervalos,
229
                                        minValue, maxValue, fieldName);
230

    
231
                        break;
232

    
233
                case VectorialIntervalLegend.QUANTILE_INTERVALS:
234
                        intervalArray = calculateQuantileIntervals(featureStore, numIntervalos,
235
                                        minValue, maxValue, fieldName);
236

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

    
251

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

    
268
        if (numIntervals > 1) {
269
            theIntervalArray[0] = new FInterval(minValue, minValue + step);
270

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

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

    
282
        return theIntervalArray;
283
    }
284

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

    
304
        intervalGenerator.generarIntervalos();
305

    
306
        int numIntervalsGen = intervalGenerator.getNumIntervals() - 1;
307

    
308
        if (numIntervalsGen == -1) {
309
            //TODO cuando no puede calcular los intervalos.
310
            numIntervalsGen = 1;
311
        }
312

    
313
        FInterval[] theIntervalArray = new FInterval[numIntervalsGen];
314

    
315
        if (numIntervalsGen > 1) {
316
            theIntervalArray[0] = new FInterval(minValue,
317
                    intervalGenerator.getValorRuptura(0));
318

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

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

    
331
        return theIntervalArray;
332
    }
333

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

    
353
        intervalGenerator.generarIntervalos();
354

    
355
        int numIntervalsGen = intervalGenerator.getNumIntervalGen();
356
        FInterval[] theIntervalArray = new FInterval[numIntervalsGen];
357

    
358
        if (intervalGenerator.getNumIntervalGen() > 1) {
359
            theIntervalArray[0] = new FInterval(minValue,
360
                    intervalGenerator.getValRuptura(0));
361

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

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

    
374
        return theIntervalArray;
375
    }
376

    
377
    public ISymbol getSymbolByInterval(IInterval key) {
378

    
379
                if (key == null){
380
                        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
        symbolList = new ISymbol[symbols.size()];
422
        return (ISymbol[]) symbols.values().toArray(symbolList);
423
        }
424

    
425
        public void setDefaultSymbol(ISymbol s) {
426
            ISymbol old = defaultSymbol;
427
                if (s == null) {
428
                        throw new NullPointerException("Default symbol cannot be null");
429
                }
430
                defaultSymbol = s;
431
                fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
432
        }
433

    
434
        public ISymbol getDefaultSymbol() {
435
//                NullIntervalValue niv=new NullIntervalValue();
436
//                if (symbols.containsKey(niv)) {
437
//                        return (ISymbol)symbols.get(niv);
438
//                }
439

    
440
                if(defaultSymbol==null) {
441
                        defaultSymbol = getSymbolManager().createSymbol(getShapeType());
442
                }
443
                return defaultSymbol;
444
        }
445

    
446

    
447

    
448
//    public void setFeatureStore(FeatureStore featureStore)
449
//        throws DataException {
450
//                    /*
451
//                     * when we move definitely to feature iterators this
452
//                     * method
453
//                     */
454
//                    this.featureStore = featureStore;
455
////                    fieldId = ((FeatureType)featureStore.getFeatureTypes().get(0)).getIndex(fieldNames[0]);
456
//    }
457

    
458

    
459
        public IInterval getInterval(Object v) {
460
                if (v != null ) {
461
                        for (int i = 0; i < keys.size(); i++) {
462
                            
463
                            Object obj_key = keys.get(i);
464
                            if (obj_key instanceof IInterval) {
465
                        if (((IInterval) obj_key).isInInterval(v)) {
466
                            return (IInterval) obj_key;
467
                        }
468
                            }
469
                        }
470
                }
471

    
472
                return null;
473
        }
474

    
475
        public void setIntervalType(int intervalType) {
476
                this.intervalType = intervalType;
477
        }
478

    
479

    
480
        public int getIntervalType() {
481
                return intervalType;
482
        }
483

    
484
        public void useDefaultSymbol(boolean b) {
485
                useDefaultSymbol = b;
486
        }
487

    
488

    
489
        public boolean isUseDefaultSymbol() {
490
                return useDefaultSymbol;
491
        }
492

    
493

    
494
        public void delSymbol(Object obj) {
495
                keys.remove(obj);
496
                symbols.remove(obj);
497
                fireClassifiedSymbolChangeEvent(
498
                                new SymbolLegendEvent(
499
                                                (ISymbol)symbols.remove(obj),
500
                                                null));
501
        }
502

    
503

    
504
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
505
                if (symbols.containsValue(oldSymbol)) {
506
                    
507
                        Iterator<Object> it = symbols.keySet().iterator();
508
                        List key_list = new ArrayList();
509
                        
510
                        while (it.hasNext()) {
511
                                Object key = it.next();
512
                                if (symbols.get(key).equals(oldSymbol)) {
513
                                    key_list.add(key);
514
                                    // symbols.remove(key);
515
                                }
516
                        }
517
                        
518
                        for (int i=0; i<key_list.size(); i++) {
519
                            Object k = key_list.get(i);
520
                            symbols.put(k, newSymbol);
521
                        }
522
            fireClassifiedSymbolChangeEvent(
523
                new SymbolLegendEvent(oldSymbol, newSymbol));
524

    
525
                }
526
        }
527

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

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

    
559
                return clone;
560
        }
561

    
562
        @SuppressWarnings("unchecked")
563
        public void loadFromState(PersistentState state)
564
                        throws PersistenceException {
565
                // Set parent properties
566
                super.loadFromState(state);
567
                // Set own properties
568
                setIntervalType(state.getInt(FIELD_INTERVAL_TYPE));
569
                keys = new ArrayList<Object>(state.getList(FIELD_KEYS));
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_USE_DEFAULT_SYMBOL, isUseDefaultSymbol());
584
                state.set(FIELD_SYMBOLS, symbols);
585
        }
586

    
587
        public static class RegisterPersistence implements Callable {
588

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

    
603
                                // Interval type
604
                                definition.addDynFieldInt(FIELD_INTERVAL_TYPE).setMandatory(true);
605
                                // Keys
606
                                definition.addDynFieldList(FIELD_KEYS)
607
                                        .setClassOfItems(int.class);
608
                                // Use default symbol?
609
                                definition.addDynFieldBoolean(FIELD_USE_DEFAULT_SYMBOL);
610
                                // Symbols
611
                                definition.addDynFieldMap(FIELD_SYMBOLS).setClassOfItems(ISymbol.class);
612
                        }
613
                        return Boolean.TRUE;
614
                }
615
                
616
        }
617
        
618

    
619
        
620
        
621
        private Map<Object, ISymbol> createSymbolMap() {
622
                return new TreeMap<Object, ISymbol>
623
                (new Comparator<Object>() { 
624
                                        public int compare(Object o1, Object o2) {
625
                                                if ((o1 != null) && (o2 != null)) {
626
                                                    
627
                                                    boolean o1_inte = (o1 instanceof FInterval);
628
                            boolean o2_inte = (o2 instanceof FInterval);
629
                            
630
                            if (!o1_inte && !o2_inte) {
631
                                return 0;
632
                            } else {
633
                                if (o1_inte && !o2_inte) {
634
                                    return 1;
635
                                } else {
636
                                    if (!o1_inte && o2_inte) {
637
                                        return -1;
638
                                    }
639
                                }
640
                            }
641

    
642
                                                        FInterval i2 = (FInterval) o2;
643
                                                        FInterval i1 = (FInterval) o1;
644

    
645
                                                        if (i1.getMin() > i2.getMin()) {
646
                                                                return 1;
647
                                                        }
648

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

    
660
                                                return 0;
661
                                        }
662
                                });
663
        }
664
}