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 @ 42858

History | View | Annotate | Download (23.5 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.awt.Color;
27
import java.text.NumberFormat;
28
import java.util.ArrayList;
29
import java.util.Comparator;
30
import java.util.Date;
31
import java.util.HashMap;
32
import java.util.Iterator;
33
import java.util.List;
34
import java.util.Map;
35
import java.util.Map.Entry;
36
import java.util.TreeMap;
37
import javax.swing.JOptionPane;
38

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

    
64
/**
65
 * @author 2005-2008 jaume dominguez faus - jaume.dominguez@iver.es
66
 * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
67
 */
68
public abstract class AbstractIntervalLegend extends
69
                AbstractClassifiedVectorLegend implements IVectorialIntervalLegend {
70

    
71
        public static final String INTERVAL_LEGEND_PERSISTENCE_DEFINITION_NAME = "IntervalLegend";
72

    
73
        private static final String FIELD_KEYS = "keys";
74
        private static final String FIELD_INTERVAL_TYPE = "intervalType";
75
        private static final String FIELD_USE_DEFAULT_SYMBOL = "useDefaultSymbol";
76
        private static final String FIELD_SYMBOLS = "symbols";
77
        
78
        protected List<Object> keys = new ArrayList<Object>(); // <Object>
79
        // protected int index = 0;
80
        // protected int fieldId;
81
        protected ISymbol defaultSymbol;
82
        // protected FeatureStore featureStore;
83
        protected int intervalType = NATURAL_INTERVALS;
84
        protected boolean useDefaultSymbol = false;
85

    
86
        // private ISymbol nullIntervalSymbol = null;
87

    
88
        public static final int EQUAL_INTERVALS = 0;
89
        public static final int NATURAL_INTERVALS = 1;
90
        public static final int QUANTILE_INTERVALS = 2;
91
        protected Map<Object, ISymbol> symbols = createSymbolMap();
92
        final static private Logger logger = LoggerFactory.getLogger(AbstractIntervalLegend.class);
93
        
94
        public void addSymbol(Object key, ISymbol symbol) {
95
                if (key == null) {
96
                    // why did we use this?
97
                        // nullIntervalSymbol = symbol;
98
                    logger.info(
99
                        "Warning: tried to add symbol with null key.",
100
                        new Exception("Key is NULL"));
101
                } else {
102
                        symbols.put(key, symbol);
103
                        keys.add(key);
104
                        fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(null, symbol));
105
                }
106
        }
107

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

    
126
        }
127

    
128
        public ISymbol getSymbolByFeature(Feature feat) throws MapContextException {
129
                Object val = feat.get(getClassifyingFieldNames()[0]);
130
                IInterval interval = getInterval(val);
131
                ISymbol theSymbol = getSymbolByInterval(interval);
132

    
133
                if (theSymbol != null) {
134
                        return theSymbol;
135
                } else if (useDefaultSymbol) {
136
                        return getDefaultSymbol();
137
                }
138
                
139
                return null;
140
//                return theSymbol;
141
        }
142

    
143

    
144
        public IInterval[] calculateIntervals(FeatureStore featureStore,
145
                        String fieldName, int numIntervalos, int shapeType)
