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 | } |