Statistics
| Revision:

root / org.gvsig.legend.proportionalsymbols.app.mainplugin / trunk / org.gvsig.legend.proportionalsymbols.app.mainplugin / src / main / java / org / gvsig / symbology / fmap / rendering / ProportionalSymbolsLegend.java @ 1855

History | View | Annotate | Download (19 KB)

1 12 jldominguez
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.symbology.fmap.rendering;
42
43
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
45
46
import org.gvsig.fmap.dal.feature.Feature;
47
import org.gvsig.fmap.geom.Geometry;
48 1855 jjdelcerro
import org.gvsig.fmap.geom.GeometryLocator;
49
import org.gvsig.fmap.geom.GeometryManager;
50 12 jldominguez
import org.gvsig.fmap.mapcontext.MapContextLocator;
51
import org.gvsig.fmap.mapcontext.MapContextManager;
52
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
53
import org.gvsig.fmap.mapcontext.rendering.legend.ZSort;
54
import org.gvsig.fmap.mapcontext.rendering.legend.events.IntervalLegendEvent;
55
import org.gvsig.fmap.mapcontext.rendering.legend.events.LabelLegendEvent;
56
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
57
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
58
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
59
import org.gvsig.fmap.mapcontext.rendering.legend.events.ValueLegendEvent;
60
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
61
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
62
import org.gvsig.i18n.Messages;
63
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.VectorialUniqueValueLegend;
64
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.impl.MarkerFillSymbol;
65
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.impl.MultiLayerFillSymbol;
66
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
67
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
68
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.SimpleMarkerFillPropertiesStyle;
69
import org.gvsig.tools.ToolsLocator;
70
import org.gvsig.tools.dynobject.DynStruct;
71
import org.gvsig.tools.persistence.PersistenceManager;
72
import org.gvsig.tools.persistence.PersistentState;
73
import org.gvsig.tools.persistence.exception.PersistenceException;
74
import org.gvsig.tools.util.Callable;
75
76
77
/**
78
 * Implements a legend which represents the quantitative information
79
 * (numeric values). This representation is possible thanks to a symbol
80
 * whose size is different each time (depending on the numeric values
81
 * and if we want to use normalization or not).
82
 *
83
 * @author jaume dominguez faus - jaume.dominguez@iver.es
84
 * @author jldominguez
85
 */