146
        throws DataException {
147
                logger.debug("elRs.start()");
148
//                recordSet.start();
149

    
150
//                int idField = -1;
151
                FeatureSet set = null;
152
                DisposableIterator iterator = null;
153
                try {
154

    
155
                setClassifyingFieldNames(new String[] {fieldName});
156

    
157
                String[] fieldNames = getClassifyingFieldNames();
158
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
159
                featureQuery.setAttributeNames(fieldNames);
160

    
161
                set = featureStore.getFeatureSet(featureQuery);
162
                iterator = set.fastIterator();
163

    
164

    
165
//                for (int i = 0; i < recordSet.getFieldCount(); i++) {
166
//                        String nomAux = recordSet.getFieldName(i).trim();
167
//
168
//                        if (fieldNames[0].compareToIgnoreCase(nomAux) == 0) {
169
//                                idField = i;
170
//
171
//                                break;
172
//                        }
173
//                }
174

    
175
//                if (idField == -1) {
176
//                        logger.error("Campo no reconocido " + fieldNames);
177
//
178
//                        return null;
179
//                }
180

    
181
                double minValue = Double.MAX_VALUE;
182
                double maxValue = Double.NEGATIVE_INFINITY;
183

    
184
                IVectorialIntervalLegend auxLegend = (IVectorialIntervalLegend) MapContextLocator
185
                                        .getMapContextManager().createLegend("VectorialInterval");
186
                auxLegend.setShapeType(shapeType);
187

    
188
                Object clave;
189

    
190
                while (iterator.hasNext()) {
191
                        Feature feature = (Feature) iterator.next();
192

    
193
//                for (int j = 0; j < recordSet.getRowCount(); j++) {
194
                        clave = feature.get(fieldName);
195

    
196
                        IInterval interval = auxLegend.getInterval(clave);
197

    
198
                        ////Comprobar que no esta repetido y no hace falta introducir en el hashtable el campo junto con el simbolo.
199
                        if (auxLegend.getSymbolByInterval(interval) == null) {
200
                                //si no esta creado el simbolo se crea
201
                                double valor = 0;
202

    
203

    
204
                                if (clave instanceof Number) {
205
                                        valor=((Number)clave).doubleValue();
206
                                }else if (clave instanceof Date) {
207
                                        //TODO POR IMPLEMENTAR
208
                                        ///valorDate = elRs.getFieldValueAsDate(idField);
209
                                        ///if (valorDate.before(minValueDate)) minValueDate = valorDate;
210
                                        ///if (valorDate.after(maxValueDate)) maxValueDate = valorDate;
211
//                                } else if (clave instanceof NullValue) {
212
//                                        continue;
213
                                }
214

    
215
                                if (valor < minValue) {
216
                                        minValue = valor;
217
                                }
218

    
219
                                if (valor > maxValue) {
220
                                        maxValue = valor;
221
                                }
222
                        }
223
                }
224

    
225
                        IInterval[] intervalArray = null;
226
                switch (getIntervalType()) {
227
                case VectorialIntervalLegend.EQUAL_INTERVALS:
228
                        intervalArray = calculateEqualIntervals(numIntervalos,
229
                                        minValue, maxValue, fieldName);
230

    
231
                        break;
232

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

    
237
                        break;
238

    
239
                case VectorialIntervalLegend.QUANTILE_INTERVALS:
240
                        intervalArray = calculateQuantileIntervals(featureStore, numIntervalos,
241
                                        minValue, maxValue, fieldName);
242

    
243
                        break;
244
                }
245
//                recordSet.stop();
246
                return intervalArray;
247
                } finally {
248
                        if (iterator != null) {
249
                                iterator.dispose();
250
                        }
251
                        if (set != null) {
252
                                set.dispose();
253
                        }
254
                }
255
        }
256

    
257

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

    
274
        if (numIntervals > 1) {
275
            theIntervalArray[0] = new FInterval(minValue, minValue + step);
276

    
277
            for (int i = 1; i < (numIntervals - 1); i++) {
278
                theIntervalArray[i] = new FInterval(minValue + (i * step) +
279
                        0.01, minValue + ((i + 1) * step));
280
            }
281

    
282
            theIntervalArray[numIntervals - 1] = new FInterval(minValue +
283
                    ((numIntervals - 1) * step) + 0.01, maxValue);
284
        } else {
285
            theIntervalArray[0] = new FInterval(minValue, maxValue);
286
        }
287

    
288
        return theIntervalArray;
289
    }
290

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

    
310
        intervalGenerator.generarIntervalos();
311

    
312
        int numIntervalsGen = intervalGenerator.getNumIntervals() - 1;
313

    
314
        if (numIntervalsGen == -1) {
315
            //TODO cuando no puede calcular los intervalos.
316
            numIntervalsGen = 1;
317
        }
318

    
319
        FInterval[] theIntervalArray = new FInterval[numIntervalsGen];
320

    
321
        if (numIntervalsGen > 1) {
322
            theIntervalArray[0] = new FInterval(minValue,
323
                    intervalGenerator.getValorRuptura(0));
324

    
325
            for (int i = 1; i < (numIntervalsGen - 1); i++) {
326
                theIntervalArray[i] = new FInterval(intervalGenerator.getValInit(i -
327
                            1), intervalGenerator.getValorRuptura(i));
328
            }
329

    
330
            theIntervalArray[numIntervalsGen - 1] = new FInterval(intervalGenerator.getValInit(numIntervalsGen -
331
                        2), maxValue);
332
        } else {
333
            theIntervalArray[numIntervalsGen - 1] = new FInterval(minValue,
334
                    maxValue);
335
        }
336

    
337
        return theIntervalArray;
338
    }
339

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

    
359
        intervalGenerator.generarIntervalos();
360

    
361
        int numIntervalsGen = intervalGenerator.getNumIntervalGen();
362
        FInterval[] theIntervalArray = new FInterval[numIntervalsGen];
363

    
364
        if (intervalGenerator.getNumIntervalGen() > 1) {
365
            theIntervalArray[0] = new FInterval(minValue,
366
                    intervalGenerator.getValRuptura(0));
367

    
368
            for (int i = 1; i < (numIntervalsGen - 1); i++) {
369
                theIntervalArray[i] = new FInterval(intervalGenerator.getValInit(i -
370
                            1), intervalGenerator.getValRuptura(i));
371
            }
372

    
373
            theIntervalArray[numIntervalsGen - 1] = new FInterval(intervalGenerator.getValInit(numIntervalsGen -
374
                        2), maxValue);
375
        } else {
376
            theIntervalArray[numIntervalsGen - 1] = new FInterval(minValue,
377
                    maxValue);
378
        }
