root / trunk / extensions / extSymbology / src / org / gvsig / symbology / fmap / rendering / QuantityByCategoryLegend.java @ 29131
History | View | Annotate | Download (11.3 KB)
1 |
package org.gvsig.symbology.fmap.rendering; |
---|---|
2 |
|
3 |
import java.util.ArrayList; |
4 |
|
5 |
import org.apache.log4j.Logger; |
6 |
import org.gvsig.symbology.fmap.styles.SimpleMarkerFillPropertiesStyle; |
7 |
import org.gvsig.symbology.fmap.symbols.MarkerFillSymbol; |
8 |
|
9 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
10 |
import com.hardcode.gdbms.engine.data.DataSource; |
11 |
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException; |
12 |
import com.hardcode.gdbms.engine.values.Value; |
13 |
import com.iver.cit.gvsig.fmap.core.FShape; |
14 |
import com.iver.cit.gvsig.fmap.core.IFeature; |
15 |
import com.iver.cit.gvsig.fmap.core.SymbologyFactory; |
16 |
import com.iver.cit.gvsig.fmap.core.symbols.IFillSymbol; |
17 |
import com.iver.cit.gvsig.fmap.core.symbols.IMarkerSymbol; |
18 |
import com.iver.cit.gvsig.fmap.core.symbols.IMultiLayerSymbol; |
19 |
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol; |
20 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
21 |
import com.iver.cit.gvsig.fmap.layers.XMLException; |
22 |
import com.iver.cit.gvsig.fmap.rendering.AbstractClassifiedVectorLegend; |
23 |
import com.iver.cit.gvsig.fmap.rendering.IClassifiedVectorLegend; |
24 |
import com.iver.cit.gvsig.fmap.rendering.IInterval; |
25 |
import com.iver.cit.gvsig.fmap.rendering.ILegend; |
26 |
import com.iver.cit.gvsig.fmap.rendering.LegendFactory; |
27 |
import com.iver.cit.gvsig.fmap.rendering.SymbolLegendEvent; |
28 |
import com.iver.cit.gvsig.fmap.rendering.VectorialIntervalLegend; |
29 |
import com.iver.utiles.XMLEntity; |
30 |
/**
|
31 |
* Implements a legend where the user can compare two different characteristics
|
32 |
* of a region in the map. These two "fields" will be compared, on one side,
|
33 |
* using a color for the region and , on the other side, using a graduated symbol.
|
34 |
* Both methods will change (the color or the size of the symbol) depending on
|
35 |
* the value of the fields.
|
36 |
*
|
37 |
* @author jaume dominguez faus - jaume.dominguez@iver.es
|
38 |
*/
|
39 |
public class QuantityByCategoryLegend extends AbstractClassifiedVectorLegend implements IClassifiedVectorLegend { |
40 |
private GraduatedSymbolLegend graduatedSymbol;
|
41 |
private VectorialIntervalLegend colorRamp;
|
42 |
private ISymbol defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(FShape.POLYGON);
|
43 |
private int shapeType; |
44 |
private boolean isUseDefaultSymbol; |
45 |
private DataSource ds; |
46 |
|
47 |
public QuantityByCategoryLegend() {
|
48 |
graduatedSymbol = new GraduatedSymbolLegend();
|
49 |
colorRamp = new VectorialIntervalLegend();
|
50 |
} |
51 |
|
52 |
|
53 |
public void clear() { |
54 |
colorRamp.clear(); |
55 |
graduatedSymbol.clear(); |
56 |
} |
57 |
|
58 |
public String[] getClassifyingFieldNames() { |
59 |
ArrayList<String> l = new ArrayList<String>(); |
60 |
for (int i = 0; i < graduatedSymbol.getClassifyingFieldNames().length; i++) { |
61 |
l.add(graduatedSymbol.getClassifyingFieldNames()[i]); |
62 |
} |
63 |
|
64 |
for (int i = 0; i < colorRamp.getClassifyingFieldNames().length; i++) { |
65 |
l.add(colorRamp.getClassifyingFieldNames()[i]); |
66 |
} |
67 |
return l.toArray(new String[l.size()]); |
68 |
} |
69 |
|
70 |
|
71 |
@Override
|
72 |
public int[] getClassifyingFieldTypes() { |
73 |
return null; |
74 |
} |
75 |
|
76 |
public void setClassifyingFieldTypes(int[] fieldTypes) { |
77 |
if (fieldTypes.length!=2) { |
78 |
|
79 |
} |
80 |
colorRamp.setClassifyingFieldTypes(new int[] {fieldTypes[1]}); |
81 |
graduatedSymbol.setClassifyingFieldTypes(new int[] {fieldTypes[0]}); |
82 |
} |
83 |
|
84 |
|
85 |
/**
|
86 |
* Sets the field names required to build this legend. In this case
|
87 |
* fieldNames is an array of length 2 where the first element is
|
88 |
* the field name for the embedded GraduatedSymbolLegend, and the
|
89 |
* second is the field name for the embedded colorRamp (VectorialIntervalLegend)
|
90 |
* legend.
|
91 |
*/
|
92 |
public void setClassifyingFieldNames(String[] fieldNames) { |
93 |
|
94 |
if (fieldNames.length!=2) { |
95 |
|
96 |
} |
97 |
colorRamp.setClassifyingFieldNames(new String[] {fieldNames[1]}); |
98 |
graduatedSymbol.setClassifyingFieldNames(new String[] {fieldNames[0]}); |
99 |
} |
100 |
|
101 |
public void addSymbol(Object key, ISymbol symbol) { |
102 |
// System.out.println("adding "+key+"["+symbol+"]");
|
103 |
|
104 |
if(symbol instanceof IFillSymbol) |
105 |
colorRamp.addSymbol(key, symbol); |
106 |
else if(symbol instanceof IMarkerSymbol) |
107 |
graduatedSymbol.addSymbol(key, symbol); |
108 |
|
109 |
fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(null, symbol)); |
110 |
} |
111 |
|
112 |
public void delSymbol(Object key) { |
113 |
colorRamp.delSymbol(key); |
114 |
graduatedSymbol.delSymbol(key); |
115 |
fireClassifiedSymbolChangeEvent( |
116 |
new SymbolLegendEvent(
|
117 |
null,
|
118 |
null));
|
119 |
} |
120 |
|
121 |
public String[] getDescriptions() { |
122 |
String[] desc1 = colorRamp.getDescriptions(); |
123 |
String[] desc2 = graduatedSymbol.getDescriptions(); |
124 |
|
125 |
String[] descriptions = new String[desc1.length + desc2.length]; |
126 |
|
127 |
if(desc1.length == 0) |
128 |
return desc2;
|
129 |
else {
|
130 |
for (int i = 0; i < descriptions.length; i++) { |
131 |
descriptions[i] = (i <desc1.length) ? desc1[i] : desc2[i - desc1.length]; |
132 |
} |
133 |
return descriptions;
|
134 |
} |
135 |
} |
136 |
|
137 |
public ISymbol[] getSymbols() { |
138 |
ISymbol[] symbols1 = colorRamp.getSymbols();
|
139 |
ISymbol[] symbols2 = graduatedSymbol.getSymbols();
|
140 |
|
141 |
ISymbol[] symbols = new ISymbol[symbols1.length + symbols2.length]; |
142 |
|
143 |
if(symbols1.length == 0) |
144 |
return symbols2;
|
145 |
else {
|
146 |
for (int i = 0; i < symbols.length; i++) { |
147 |
symbols[i] = (i < symbols1.length) ? symbols1[i] : symbols2[i - symbols1.length]; |
148 |
} |
149 |
} |
150 |
return symbols;
|
151 |
} |
152 |
|
153 |
public Object[] getValues() { |
154 |
Object[] objects1 = colorRamp.getValues(); |
155 |
Object[] objects2 = graduatedSymbol.getValues(); |
156 |
|
157 |
Object[] objects = new IInterval[objects1.length + objects2.length]; |
158 |
|
159 |
if(objects1.length == 0) |
160 |
return objects2;
|
161 |
|
162 |
|
163 |
else {
|
164 |
for (int i = 0; i < objects.length; i++) { |
165 |
objects[i] = (i < objects1.length) ? objects1[i] : objects2[i - objects1.length]; |
166 |
} |
167 |
return objects;
|
168 |
} |
169 |
|
170 |
} |
171 |
|
172 |
|
173 |
|
174 |
public XMLEntity getXMLEntity() {
|
175 |
XMLEntity xml = new XMLEntity();
|
176 |
xml.putProperty("className", getClass().getName());
|
177 |
xml.putProperty("shapeType", shapeType);
|
178 |
xml.putProperty("isUseDefaultSymbol", isUseDefaultSymbol);
|
179 |
|
180 |
xml.addChild(colorRamp.getXMLEntity()); |
181 |
xml.addChild(graduatedSymbol.getXMLEntity()); |
182 |
|
183 |
return xml;
|
184 |
} |
185 |
|
186 |
public ILegend cloneLegend() throws XMLException { |
187 |
return LegendFactory.createFromXML(getXMLEntity());
|
188 |
|
189 |
} |
190 |
/**
|
191 |
* Obtains the GraduatedSymbolLegend
|
192 |
*
|
193 |
* @return GraduatedSymbolLegend
|
194 |
*/
|
195 |
public GraduatedSymbolLegend getGraduatedSymbolLegend() {
|
196 |
return graduatedSymbol;
|
197 |
} |
198 |
/**
|
199 |
* Obtains the VectorialIntervalLegend
|
200 |
*
|
201 |
* @return VectorialIntervalLegend
|
202 |
*/
|
203 |
public VectorialIntervalLegend getColorRampLegend() {
|
204 |
return colorRamp;
|
205 |
} |
206 |
|
207 |
public void setDataSource(DataSource ds) throws FieldNotFoundException, ReadDriverException { |
208 |
// TODO remove it when FLyrVect.forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD is removed
|
209 |
// if (FLyrVect.forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
|
210 |
this.ds = ds;
|
211 |
// }
|
212 |
graduatedSymbol.setDataSource(ds); |
213 |
colorRamp.setDataSource(ds); |
214 |
} |
215 |
|
216 |
public ISymbol getSymbol(int i) throws ReadDriverException { |
217 |
IMarkerSymbol sym1 = (IMarkerSymbol) graduatedSymbol.getSymbol(i); |
218 |
ISymbol sym2 = colorRamp.getSymbol(i); |
219 |
IMultiLayerSymbol multiSym = null;
|
220 |
switch (shapeType%FShape.Z) {
|
221 |
case FShape.POLYGON:
|
222 |
/*
|
223 |
* symbol from the GraduatedSymbolLegend is a marker, but
|
224 |
* what we need is a fill symbol. Will use a MarkerFillSymbol
|
225 |
* to enable support for Polygons
|
226 |
*/
|
227 |
MarkerFillSymbol aux = new MarkerFillSymbol();
|
228 |
// tell the fill style to draw the IMarkerSymbol
|
229 |
// as a IFillSymbol centering it in the shape polygon
|
230 |
// centroid and applying offset (if any).
|
231 |
aux.setMarker(sym1); |
232 |
SimpleMarkerFillPropertiesStyle p = new SimpleMarkerFillPropertiesStyle();
|
233 |
p.setFillStyle(SimpleMarkerFillPropertiesStyle.SINGLE_CENTERED_SYMBOL); |
234 |
aux.setMarkerFillProperties(p); |
235 |
|
236 |
multiSym = SymbologyFactory. |
237 |
createEmptyMultiLayerSymbol(FShape.POLYGON); |
238 |
multiSym.addLayer(sym2); |
239 |
multiSym.addLayer(aux); |
240 |
break;
|
241 |
case FShape.LINE:
|
242 |
throw new Error("Shape type not yet supported"); |
243 |
default:
|
244 |
throw new Error("Unsupported shape type"); |
245 |
|
246 |
} |
247 |
|
248 |
return multiSym;
|
249 |
} |
250 |
|
251 |
public ISymbol getSymbolByFeature(IFeature feat) {
|
252 |
ISymbol sym1 = null, sym2 = null; |
253 |
// try {
|
254 |
Value gsVal; |
255 |
// if (!FLyrVect.forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
|
256 |
// gsVal = feat.getAttribute(ds.getFieldIndexByName(getClassifyingFieldNames()[0]));
|
257 |
//
|
258 |
// } else {
|
259 |
gsVal = feat.getAttribute(0);
|
260 |
// }
|
261 |
sym1 = graduatedSymbol.getSymbolByInterval(graduatedSymbol.getInterval(gsVal)); |
262 |
|
263 |
// } catch (ReadDriverException e) {
|
264 |
// Logger.getLogger(getClass()).error("Graduated Symbol Legend failed", e);
|
265 |
// }
|
266 |
|
267 |
|
268 |
// try {
|
269 |
Value crVal; |
270 |
// if (!FLyrVect.forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
|
271 |
// crVal = feat.getAttribute(ds.getFieldIndexByName(getClassifyingFieldNames()[1]));
|
272 |
// } else {
|
273 |
crVal = feat.getAttribute(1);
|
274 |
// }
|
275 |
sym2 = colorRamp.getSymbolByInterval(colorRamp.getInterval(crVal)); |
276 |
|
277 |
// } catch (ReadDriverException e) {
|
278 |
// Logger.getLogger(getClass()).error("Color Ramp Symbol Legend failed", e);
|
279 |
// }
|
280 |
|
281 |
IMultiLayerSymbol multiSym = null;
|
282 |
switch (shapeType%FShape.Z) {
|
283 |
case FShape.POLYGON:
|
284 |
multiSym = SymbologyFactory. |
285 |
createEmptyMultiLayerSymbol(FShape.POLYGON); |
286 |
if (sym2 != null) multiSym.addLayer(sym2); |
287 |
if (sym1 != null) multiSym.addLayer(sym1); |
288 |
break;
|
289 |
case FShape.LINE:
|
290 |
throw new Error("Shape type not yet supported"); |
291 |
default:
|
292 |
throw new Error("Unsupported shape type"); |
293 |
|
294 |
} |
295 |
|
296 |
return multiSym;
|
297 |
} |
298 |
|
299 |
public int getShapeType() { |
300 |
return shapeType;
|
301 |
} |
302 |
|
303 |
public void setShapeType(int shapeType) { |
304 |
this.shapeType = shapeType;
|
305 |
graduatedSymbol.setShapeType(FShape.POINT); |
306 |
graduatedSymbol.setDefaultSymbol(SymbologyFactory.createDefaultSymbolByShapeType(FShape.POINT)); |
307 |
colorRamp.setShapeType(shapeType); |
308 |
colorRamp.setDefaultSymbol(SymbologyFactory.createDefaultSymbolByShapeType(shapeType)); |
309 |
} |
310 |
|
311 |
|
312 |
public void setXMLEntity(XMLEntity xml) { |
313 |
shapeType = xml.getIntProperty("shapeType");
|
314 |
isUseDefaultSymbol = xml.getBooleanProperty("isUseDefaultSymbol");
|
315 |
try {
|
316 |
colorRamp = (VectorialIntervalLegend) LegendFactory.createFromXML(xml.getChild(0));
|
317 |
graduatedSymbol = (GraduatedSymbolLegend) LegendFactory.createFromXML(xml.getChild(1));
|
318 |
colorRamp.setShapeType(shapeType); |
319 |
graduatedSymbol.setShapeType(shapeType); |
320 |
} catch (XMLException e) {
|
321 |
// TODO Auto-generated catch block
|
322 |
Logger.getLogger(getClass()).error(e.getFormatString());
|
323 |
} |
324 |
} |
325 |
|
326 |
public void setXMLEntity03(XMLEntity xml) { |
327 |
// nothing to do here
|
328 |
} |
329 |
|
330 |
public boolean isUseDefaultSymbol() { |
331 |
return isUseDefaultSymbol;
|
332 |
} |
333 |
|
334 |
public void useDefaultSymbol(boolean b) { |
335 |
this.isUseDefaultSymbol = b;
|
336 |
} |
337 |
|
338 |
public String[] getUsedFields() { |
339 |
// TODO Implement it
|
340 |
throw new Error("Not yet implemented!"); |
341 |
} |
342 |
|
343 |
public void setGraduateSymbolLegend(ILegend legend) { |
344 |
this.graduatedSymbol = (GraduatedSymbolLegend) legend;
|
345 |
} |
346 |
|
347 |
public void setColorRampLegend(ILegend legend) { |
348 |
this.colorRamp = (VectorialIntervalLegend) legend;
|
349 |
} |
350 |
|
351 |
public String getClassName() { |
352 |
return getClass().getName();
|
353 |
} |
354 |
|
355 |
public void replace(ISymbol oldSymbol, ISymbol newSymbol) { |
356 |
ISymbol[] symbols;
|
357 |
// look first in the graduated symbol legend
|
358 |
symbols = graduatedSymbol.getSymbols(); |
359 |
|
360 |
for (int i = 0; i < symbols.length; i++) { |
361 |
if (symbols[i].equals(oldSymbol)) {
|
362 |
graduatedSymbol.replace(oldSymbol, newSymbol); |
363 |
return;
|
364 |
} |
365 |
} |
366 |
|
367 |
// if the symbol wasn't found yet, proceed with color ramp
|
368 |
symbols = colorRamp.getSymbols(); |
369 |
|
370 |
for (int i = 0; i < symbols.length; i++) { |
371 |
if (symbols[i].equals(oldSymbol)) {
|
372 |
colorRamp.replace(oldSymbol, newSymbol); |
373 |
return;
|
374 |
} |
375 |
} |
376 |
|
377 |
} |
378 |
|
379 |
public ISymbol getDefaultSymbol() {
|
380 |
return defaultSymbol;
|
381 |
} |
382 |
|
383 |
public void setDefaultSymbol(ISymbol s) throws IllegalArgumentException { |
384 |
this.defaultSymbol = s;
|
385 |
} |
386 |
|
387 |
} |