Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / ZSort.java @ 38563

History | View | Annotate | Download (10.5 KB)

1 11741 jaume
/* 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 com.iver.cit.gvsig.fmap.rendering;
42
43
import java.util.Hashtable;
44
45
import com.iver.cit.gvsig.fmap.core.symbols.IMultiLayerSymbol;
46
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
47 18621 jdominguez
import com.iver.cit.gvsig.fmap.layers.LegendChangedEvent;
48 13913 jaume
import com.iver.utiles.IPersistence;
49 12786 jaume
import com.iver.utiles.XMLEntity;
50 11741 jaume
51
/**
52 13913 jaume
 * Class ZSort is used in order to store information about the symbols
53
 * which are placed in the Z axis (because a level of symbols has been
54
 * used).
55 25107 vcaballero
 *
56 11741 jaume
 * @author jaume dominguez faus - jaume.dominguez@iver.es
57
 */
58 18621 jdominguez
public class ZSort implements IPersistence, LegendContentsChangedListener {
59 13953 jaume
        private static final String COLUMN_SEPARATOR = ",";
60
        private static final String ROW_SEPARATOR = ";";
61 13927 jaume
        private int[][] matrix;
62
        private boolean usingZSort;
63 25107 vcaballero
        private Hashtable<ISymbol, Integer> symbols = new Hashtable<ISymbol, Integer>();
64 11741 jaume
65 13927 jaume
        public ZSort(ILegend legend) {
66 18621 jdominguez
                initialize(legend);
67
        }
68
69
        private void initialize(ILegend legend) {
70 13927 jaume
                ISymbol[] symbols;
71
                if (legend instanceof IClassifiedLegend) {
72
                        symbols = ((IClassifiedLegend) legend).getSymbols();
73 25107 vcaballero
74 13927 jaume
                } else {
75
                        symbols = new ISymbol[] {legend.getDefaultSymbol()};
76
                }
77
                matrix = new int[symbols.length][];
78 25107 vcaballero
79 13927 jaume
                for (int i = 0; i < symbols.length; i++) {
80
                        this.symbols.put(symbols[i], i);
81 25107 vcaballero
                        int rowLength =  symbols[i] instanceof IMultiLayerSymbol ?
82
                           ((IMultiLayerSymbol) symbols[i]).getLayerCount() :
83 14161 jdominguez
                         1;
84
                        matrix[i] = new int[rowLength];
85 13927 jaume
                }
86 22465 vcaballero
                legend.addLegendListener(this);
87 13927 jaume
        }
88 11741 jaume
89 26364 vcaballero
        private void addSymbol(ISymbol sym){
90
                if(!symbols.contains(sym)){
91
                        int rowLength =  sym instanceof IMultiLayerSymbol ?
92
                                        ((IMultiLayerSymbol) sym).getLayerCount() : 1;
93
                        int[][] auxMatrix = new int[matrix.length+1][];
94
                        int newIndex = matrix.length;
95
                        for (int i=0; i<newIndex; i++){
96
                                auxMatrix[i] = matrix[i];
97
                        }
98
                        int[] row = new int[rowLength];
99
                        for (int i=0; i<rowLength; i++){
100
                                row[i] = 0;
101
                        }
102
                        auxMatrix[newIndex] = row;
103
                        matrix = auxMatrix;
104
                        this.symbols.put(sym, newIndex);
105
                }
106
        }
107
108 18621 jdominguez
        public void legendChanged(LegendChangedEvent e) {
109
                symbols.clear();
110
                usingZSort = false;
111
                initialize(e.getNewLegend());
112 25107 vcaballero
113 18621 jdominguez
        }
114 11741 jaume
115 13927 jaume
        public String getClassName() {
116
                return getClass().getName();
117
        }
118 11741 jaume
119 13927 jaume
        public XMLEntity getXMLEntity() {
120 13953 jaume
                XMLEntity xml = new XMLEntity();
121
                xml.putProperty("className", getClassName());
122
123 25107 vcaballero
                /*
124
                 * ADVICE:
125
                 * don't try to persist symbols!!
126 13953 jaume
                 * they are already persisted by the legend!!!
127
                 */
128 25107 vcaballero
129 13953 jaume
                xml.putProperty("usingZSort", isUsingZSort());
130
131 25107 vcaballero
132 13953 jaume
                String strMatrix = "";
133
                for (int i = 0; i < matrix.length; i++) {
134
                        int[] row = matrix[i];
135
                        String strRow = "";
136
                        for (int j = 0; j < row.length; j++) {
137
                                strRow += matrix[i][j] + COLUMN_SEPARATOR;
138
                        }
139
                        strMatrix += strRow + ROW_SEPARATOR;
140
                }
141 25107 vcaballero
142 13953 jaume
                xml.putProperty("matrix", strMatrix);
143
                return xml;
144 13927 jaume
        }
145 25107 vcaballero
146 13927 jaume
        public void setXMLEntity(XMLEntity xml) {
147 13953 jaume
                setUsingZSort(xml.getBooleanProperty("usingZSort"));
148
149 25107 vcaballero
                /*
150
                 * ADVICE:
151
                 * don't try to initialize the symbols!!
152 13953 jaume
                 * they must be initialized by the legend!!!
153
                 */
154
155
                String strMatrix = xml.getStringProperty("matrix");
156
                String[] strRows = strMatrix.split(ROW_SEPARATOR);
157 25107 vcaballero
158 13953 jaume
                matrix = new int[strRows.length][];
159
                for (int i = 0; i < strRows.length; i++) {
160
                        String[] strColumns = strRows[i].split(COLUMN_SEPARATOR);
161
                        matrix[i] = new int[strColumns.length];
162
                        for (int j = 0; j < strColumns.length; j++) {
163
                                matrix[i][j] = Integer.parseInt(strColumns[j]);
164
                        }
165
                }
166 13927 jaume
        }
167 11741 jaume
168
169 13927 jaume
        public int getLevelCount() {
170
                int count = -1;
171
                for (int i = 0; i < matrix.length; i++) {
172
                        for (int j = 0; j < matrix[i].length; j++) {
173
                                count = Math.max(count, matrix[i][j]);
174
                        }
175
                }
176
                return count + 1;
177
        }
178 11741 jaume
179
180 13927 jaume
        public void setUsingZSort(boolean usingZSort) {
181
                this.usingZSort = usingZSort;
182
        }
183 11741 jaume
184 13927 jaume
        public void setLevels(ISymbol sym, int[] values) {
185
                setLevels(symbols.get(sym), values);
186
        }
187 11741 jaume
188
189 13927 jaume
        public void setLevels(int row, int[] values) {
190
                matrix[row] = values;
191
        }
192 11741 jaume
193 26364 vcaballero
        public int[] getLevels(ISymbol sym) {
194
                Integer row = symbols.get(sym);
195
                if (row != null) {
196
                        return getLevels(row);
197
                } else {
198
                        ISymbol[] theSymbols = getSymbols();
199
                        for (int i = 0; i < theSymbols.length; i++) {
200
                                ISymbol auxSymbol = theSymbols[i];
201
                                if (auxSymbol.equals(sym)){
202
                                        return getLevels(symbols.get(auxSymbol));
203
                                }
204
                        }
205
                }
206
                return null;
207
        }
208 11808 jaume
209 26364 vcaballero
210
        public int[] getLevels(int row) {
211
                return matrix[row];
212
        }
213
214
215 13927 jaume
        public boolean isUsingZSort() {
216
                return usingZSort;
217
        }
218 11808 jaume
219 11741 jaume
220 13927 jaume
        public ISymbol[] getSymbols() {
221
                return symbols.keySet().toArray(new ISymbol[0]);
222
        }
223 11808 jaume
224
225 13927 jaume
        public String[] getDescriptions() {
226
                ISymbol[] symbols = getSymbols();
227
                String[] descs = new String[symbols.length];
228
                for (int i = 0; i < descs.length; i++) {
229
                        descs[i] = symbols[i].getDescription();
230
                }
231
                return descs;
232
        }
233 30082 vcaballero
234
        public void copyLevels(ZSort zsort) {
235
                ISymbol[] syms = zsort.getSymbols();
236
                for (int i=0; i<syms.length; i++){
237
                        ISymbol sym = syms[i];
238
                        int[] levels = zsort.getLevels(sym);
239
                        if (levels!=null){
240
                                ISymbol[] mySymbols = getSymbols();
241
                                for (int j = 0; j < mySymbols.length; j++) {
242
                                        ISymbol auxSymbol = mySymbols[j];
243
                                        if (auxSymbol.equals(sym)){
244
                                                setLevels(auxSymbol, levels);
245
                                        }
246
                                }
247
                        }
248
                }
249
        }
250 11808 jaume
251 11741 jaume
252 26364 vcaballero
        /*
253
         * [PACO] Comentarizado porque no hace lo que se esperar?a de ?l.
254
         * Si tenemos una leyenda con un simbolo Multilayer compuesto
255
         * por, entre otros, un simbolo simple que coincide con otro de
256
         * los simbolos de la leyenda, este metodo devuelve el nivel
257
         * del s?mbolo que encuentra primero.
258
         *
259
         * Se ha eliminado cualquier referencia a este metodo en el resto
260
         * del workspace, sustituyendola convenientemente por
261
         * referencias a getLevels.
262
         */
263
//        public int getSymbolLevel(ISymbol layer) {
264
//                ISymbol[] theSymbols = getSymbols();
265
//
266
//                for (int i = 0; i < theSymbols.length; i++) {
267
//                        ISymbol mySymbol = theSymbols[i];
268
//
269
//                        if (mySymbol instanceof IMultiLayerSymbol) {
270
//                                IMultiLayerSymbol multiSym = (IMultiLayerSymbol) mySymbol;
271
//                                for (int j = 0; j < multiSym.getLayerCount(); j++) {
272
//                                        ISymbol myInnerSymbol = multiSym.getLayer(j);
273
//                                        if (myInnerSymbol.equals(layer)) {
274
//                                                int row = symbols.get(multiSym);
275
//                                                return matrix[row][j];
276
//                                        }
277
//                                }
278
//                        } else {
279
//                                if (mySymbol.equals(layer)){
280
//                                        return matrix[symbols.get(mySymbol)][0];
281
//                                }
282
//                        }
283
//                }
284
//
285
////                return 0;
286
//                return -1;
287
//        }
288 25107 vcaballero
289
290 13927 jaume
        public int getTopLevelIndexAllowed() {
291
                ISymbol[] symbols = getSymbols();
292
                int count=0;
293
                for (int i = 0; i < symbols.length; i++) {
294
                        if (symbols[i] instanceof IMultiLayerSymbol) {
295
                                IMultiLayerSymbol mSymbol = (IMultiLayerSymbol) symbols[i];
296
                                count = Math.max(count, mSymbol.getLayerCount());
297
                        } else
298
                                count = Math.max(count, 1);
299
                }
300
                return count;
301
        }
302 25107 vcaballero
303 13927 jaume
        @Override
304
        public String toString() {
305
                String out = "Symbols:\n---------\n\n";
306
                ISymbol[] syms = getSymbols();
307
                for (int i = 0; i < syms.length; i++) {
308
                        out += syms.getClass()+":\t"+syms[i].getDescription();
309
                }
310
                out += "\nMatrix:\n--------\n\n";
311
                out += "    \t";
312
                for (int i = 0; i < getTopLevelIndexAllowed(); i++) {
313
                        out += "column"+i+"\t\t";
314
                }
315
                out += "\n";
316
                for (int i = 0; i < matrix.length; i++) {
317
                        out += "row "+i+":\t";
318
                        for (int j = 0; j < matrix[i].length; j++) {
319
                                out += matrix[i][j]+"\t\t";
320
                        }
321
                        out += "\n";
322
                }
323
                return out;
324 25107 vcaballero
        }
325
326 14202 jvidal
        private void replaceSymbol(ISymbol oldSymbol, ISymbol newSymbol) {
327 14234 jdominguez
                if (oldSymbol == newSymbol) return;
328 25107 vcaballero
329 26364 vcaballero
                if(oldSymbol != null){
330
                        Integer value = symbols.get(oldSymbol);
331
                        if (value != null){
332
                                if (newSymbol == null) {
333
                                        // emptying
334
                                        symbols.remove(oldSymbol);
335
                                        matrix[value] = new int[1];
336
                                } else {
337
                                        symbols.remove(oldSymbol);
338 25107 vcaballero
339 26364 vcaballero
                                        symbols.put(newSymbol, value);
340 14202 jvidal
341 26364 vcaballero
                                        // update matrix values if need
342
                                        int newArrayLength = newSymbol instanceof IMultiLayerSymbol ?
343
                                                        ((IMultiLayerSymbol) newSymbol).getLayerCount() : 1;
344 14277 jdominguez
345 26364 vcaballero
                                                        int[] newRow = new int[newArrayLength];
346
                                                        if (matrix[value].length == newArrayLength) {
347
                                                                /*
348
                                                                 * the new row is exactly the same long than the
349
                                                                 * old one. Will use the old values
350
                                                                 */
351
                                                                newRow = matrix[value];
352
                                                        } else        if (matrix[value].length < newArrayLength) {
353
                                                                /*
354
                                                                 * the new row is larger than the old one,
355
                                                                 * let's copy all the first values and fill
356
                                                                 * the rest with the last copied value
357
                                                                 */
358
                                                                int val=0;
359
                                                                for (int i = 0; i < newRow.length; i++) {
360
                                                                        if (i<matrix[value].length) {
361
                                                                                val = matrix[value][i];
362
                                                                        }
363 14277 jdominguez
364 26364 vcaballero
                                                                        newRow[i] = val;
365
                                                                }
366
                                                        } else if (matrix[value].length > newArrayLength) {
367
                                                                /*
368
                                                                 * the new row is smaller than the old one,
369
                                                                 * let's copy the first values
370
                                                                 */
371
                                                                for (int i = 0; i < newRow.length; i++) {
372
                                                                        newRow[i] = matrix[value][i];
373
                                                                }
374
                                                        }
375
                                                        matrix[value] = newRow;
376 14277 jdominguez
                                }
377
                        }
378 26364 vcaballero
                } else {
379
                        addSymbol(newSymbol);
380 14234 jdominguez
                }
381 14202 jvidal
        }
382
383 18621 jdominguez
        public boolean symbolChanged(SymbolLegendEvent e) {
384 20778 vcaballero
                replaceSymbol(e.getOldSymbol(), e.getNewSymbol());
385 14202 jvidal
                return true;
386
        }
387
388
389
        public boolean classifiedSymbolChange(SymbolLegendEvent e) {
390 20778 vcaballero
                replaceSymbol(e.getOldSymbol(), e.getNewSymbol());
391 14202 jvidal
                return true;
392
        }
393
394
        public boolean intervalChange(IntervalLegendEvent e) {
395
                return false;
396
        }
397
398
        public boolean valueChange(ValueLegendEvent e) {
399
                return false;
400
        }
401
402
        // TODO should not exist here
403
        public boolean labelFieldChange(LabelLegendEvent e) {
404
                return false;
405
        }
406
407
408 18621 jdominguez
        public void legendCleared(LegendClearEvent event) {
409 14202 jvidal
//                this.usingZSort = false;
410
//                symbols.clear();
411
//                matrix = null;
412
        }
413 11741 jaume
}