/[schmitzm]/trunk/src/skrueger/geotools/LegendIconFeatureRenderer.java
ViewVC logotype

Annotation of /trunk/src/skrueger/geotools/LegendIconFeatureRenderer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1223 - (hide annotations)
Wed Nov 3 15:44:54 2010 UTC (14 years, 3 months ago) by alfonx
File size: 13760 byte(s)
added debug statements
1 alfonx 244 /*******************************************************************************
2     * Copyright (c) 2009 Martin O. J. Schmitz.
3     *
4     * This file is part of the SCHMITZM library - a collection of utility
5 alfonx 256 * classes based on Java 1.6, focusing (not only) on Java Swing
6 alfonx 244 * and the Geotools library.
7     *
8     * The SCHMITZM project is hosted at:
9     * http://wald.intevation.org/projects/schmitzm/
10     *
11     * This program is free software; you can redistribute it and/or
12     * modify it under the terms of the GNU Lesser General Public License
13     * as published by the Free Software Foundation; either version 3
14     * of the License, or (at your option) any later version.
15     *
16     * This program is distributed in the hope that it will be useful,
17     * but WITHOUT ANY WARRANTY; without even the implied warranty of
18     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19     * GNU General Public License for more details.
20     *
21     * You should have received a copy of the GNU Lesser General Public License (license.txt)
22     * along with this program; if not, write to the Free Software
23     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24     * or try this link: http://www.gnu.org/licenses/lgpl.html
25     *
26     * Contributors:
27     * Martin O. J. Schmitz - initial API and implementation
28 alfonx 862 * Stefan A. Tzeggai - additional utility classes
29 alfonx 244 ******************************************************************************/
30 alfonx 154 /**
31 alfonx 862 Copyright 2008 Stefan Alfons Tzeggai and parts from some Geotools code
32 alfonx 1223
33 alfonx 154 atlas-framework - This file is part of the Atlas Framework
34    
35     This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
36     This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
37     You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
38    
39     Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
40     Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
41     Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
42     **/
43     package skrueger.geotools;
44    
45     import java.awt.Color;
46     import java.awt.Dimension;
47     import java.awt.Graphics2D;
48     import java.awt.RenderingHints;
49     import java.awt.image.BufferedImage;
50    
51     import javax.swing.tree.DefaultTreeCellRenderer;
52    
53     import org.apache.log4j.Logger;
54     import org.geotools.factory.GeoTools;
55     import org.geotools.factory.Hints;
56     import org.geotools.feature.IllegalAttributeException;
57     import org.geotools.geometry.jts.LiteShape2;
58     import org.geotools.renderer.lite.StyledShapePainter;
59     import org.geotools.renderer.style.SLDStyleFactory;
60     import org.geotools.renderer.style.Style2D;
61     import org.geotools.styling.LineSymbolizer;
62     import org.geotools.styling.PointSymbolizer;
63     import org.geotools.styling.PolygonSymbolizer;
64     import org.geotools.styling.RasterSymbolizer;
65     import org.geotools.styling.Rule;
66     import org.geotools.styling.Style;
67     import org.geotools.styling.Symbolizer;
68     import org.geotools.styling.TextSymbolizer;
69     import org.geotools.util.NumberRange;
70 mojays 325 import org.opengis.feature.simple.SimpleFeature;
71     import org.opengis.feature.simple.SimpleFeatureType;
72 alfonx 332 import org.opengis.feature.type.AttributeDescriptor;
73 alfonx 154
74     import schmitzm.geotools.feature.FeatureUtil;
75    
76     import com.vividsolutions.jts.geom.Coordinate;
77     import com.vividsolutions.jts.geom.GeometryFactory;
78     import com.vividsolutions.jts.geom.LineString;
79     import com.vividsolutions.jts.geom.LinearRing;
80     import com.vividsolutions.jts.geom.Polygon;
81    
82     /**
83     * Based on geoserver!
84     * <hr>
85     * <b>Changes by <a href="mailto:[email protected]">Martin Schmitz</a></b>
86     * <br>
87     * <ul>
88     * <li>07.02.2008:<br>
89 alfonx 318 * Determining the default values of a {@link SimpleFeatureType} by
90 alfonx 1223 * {@link FeatureUtil#getDefaultAttributeValues(SimpleFeatureType)} instead of
91     * using {@link AttributeDescriptor#createDefaultValue()} directly, because the
92     * latter returns {@code null} even though the attribut is not nillable.</li>
93 alfonx 154 * </ul>
94     *
95 alfonx 862 * @author Stefan Alfons Tzeggai
96 alfonx 154 */
97     public class LegendIconFeatureRenderer extends DefaultTreeCellRenderer {
98 alfonx 1223 // private static final Dimension SIZE = new Dimension(30,20);
99 alfonx 154
100     Logger LOGGER = Logger.getLogger(LegendIconFeatureRenderer.class);
101    
102     /**
103     * This is a static class
104     */
105     private LegendIconFeatureRenderer() {
106     }
107    
108     final static LegendIconFeatureRenderer instance = new LegendIconFeatureRenderer();
109    
110     public static LegendIconFeatureRenderer getInstance() {
111     // In GT 2.4.5 it we have to create a new one all the time!
112 alfonx 1223
113 alfonx 377 // TODO TEST, whether we still need to recreate the renderer here....
114 alfonx 452 // TODO TEST, whether we still need to recreate the renderer here....
115     // TODO TEST, whether we still need to recreate the renderer here....
116     // TODO TEST, whether we still need to recreate the renderer here....
117     // TODO TEST, whether we still need to recreate the renderer here....
118     // TODO TEST, whether we still need to recreate the renderer here....
119     // TODO TEST, whether we still need to recreate the renderer here....
120     // TODO TEST, whether we still need to recreate the renderer here....
121 alfonx 154 return new LegendIconFeatureRenderer();
122 alfonx 1223 // return instance;
123 alfonx 154 }
124    
125     /**
126     * used to create sample point shapes with LiteShape (not lines nor
127     * polygons)
128     */
129 alfonx 377 private static final GeometryFactory geomFac = FeatureUtil.GEOMETRY_FACTORY;
130 alfonx 154
131     /** padding percentage factor at both sides of the legend. */
132     private static final float hpaddingFactor = 0.11f; // was 0.15
133    
134     /** top & bottom padding percentage factor for the legend */
135     private static final float vpaddingFactor = 0.08f; // was 0.15
136    
137     /**
138     * Just a holder to avoid creating many polygon shapes from inside
139     * <code>getSampleShape()</code>
140     */
141     private LiteShape2 sampleRect;
142    
143     /**
144     * Just a holder to avoid creating many line shapes from inside
145     * <code>getSampleShape()</code>
146     */
147     private LiteShape2 sampleLine;
148    
149     /**
150     * Just a holder to avoid creating many point shapes from inside
151     * <code>getSampleShape()</code>
152     */
153     private LiteShape2 samplePoint;
154    
155     private Hints hints;
156    
157     /**
158     * Returns a <code>java.awt.Shape</code> appropiate to render a legend
159     * graphic given the symbolizer type and the legend dimensions.
160     *
161     * @param symbolizer
162     * the Symbolizer for whose type a sample shape will be created
163     * @param legendWidth
164     * the requested width, in output units, of the legend graphic
165     * @param legendHeight
166     * the requested height, in output units, of the legend graphic
167     *
168     * @return an appropiate Line2D, Rectangle2D or LiteShape(Point) for the
169     * symbolizer, wether it is a LineSymbolizer, a PolygonSymbolizer,
170     * or a Point ot Text Symbolizer
171     *
172     * @throws IllegalArgumentException
173     * if an unknown symbolizer impl was passed in.
174     */
175     private LiteShape2 getSampleShape(Symbolizer symbolizer, int legendWidth,
176     int legendHeight) {
177     LiteShape2 sampleShape;
178     final float hpad = (legendWidth * hpaddingFactor);
179     final float vpad = (legendHeight * vpaddingFactor);
180    
181     if (symbolizer instanceof LineSymbolizer) {
182     if (this.sampleLine == null) {
183     Coordinate[] coords = {
184     new Coordinate(hpad, legendHeight - vpad),
185     new Coordinate(legendWidth - hpad, vpad) };
186     LineString geom = geomFac.createLineString(coords);
187    
188     try {
189     this.sampleLine = new LiteShape2(geom, null, null, false);
190     } catch (Exception e) {
191     this.sampleLine = null;
192     }
193     }
194    
195     sampleShape = this.sampleLine;
196     } else if ((symbolizer instanceof PolygonSymbolizer)
197     || (symbolizer instanceof RasterSymbolizer)) {
198     if (this.sampleRect == null) {
199     final float w = legendWidth - (2 * hpad);
200     final float h = legendHeight - (2 * vpad);
201    
202     Coordinate[] coords = { new Coordinate(hpad, vpad),
203     new Coordinate(hpad, vpad + h),
204     new Coordinate(hpad + w, vpad + h),
205     new Coordinate(hpad + w, vpad),
206     new Coordinate(hpad, vpad) };
207     LinearRing shell = geomFac.createLinearRing(coords);
208     Polygon geom = geomFac.createPolygon(shell, null);
209    
210     try {
211     this.sampleRect = new LiteShape2(geom, null, null, false);
212     } catch (Exception e) {
213     this.sampleRect = null;
214     }
215     }
216    
217     sampleShape = this.sampleRect;
218     } else if (symbolizer instanceof PointSymbolizer
219     || symbolizer instanceof TextSymbolizer) {
220     if (this.samplePoint == null) {
221     Coordinate coord = new Coordinate(legendWidth / 2,
222     legendHeight / 2);
223    
224     try {
225 alfonx 1223 this.samplePoint = new LiteShape2(
226     geomFac.createPoint(coord), null, null, false);
227 alfonx 154 } catch (Exception e) {
228     this.samplePoint = null;
229     }
230     }
231    
232     sampleShape = this.samplePoint;
233     } else {
234     throw new IllegalArgumentException("Unknown symbolizer: "
235     + symbolizer);
236     }
237     return sampleShape;
238     }
239 alfonx 1223
240 alfonx 154 /**
241     * Creates a little BufferedImage that presents the Style/Symbols used by
242 alfonx 318 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
243 alfonx 154 *
244     * @param rule
245     * {@link Rule} that provides the text and the style to present
246     * @param featureType
247 alfonx 1223 * Schema that describes the kind of the sample
248     * {@link SimpleFeature} that will be rendered with the
249     * {@link Style}
250 alfonx 154 * @param bg
251     * Background {@link Color} or <code>null</code>
252     *
253     * @throws IllegalAttributeException
254     */
255 alfonx 1223 public BufferedImage createImageForRule(Rule rule,
256     SimpleFeatureType featureType, Dimension size, Color bg) {
257 alfonx 154
258     Symbolizer[] symbolizers = rule.getSymbolizers();
259    
260     BufferedImage buffImage = new BufferedImage(size.width, size.height,
261     BufferedImage.TYPE_INT_ARGB);
262     Graphics2D graphics = buffImage.createGraphics();
263    
264     if (bg != null) {
265     // ****************************************************************************
266 alfonx 918 // The following lines define the background color for the rendered
267 alfonx 154 // images
268     // ****************************************************************************
269     graphics.setBackground(bg);
270     graphics.setColor(bg);
271     graphics.fillRect(0, 0, size.width, size.height);
272     }
273    
274     // Enable anti-aliasing for the legend symbols
275     graphics.setRenderingHints(getHints());
276    
277 alfonx 1223 final NumberRange<Integer> scaleRange = NumberRange.create(
278     Integer.MAX_VALUE, Integer.MAX_VALUE);
279 alfonx 154
280     try {
281    
282     for (int sIdx = 0; sIdx < symbolizers.length; sIdx++) {
283     Symbolizer symbolizer = symbolizers[sIdx];
284    
285     if (symbolizer instanceof TextSymbolizer) {
286     continue;
287     }
288    
289     // if (symbolizer instanceof RasterSymbolizer) {
290     // log.warn("createImageForRule method can't be used for
291     // RasterSymbolizers..");
292     // }
293     // else
294 alfonx 1223 final SimpleFeature sampleFeature = FeatureUtil
295     .createSampleFeature(featureType);
296 alfonx 154
297 alfonx 1223 if (sampleFeature == null)
298     LOGGER.debug("sampleFeature " + sampleFeature);
299    
300 alfonx 154 // The SLDStyleFactory has to be recreated, as it seams to cache
301     // some stuff.
302     SLDStyleFactory sldStyleFactory = new SLDStyleFactory();
303     Style2D style2d = sldStyleFactory.createStyle(sampleFeature,
304     symbolizer, scaleRange);
305    
306     LiteShape2 shape = getSampleShape(symbolizer, size.width,
307     size.height);
308    
309     if (style2d != null) {
310     new StyledShapePainter(null).paint(graphics, shape,
311 alfonx 1223 style2d, Integer.MAX_VALUE);
312 alfonx 154 }
313     }
314     } catch (Exception e) {
315 alfonx 1223 LOGGER.error(
316     "Error during createImageForRule, returning empty Image", e);
317 alfonx 154 }
318     return buffImage;
319     }
320    
321     /**
322     * Define Java2D and other Hints
323     *
324     * @param hints
325 alfonx 1223 * @author <a href="mailto:[email protected]">Stefan Alfons Tzeggai</a>
326 alfonx 154 */
327     public void setHints(Hints hints) {
328     getHints().add(hints);
329     }
330    
331     private Hints getHints() {
332     if (hints == null) {
333     hints = GeoTools.getDefaultHints();
334     hints.put(RenderingHints.KEY_ANTIALIASING,
335     RenderingHints.VALUE_ANTIALIAS_ON);
336     hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
337     RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
338     hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
339     RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
340     hints.put(RenderingHints.KEY_RENDERING,
341     RenderingHints.VALUE_RENDER_QUALITY);
342     hints.put(RenderingHints.KEY_COLOR_RENDERING,
343     RenderingHints.VALUE_COLOR_RENDER_QUALITY);
344     }
345     return hints;
346     }
347    
348     /**
349     * Creates a little BufferedImage that presents the Style/Symbols used by
350 alfonx 318 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
351 alfonx 154 *
352     * @param rule
353     * {@link Rule} that provides the text and the style to present
354     * @param featureType
355 alfonx 1223 * Schema that describes the kind of the sample
356     * {@link SimpleFeature} that will be rendered with the
357     * {@link Style}
358 alfonx 154 *
359     * @throws IllegalAttributeException
360     */
361     public BufferedImage createImageForRule(final Rule rule,
362 alfonx 318 final SimpleFeatureType featureType, final Dimension size) {
363 alfonx 154 return createImageForRule(rule, featureType, size, null);
364     }
365    
366     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26