/[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 516 - (show annotations)
Wed Nov 11 21:17:33 2009 UTC (15 years, 3 months ago) by alfonx
Original Path: branches/1.0-gt2-2.6/src/skrueger/geotools/LegendIconFeatureRenderer.java
File size: 13852 byte(s)
* Extended schmitzm.JPanel to generally set its background to white when printed, by overwriting the print() method.
* Simplified the creation and update logic of ((Design)Atlas)MapLegend and ((Design)Atlas)MapLayerLegend. Besides other things there now is a LegendHelper class in AtlasProject... 
* Orginized Imports
* Removed a lot of DEBUG messages...
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. Krüger - additional utility classes
29 ******************************************************************************/
30 /**
31 Copyright 2008 Stefan Alfons Krüger 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 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 import org.opengis.feature.simple.SimpleFeature;
71 import org.opengis.feature.simple.SimpleFeatureType;
72 import org.opengis.feature.type.AttributeDescriptor;
73
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 * Determining the default values of a {@link SimpleFeatureType} by
90 * {@link FeatureUtil#getDefaultAttributeValues(SimpleFeatureType)} instead of using
91 * {@link AttributeDescriptor#createDefaultValue()} directly, because the latter
92 * returns {@code null} even though the attribut is not nillable.</li>
93 * </ul>
94 *
95 * @author Stefan Alfons Krüger
96 */
97 public class LegendIconFeatureRenderer extends DefaultTreeCellRenderer {
98 // private static final Dimension SIZE = new Dimension(30,20);
99
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
113 // TODO TEST, whether we still need to recreate the renderer here....
114 // 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 return new LegendIconFeatureRenderer();
122 // return instance;
123 }
124
125 /**
126 * used to create sample point shapes with LiteShape (not lines nor
127 * polygons)
128 */
129 private static final GeometryFactory geomFac = FeatureUtil.GEOMETRY_FACTORY;
130
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 this.samplePoint = new LiteShape2(geomFac
226 .createPoint(coord), null, null, false);
227 } 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
240 /**
241 * Creates a little BufferedImage that presents the Style/Symbols used by
242 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
243 *
244 * @param rule
245 * {@link Rule} that provides the text and the style to present
246 * @param featureType
247 * Schema that describes the kind of the sample {@link SimpleFeature}
248 * that will be rendered with the {@link Style}
249 * @param bg
250 * Background {@link Color} or <code>null</code>
251 *
252 * @throws IllegalAttributeException
253 */
254 public BufferedImage createImageForRule(Rule rule, SimpleFeatureType featureType,
255 Dimension size, Color bg) {
256
257 Symbolizer[] symbolizers = rule.getSymbolizers();
258
259 BufferedImage buffImage = new BufferedImage(size.width, size.height,
260 BufferedImage.TYPE_INT_ARGB);
261 Graphics2D graphics = buffImage.createGraphics();
262
263 if (bg != null) {
264 // ****************************************************************************
265 // The following lines define the backgroup color for the rendered
266 // images
267 // ****************************************************************************
268 graphics.setBackground(bg);
269 graphics.setColor(bg);
270 graphics.fillRect(0, 0, size.width, size.height);
271 }
272
273 // Enable anti-aliasing for the legend symbols
274 graphics.setRenderingHints(getHints());
275
276 // TODO scaleDenominator = 100000000000000000000000000000d; Was ist das
277 // fuer ein Quatsch?
278 final NumberRange<Integer> scaleRange = NumberRange.create(Integer.MAX_VALUE,Integer.MAX_VALUE);
279
280 try {
281
282 for (int sIdx = 0; sIdx < symbolizers.length; sIdx++) {
283 Symbolizer symbolizer = symbolizers[sIdx];
284
285 if (symbolizer instanceof TextSymbolizer) {
286 LOGGER
287 .warn("createImageForRule for a TextSymbolizer. Sure we want that?");
288 continue;
289 }
290
291 // if (symbolizer instanceof RasterSymbolizer) {
292 // log.warn("createImageForRule method can't be used for
293 // RasterSymbolizers..");
294 // }
295 // else
296 final SimpleFeature sampleFeature = FeatureUtil.createSampleFeature(featureType);
297
298 // The SLDStyleFactory has to be recreated, as it seams to cache
299 // some stuff.
300 SLDStyleFactory sldStyleFactory = new SLDStyleFactory();
301 Style2D style2d = sldStyleFactory.createStyle(sampleFeature,
302 symbolizer, scaleRange);
303
304 LiteShape2 shape = getSampleShape(symbolizer, size.width,
305 size.height);
306
307 if (style2d != null) {
308 new StyledShapePainter(null).paint(graphics, shape,
309 style2d, Integer.MAX_VALUE );
310 }
311 }
312 } catch (Exception e) {
313 LOGGER
314 .error(
315 "Error during createImageForRule, returning empty Image",
316 e);
317 }
318 return buffImage;
319 }
320
321 /**
322 * Define Java2D and other Hints
323 *
324 * @param hints
325 * @author <a href="mailto:[email protected]">Stefan Alfons
326 * Kr&uuml;ger</a>
327 */
328 public void setHints(Hints hints) {
329 getHints().add(hints);
330 }
331
332 private Hints getHints() {
333 if (hints == null) {
334 hints = GeoTools.getDefaultHints();
335 hints.put(RenderingHints.KEY_ANTIALIASING,
336 RenderingHints.VALUE_ANTIALIAS_ON);
337 hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
338 RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
339 hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
340 RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
341 hints.put(RenderingHints.KEY_RENDERING,
342 RenderingHints.VALUE_RENDER_QUALITY);
343 hints.put(RenderingHints.KEY_COLOR_RENDERING,
344 RenderingHints.VALUE_COLOR_RENDER_QUALITY);
345 }
346 return hints;
347 }
348
349 /**
350 * Creates a little BufferedImage that presents the Style/Symbols used by
351 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
352 *
353 * @param rule
354 * {@link Rule} that provides the text and the style to present
355 * @param featureType
356 * Schema that describes the kind of the sample {@link SimpleFeature}
357 * that will be rendered with the {@link Style}
358 *
359 * @throws IllegalAttributeException
360 */
361 public BufferedImage createImageForRule(final Rule rule,
362 final SimpleFeatureType featureType, final Dimension size) {
363 return createImageForRule(rule, featureType, size, null);
364 }
365
366 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26