/[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 1273 - (show 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 /*******************************************************************************
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 final static LegendIconFeatureRenderer instance = new LegendIconFeatureRenderer();
105
106 public static LegendIconFeatureRenderer getInstance() {
107 return instance;
108 }
109
110 /**
111 * used to create sample point shapes with LiteShape (not lines nor
112 * polygons)
113 */
114 private static final GeometryFactory geomFac = FeatureUtil.GEOMETRY_FACTORY;
115
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 * Returns a <code>java.awt.Shape</code> appropriate to render a legend
144 * 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 this.samplePoint = new LiteShape2(
209 geomFac.createPoint(coord), null, null, false);
210 } 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
223 /**
224 * Creates a little BufferedImage that presents the Style/Symbols used by
225 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
226 *
227 * @param rule
228 * {@link Rule} that provides the text and the style to present
229 * @param featureType
230 * Schema that describes the kind of the sample
231 * {@link SimpleFeature} that will be rendered with the
232 * {@link Style}
233 * @param bg
234 * Background {@link Color} or <code>null</code>
235 *
236 * @throws IllegalAttributeException
237 */
238 public BufferedImage createImageForRule(Rule rule,
239 SimpleFeatureType featureType, Dimension size, Color bg) {
240
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 // The following lines define the background color for the rendered
250 // 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 final NumberRange<Integer> scaleRange = NumberRange.create(
261 Integer.MAX_VALUE, Integer.MAX_VALUE);
262
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 final SimpleFeature sampleFeature = FeatureUtil
278 .createSampleFeature(featureType);
279
280 if (sampleFeature == null)
281 LOGGER.debug("sampleFeature " + sampleFeature);
282
283 // 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 StyledShapePainter styledShapePainter = new StyledShapePainter(
294 null);
295 styledShapePainter.paint(graphics, shape, style2d,
296 Integer.MAX_VALUE);
297 }
298 }
299 } catch (Exception e) {
300 LOGGER.error(
301 "Error during createImageForRule, returning empty Image", e);
302 }
303 return buffImage;
304 }
305
306 /**
307 * Define Java2D and other Hints
308 *
309 * @param hints
310 * @author <a href="mailto:[email protected]">Stefan Alfons Tzeggai</a>
311 */
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 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
336 *
337 * @param rule
338 * {@link Rule} that provides the text and the style to present
339 * @param featureType
340 * Schema that describes the kind of the sample
341 * {@link SimpleFeature} that will be rendered with the
342 * {@link Style}
343 *
344 * @throws IllegalAttributeException
345 */
346 public BufferedImage createImageForRule(final Rule rule,
347 final SimpleFeatureType featureType, final Dimension size) {
348 return createImageForRule(rule, featureType, size, null);
349 }
350
351 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26