Revision 1846 org.gvsig.legend.aggregate/trunk/org.gvsig.legend.aggregate/org.gvsig.legend.aggregate.lib/org.gvsig.legend.aggregate.lib.impl/src/main/java/org/gvsig/legend/aggregate/lib/impl/DefaultAggregateLegend.java
DefaultAggregateLegend.java | ||
---|---|---|
2 | 2 |
|
3 | 3 |
import java.awt.Color; |
4 | 4 |
import java.awt.Dimension; |
5 |
import java.awt.Font; |
|
5 | 6 |
import java.awt.FontMetrics; |
6 | 7 |
import java.awt.Graphics2D; |
7 | 8 |
import java.awt.Rectangle; |
8 |
import java.awt.Stroke; |
|
9 | 9 |
import java.awt.geom.AffineTransform; |
10 | 10 |
import java.awt.geom.Ellipse2D; |
11 |
import java.awt.geom.Point2D; |
|
12 | 11 |
import java.awt.geom.Rectangle2D; |
13 | 12 |
import java.awt.image.BufferedImage; |
14 | 13 |
import java.util.ArrayList; |
15 | 14 |
import java.util.List; |
16 | 15 |
import java.util.Map; |
16 |
import java.util.logging.Level; |
|
17 |
import javax.swing.UIManager; |
|
17 | 18 |
|
18 | 19 |
import org.cresques.cts.ICoordTrans; |
19 | 20 |
import org.slf4j.Logger; |
... | ... | |
30 | 31 |
import org.gvsig.fmap.mapcontext.MapContextException; |
31 | 32 |
import org.gvsig.fmap.mapcontext.ViewPort; |
32 | 33 |
import org.gvsig.fmap.mapcontext.rendering.legend.LegendException; |
34 |
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent; |
|
33 | 35 |
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol; |
34 |
import org.gvsig.fmap.mapcontext.rendering.symbols.ITextSymbol; |
|
35 | 36 |
import org.gvsig.fmap.mapcontext.rendering.symbols.styles.ILabelStyle; |
36 | 37 |
import org.gvsig.legend.aggregate.lib.api.AggregateLegend; |
38 |
import org.gvsig.legend.aggregate.lib.api.AggregateLegendLocator; |
|
39 |
import org.gvsig.legend.aggregate.lib.api.Operation; |
|
37 | 40 |
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.AbstractVectorialLegend; |
38 | 41 |
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.DefaultFeatureDrawnNotification; |
39 |
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.impl.SimpleTextSymbol; |
|
42 |
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.impl.SimpleFillSymbol; |
|
43 |
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.impl.SimpleLineSymbol; |
|
40 | 44 |
import org.gvsig.tools.exception.BaseException; |
41 | 45 |
import org.gvsig.tools.logger.FilteredLogger; |
42 | 46 |
import org.gvsig.tools.task.Cancellable; |
... | ... | |
47 | 51 |
|
48 | 52 |
private static class Group { |
49 | 53 |
|
50 |
private final Point pointGeo; |
|
54 |
// private final Point pointGeo; |
|
55 |
// private final Rectangle2D rectangle; |
|
56 |
private Operation op; |
|
51 | 57 |
private final Point pointPixels; |
52 |
private int count; |
|
53 |
private final Rectangle2D rectangle; |
|
54 | 58 |
private final Ellipse2D circle; |
55 | 59 |
|
56 |
public Group(Point pointGeo, Point pointPixels, double distance) { |
|
57 |
this.count = 1; |
|
58 |
this.pointGeo = pointGeo; |
|
60 |
public Group(Point pointGeo, Point pointPixels, double size, Operation op) { |
|
61 |
this.op = op; |
|
62 |
this.op.reset(); |
|
63 |
// this.pointGeo = pointGeo; |
|
59 | 64 |
this.pointPixels = pointPixels; |
60 |
double d2 = distance * 2;
|
|
61 |
this.rectangle = new Rectangle2D.Double(pointPixels.getX() - distance, pointPixels.getY() - distance, d2, d2); |
|
62 |
this.circle = new Ellipse2D.Double(pointPixels.getX() - distance, pointPixels.getY() - distance, d2, d2);
|
|
65 |
double d2 = size * 2;
|
|
66 |
// this.rectangle = new Rectangle2D.Double(pointPixels.getX() - distance, pointPixels.getY() - distance, d2, d2);
|
|
67 |
this.circle = new Ellipse2D.Double(pointPixels.getX() - size, pointPixels.getY() - size, d2, d2);
|
|
63 | 68 |
} |
64 | 69 |
|
65 | 70 |
public boolean contains(Point pointPixels) { |
... | ... | |
68 | 73 |
} |
69 | 74 |
|
70 | 75 |
public void add(Feature feature) { |
71 |
this.count++;
|
|
76 |
op.perform(feature);
|
|
72 | 77 |
} |
78 |
|
|
79 |
public Operation getOperation() { |
|
80 |
return this.op; |
|
81 |
} |
|
73 | 82 |
} |
74 | 83 |
|
75 | 84 |
private static final Logger LOG = LoggerFactory.getLogger(DefaultAggregateLegend.class); |
76 | 85 |
|
77 |
private int distance; // Pixels |
|
78 | 86 |
private List<Group> groups; |
79 |
private ITextSymbol textSymbol; |
|
87 |
|
|
88 |
private int symbolSize; // Pixels |
|
89 |
private Color fillColor; |
|
90 |
private Color outlineColor; |
|
91 |
private Color textColor; |
|
92 |
private boolean showBounds; |
|
93 |
private Font font; |
|
94 |
|
|
95 |
private boolean useStyle; |
|
80 | 96 |
private ILabelStyle labelStyle; |
97 |
|
|
98 |
private Operation operation; |
|
99 |
|
|
100 |
private SimpleFillSymbol defaultSymbol; |
|
81 | 101 |
|
82 | 102 |
public DefaultAggregateLegend() { |
83 |
this.textSymbol = new SimpleTextSymbol(); |
|
84 |
this.labelStyle = null; |
|
85 | 103 |
this.groups = null; |
86 |
this.distance = 30; |
|
104 |
|
|
105 |
this.useStyle = false; |
|
106 |
this.symbolSize = 30; |
|
107 |
this.fillColor = new Color(0xd0ffcccc, true); // Un rojo |
|
108 |
this.outlineColor = new Color(0xff5f60de, true); // un azul |
|
109 |
this.textColor = new Color(0xff000000, true); // negro |
|
110 |
this.showBounds = false; |
|
111 |
this.labelStyle = null; |
|
112 |
this.font = UIManager.getFont("Label.font"); |
|
113 |
this.operation = AggregateLegendLocator.getAggregateLegendManager().getDefaultOperation().clone(); |
|
114 |
this.defaultSymbol = new SimpleFillSymbol(); |
|
115 |
this.defaultSymbol.setOutline(new SimpleLineSymbol()); |
|
116 |
this.defaultSymbol.getOutline().setLineColor(this.outlineColor); |
|
117 |
this.defaultSymbol.setFillColor(this.fillColor); |
|
118 |
|
|
87 | 119 |
} |
88 | 120 |
|
89 | 121 |
@Override |
90 | 122 |
protected String[] getRequiredFeatureAttributeNames(FeatureStore featureStore) throws DataException { |
123 |
if( this.operation.isAttributeRequiered() && this.operation.getAttributeName()!=null ) { |
|
124 |
return new String[]{ |
|
125 |
this.operation.getAttributeName(), |
|
126 |
featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName() |
|
127 |
}; |
|
128 |
} |
|
91 | 129 |
return new String[]{ |
92 |
featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()}; |
|
130 |
featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName() |
|
131 |
}; |
|
93 | 132 |
} |
94 | 133 |
|
95 | 134 |
@Override |
96 | 135 |
public ISymbol getDefaultSymbol() { |
97 |
return this.textSymbol;
|
|
136 |
return this.defaultSymbol;
|
|
98 | 137 |
} |
99 | 138 |
|
100 | 139 |
@Override |
... | ... | |
103 | 142 |
|
104 | 143 |
@Override |
105 | 144 |
public ISymbol getSymbolByFeature(Feature ftr) throws MapContextException { |
106 |
return this.textSymbol;
|
|
145 |
return this.getDefaultSymbol();
|
|
107 | 146 |
} |
108 | 147 |
|
109 | 148 |
@Override |
... | ... | |
132 | 171 |
@Override |
133 | 172 |
protected void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, Map queryParameters, ICoordTrans coordTrans, FeatureStore featureStore, FeatureQuery featureQuery, double dpi) throws LegendException { |
134 | 173 |
super.draw(image, g, viewPort, cancel, scale, queryParameters, coordTrans, featureStore, featureQuery, dpi); |
135 |
this.drawMarkers(image, g, cancel, viewPort.getAffineTransform());
|
|
174 |
this.drawGroups(image, g, cancel, viewPort.getAffineTransform());
|
|
136 | 175 |
} |
137 | 176 |
|
138 | 177 |
@Override |
... | ... | |
172 | 211 |
} |
173 | 212 |
} |
174 | 213 |
if( !inGroup ) { |
175 |
groups.add(new Group(pointGeo, pointPixels, getDistance()));
|
|
214 |
groups.add(new Group(pointGeo, pointPixels, getSymbolSize(), getOperation().clone()));
|
|
176 | 215 |
} |
177 | 216 |
} |
178 | 217 |
} |
179 | 218 |
}); |
180 | 219 |
} |
181 | 220 |
|
182 |
private void drawMarkers(BufferedImage image, Graphics2D g1, Cancellable cancel, AffineTransform affineTransform) {
|
|
221 |
private void drawGroups(BufferedImage image, Graphics2D g, Cancellable cancel, AffineTransform affineTransform) {
|
|
183 | 222 |
FilteredLogger logger = new FilteredLogger(LOG, "", 10); |
184 | 223 |
AffineTransform identity = new AffineTransform(); |
185 |
Stroke stroke = g1.getStroke(); |
|
186 |
Color circlebg = new Color(0x80e29ea8, true); |
|
224 |
|
|
225 |
g.setFont(this.font); |
|
226 |
FontMetrics fm = g.getFontMetrics(); |
|
227 |
int fontAscent = fm.getAscent(); |
|
228 |
int fontAscentAddDescentDiv2 = ((fm.getAscent() + fm.getDescent())) / 2; |
|
229 |
|
|
187 | 230 |
for( Group group : groups ) { |
188 | 231 |
if( cancel.isCanceled() ) { |
189 | 232 |
return; |
190 | 233 |
} |
191 |
final Graphics2D g = (Graphics2D)g1.create(); |
|
192 | 234 |
try { |
193 | 235 |
int x = (int) group.pointPixels.getX(); |
194 | 236 |
int y = (int) group.pointPixels.getY(); |
195 |
this.textSymbol.setDrawWithHalo(false); |
|
196 |
String txt = String.valueOf(group.count); |
|
197 |
this.textSymbol.setText(txt); |
|
198 |
if( this.labelStyle != null ) { |
|
237 |
String txt = group.getOperation().format(); |
|
238 |
if( this.useStyle && this.labelStyle != null ) { |
|
199 | 239 |
Dimension size = this.labelStyle.getSize(); |
200 |
this.labelStyle.setTextFields(new String[]{ |
|
201 |
txt} |
|
202 |
); |
|
240 |
this.labelStyle.setTextFields(new String[]{txt}); |
|
203 | 241 |
g.setTransform(identity); |
204 | 242 |
g.translate(x-size.getWidth()/2, y-size.getHeight()/2); |
205 |
Point2D markerPoint = this.labelStyle.getMarkerPoint(); |
|
206 | 243 |
Rectangle rect = new Rectangle( |
207 | 244 |
0, |
208 | 245 |
0, |
... | ... | |
218 | 255 |
bound.getWidth()*size.getWidth(), |
219 | 256 |
bound.getHeight()*size.getHeight()); |
220 | 257 |
drawCenteredString(txt, expandedBound, g); |
221 |
|
|
222 | 258 |
} |
223 | 259 |
g.translate(-(x-size.getWidth()/2), -(y-size.getHeight()/2)); |
224 | 260 |
} else { |
225 |
int r = distance; //2; |
|
226 |
g.setStroke(stroke); |
|
227 |
g.setColor(circlebg); |
|
261 |
int r = symbolSize/2; |
|
262 |
g.setColor(this.fillColor); |
|
228 | 263 |
g.fillOval( x-r, y-r, 2*r, 2*r); |
229 |
g.setColor(Color.BLACK);
|
|
264 |
g.setColor(this.outlineColor);
|
|
230 | 265 |
g.drawOval( x-r, y-r, 2*r, 2*r); |
231 |
g.drawRect( x-r, y-r, 2*r, 2*r); |
|
232 |
FontMetrics fm = g.getFontMetrics(); |
|
266 |
if( this.showBounds ) { |
|
267 |
g.drawRect( x-r, y-r, 2*r, 2*r); |
|
268 |
} |
|
269 |
g.setColor(this.textColor); |
|
233 | 270 |
int txtX = x - (fm.stringWidth(txt) / 2); |
234 |
int txtY = fm.getAscent() + y - ((fm.getAscent() + fm.getDescent())) / 2; |
|
235 |
|
|
271 |
int txtY = fontAscent + y - fontAscentAddDescentDiv2; //((fm.getAscent() + fm.getDescent())) / 2; |
|
236 | 272 |
g.drawString(txt, txtX, txtY); |
237 | 273 |
} |
238 | 274 |
} catch (Exception ex) { |
239 | 275 |
logger.warn("Can't draw group",ex); |
240 |
} finally { |
|
241 |
g.dispose(); |
|
242 | 276 |
} |
243 | 277 |
} |
244 | 278 |
} |
... | ... | |
258 | 292 |
} |
259 | 293 |
|
260 | 294 |
@Override |
261 |
public int getDistance() {
|
|
262 |
return distance;
|
|
295 |
public ILabelStyle getLabelStyle() {
|
|
296 |
return this.labelStyle;
|
|
263 | 297 |
} |
264 | 298 |
|
265 | 299 |
@Override |
266 |
public void setDistance(int distance) {
|
|
267 |
this.distance = distance;
|
|
300 |
public void setLabelStyle(ILabelStyle labelStyle) {
|
|
301 |
this.labelStyle = labelStyle;
|
|
268 | 302 |
} |
269 | 303 |
|
270 | 304 |
@Override |
271 |
public ILabelStyle getLabelStyle() {
|
|
272 |
return this.labelStyle;
|
|
305 |
public int getSymbolSize() {
|
|
306 |
return this.symbolSize;
|
|
273 | 307 |
} |
274 | 308 |
|
275 | 309 |
@Override |
276 |
public void setLabelStyle(ILabelStyle labelStyle) { |
|
277 |
this.labelStyle = labelStyle; |
|
310 |
public void setSymbolSize(int simbolSize) { |
|
311 |
boolean changed = (this.symbolSize == simbolSize); |
|
312 |
this.symbolSize = simbolSize; |
|
313 |
if( changed ) { |
|
314 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
315 |
} |
|
278 | 316 |
} |
279 | 317 |
|
280 | 318 |
@Override |
281 |
public ITextSymbol getTextSymbol() {
|
|
282 |
return this.textSymbol;
|
|
319 |
public Operation getOperation() {
|
|
320 |
return this.operation;
|
|
283 | 321 |
} |
322 |
|
|
323 |
@Override |
|
324 |
public void setOperation(Operation operation) { |
|
325 |
boolean changed = (this.operation.getName().equalsIgnoreCase(operation.getName())); |
|
326 |
this.operation = operation; |
|
327 |
if( changed ) { |
|
328 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
329 |
} |
|
330 |
} |
|
284 | 331 |
|
285 | 332 |
@Override |
286 |
public void setTextSymbol(ITextSymbol textSymbol) {
|
|
287 |
this.textSymbol = textSymbol;
|
|
333 |
public Color getFillColor() {
|
|
334 |
return fillColor;
|
|
288 | 335 |
} |
289 | 336 |
|
337 |
@Override |
|
338 |
public void setFillColor(Color fillColor) { |
|
339 |
boolean changed = (this.fillColor.equals(fillColor)); |
|
340 |
this.fillColor = fillColor; |
|
341 |
this.defaultSymbol.setFillColor(this.fillColor); |
|
342 |
if( changed ) { |
|
343 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
344 |
} |
|
345 |
} |
|
346 |
|
|
347 |
@Override |
|
348 |
public Color getOutlineColor() { |
|
349 |
return outlineColor; |
|
350 |
} |
|
351 |
|
|
352 |
@Override |
|
353 |
public void setOutlineColor(Color outlineColor) { |
|
354 |
boolean changed = (this.outlineColor.equals(outlineColor)); |
|
355 |
this.outlineColor = outlineColor; |
|
356 |
this.defaultSymbol.getOutline().setLineColor(this.outlineColor); |
|
357 |
if( changed ) { |
|
358 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
359 |
} |
|
360 |
} |
|
361 |
|
|
362 |
@Override |
|
363 |
public boolean isShowBounds() { |
|
364 |
return showBounds; |
|
365 |
} |
|
366 |
|
|
367 |
@Override |
|
368 |
public void setShowBounds(boolean showBounds) { |
|
369 |
boolean changed = (this.showBounds == showBounds); |
|
370 |
this.showBounds = showBounds; |
|
371 |
if( changed ) { |
|
372 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
373 |
} |
|
374 |
} |
|
375 |
|
|
376 |
@Override |
|
377 |
public Font getFont() { |
|
378 |
return font; |
|
379 |
} |
|
380 |
|
|
381 |
@Override |
|
382 |
public void setFont(Font font) { |
|
383 |
this.font = font; |
|
384 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
385 |
} |
|
386 |
|
|
387 |
@Override |
|
388 |
public boolean isUseStyle() { |
|
389 |
return useStyle; |
|
390 |
} |
|
391 |
|
|
392 |
@Override |
|
393 |
public void setUseStyle(boolean useStyle) { |
|
394 |
boolean changed = (this.useStyle == useStyle); |
|
395 |
this.useStyle = useStyle; |
|
396 |
if( changed ) { |
|
397 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
398 |
} |
|
399 |
} |
|
400 |
|
|
401 |
@Override |
|
402 |
public Color getTextColor() { |
|
403 |
return this.textColor; |
|
404 |
} |
|
405 |
|
|
406 |
@Override |
|
407 |
public void setTextColor(Color textColor) { |
|
408 |
boolean changed = (this.textColor.equals(textColor)); |
|
409 |
this.textColor = textColor; |
|
410 |
if( changed ) { |
|
411 |
this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null,null)); |
|
412 |
} |
|
413 |
} |
|
290 | 414 |
} |
Also available in: Unified diff