86
public class ProportionalSymbolsLegend extends VectorialUniqueValueLegend  {
87
88
    private static Logger logger = LoggerFactory.getLogger(ProportionalSymbolsLegend.class);
89
    public static final String
90
    PROPORTIONAL_SYMBOL_LEGEND_NAME =
91 102 fdiaz
        "PROPORTIONAL_SYMBOL_LEGEND";
92 12 jldominguez
    public static final String
93
    PROPORTIONAL_SYMBOL_LEGEND_PERSISTENCE_DEFINITION_NAME =
94 102 fdiaz
        "PROPORTIONAL_SYMBOL_LEGEND_PERSISTENCE_DEFINITION";
95
96 12 jldominguez
        public void setClassifyingFieldNames(String[] fNames) {
97
                super.setClassifyingFieldNames(fNames);
98
                valueField = fNames[0];
99
                normalizationField = fNames[1];
100
        }
101
102
        private ISymbol backgroundSymbol;
103
        private String valueField;
104
        private String normalizationField;
105
        private double minSize;
106
        private double maxSize;
107
        private int templateShapeType;
108
        private boolean useNormalization;
109
        private double maxFeature, minFeature;
110
        private ZSort zSort = null;
111
112
113
        public ISymbol getSymbolByValue(Object key) {
114
                return null;
115
        }
116
117
        public ISymbol getSymbolByFeature(Feature feat) {
118 102 fdiaz
119 12 jldominguez
                ISymbol theSymbol = getDefaultSymbol();
120
                ISymbol auxSymbol;
121 102 fdiaz
122 12 jldominguez
                double value = 0;
123
                double normValue = 0;
124
                double size;
125
                double separation = maxSize-minSize;
126 102 fdiaz
127 12 jldominguez
                if (separation == 0) {
128
                        separation = 1;
129
                }
130
131
                try {
132
133
                        value = feat.getDouble(this.valueField);
134
                        if (useNormalization) {
135 102 fdiaz
136 12 jldominguez
                            normValue = feat.getDouble(this.normalizationField);
137
                            if (normValue == 0) {
138
                                size = (value >= 0) ?
139
                                    Double.POSITIVE_INFINITY :
140 102 fdiaz
                                    Double.NEGATIVE_INFINITY;
141 12 jldominguez
                            } else {
142
                        value = value / normValue;
143
                        size = minSize + (value * separation) ;
144
                            }
145 102 fdiaz
146 12 jldominguez
                        } else {
147
                                double difFeat = maxFeature - minFeature;
148
                                double step = difFeat/separation;
149
                                size = minSize + ((value - minFeature)/step);
150
                        }
151
152
                } catch (Exception e) {
153
                        logger.info("Error while getting value in ProportionalSymbolsLegend.", e);
154
                        return null;
155
                }
156
157
                if (size == Double.NaN || size == Double.POSITIVE_INFINITY
158
                    || size == Double.NEGATIVE_INFINITY) {
159 102 fdiaz
160 12 jldominguez
            // logger.info("The symbol size is NaN or INFINITE.");
161
                        return null;
162
                }
163
164
                Geometry defgeom = feat.getDefaultGeometry();
165
                int def_geom_type = defgeom.getGeometryType().getType();
166 102 fdiaz
167 12 jldominguez
                if (isPolygonal(def_geom_type) && theSymbol instanceof IMarkerSymbol) {
168 102 fdiaz
169 12 jldominguez
                        MarkerFillSymbol aux = new MarkerFillSymbol();
170
                        ((IMarkerSymbol) theSymbol).setSize(size);
171
                        aux.setMarker((IMarkerSymbol) theSymbol);
172
                        SimpleMarkerFillPropertiesStyle p = new SimpleMarkerFillPropertiesStyle();
173
                        p.setFillStyle(SimpleMarkerFillPropertiesStyle.SINGLE_CENTERED_SYMBOL);
174
                        aux.setMarkerFillProperties(p);
175
                        theSymbol = aux;
176
                }
177
                else if (isLinear(def_geom_type)) {
178 102 fdiaz
179 12 jldominguez
                        ILineSymbol line = (ILineSymbol) theSymbol;
180
                        line.setLineWidth(size);
181
                        theSymbol = line;
182
                }
183
                else if (isPoint(def_geom_type)) {
184
                        IMarkerSymbol marker = (IMarkerSymbol) theSymbol;
185
                        marker.setSize(size);
186
                        theSymbol = marker;
187
                }
188 102 fdiaz
189 12 jldominguez
                if (backgroundSymbol != null) {
190
                        MultiLayerFillSymbol multi = new MultiLayerFillSymbol() ;
191
                        multi.addLayer(backgroundSymbol);
192
                        multi.addLayer(theSymbol);
193
                        return multi;
194
                }
195
                auxSymbol = theSymbol;
196
197
                return auxSymbol;
198
199
        }
200
201 1855 jjdelcerro
    public static boolean isPolygonal(int ty) {
202
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
203
        return geomManager.isSubtype(Geometry.TYPES.MULTISURFACE, ty) ||
204
            geomManager.isSubtype(Geometry.TYPES.SURFACE, ty);
205
    }
206 12 jldominguez
207 1855 jjdelcerro
    public static boolean isLinear(int ty) {
208
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
209
        return geomManager.isSubtype(Geometry.TYPES.MULTICURVE, ty) ||
210
            geomManager.isSubtype(Geometry.TYPES.CURVE, ty);
211 12 jldominguez
    }
212 1855 jjdelcerro
213
    public static boolean isPoint(int ty) {
214
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
215
        return geomManager.isSubtype(Geometry.TYPES.MULTIPOINT, ty) ||
216
            geomManager.isSubtype(Geometry.TYPES.POINT, ty);
217
    }
218 12 jldominguez
219
        /**
220
         * Gets the background symbol which only can appear when the shapetype of the layer
221
         * is polygonal
222
         *
223
         * @return ISymbol the symbol for the background
224
         */
225
        public ISymbol getBackgroundSymbol() {return backgroundSymbol;}
226
        /**
227
         * Sets the background symbol which is used only when the shapetype of the layer is polygonal
228
         *
229
         * @param backgroundSymbol the symbol for the background
230
         */
231
        public void setBackgroundSymbol(ISymbol backgroundSymbol) {this.backgroundSymbol = backgroundSymbol;}
232
        /**
233
         * Obtains the classifying field name to be used to calculate the size of the symbol
234
         *
235
         * @return String  the name of the field
236 102 fdiaz
         * @throws ReadDriverException
237 12 jldominguez
         */
238
        public String getValueField() {
239
//                try {
240
//                        // TODO:
241
//                        // Por los alias, al guardar un proyecto no podemos
242
//                        // permitir que se guarde con campos que luego
243
//                        // no van a existir.
244
////                        int id = dataSource.getFieldIndexByName(valueField);
245
////                        valueField = dataSource.getFieldName(id);
246
//                } catch (ReadDriverException e) {
247
//                        e.printStackTrace();
248
//                        throw new RuntimeException(e);
249
//                }
250
                return valueField;
251
        }
252
        /**
253
         * Sets the classifying field name to be used to calculate the size of the symbol
254
         *
255
         * @param String  the name of the field
256
         */
257
        public void setValueField(String valueField) {this.valueField = valueField;}
258
        /**
259
         * Obtains the classifying field name to be used to calculate the size of the symbol when the
260
         * user is doing it with a normalization value.
261
         *
262
         * @return String  the name of the field
263
         */
264
        public String getNormalizationField() {
265
                return normalizationField;
266
        }
267
        /**
268
         * Sets the classifying field name to be used to calculate the size of the symbol when the
269
         * user is doing it with a normalization value.
270
         *
271
         * @param String  the name of the field
272
         */
273
        public void setNormalizationField(String normalizationField) {this.normalizationField = normalizationField;}
274
        /**
275
         * Obtains the minimum size for the symbol
276
         *
277
         * @return double  the minimum size for the symbol
278
         */
279
        public double getMinSize() {return minSize;}
280
        /**
281
         * Sets the minimum size for the symbol
282
         *
283
         * @param minSize  the minimum size for the symbol
284
         */
285
        public void setMinSize(double minSize) {this.minSize = minSize;}
286
        /**
287
         * Obtains the maximum size for the symbol
288
         *
289
         * @return double  the minimum size for the symbol
290
         */
291
        public double getMaxSize() {return maxSize;}
292
        /**
293
         * Sets the maximum size for the symbol
294
         *
295
         * @param maxSize  the minimum size for the symbol
296
         */
297
        public void setMaxSize(double maxSize) {this.maxSize = maxSize;}
298
        /**
299
         * Obtains the shapetype of the template symbol
300
         *
301
         * @return int shape type for the template symbol
302
         */
303
        public int getTemplateShapeType() {return templateShapeType;}
304
        /**
305
         * Sets the shapetype of the template symbol
306
         *
307
         * @param templateShapeType shape type for the template symbol
308
         */
309
        public void setTemplateShapeType(int tst) {
310 102 fdiaz
311 12 jldominguez
                if (isPolygonal(getShapeType())) {
312
                        if (isPoint(tst) || isPolygonal(tst)) {
313
                            this.templateShapeType = tst;
314
                        }
315
                } else {
316 102 fdiaz
317 12 jldominguez
                    if ((isPoint(tst) && isPoint(getShapeType()))
318
                        || (isLinear(tst) && isLinear(getShapeType()))) {
319
                        // || (getShapeType() == Geometry.TYPES.NULL)) {
320 102 fdiaz
321 12 jldominguez
                        this.templateShapeType = tst;
322
                    }
323
                }
324
        }
325 102 fdiaz
326 12 jldominguez
        /**
327
         * Obtains the boolean which is true if the user wants to calculate the size of the
328
         * symbol using a normalization field.
329
         *
330
         * @return boolean true if the user wants normalization.Otherwise, false.
331
         */
332
        public boolean getUseNormalization() {return useNormalization;}
333
        /**
334
         * Sets the boolean which is true if the user wants to calculate the size of the
335
         * symbol using a normalization field.
336
         *
337
         * @param useNormalization true if the user wants normalization.Otherwise, false.
338
         */
339
        public void setUseNormalization(boolean useNormalization) {this.useNormalization = useNormalization;}
340
        /**
341
         * Obtains the variable which represents the maximum value of the classifying field that is used
342
         * to calculate the size of the symbol
343
         *
344
         * @return double  the maximum value of the classifying field
345
         */
346
        public double getMaxFeature() {return maxFeature;}
347
        /**
348
         * Sets the variable which represents the maximum value of the classifying field that is used
349
         * to calculate the size of the symbol
350
         *
351
         * @param maxFeature
352
         */
353
        public void setMaxFeature(double maxFeature) {this.maxFeature = maxFeature;}
354
        /**
355
         * Obtains the variable which represents the minimum value of the classifying field that is used
356
         * to calculate the size of the symbol
357
         *
358
         * @return double  the minimum value of the classifying field
359
         */
360
        public double getMinFeature() {return minFeature;}
361
        /**
362
         * Sets the variable which represents the minimum value of the classifying field that is used
363
         * to calculate the size of the symbol
364
         *
365
         * @param minFeature
366
         */
367
        public void setMinFeature(double minFeature) {this.minFeature = minFeature;}
368
369
370
        public ISymbol[] getSymbols() {
371
                ISymbol[] auxSymbols=super.getSymbols();
372
                if(backgroundSymbol != null){
373
                        ISymbol[] symbols=new ISymbol[auxSymbols.length+1];
374
                        for (int i = 0; i < auxSymbols.length; i++) {
375
                                symbols[i]=auxSymbols[i];
376
                        }
377
                        symbols[symbols.length-1]=backgroundSymbol;
378
                        return symbols;
379
                } else {
380
                        return auxSymbols;
381
                }
382
        }
383
384
385
386
        public ZSort getZSort() {
387
                if (zSort == null){
388
                        zSort = new MyZSort(this);
389
                }
390
                return zSort;
391
        }
392
393
        public void setZSort(ZSort zSort){
394
                return;
395
        }
396
397
        private class MyZSort extends ZSort {
398
399
                public MyZSort(ILegend legend) {
400
                        super(legend);
401
                }
402
403
                public void legendChanged(LegendChangedEvent e) {
404
                }
405
406
                public String getClassName() {
407
                        return getClass().getName();
408
                }
409
410
                public int getLevelCount() {
411
                        int levels = 0;
412
                        if (backgroundSymbol!=null){
413
                                if(backgroundSymbol instanceof IMultiLayerSymbol){
414
                                        levels += ((IMultiLayerSymbol)backgroundSymbol).getLayerCount();
415
                                } else {
416
                                        levels += 1;
417
                                }
418
                        }
419
                        ISymbol sym = getDefaultSymbol();
420
                        if(getDefaultSymbol() instanceof IMultiLayerSymbol){
421
                                levels += ((IMultiLayerSymbol)sym).getLayerCount();
422
                        } else {
423
                                levels += 1;
424
                        }
425
                        return levels+1;
426
                }
427
428
429
                public void setUsingZSort(boolean usingZSort) {
430
                }
431
432
                public void setLevels(ISymbol sym, int[] values) {
433
                }
434
435
436
                public void setLevels(int row, int[] values) {
437
                }
438
439
                public int[] getLevels(ISymbol sym) {
440
                        return getLevels(0);
441
                }
442
443
                public int[] getLevels(int row) {
444
                        int levelsCount = getLevelCount();
445
                        int[] levels = new int[levelsCount];
446
                        int bgLevels = 1;
447
                        if (backgroundSymbol!=null){
448
                                if(backgroundSymbol instanceof IMultiLayerSymbol){
449
                                        bgLevels = ((IMultiLayerSymbol)backgroundSymbol).getLayerCount();
450
                                }
451
                                for (int i=0; i<bgLevels; i++) {
452
                                        levels[i]=i;
453
                                }
454
                        }
455
456
                        ISymbol sym = getDefaultSymbol();
457
                        int frLevels = 1;
458
                        if(getDefaultSymbol() instanceof IMultiLayerSymbol){
459
                                frLevels = ((IMultiLayerSymbol)sym).getLayerCount();
460
                        }
461
                        for (int i=0; i<frLevels; i++) {
462
                                levels[i+bgLevels]=i+bgLevels;
463
                        }
464
                        levels[frLevels+bgLevels]=frLevels+bgLevels;
465
                        return levels;
466
                }
467
468
469
                public boolean isUsingZSort() {
470
                        return backgroundSymbol!=null;
471
                }
472
473
474
                public ISymbol[] getSymbols() {
475
                        return getSymbols();
476
                }
477
478
                public String[] getDescriptions() {
479
                        return getDescriptions();
480
                }
481
482
                public int getTopLevelIndexAllowed() {
483
                        return getLevelCount();
484
                }
485
486
                @Override
487
                public String toString() {
488
                        String out = "ZSort for ProportionalSymbolLegend";
489
                        return out;
490
                }
491
492
                public boolean symbolChanged(SymbolLegendEvent e) {
493
                        return true;
494
                }
495
496
                public boolean classifiedSymbolChange(SymbolLegendEvent e) {
497
                        return true;
498
                }
499
500
                public boolean intervalChange(IntervalLegendEvent e) {
501
                        return false;
502
                }
503
504
                public boolean valueChange(ValueLegendEvent e) {
505
                        return false;
506
                }
507
508
                // TODO should not exist here
509
                public boolean labelFieldChange(LabelLegendEvent e) {
510
                        return false;
511
                }
512
513
                public void legendCleared(LegendClearEvent event) {
514
                }
515
        }
516
517 102 fdiaz
518 12 jldominguez
    public void loadFromState(PersistentState state)
519
        throws PersistenceException {
520 102 fdiaz
521 12 jldominguez
        int[] ft = state.getIntArray("fieldTypes");
522
        this.setClassifyingFieldTypes(ft);
523 102 fdiaz
524 12 jldominguez
        this.valueField = state.getString("valueField");
525
        this.normalizationField = state.getString("normalizationField");
526
        this.templateShapeType = state.getInt("templateShapeType");
527
        this.maxSize = state.getDouble("maxSize");
528
        this.minSize = state.getDouble("minSize");
529
        this.maxFeature = state.getDouble("maxFeature");
530
        this.minFeature = state.getDouble("minFeature");
531
        this.useNormalization = state.getBoolean("useNormalization");
532 102 fdiaz
533 12 jldominguez
        ISymbol sym = (ISymbol) state.get("defaultSymbol");
534
        this.setDefaultSymbol(sym);
535 102 fdiaz
536 12 jldominguez
        sym = (ISymbol) state.get("backgroundSymbol");
537
        this.setBackgroundSymbol(sym);
538 102 fdiaz
539 12 jldominguez
        String[] fieldNames = new String[2];
540
        fieldNames[0]= valueField;
541
        if (normalizationField.compareTo(Messages.getText("none")) == 0) {
542
            fieldNames[1]= fieldNames[0];
543
        } else {
544
            fieldNames[1] = normalizationField;
545
        }
546
        setClassifyingFieldNames(fieldNames);
547
    }
548
549
550
    public void saveToState(PersistentState state) throws PersistenceException {
551
552
        int[] ft = this.getClassifyingFieldTypes();
553
        state.set("fieldTypes", ft);
554
555
        state.set("valueField", this.valueField);
556
        state.set("normalizationField", this.normalizationField);
557
        state.set("templateShapeType", this.templateShapeType);
558
        state.set("maxSize", this.maxSize);
559
        state.set("minSize", this.minSize);
560
        state.set("maxFeature", this.maxFeature);
561
        state.set("minFeature", this.minFeature);
562
        state.set("useNormalization", this.useNormalization);
563
        state.set("defaultSymbol", this.getDefaultSymbol());
564
        state.set("backgroundSymbol", this.backgroundSymbol);
565
    }
566
567
568
    public static class RegisterPersistence implements Callable {
569
570
        public Object call() throws Exception {
571 102 fdiaz
572 12 jldominguez
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
573
            if (manager
574
                .getDefinition(PROPORTIONAL_SYMBOL_LEGEND_PERSISTENCE_DEFINITION_NAME) == null) {
575
                DynStruct definition =
576
                    manager
577
                        .addDefinition(
578
                            ProportionalSymbolsLegend.class,
579
                            PROPORTIONAL_SYMBOL_LEGEND_PERSISTENCE_DEFINITION_NAME,
580
                            PROPORTIONAL_SYMBOL_LEGEND_PERSISTENCE_DEFINITION_NAME
581
                                + " Persistence definition", null, null);
582 102 fdiaz
583 12 jldominguez
                definition.addDynFieldString("valueField").setMandatory(true);
584
                definition.addDynFieldString("normalizationField").setMandatory(true);
585
                definition.addDynFieldInt("templateShapeType").setMandatory(true);
586 102 fdiaz
                definition.addDynFieldArray("fieldTypes").setClassOfItems(Integer.class).setMandatory(true);
587 12 jldominguez
                definition.addDynFieldDouble("maxSize").setMandatory(true);
588
                definition.addDynFieldDouble("minSize").setMandatory(true);
589
                definition.addDynFieldDouble("maxFeature").setMandatory(true);
590
                definition.addDynFieldDouble("minFeature").setMandatory(true);
591
                definition.addDynFieldBoolean("useNormalization").setMandatory(true);
592 102 fdiaz
593 12 jldominguez
                definition.addDynFieldObject("defaultSymbol")
594
                .setClassOfValue(ISymbol.class).setMandatory(true);
595
                definition.addDynFieldObject("backgroundSymbol")
596
                .setClassOfValue(ISymbol.class).setMandatory(true);
597
            }
598
            return Boolean.TRUE;
599
        }
600
601
    }
602
603
    public static class RegisterLegend implements Callable {
604
605
        public Object call() throws Exception {
606
            MapContextManager manager =
607
                MapContextLocator.getMapContextManager();
608
609
            manager.registerLegend(
610
                PROPORTIONAL_SYMBOL_LEGEND_NAME,
611
                ProportionalSymbolsLegend.class);
612
613
            return Boolean.TRUE;
614
        }
615
616
    }
617
618
}