Statistics
| Revision:

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

History | View | Annotate | Download (8.47 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
        }
87

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

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

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

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

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

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

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

    
148

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

    
159

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

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

    
168

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

    
173

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

    
178

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

    
183

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

    
193

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

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

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

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

    
307
        public boolean symbolChanged(SymbolLegendEvent e) {
308
                replaceSymbol(e.getOldValue(), e.getNewValue());
309
                return true;
310
        }
311

    
312

    
313
        public boolean classifiedSymbolChange(SymbolLegendEvent e) {
314
                replaceSymbol(e.getOldValue(), e.getNewValue());
315
                return true;
316
        }
317

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

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

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

    
332

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