379

    
380
        return theIntervalArray;
381
    }
382

    
383
    public ISymbol getSymbolByInterval(IInterval key) {
384

    
385
                if (key == null){
386
                        if (isUseDefaultSymbol()) {
387
                                return defaultSymbol;
388
                        }
389
                        return null;
390
                }
391
                if (symbols.containsKey(key)) {
392
                        return (ISymbol) symbols.get(key);
393
                }
394

    
395
                if (isUseDefaultSymbol()) {
396
                        return defaultSymbol;
397
                }
398

    
399
                return null;
400
        }
401

    
402

    
403
        public String[] getDescriptions() {
404
                String[] descriptions = new String[symbols.size()];
405
                ISymbol[] auxSym = getSymbols();
406

    
407
                for (int i = 0; i < descriptions.length; i++) {
408
                        descriptions[i] = auxSym[i].getDescription();
409
                }
410

    
411
                return descriptions;
412
        }
413

    
414

    
415
        public Object[] getValues() {
416
                return symbols.keySet().toArray();
417
        }
418

    
419
        public void clear() {
420
                // index = 0;
421
                keys.clear();
422
                symbols.clear();
423
        }
424

    
425
        public ISymbol[] getSymbols() {
426
                ISymbol[] symbolList;
427
        symbolList = new ISymbol[symbols.size()];
428
        return (ISymbol[]) symbols.values().toArray(symbolList);
429
        }
430

    
431
        public void setDefaultSymbol(ISymbol s) {
432
            ISymbol old = defaultSymbol;
433
                if (s == null) {
434
                        throw new NullPointerException("Default symbol cannot be null");
435
                }
436
                defaultSymbol = s;
437
                fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
438
        }
439

    
440
        @Override
441
        public ISymbol getDefaultSymbol() {
442
//                NullIntervalValue niv=new NullIntervalValue();
443
//                if (symbols.containsKey(niv)) {
444
//                        return (ISymbol)symbols.get(niv);
445
//                }
446

    
447
                if(defaultSymbol==null) {
448
                        defaultSymbol = getSymbolManager().createSymbol(getShapeType());
449
                }
450
                return defaultSymbol;
451
        }
452

    
453

    
454

    
455
//    public void setFeatureStore(FeatureStore featureStore)
456
//        throws DataException {
457
//                    /*
458
//                     * when we move definitely to feature iterators this
459
//                     * method
460
//                     */
461
//                    this.featureStore = featureStore;
462
////                    fieldId = ((FeatureType)featureStore.getFeatureTypes().get(0)).getIndex(fieldNames[0]);
463
//    }
464

    
465

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

    
479
                return null;
480
        }
481

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

    
486

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

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

    
495

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

    
500

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

    
510

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

    
532
                }
533
        }
534

    
535
        public Object clone() throws CloneNotSupportedException {
536
                AbstractIntervalLegend clone = (AbstractIntervalLegend) super.clone();
537

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

    
566
                return clone;
567
        }
568

    
569
        @SuppressWarnings("unchecked")
570
        public void loadFromState(PersistentState state)
571
                        throws PersistenceException {
572
                // Set parent properties
573
                super.loadFromState(state);
574
                // Set own properties
575
                setIntervalType(state.getInt(FIELD_INTERVAL_TYPE));
576
                keys = new ArrayList<Object>(state.getList(FIELD_KEYS));
577
                useDefaultSymbol(state.getBoolean(FIELD_USE_DEFAULT_SYMBOL));
578
                Map persistedSymbolMap = (Map) state.get(FIELD_SYMBOLS);
579
                if (persistedSymbolMap != null) {
580
                        symbols.putAll(persistedSymbolMap);
581
                }
582
        }
583

    
584
        public void saveToState(PersistentState state) throws PersistenceException {
585
                // Save parent properties
586
                super.saveToState(state);
587
                // Save own properties
588
                state.set(FIELD_INTERVAL_TYPE, getIntervalType());
589
                state.set(FIELD_KEYS, keys);
590
                state.set(FIELD_USE_DEFAULT_SYMBOL, isUseDefaultSymbol());
591
                state.set(FIELD_SYMBOLS, symbols);
592
        }
593

    
594
        public static class RegisterPersistence implements Callable {
595

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

    
610
                                // Interval type
611
                                definition.addDynFieldInt(FIELD_INTERVAL_TYPE).setMandatory(true);
612
                                // Keys
613
                                definition.addDynFieldList(FIELD_KEYS)
614
                                        .setClassOfItems(int.class);
615
                                // Use default symbol?
616
                                definition.addDynFieldBoolean(FIELD_USE_DEFAULT_SYMBOL);
617
                                // Symbols
618
                                definition.addDynFieldMap(FIELD_SYMBOLS).setClassOfItems(ISymbol.class);
619
                        }
