/[schmitzm]/branches/2.4.x/src/skrueger/geotools/LegendIconFeatureRenderer.java
ViewVC logotype

Annotation of /branches/2.4.x/src/skrueger/geotools/LegendIconFeatureRenderer.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1276 - (hide annotations)
Tue Nov 16 11:51:41 2010 UTC (14 years, 3 months ago) by alfonx
Original Path: trunk/src/skrueger/geotools/LegendIconFeatureRenderer.java
File size: 13074 byte(s)
Fixed the preview symbol size
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 org.apache.log4j.Logger;
52     import org.geotools.factory.GeoTools;
53     import org.geotools.factory.Hints;
54     import org.geotools.geometry.jts.LiteShape2;
55     import org.geotools.renderer.lite.StyledShapePainter;
56     import org.geotools.renderer.style.SLDStyleFactory;
57     import org.geotools.renderer.style.Style2D;
58     import org.geotools.styling.LineSymbolizer;
59     import org.geotools.styling.PointSymbolizer;
60     import org.geotools.styling.PolygonSymbolizer;
61     import org.geotools.styling.RasterSymbolizer;
62     import org.geotools.styling.Rule;
63     import org.geotools.styling.Style;
64     import org.geotools.styling.Symbolizer;
65     import org.geotools.styling.TextSymbolizer;
66     import org.geotools.util.NumberRange;
67 alfonx 1270 import org.opengis.feature.IllegalAttributeException;
68 mojays 325 import org.opengis.feature.simple.SimpleFeature;
69     import org.opengis.feature.simple.SimpleFeatureType;
70 alfonx 332 import org.opengis.feature.type.AttributeDescriptor;
71 alfonx 154
72     import schmitzm.geotools.feature.FeatureUtil;
73    
74     import com.vividsolutions.jts.geom.Coordinate;
75     import com.vividsolutions.jts.geom.GeometryFactory;
76     import com.vividsolutions.jts.geom.LineString;
77     import com.vividsolutions.jts.geom.LinearRing;
78     import com.vividsolutions.jts.geom.Polygon;
79    
80     /**
81     * Based on geoserver!
82     * <hr>
83     * <b>Changes by <a href="mailto:[email protected]">Martin Schmitz</a></b>
84     * <li>07.02.2008:<br>
85 alfonx 318 * Determining the default values of a {@link SimpleFeatureType} by
86 alfonx 1223 * {@link FeatureUtil#getDefaultAttributeValues(SimpleFeatureType)} instead of
87     * using {@link AttributeDescriptor#createDefaultValue()} directly, because the
88     * latter returns {@code null} even though the attribut is not nillable.</li>
89 alfonx 154 * </ul>
90     *
91 alfonx 862 * @author Stefan Alfons Tzeggai
92 alfonx 154 */
93 alfonx 1270 public class LegendIconFeatureRenderer {
94 alfonx 1223 // private static final Dimension SIZE = new Dimension(30,20);
95 alfonx 154
96     Logger LOGGER = Logger.getLogger(LegendIconFeatureRenderer.class);
97    
98     /**
99     * This is a static class
100     */
101     private LegendIconFeatureRenderer() {
102     }
103    
104 alfonx 1276 /**
105     * We have to return new instances here. Otherwise the sample features are
106     * not recreated and the sizes of the previews are locaked to the size of
107     * the first request.
108     */
109 alfonx 154 public static LegendIconFeatureRenderer getInstance() {
110 alfonx 1276 return new LegendIconFeatureRenderer();
111 alfonx 154 }
112    
113     /**
114     * used to create sample point shapes with LiteShape (not lines nor
115     * polygons)
116     */
117 alfonx 377 private static final GeometryFactory geomFac = FeatureUtil.GEOMETRY_FACTORY;
118 alfonx 154
119     /** padding percentage factor at both sides of the legend. */
120     private static final float hpaddingFactor = 0.11f; // was 0.15
121    
122     /** top & bottom padding percentage factor for the legend */
123     private static final float vpaddingFactor = 0.08f; // was 0.15
124    
125     /**
126     * Just a holder to avoid creating many polygon shapes from inside
127     * <code>getSampleShape()</code>
128     */
129     private LiteShape2 sampleRect;
130    
131     /**
132     * Just a holder to avoid creating many line shapes from inside
133     * <code>getSampleShape()</code>
134     */
135     private LiteShape2 sampleLine;
136    
137     /**
138     * Just a holder to avoid creating many point shapes from inside
139     * <code>getSampleShape()</code>
140     */
141     private LiteShape2 samplePoint;
142    
143     private Hints hints;
144    
145     /**
146 alfonx 1270 * Returns a <code>java.awt.Shape</code> appropriate to render a legend
147 alfonx 154 * graphic given the symbolizer type and the legend dimensions.
148     *
149     * @param symbolizer
150     * the Symbolizer for whose type a sample shape will be created
151     * @param legendWidth
152     * the requested width, in output units, of the legend graphic
153     * @param legendHeight
154     * the requested height, in output units, of the legend graphic
155     *
156     * @return an appropiate Line2D, Rectangle2D or LiteShape(Point) for the
157     * symbolizer, wether it is a LineSymbolizer, a PolygonSymbolizer,
158     * or a Point ot Text Symbolizer
159     *
160     */
161     private LiteShape2 getSampleShape(Symbolizer symbolizer, int legendWidth,
162     int legendHeight) {
163     LiteShape2 sampleShape;
164     final float hpad = (legendWidth * hpaddingFactor);
165     final float vpad = (legendHeight * vpaddingFactor);
166    
167     if (symbolizer instanceof LineSymbolizer) {
168     if (this.sampleLine == null) {
169     Coordinate[] coords = {
170     new Coordinate(hpad, legendHeight - vpad),
171     new Coordinate(legendWidth - hpad, vpad) };
172     LineString geom = geomFac.createLineString(coords);
173    
174     try {
175     this.sampleLine = new LiteShape2(geom, null, null, false);
176     } catch (Exception e) {
177     this.sampleLine = null;
178     }
179     }
180    
181     sampleShape = this.sampleLine;
182     } else if ((symbolizer instanceof PolygonSymbolizer)
183     || (symbolizer instanceof RasterSymbolizer)) {
184     if (this.sampleRect == null) {
185     final float w = legendWidth - (2 * hpad);
186     final float h = legendHeight - (2 * vpad);
187    
188     Coordinate[] coords = { new Coordinate(hpad, vpad),
189     new Coordinate(hpad, vpad + h),
190     new Coordinate(hpad + w, vpad + h),
191     new Coordinate(hpad + w, vpad),
192     new Coordinate(hpad, vpad) };
193     LinearRing shell = geomFac.createLinearRing(coords);
194     Polygon geom = geomFac.createPolygon(shell, null);
195    
196     try {
197     this.sampleRect = new LiteShape2(geom, null, null, false);
198     } catch (Exception e) {
199     this.sampleRect = null;
200     }
201     }
202    
203     sampleShape = this.sampleRect;
204     } else if (symbolizer instanceof PointSymbolizer
205     || symbolizer instanceof TextSymbolizer) {
206     if (this.samplePoint == null) {
207     Coordinate coord = new Coordinate(legendWidth / 2,
208     legendHeight / 2);
209    
210     try {
211 alfonx 1223 this.samplePoint = new LiteShape2(
212     geomFac.createPoint(coord), null, null, false);
213 alfonx 154 } catch (Exception e) {
214     this.samplePoint = null;
215     }
216     }
217    
218     sampleShape = this.samplePoint;
219     } else {
220     throw new IllegalArgumentException("Unknown symbolizer: "
221     + symbolizer);
222     }
223     return sampleShape;
224     }
225 alfonx 1223
226 alfonx 154 /**
227     * Creates a little BufferedImage that presents the Style/Symbols used by
228 alfonx 318 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
229 alfonx 154 *
230     * @param rule
231     * {@link Rule} that provides the text and the style to present
232     * @param featureType
233 alfonx 1223 * Schema that describes the kind of the sample
234     * {@link SimpleFeature} that will be rendered with the
235     * {@link Style}
236 alfonx 154 * @param bg
237     * Background {@link Color} or <code>null</code>
238     *
239     * @throws IllegalAttributeException
240     */
241 alfonx 1223 public BufferedImage createImageForRule(Rule rule,
242     SimpleFeatureType featureType, Dimension size, Color bg) {
243 alfonx 154
244     Symbolizer[] symbolizers = rule.getSymbolizers();
245    
246     BufferedImage buffImage = new BufferedImage(size.width, size.height,
247     BufferedImage.TYPE_INT_ARGB);
248     Graphics2D graphics = buffImage.createGraphics();
249    
250     if (bg != null) {
251     // ****************************************************************************
252 alfonx 918 // The following lines define the background color for the rendered
253 alfonx 154 // images
254     // ****************************************************************************
255     graphics.setBackground(bg);
256     graphics.setColor(bg);
257     graphics.fillRect(0, 0, size.width, size.height);
258     }
259    
260     // Enable anti-aliasing for the legend symbols
261     graphics.setRenderingHints(getHints());
262    
263 alfonx 1223 final NumberRange<Integer> scaleRange = NumberRange.create(
264     Integer.MAX_VALUE, Integer.MAX_VALUE);
265 alfonx 154
266     try {
267    
268     for (int sIdx = 0; sIdx < symbolizers.length; sIdx++) {
269     Symbolizer symbolizer = symbolizers[sIdx];
270    
271     if (symbolizer instanceof TextSymbolizer) {
272     continue;
273     }
274    
275     // if (symbolizer instanceof RasterSymbolizer) {
276     // log.warn("createImageForRule method can't be used for
277     // RasterSymbolizers..");
278     // }
279     // else
280 alfonx 1223 final SimpleFeature sampleFeature = FeatureUtil
281     .createSampleFeature(featureType);
282 alfonx 154
283 alfonx 1223 if (sampleFeature == null)
284     LOGGER.debug("sampleFeature " + sampleFeature);
285    
286 alfonx 154 // The SLDStyleFactory has to be recreated, as it seams to cache
287     // some stuff.
288     SLDStyleFactory sldStyleFactory = new SLDStyleFactory();
289     Style2D style2d = sldStyleFactory.createStyle(sampleFeature,
290     symbolizer, scaleRange);
291    
292     LiteShape2 shape = getSampleShape(symbolizer, size.width,
293     size.height);
294    
295     if (style2d != null) {
296 alfonx 1270 StyledShapePainter styledShapePainter = new StyledShapePainter(
297     null);
298     styledShapePainter.paint(graphics, shape, style2d,
299     Integer.MAX_VALUE);
300 alfonx 154 }
301     }
302     } catch (Exception e) {
303 alfonx 1223 LOGGER.error(
304     "Error during createImageForRule, returning empty Image", e);
305 alfonx 154 }
306     return buffImage;
307     }
308    
309     /**
310     * Define Java2D and other Hints
311     *
312     * @param hints
313 alfonx 1273 * @author <a href="mailto:[email protected]">Stefan Alfons Tzeggai</a>
314 alfonx 154 */
315     public void setHints(Hints hints) {
316     getHints().add(hints);
317     }
318    
319     private Hints getHints() {
320     if (hints == null) {
321     hints = GeoTools.getDefaultHints();
322     hints.put(RenderingHints.KEY_ANTIALIASING,
323     RenderingHints.VALUE_ANTIALIAS_ON);
324     hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
325     RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
326     hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
327     RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
328     hints.put(RenderingHints.KEY_RENDERING,
329     RenderingHints.VALUE_RENDER_QUALITY);
330     hints.put(RenderingHints.KEY_COLOR_RENDERING,
331     RenderingHints.VALUE_COLOR_RENDER_QUALITY);
332     }
333     return hints;
334     }
335    
336     /**
337     * Creates a little BufferedImage that presents the Style/Symbols used by
338 alfonx 318 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
339 alfonx 154 *
340     * @param rule
341     * {@link Rule} that provides the text and the style to present
342     * @param featureType
343 alfonx 1223 * Schema that describes the kind of the sample
344     * {@link SimpleFeature} that will be rendered with the
345     * {@link Style}
346 alfonx 154 *
347     * @throws IllegalAttributeException
348     */
349     public BufferedImage createImageForRule(final Rule rule,
350 alfonx 318 final SimpleFeatureType featureType, final Dimension size) {
351 alfonx 154 return createImageForRule(rule, featureType, size, null);
352     }
353    
354     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26