Statistics
| Revision:

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

History | View | Annotate | Download (8.51 KB)

1
/* 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
import com.iver.cit.gvsig.fmap.layers.LegendChangedEvent;
48
import com.iver.utiles.IPersistence;
49
import com.iver.utiles.XMLEntity;
50

    
51
/**
52
 * 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
 * 
56
 * @author jaume dominguez faus - jaume.dominguez@iver.es
57
 */
58
public class ZSort implements IPersistence, LegendContentsChangedListener {
59
        private static final String COLUMN_SEPARATOR = ",";
60
        private static final String ROW_SEPARATOR = ";";
61
        private int[][] matrix;
62
        private boolean usingZSort;
63
        private Hashtable<ISymbol, Integer> symbols = new Hashtable<ISymbol, Integer>(); 
64

    
65
        public ZSort(ILegend legend) {
66
                initialize(legend);
67
        }
68

    
69
        private void initialize(ILegend legend) {
70
                ISymbol[] symbols;
71
                if (legend instanceof IClassifiedLegend) {
72
                        symbols = ((IClassifiedLegend) legend).getSymbols();
73
                        
74
                } else {
75
                        symbols = new ISymbol[] {legend.getDefaultSymbol()};
76
                }
77
                matrix = new int[symbols.length][];
78
                
79
                for (int i = 0; i < symbols.length; i++) {
80
                        this.symbols.put(symbols[i], i);
81
                        int rowLength =  symbols[i] instanceof IMultiLayerSymbol ? 
82
                           ((IMultiLayerSymbol) symbols[i]).getLayerCount() : 
83
                         1;
84
                        matrix[i] = new int[rowLength];
85
                }
86
                legend.addLegendListener(this);
87
        }
88

    
89
        public void legendChanged(LegendChangedEvent e) {
90
                symbols.clear();
91
                usingZSort = false;
92
                initialize(e.getNewLegend());
93
                
94
        }
95

    
96
        public String getClassName() {
97
                return getClass().getName();
98
        }
99

    
100
        public XMLEntity getXMLEntity() {
101
                XMLEntity xml = new XMLEntity();
102
                xml.putProperty("className", getClassName());
103

    
104
                /* 
105
                 * ADVICE: 
106
                 * don't try to persist symbols!! 
107
                 * they are already persisted by the legend!!!
108
                 */
109
                
110
                xml.putProperty("usingZSort", isUsingZSort());
111

    
112
                
113
                String strMatrix = "";
114
                for (int i = 0; i < matrix.length; i++) {
115
                        int[] row = matrix[i];
116
                        String strRow = "";
117
                        for (int j = 0; j < row.length; j++) {
118
                                strRow += matrix[i][j] + COLUMN_SEPARATOR;
119
                        }
120
                        strMatrix += strRow + ROW_SEPARATOR;
121
                }
122
                
123
                xml.putProperty("matrix", strMatrix);
124
                return xml;
125
        }
126
        
127
        public void setXMLEntity(XMLEntity xml) {
128
                setUsingZSort(xml.getBooleanProperty("usingZSort"));
129

    
130
                /* 
131
                 * ADVICE: 
132
                 * don't try to initialize the symbols!! 
133
                 * they must be initialized by the legend!!!
134
                 */
135

    
136
                String strMatrix = xml.getStringProperty("matrix");
137
                String[] strRows = strMatrix.split(ROW_SEPARATOR);
138
                
139
                matrix = new int[strRows.length][];
140
                for (int i = 0; i < strRows.length; i++) {
141
                        String[] strColumns = strRows[i].split(COLUMN_SEPARATOR);
142
                        matrix[i] = new int[strColumns.length];
143
                        for (int j = 0; j < strColumns.length; j++) {
144
                                matrix[i][j] = Integer.parseInt(strColumns[j]);
145
                        }
146
                }
147
        }
148

    
149

    
150
        public int getLevelCount() {
151
                int count = -1;
152
                for (int i = 0; i < matrix.length; i++) {
153
                        for (int j = 0; j < matrix[i].length; j++) {
154
                                count = Math.max(count, matrix[i][j]);
155
                        }
156
                }
157
                return count + 1;
158
        }
159

    
160

    
161
        public void setUsingZSort(boolean usingZSort) {
162
                this.usingZSort = usingZSort;
163
        }
164

    
165
        public void setLevels(ISymbol sym, int[] values) {
166
                setLevels(symbols.get(sym), values);
167
        }
168

    
169

    
170
        public void setLevels(int row, int[] values) {
171
                matrix[row] = values;
172
        }
173

    
174

    
175
        public boolean isUsingZSort() {
176
                return usingZSort;
177
        }
178

    
179

    
180
        public ISymbol[] getSymbols() {
181
                return symbols.keySet().toArray(new ISymbol[0]);
182
        }
183

    
184

    
185
        public String[] getDescriptions() {
186
                ISymbol[] symbols = getSymbols();
187
                String[] descs = new String[symbols.length];
188
                for (int i = 0; i < descs.length; i++) {
189
                        descs[i] = symbols[i].getDescription();
190
                }
191
                return descs;
192
        }
193

    
194

    
195
        public int getSymbolLevel(ISymbol layer) {
196
                ISymbol[] theSymbols = getSymbols();
197
                
198
                for (int i = 0; i < theSymbols.length; i++) {
199
                        ISymbol mySymbol = theSymbols[i];
200
                        
201
                        if (mySymbol instanceof IMultiLayerSymbol) {
202
                                IMultiLayerSymbol multiSym = (IMultiLayerSymbol) mySymbol;
203
                                for (int j = 0; j < multiSym.getLayerCount(); j++) {
204
                                        ISymbol myInnerSymbol = multiSym.getLayer(j);
205
                                        if (myInnerSymbol.equals(layer)) {
206
                                                int row = symbols.get(multiSym);
207
                                                return matrix[row][j];
208
                                        }
209
                                }
210
                        } else {
211
                                if (mySymbol.equals(layer)) {
212
                                        return matrix[symbols.get(layer)][0];
213
                                }
214
                        }
215
                }
216
                
217
//                return 0;
218
                return -1;
219
        }
220
        
221
        public int getTopLevelIndexAllowed() {
222
                ISymbol[] symbols = getSymbols();
223
                int count=0;
224
                for (int i = 0; i < symbols.length; i++) {
225
                        if (symbols[i] instanceof IMultiLayerSymbol) {
226
                                IMultiLayerSymbol mSymbol = (IMultiLayerSymbol) symbols[i];
227
                                count = Math.max(count, mSymbol.getLayerCount());
228
                        } else
229
                                count = Math.max(count, 1);
230
                }
231
                return count;
232
        }
233
        
234
        @Override
235
        public String toString() {
236
                String out = "Symbols:\n---------\n\n";
237
                ISymbol[] syms = getSymbols();
238
                for (int i = 0; i < syms.length; i++) {
239
                        out += syms.getClass()+":\t"+syms[i].getDescription();
240
                }
241
                out += "\nMatrix:\n--------\n\n";
242
                out += "    \t";
243
                for (int i = 0; i < getTopLevelIndexAllowed(); i++) {
244
                        out += "column"+i+"\t\t";
245
                }
246
                out += "\n";
247
                for (int i = 0; i < matrix.length; i++) {
248
                        out += "row "+i+":\t";
249
                        for (int j = 0; j < matrix[i].length; j++) {
250
                                out += matrix[i][j]+"\t\t";
251
                        }
252
                        out += "\n";
253
                }
254
                return out;
255
        }         
256
        
257
        private void replaceSymbol(ISymbol oldSymbol, ISymbol newSymbol) {
258
                if (oldSymbol == newSymbol) return;
259
                Integer value = symbols.get(oldSymbol);
260
                
261
                if (newSymbol == null) {
262
                        // emptying
263
                        symbols.remove(oldSymbol);
264
                        matrix[value] = new int[1];
265
                } else {
266
                        symbols.remove(oldSymbol);
267
                        
268
                        symbols.put(newSymbol, value);
269

    
270
                        // update matrix values if need
271
                        int newArrayLength = newSymbol instanceof IMultiLayerSymbol ?
272
                                        ((IMultiLayerSymbol) newSymbol).getLayerCount() : 1;
273

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

    
293
                                        newRow[i] = val; 
294
                                }
295
                        } else if (matrix[value].length > newArrayLength) {
296
                                /*
297
                                 * the new row is smaller than the old one, 
298
                                 * let's copy the first values 
299
                                 */
300
                                for (int i = 0; i < newRow.length; i++) {
301
                                        newRow[i] = matrix[value][i];
302
                                }
303
                        }
304
                        matrix[value] = newRow;
305
                }
306
        }
307

    
308
        public boolean symbolChanged(SymbolLegendEvent e) {
309
                replaceSymbol(e.getOldSymbol(), e.getNewSymbol());
310
                return true;
311
        }
312

    
313

    
314
        public boolean classifiedSymbolChange(SymbolLegendEvent e) {
315
                replaceSymbol(e.getOldSymbol(), e.getNewSymbol());
316
                return true;
317
        }
318

    
319
        public boolean intervalChange(IntervalLegendEvent e) {
320
                return false;
321
        }
322

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

    
328
        // TODO should not exist here
329
        public boolean labelFieldChange(LabelLegendEvent e) {
330
                return false;
331
        }
332

    
333

    
334
        public void legendCleared(LegendClearEvent event) {
335
//                this.usingZSort = false;
336
//                symbols.clear();
337
//                matrix = null;
338
        }
339
}
340