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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1276 - (show annotations)
Tue Nov 16 11:51:41 2010 UTC (14 years, 3 months ago) by alfonx
File size: 13074 byte(s)
Fixed the preview symbol size
1 /*******************************************************************************
2 * Copyright (c) 2009 Martin O. J. Schmitz.
3 *
4 * This file is part of the SCHMITZM library - a collection of utility
5 * classes based on Java 1.6, focusing (not only) on Java Swing
6 * 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 * Stefan A. Tzeggai - additional utility classes
29 ******************************************************************************/
30 /**
31 Copyright 2008 Stefan Alfons Tzeggai and parts from some Geotools code
32
33 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 import org.opengis.feature.IllegalAttributeException;
68 import org.opengis.feature.simple.SimpleFeature;
69 import org.opengis.feature.simple.SimpleFeatureType;
70 import org.opengis.feature.type.AttributeDescriptor;
71
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 * Determining the default values of a {@link SimpleFeatureType} by
86 * {@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 * </ul>
90 *
91 * @author Stefan Alfons Tzeggai
92 */
93 public class LegendIconFeatureRenderer {
94 // private static final Dimension SIZE = new Dimension(30,20);
95
96 Logger LOGGER = Logger.getLogger(LegendIconFeatureRenderer.class);
97
98 /**
99 * This is a static class
100 */
101 private LegendIconFeatureRenderer() {
102 }
103
104 /**
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 public static LegendIconFeatureRenderer getInstance() {
110 return new LegendIconFeatureRenderer();
111 }
112
113 /**
114 * used to create sample point shapes with LiteShape (not lines nor
115 * polygons)
116 */
117 private static final GeometryFactory geomFac = FeatureUtil.GEOMETRY_FACTORY;
118
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 * Returns a <code>java.awt.Shape</code> appropriate to render a legend
147 * 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 this.samplePoint = new LiteShape2(
212 geomFac.createPoint(coord), null, null, false);
213 } 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
226 /**
227 * Creates a little BufferedImage that presents the Style/Symbols used by
228 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
229 *
230 * @param rule
231 * {@link Rule} that provides the text and the style to present
232 * @param featureType
233 * Schema that describes the kind of the sample
234 * {@link SimpleFeature} that will be rendered with the
235 * {@link Style}
236 * @param bg
237 * Background {@link Color} or <code>null</code>
238 *
239 * @throws IllegalAttributeException
240 */
241 public BufferedImage createImageForRule(Rule rule,
242 SimpleFeatureType featureType, Dimension size, Color bg) {
243
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 // The following lines define the background color for the rendered
253 // 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 final NumberRange<Integer> scaleRange = NumberRange.create(
264 Integer.MAX_VALUE, Integer.MAX_VALUE);
265
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 final SimpleFeature sampleFeature = FeatureUtil
281 .createSampleFeature(featureType);
282
283 if (sampleFeature == null)
284 LOGGER.debug("sampleFeature " + sampleFeature);
285
286 // 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 StyledShapePainter styledShapePainter = new StyledShapePainter(
297 null);
298 styledShapePainter.paint(graphics, shape, style2d,
299 Integer.MAX_VALUE);
300 }
301 }
302 } catch (Exception e) {
303 LOGGER.error(
304 "Error during createImageForRule, returning empty Image", e);
305 }
306 return buffImage;
307 }
308
309 /**
310 * Define Java2D and other Hints
311 *
312 * @param hints
313 * @author <a href="mailto:[email protected]">Stefan Alfons Tzeggai</a>
314 */
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 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
339 *
340 * @param rule
341 * {@link Rule} that provides the text and the style to present
342 * @param featureType
343 * Schema that describes the kind of the sample
344 * {@link SimpleFeature} that will be rendered with the
345 * {@link Style}
346 *
347 * @throws IllegalAttributeException
348 */
349 public BufferedImage createImageForRule(final Rule rule,
350 final SimpleFeatureType featureType, final Dimension size) {
351 return createImageForRule(rule, featureType, size, null);
352 }
353
354 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26