/[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 1273 - (hide annotations)
Mon Nov 15 16:22:47 2010 UTC (14 years, 3 months ago) by alfonx
File size: 12952 byte(s)
Change email address
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     final static LegendIconFeatureRenderer instance = new LegendIconFeatureRenderer();
105    
106     public static LegendIconFeatureRenderer getInstance() {
107 alfonx 1270 return instance;
108 alfonx 154 }
109    
110     /**
111     * used to create sample point shapes with LiteShape (not lines nor
112     * polygons)
113     */
114 alfonx 377 private static final GeometryFactory geomFac = FeatureUtil.GEOMETRY_FACTORY;
115 alfonx 154
116     /** padding percentage factor at both sides of the legend. */
117     private static final float hpaddingFactor = 0.11f; // was 0.15
118    
119     /** top & bottom padding percentage factor for the legend */
120     private static final float vpaddingFactor = 0.08f; // was 0.15
121    
122     /**
123     * Just a holder to avoid creating many polygon shapes from inside
124     * <code>getSampleShape()</code>
125     */
126     private LiteShape2 sampleRect;
127    
128     /**
129     * Just a holder to avoid creating many line shapes from inside
130     * <code>getSampleShape()</code>
131     */
132     private LiteShape2 sampleLine;
133    
134     /**
135     * Just a holder to avoid creating many point shapes from inside
136     * <code>getSampleShape()</code>
137     */
138     private LiteShape2 samplePoint;
139    
140     private Hints hints;
141    
142     /**
143 alfonx 1270 * Returns a <code>java.awt.Shape</code> appropriate to render a legend
144 alfonx 154 * graphic given the symbolizer type and the legend dimensions.
145     *
146     * @param symbolizer
147     * the Symbolizer for whose type a sample shape will be created
148     * @param legendWidth
149     * the requested width, in output units, of the legend graphic
150     * @param legendHeight
151     * the requested height, in output units, of the legend graphic
152     *
153     * @return an appropiate Line2D, Rectangle2D or LiteShape(Point) for the
154     * symbolizer, wether it is a LineSymbolizer, a PolygonSymbolizer,
155     * or a Point ot Text Symbolizer
156     *
157     */
158     private LiteShape2 getSampleShape(Symbolizer symbolizer, int legendWidth,
159     int legendHeight) {
160     LiteShape2 sampleShape;
161     final float hpad = (legendWidth * hpaddingFactor);
162     final float vpad = (legendHeight * vpaddingFactor);
163    
164     if (symbolizer instanceof LineSymbolizer) {
165     if (this.sampleLine == null) {
166     Coordinate[] coords = {
167     new Coordinate(hpad, legendHeight - vpad),
168     new Coordinate(legendWidth - hpad, vpad) };
169     LineString geom = geomFac.createLineString(coords);
170    
171     try {
172     this.sampleLine = new LiteShape2(geom, null, null, false);
173     } catch (Exception e) {
174     this.sampleLine = null;
175     }
176     }
177    
178     sampleShape = this.sampleLine;
179     } else if ((symbolizer instanceof PolygonSymbolizer)
180     || (symbolizer instanceof RasterSymbolizer)) {
181     if (this.sampleRect == null) {
182     final float w = legendWidth - (2 * hpad);
183     final float h = legendHeight - (2 * vpad);
184    
185     Coordinate[] coords = { new Coordinate(hpad, vpad),
186     new Coordinate(hpad, vpad + h),
187     new Coordinate(hpad + w, vpad + h),
188     new Coordinate(hpad + w, vpad),
189     new Coordinate(hpad, vpad) };
190     LinearRing shell = geomFac.createLinearRing(coords);
191     Polygon geom = geomFac.createPolygon(shell, null);
192    
193     try {
194     this.sampleRect = new LiteShape2(geom, null, null, false);
195     } catch (Exception e) {
196     this.sampleRect = null;
197     }
198     }
199    
200     sampleShape = this.sampleRect;
201     } else if (symbolizer instanceof PointSymbolizer
202     || symbolizer instanceof TextSymbolizer) {
203     if (this.samplePoint == null) {
204     Coordinate coord = new Coordinate(legendWidth / 2,
205     legendHeight / 2);
206    
207     try {
208 alfonx 1223 this.samplePoint = new LiteShape2(
209     geomFac.createPoint(coord), null, null, false);
210 alfonx 154 } catch (Exception e) {
211     this.samplePoint = null;
212     }
213     }
214    
215     sampleShape = this.samplePoint;
216     } else {
217     throw new IllegalArgumentException("Unknown symbolizer: "
218     + symbolizer);
219     }
220     return sampleShape;
221     }
222 alfonx 1223
223 alfonx 154 /**
224     * Creates a little BufferedImage that presents the Style/Symbols used by
225 alfonx 318 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
226 alfonx 154 *
227     * @param rule
228     * {@link Rule} that provides the text and the style to present
229     * @param featureType
230 alfonx 1223 * Schema that describes the kind of the sample
231     * {@link SimpleFeature} that will be rendered with the
232     * {@link Style}
233 alfonx 154 * @param bg
234     * Background {@link Color} or <code>null</code>
235     *
236     * @throws IllegalAttributeException
237     */
238 alfonx 1223 public BufferedImage createImageForRule(Rule rule,
239     SimpleFeatureType featureType, Dimension size, Color bg) {
240 alfonx 154
241     Symbolizer[] symbolizers = rule.getSymbolizers();
242    
243     BufferedImage buffImage = new BufferedImage(size.width, size.height,
244     BufferedImage.TYPE_INT_ARGB);
245     Graphics2D graphics = buffImage.createGraphics();
246    
247     if (bg != null) {
248     // ****************************************************************************
249 alfonx 918 // The following lines define the background color for the rendered
250 alfonx 154 // images
251     // ****************************************************************************
252     graphics.setBackground(bg);
253     graphics.setColor(bg);
254     graphics.fillRect(0, 0, size.width, size.height);
255     }
256    
257     // Enable anti-aliasing for the legend symbols
258     graphics.setRenderingHints(getHints());
259    
260 alfonx 1223 final NumberRange<Integer> scaleRange = NumberRange.create(
261     Integer.MAX_VALUE, Integer.MAX_VALUE);
262 alfonx 154
263     try {
264    
265     for (int sIdx = 0; sIdx < symbolizers.length; sIdx++) {
266     Symbolizer symbolizer = symbolizers[sIdx];
267    
268     if (symbolizer instanceof TextSymbolizer) {
269     continue;
270     }
271    
272     // if (symbolizer instanceof RasterSymbolizer) {
273     // log.warn("createImageForRule method can't be used for
274     // RasterSymbolizers..");
275     // }
276     // else
277 alfonx 1223 final SimpleFeature sampleFeature = FeatureUtil
278     .createSampleFeature(featureType);
279 alfonx 154
280 alfonx 1223 if (sampleFeature == null)
281     LOGGER.debug("sampleFeature " + sampleFeature);
282    
283 alfonx 154 // The SLDStyleFactory has to be recreated, as it seams to cache
284     // some stuff.
285     SLDStyleFactory sldStyleFactory = new SLDStyleFactory();
286     Style2D style2d = sldStyleFactory.createStyle(sampleFeature,
287     symbolizer, scaleRange);
288    
289     LiteShape2 shape = getSampleShape(symbolizer, size.width,
290     size.height);
291    
292     if (style2d != null) {
293 alfonx 1270 StyledShapePainter styledShapePainter = new StyledShapePainter(
294     null);
295     styledShapePainter.paint(graphics, shape, style2d,
296     Integer.MAX_VALUE);
297 alfonx 154 }
298     }
299     } catch (Exception e) {
300 alfonx 1223 LOGGER.error(
301     "Error during createImageForRule, returning empty Image", e);
302 alfonx 154 }
303     return buffImage;
304     }
305    
306     /**
307     * Define Java2D and other Hints
308     *
309     * @param hints
310 alfonx 1273 * @author <a href="mailto:[email protected]">Stefan Alfons Tzeggai</a>
311 alfonx 154 */
312     public void setHints(Hints hints) {
313     getHints().add(hints);
314     }
315    
316     private Hints getHints() {
317     if (hints == null) {
318     hints = GeoTools.getDefaultHints();
319     hints.put(RenderingHints.KEY_ANTIALIASING,
320     RenderingHints.VALUE_ANTIALIAS_ON);
321     hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
322     RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
323     hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
324     RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
325     hints.put(RenderingHints.KEY_RENDERING,
326     RenderingHints.VALUE_RENDER_QUALITY);
327     hints.put(RenderingHints.KEY_COLOR_RENDERING,
328     RenderingHints.VALUE_COLOR_RENDER_QUALITY);
329     }
330     return hints;
331     }
332    
333     /**
334     * Creates a little BufferedImage that presents the Style/Symbols used by
335 alfonx 318 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
336 alfonx 154 *
337     * @param rule
338     * {@link Rule} that provides the text and the style to present
339     * @param featureType
340 alfonx 1223 * Schema that describes the kind of the sample
341     * {@link SimpleFeature} that will be rendered with the
342     * {@link Style}
343 alfonx 154 *
344     * @throws IllegalAttributeException
345     */
346     public BufferedImage createImageForRule(final Rule rule,
347 alfonx 318 final SimpleFeatureType featureType, final Dimension size) {
348 alfonx 154 return createImageForRule(rule, featureType, size, null);
349     }
350    
351     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26