620
                        return Boolean.TRUE;
621
                }
622
                
623
        }
624
        
625

    
626
        
627
        
628
        private Map<Object, ISymbol> createSymbolMap() {
629
                return new TreeMap<Object, ISymbol>
630
                (new Comparator<Object>() { 
631
                                        public int compare(Object o1, Object o2) {
632
                                                if ((o1 != null) && (o2 != null)) {
633
                                                    
634
                                                    boolean o1_inte = (o1 instanceof FInterval);
635
                            boolean o2_inte = (o2 instanceof FInterval);
636
                            
637
                            if (!o1_inte && !o2_inte) {
638
                                return 0;
639
                            } else {
640
                                if (o1_inte && !o2_inte) {
641
                                    return 1;
642
                                } else {
643
                                    if (!o1_inte && o2_inte) {
644
                                        return -1;
645
                                    }
646
                                }
647
                            }
648

    
649
                                                        FInterval i2 = (FInterval) o2;
650
                                                        FInterval i1 = (FInterval) o1;
651

    
652
                                                        if (i1.getMin() > i2.getMin()) {
653
                                                                return 1;
654
                                                        }
655

    
656
                                                        if (i1.getMin() < i2.getMin()) {
657
                                                                return -1;
658
                                                        }
659
                                                        if (i1.getMax() < i2.getMax()) {
660
                                                                return -1;
661
                                                        }
662
                                                        if (i1.getMax() > i2.getMax()) {
663
                                                                return 1;
664
                                                        }
665
                                                }
666

    
667
                                                return 0;
668
                                        }
669
                                });
670
        }
671

    
672
        @Override
673
    public Map<IInterval,ISymbol> createSymbols(IInterval[] intervals) {
674
        try {
675
            IInterval interval;
676
            NumberFormat formatter = NumberFormat.getInstance();
677
            Color startColor = this.getStartColor();
678
            Color endColor = this.getEndColor();
679
            Map<IInterval,ISymbol> symbols = new HashMap<>();
680
            SymbolManager symbolManager = MapContextLocator.getSymbolManager();
681

    
682
            int r;
683
            int g;
684
            int b;
685
            int stepR;
686
            int stepG;
687
            int stepB;
688

    
689
            formatter.setMaximumFractionDigits(2);
690
            r = startColor.getRed();
691
            g = startColor.getGreen();
692
            b = startColor.getBlue();
693
            stepR = (int) Math.floor((endColor.getRed() - r) / (intervals.length - 1));
694
            stepG = (int) Math.floor((endColor.getGreen() - g) / (intervals.length - 1));
695
            stepB = (int) Math.floor((endColor.getBlue() - b) / (intervals.length - 1));
696

    
697
            for (int k = 0; k < intervals.length; k++) {
698
                interval = intervals[k];
699

    
700
                ISymbol theSymbol = null;
701
                Color color = new Color(r, g, b);
702
                int intervalos = intervals.length - 1;
703
                if (intervalos == k) {
704
                    color = endColor;
705
                }
706

    
707
                theSymbol = symbolManager.createSymbol(this.getShapeType(), color);
708

    
709
                /*
710
                 * If multishape, we need to set line and fill color here.
711
                 * This is because the symbol manager is in mapcontext.api, which cannot
712
                 * depend on symbology.lib.api
713
                 */
714
                if (theSymbol instanceof IMultiShapeSymbol) {
715
                    IMultiShapeSymbol mss = (IMultiShapeSymbol) theSymbol;
716
                    mss.getLineSymbol().setLineColor(color);
717
                    mss.getFillSymbol().setFillColor(color);
718
                }
719
                theSymbol.setDescription(
720
                        formatter.format(interval.getMin())
721
                        + " - "
722
                        + formatter.format(interval.getMax())
723
                );
724
                r = r + stepR;
725
                g = g + stepG;
726
                b = b + stepB;
727

    
728
                symbols.put(interval, theSymbol);
729
            }
730
            return symbols;
731
        } catch (Exception e) {
732
            throw new RuntimeException("Can't create symbols from the intervals",e);
733
        }
734
    }
735
    
736
    @Override
737
    public void setIntervals(IInterval[] intervals) {
738
        Map<IInterval,ISymbol>symbols = this.createSymbols(intervals);
739
        this.clear();
740
        for (Entry<IInterval, ISymbol> entrySet : symbols.entrySet()) {
741
            IInterval key = entrySet.getKey();
742
            ISymbol value = entrySet.getValue();
743
            this.addSymbol(key,value);
744
        }
745
    }
746
        
747
        
748
       
749
}