Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.api / src / main / java / org / gvsig / fmap / mapcontext / rendering / legend / ZSort.java @ 40559

History | View | Annotate | Download (9.69 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.fmap.mapcontext.rendering.legend;
25

    
26
import java.util.HashMap;
27
import java.util.Map;
28

    
29
import org.gvsig.fmap.mapcontext.MapContextException;
30
import org.gvsig.fmap.mapcontext.rendering.legend.events.IntervalLegendEvent;
31
import org.gvsig.fmap.mapcontext.rendering.legend.events.LabelLegendEvent;
32
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
33
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
34
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
35
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
36
import org.gvsig.fmap.mapcontext.rendering.legend.events.ValueLegendEvent;
37
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
38
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
39

    
40
/**
41
 * Class ZSort is used in order to store information about the symbols
42
 * which are placed in the Z axis (because a level of symbols has been
43
 * used).
44
 *
45
 * @author jaume dominguez faus - jaume.dominguez@iver.es
46
 */
47
public class ZSort implements LegendContentsChangedListener {
48
        // private static final String COLUMN_SEPARATOR = ",";
49
        // private static final String ROW_SEPARATOR = ";";
50
        private int[][] matrix;
51
        private boolean usingZSort;
52
        private Map symbols = new HashMap();
53

    
54
        public ZSort(ILegend legend) {
55
                initialize(legend);
56
        }
57

    
58
        private void initialize(ILegend legend) {
59
                ISymbol[] symbols;
60
                if (legend instanceof IClassifiedLegend) {
61
                        symbols = ((IClassifiedLegend) legend).getSymbols();
62

    
63
                } else {
64
                        symbols = new ISymbol[] {legend.getDefaultSymbol()};
65
                }
66
                matrix = new int[symbols.length][];
67

    
68
                for (int i = 0; i < symbols.length; i++) {
69
                        this.symbols.put(symbols[i], new Integer(i));
70
                        int rowLength =  symbols[i] instanceof IMultiLayerSymbol ?
71
                           ((IMultiLayerSymbol) symbols[i]).getLayerCount() :
72
                         1;
73
                        matrix[i] = new int[rowLength];
74
                }
75
                legend.addLegendListener(this);
76
        }
77

    
78
        private void addSymbol(ISymbol sym){
79
                if (!symbols.containsKey(sym)) {
80
                        int rowLength =  sym instanceof IMultiLayerSymbol ?
81
                                        ((IMultiLayerSymbol) sym).getLayerCount() : 1;
82
                        int[][] auxMatrix = new int[matrix.length+1][];
83
                        int newIndex = matrix.length;
84
                        for (int i=0; i<newIndex; i++){
85
                                auxMatrix[i] = matrix[i];
86
                        }
87
                        int[] row = new int[rowLength];
88
                        for (int i=0; i<rowLength; i++){
89
                                row[i] = 0;
90
                        }
91
                        auxMatrix[newIndex] = row;
92
                        matrix = auxMatrix;
93
                        this.symbols.put(sym, new Integer(newIndex));
94
                }
95
        }
96

    
97
        public void legendChanged(LegendChangedEvent e) throws MapContextException {
98
                symbols.clear();
99
                usingZSort = false;
100
                initialize(e.getNewLegend());
101

    
102
        }
103

    
104
        public String getClassName() {
105
                return getClass().getName();
106
        }
107

    
108
        public int getLevelCount() {
109
                int count = -1;
110
                for (int i = 0; i < matrix.length; i++) {
111
                        for (int j = 0; j < matrix[i].length; j++) {
112
                                count = Math.max(count, matrix[i][j]);
113
                        }
114
                }
115
                return count + 1;
116
        }
117

    
118

    
119
        public void setUsingZSort(boolean usingZSort) {
120
                this.usingZSort = usingZSort;
121
        }
122

    
123
        public void setLevels(ISymbol sym, int[] values) {
124
                setLevels(((Integer)symbols.get(sym)).intValue(), values);
125
        }
126

    
127

    
128
        public void setLevels(int row, int[] values) {
129
                matrix[row] = values;
130
        }
131

    
132
        public int[] getLevels(ISymbol sym) {
133
                Integer row = (Integer) symbols.get(sym);
134
                if (row != null) {
135
                        return getLevels(row.intValue());
136
                } else {
137
                        ISymbol[] theSymbols = getSymbols();
138
                        for (int i = 0; i < theSymbols.length; i++) {
139
                                ISymbol auxSymbol = theSymbols[i];
140
                                if (auxSymbol.equals(sym)){
141
                                        return getLevels(((Integer)symbols.get(auxSymbol)).intValue());
142
                                }
143
                        }
144
                }
145
                return null;
146
        }
147

    
148

    
149
        public int[] getLevels(int row) {
150
                return matrix[row];
151
        }
152

    
153

    
154
        public boolean isUsingZSort() {
155
                return usingZSort;
156
        }
157

    
158

    
159
        public ISymbol[] getSymbols() {
160
                return (ISymbol[])symbols.keySet().toArray(new ISymbol[0]);
161
        }
162

    
163

    
164
        public String[] getDescriptions() {
165
                ISymbol[] symbols = getSymbols();
166
                String[] descs = new String[symbols.length];
167
                for (int i = 0; i < descs.length; i++) {
168
                        descs[i] = symbols[i].getDescription();
169
                }
170
                return descs;
171
        }
172

    
173
        /*
174
         * [PACO] Comentarizado porque no hace lo que se esperar?a de ?l.
175
         * Si tenemos una leyenda con un simbolo Multilayer compuesto
176
         * por, entre otros, un simbolo simple que coincide con otro de
177
         * los simbolos de la leyenda, este metodo devuelve el nivel
178
         * del s?mbolo que encuentra primero.
179
         *
180
         * Se ha eliminado cualquier referencia a este metodo en el resto
181
         * del workspace, sustituyendola convenientemente por
182
         * referencias a getLevels.
183
         */
184
//        public int getSymbolLevel(ISymbol layer) {
185
//                ISymbol[] theSymbols = getSymbols();
186
//
187
//                for (int i = 0; i < theSymbols.length; i++) {
188
//                        ISymbol mySymbol = theSymbols[i];
189
//
190
//                        if (mySymbol instanceof IMultiLayerSymbol) {
191
//                                IMultiLayerSymbol multiSym = (IMultiLayerSymbol) mySymbol;
192
//                                for (int j = 0; j < multiSym.getLayerCount(); j++) {
193
//                                        ISymbol myInnerSymbol = multiSym.getLayer(j);
194
//                                        if (myInnerSymbol.equals(layer)) {
195
//                                                int row = ((Integer)symbols.get(multiSym)).intValue();
196
//                                                return matrix[row][j];
197
//                                        }
198
//                                }
199
//                        } else {
200
//                                if (mySymbol.equals(layer)) {
201
//                                        return matrix[((Integer)symbols.get(layer)).intValue()][0];
202
//                                }
203
//                        }
204
//                }
205
//
206
////                return 0;
207
//                return -1;
208
//        }
209

    
210
        public int getTopLevelIndexAllowed() {
211
                ISymbol[] symbols = getSymbols();
212
                int count=0;
213
                for (int i = 0; i < symbols.length; i++) {
214
                        if (symbols[i] instanceof IMultiLayerSymbol) {
215
                                IMultiLayerSymbol mSymbol = (IMultiLayerSymbol) symbols[i];
216
                                count = Math.max(count, mSymbol.getLayerCount());
217
                        } else
218
                                count = Math.max(count, 1);
219
                }
220
                return count;
221
        }
222

    
223
        public String toString() {
224
                String out = "Symbols:\n---------\n\n";
225
                ISymbol[] syms = getSymbols();
226
                for (int i = 0; i < syms.length; i++) {
227
                        out += syms.getClass()+":\t"+syms[i].getDescription();
228
                }
229
                out += "\nMatrix:\n--------\n\n";
230
                out += "    \t";
231
                for (int i = 0; i < getTopLevelIndexAllowed(); i++) {
232
                        out += "column"+i+"\t\t";
233
                }
234
                out += "\n";
235
                for (int i = 0; i < matrix.length; i++) {
236
                        out += "row "+i+":\t";
237
                        for (int j = 0; j < matrix[i].length; j++) {
238
                                out += matrix[i][j]+"\t\t";
239
                        }
240
                        out += "\n";
241
                }
242
                return out;
243
        }
244

    
245
        private void replaceSymbol(ISymbol oldSymbol, ISymbol newSymbol) {
246
                if (oldSymbol == newSymbol) return;
247

    
248
                if(oldSymbol != null){
249

    
250
                        Integer value = (Integer)symbols.get(oldSymbol);
251
                        if (value != null){
252

    
253
                                int intValue=value.intValue();
254
                                if (newSymbol == null) {
255
                                        // emptying
256
                                        symbols.remove(oldSymbol);
257
                                        matrix[intValue] = new int[1];
258
                                } else {
259
                                        symbols.remove(oldSymbol);
260

    
261
                                        symbols.put(newSymbol, value);
262

    
263
                                        // update matrix values if need
264
                                        int newArrayLength = newSymbol instanceof IMultiLayerSymbol ?
265
                                                        ((IMultiLayerSymbol) newSymbol).getLayerCount() : 1;
266

    
267
                                                        int[] newRow = new int[newArrayLength];
268
                                                        if (matrix[intValue].length == newArrayLength) {
269
                                                                /*
270
                                                                 * the new row is exactly the same long than the
271
                                                                 * old one. Will use the old values
272
                                                                 */
273
                                                                newRow = matrix[intValue];
274
                                                        } else        if (matrix[intValue].length < newArrayLength) {
275
                                                                /*
276
                                                                 * the new row is larger than the old one,
277
                                                                 * let's copy all the first values and fill
278
                                                                 * the rest with the last copied value
279
                                                                 */
280
                                                                int val=0;
281
                                                                for (int i = 0; i < newRow.length; i++) {
282
                                                                        if (i<matrix[intValue].length) {
283
                                                                                val = matrix[intValue][i];
284
                                                                        }
285

    
286
                                                                        newRow[i] = val;
287
                                                                }
288
                                                        } else if (matrix[intValue].length > newArrayLength) {
289
                                                                /*
290
                                                                 * the new row is smaller than the old one,
291
                                                                 * let's copy the first values
292
                                                                 */
293
                                                                for (int i = 0; i < newRow.length; i++) {
294
                                                                        newRow[i] = matrix[intValue][i];
295
                                                                }
296
                                                        }
297
                                                        matrix[intValue] = newRow;
298
                                }
299
                        }
300
                } else {
301
                        addSymbol(newSymbol);
302
                }
303
        }
304

    
305
        public boolean symbolChanged(SymbolLegendEvent e) {
306
                replaceSymbol(e.getOldSymbol(), e.getNewSymbol());
307
                return true;
308
        }
309

    
310

    
311
        public boolean classifiedSymbolChange(SymbolLegendEvent e) {
312
                replaceSymbol(e.getOldSymbol(), e.getNewSymbol());
313
                return true;
314
        }
315

    
316
        public boolean intervalChange(IntervalLegendEvent e) {
317
                return false;
318
        }
319

    
320
        public boolean valueChange(ValueLegendEvent e) {
321
                System.out.println("log ValueLegendEvent:"+e.getOldValue()+"->"+e.getNewValue());
322
                return false;
323
        }
324

    
325
        // TODO should not exist here
326
        public boolean labelFieldChange(LabelLegendEvent e) {
327
                return false;
328
        }
329

    
330

    
331
        public void legendCleared(LegendClearEvent event) {
332
//                this.usingZSort = false;
333
//                symbols.clear();
334
//                matrix = null;
335
        }
336

    
337
}