/[schmitzm]/branches/1.0-gt2-2.6/src/skrueger/geotools/StyledLayerUtil.java
ViewVC logotype

Annotation of /branches/1.0-gt2-2.6/src/skrueger/geotools/StyledLayerUtil.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 420 - (hide annotations)
Thu Oct 1 20:22:48 2009 UTC (15 years, 5 months ago) by alfonx
File size: 41461 byte(s)
* Lots of changes in this big commit for GP 1.3 
* New Interfaces: Checkable, Copyable, Cancellable, CancellableDialogAdapter to improve the GUI
* New DialogManager to unify the handling of all dialogs.
* GP-Feature: The dialog for editing/translating a DpEntry has been "enriched".
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     * Stefan A. Krüger - additional utility classes
29     ******************************************************************************/
30     package skrueger.geotools;
31    
32 alfonx 397 import java.awt.Color;
33     import java.awt.Dimension;
34     import java.awt.Graphics;
35 alfonx 400 import java.awt.Graphics2D;
36     import java.awt.Rectangle;
37     import java.awt.geom.AffineTransform;
38 alfonx 397 import java.awt.image.BufferedImage;
39 alfonx 403 import java.awt.image.ColorModel;
40 alfonx 405 import java.awt.image.ComponentColorModel;
41     import java.awt.image.DataBuffer;
42 alfonx 244 import java.io.File;
43     import java.io.FileNotFoundException;
44     import java.io.FileWriter;
45     import java.net.URL;
46     import java.text.DecimalFormat;
47     import java.util.List;
48     import java.util.Map;
49    
50 alfonx 403 import javax.swing.BorderFactory;
51 alfonx 397 import javax.swing.Box;
52     import javax.swing.BoxLayout;
53     import javax.swing.ImageIcon;
54     import javax.swing.JLabel;
55    
56 alfonx 244 import org.apache.log4j.Logger;
57 alfonx 403 import org.geotools.coverage.grid.GeneralGridEnvelope;
58 alfonx 244 import org.geotools.coverage.grid.GridCoverage2D;
59 alfonx 403 import org.geotools.coverage.grid.GridGeometry2D;
60 alfonx 244 import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
61 alfonx 405 import org.geotools.coverage.grid.io.AbstractGridFormat;
62 alfonx 244 import org.geotools.feature.FeatureCollection;
63 alfonx 403 import org.geotools.geometry.jts.ReferencedEnvelope;
64 alfonx 244 import org.geotools.map.DefaultMapLayer;
65     import org.geotools.map.MapLayer;
66 alfonx 405 import org.geotools.parameter.Parameter;
67 alfonx 400 import org.geotools.renderer.lite.gridcoverage2d.GridCoverageRenderer;
68 alfonx 244 import org.geotools.styling.ColorMap;
69     import org.geotools.styling.ColorMapEntry;
70 alfonx 397 import org.geotools.styling.FeatureTypeStyle;
71 alfonx 244 import org.geotools.styling.RasterSymbolizer;
72 alfonx 397 import org.geotools.styling.Rule;
73 alfonx 244 import org.geotools.styling.Style;
74     import org.jdom.Document;
75     import org.jdom.Element;
76     import org.jdom.input.SAXBuilder;
77     import org.jdom.output.XMLOutputter;
78 alfonx 420 import org.opengis.feature.simple.SimpleFeature;
79 alfonx 397 import org.opengis.feature.simple.SimpleFeatureType;
80 alfonx 403 import org.opengis.parameter.GeneralParameterValue;
81 alfonx 244
82 alfonx 400 import schmitzm.geotools.JTSUtil;
83 alfonx 420 import schmitzm.geotools.feature.FeatureUtil;
84 alfonx 244 import schmitzm.geotools.styling.StylingUtil;
85     import schmitzm.io.IOUtil;
86     import schmitzm.lang.LangUtil;
87     import schmitzm.swing.SwingUtil;
88     import skrueger.AttributeMetaData;
89     import skrueger.RasterLegendData;
90     import skrueger.i8n.Translation;
91    
92     /**
93     * This class provides static helper methods for dealing with
94     * {@link StyledLayerInterface} stuff.
95 alfonx 400 *
96     * @author <a href="mailto:[email protected]">Martin Schmitz</a>
97     * (University of Bonn/Germany)
98 alfonx 244 * @version 1.0
99     */
100     public class StyledLayerUtil {
101 alfonx 400 private static final Logger LOGGER = Logger.getLogger(StyledLayerUtil.class
102     .getName());
103     private static final SAXBuilder SAX_BUILDER = new SAXBuilder();
104     private static final XMLOutputter XML_OUTPUTTER = new XMLOutputter();
105 alfonx 244
106 alfonx 400 /** URL for Atlas XML schema */
107     public static final String AMLURI = "http://www.wikisquare.de/AtlasML";
108     /** Name of the XML Element for the attribute meta data map */
109     public static final String ELEM_NAME_AMD = "attributeMetaData";
110     /** Name of the XML Element for the raster legend data */
111     public static final String ELEM_NAME_RLD = "rasterLegendData";
112     /** Name of the XML Element for an attribute meta data map entry */
113     public static final String ELEM_NAME_ATTRIBUTE = "dataAttribute";
114     /** Name of the XML Element for an raster legend data entry */
115     public static final String ELEM_NAME_RASTERLEGEND = "rasterLegendItem";
116     /** Name of the XML Element for a translation */
117     public static final String ELEM_NAME_TRANSLATION = "translation";
118 alfonx 244
119 alfonx 400 /**
120     * Creates a Geotools {@link MapLayer} from an object. If the object is a
121     * {@link StyledLayerInterface} then its sytle is used. In case of direct
122     * Geotools objects ({@link GridCoverage2D},
123     * {@link AbstractGridCoverage2DReader}, {@link FeatureCollection}) a
124     * default style is generated.
125     *
126     * @param object
127     * an Object
128     * @exception Exception
129     * if {@code null} is given as object or an error occurs
130     * during layer creation
131     */
132     public static MapLayer createMapLayer(Object object) throws Exception {
133     return createMapLayer(object, null);
134     }
135 alfonx 244
136 alfonx 400 /**
137     * Creates a Geotools {@link MapLayer} from an object. If the object is a
138     * {@link StyledLayerInterface} then its sytle is used. In case of direct
139     * Geotools objects ({@link GridCoverage2D},
140     * {@link AbstractGridCoverage2DReader}, {@link FeatureCollection}) a
141     * default style is generated.
142     *
143     * @param object
144     * an Object
145     * @param forcedStyle
146     * (SLD-)Style to force for the object
147     * @exception Exception
148     * if {@code null} is given as object or an error occurs
149     * during layer creation
150     */
151     public static MapLayer createMapLayer(Object object, Style forcedStyle)
152     throws Exception {
153     MapLayer layer = null;
154     Style style = null;
155     if (object instanceof StyledLayerInterface) {
156     style = ((StyledLayerInterface<?>) object).getStyle();
157     object = ((StyledLayerInterface<?>) object).getGeoObject();
158     }
159     if (forcedStyle != null)
160     style = forcedStyle;
161     if (style == null)
162     style = StylingUtil.createDefaultStyle(object);
163 alfonx 244
164 alfonx 400 if (object instanceof GridCoverage2D)
165     layer = new DefaultMapLayer((GridCoverage2D) object, style);
166     if (object instanceof AbstractGridCoverage2DReader)
167     layer = new DefaultMapLayer((AbstractGridCoverage2DReader) object,
168     style);
169     if (object instanceof FeatureCollection)
170     layer = new DefaultMapLayer((FeatureCollection) object, style);
171 alfonx 244
172 alfonx 400 if (layer == null)
173     throw new Exception("Can not create MapLayer from "
174     + (object == null ? "null" : object.getClass()));
175 alfonx 244
176 alfonx 400 return layer;
177     }
178 alfonx 244
179 alfonx 400 /**
180     * Creates an default instance of {@link StyledLayerInterface} for a
181     * Geotools object ({@link GridCoverage2D}, {@link FeatureCollection}) with
182     * a default style.
183     *
184     * @param object
185     * an Object
186     * @param title
187     * title for the object
188     * @exception UnsupportedOperationException
189     * if {@code null} is given as object or an error occurs
190     * during creation
191     */
192     public static StyledLayerInterface<?> createStyledLayer(Object object,
193     String title) {
194     return createStyledLayer(object, title, null);
195     }
196 alfonx 244
197 alfonx 400 /**
198     * Creates an default instance of {@link StyledLayerInterface} for a
199     * Geotools object ({@link GridCoverage2D}, {@link FeatureCollection}) with
200     * a given style.
201     *
202     * @param object
203     * an Object
204     * @param title
205     * title for the object
206     * @param style
207     * style and meta data for the object
208     * @exception UnsupportedOperationException
209     * if {@code null} is given as object or an error occurs
210     * during creation
211     */
212     public static StyledLayerInterface<?> createStyledLayer(Object object,
213     String title, StyledLayerStyle style) {
214     StyledLayerInterface<?> styledLayer = null;
215 alfonx 244
216 alfonx 400 String id = (title != null) ? title : "defaultID";
217 alfonx 244
218 alfonx 400 if (object instanceof GridCoverage2D)
219     styledLayer = new StyledGridCoverage((GridCoverage2D) object, id,
220     title, style);
221     else if (object instanceof AbstractGridCoverage2DReader)
222     styledLayer = new StyledGridCoverageReader(
223     (AbstractGridCoverage2DReader) object, id, title, style);
224     else if (object instanceof FeatureCollection)
225     styledLayer = new StyledFeatureCollection(
226     (FeatureCollection) object, id, title, style);
227 alfonx 244
228 alfonx 400 if (styledLayer == null)
229     throw new UnsupportedOperationException(
230     "Can not create StyledLayerInterface object from "
231     + (object == null ? "null" : object.getClass()));
232 alfonx 244
233 alfonx 400 return styledLayer;
234     }
235 alfonx 244
236 alfonx 400 /**
237     * Return only the visible or invisible entries of an AttributeMetaData-Map.
238     *
239     * @param amdMap
240     * AttributeMetaData-Map
241     * @param visible
242     * indicated whether the visible or invisible entries are
243     * returned
244     */
245 alfonx 420 public static AttributeMetadataMap getVisibleAttributeMetaData(
246 alfonx 400 Map<Integer, AttributeMetaData> amdMap, boolean visible) {
247 alfonx 420 AttributeMetadataMap filteredMap = new AttributeMetadataMap();
248 alfonx 400 for (AttributeMetaData amd : amdMap.values())
249     if (amd.isVisible())
250     filteredMap.put(amd.getColIdx(), amd);
251 alfonx 244
252 alfonx 400 return filteredMap;
253     }
254 alfonx 244
255 alfonx 400 /**
256     * Parses a {@link AttributeMetaData} object from an JDOM-{@link Element}.
257     * This method works like {@link
258     * AMLImport#parseDataAttribute(org.w3c.dom.Node}, but for JDOM.
259     *
260     * @param element
261     * {@link Element} to parse
262     */
263     public static AttributeMetaData parseAttributeMetaData(final Element element) {
264     final Integer col = Integer.valueOf(element.getAttributeValue("col"));
265     final Boolean visible = Boolean.valueOf(element
266     .getAttributeValue("visible"));
267     final String unit = element.getAttributeValue("unit");
268 alfonx 244
269 alfonx 400 Translation name = new Translation();
270     Translation desc = new Translation();
271     for (final Element childElement : (List<Element>) element.getChildren()) {
272     if (childElement.getName() == null)
273     continue;
274 alfonx 244
275 alfonx 400 if (childElement.getName().equals("name"))
276     name = parseTranslation(childElement);
277     else if (childElement.getName().equals("desc"))
278     desc = parseTranslation(childElement);
279     }
280     return new AttributeMetaData(col, visible, name, desc, unit);
281     }
282 alfonx 244
283 alfonx 400 /**
284     * Parses a {@link AttributeMetaData} map from an JDOM-{@link Element} with
285     * {@code <attribute>}-childs.
286     *
287     * @param element
288     * {@link Element} to parse
289     */
290 alfonx 420 public static AttributeMetadataMap parseAttributeMetaDataMap(
291 alfonx 400 final Element element) {
292 alfonx 420 AttributeMetadataMap metaData = new AttributeMetadataMap();
293 alfonx 400 List<Element> attributesElements = element
294     .getChildren(ELEM_NAME_ATTRIBUTE);
295     for (Element attibuteElement : attributesElements) {
296     AttributeMetaData attrMetaData = parseAttributeMetaData(attibuteElement);
297     metaData.put(attrMetaData.getColIdx(), attrMetaData);
298     }
299     return metaData;
300     }
301 alfonx 244
302 alfonx 400 /**
303     * Loads a {@link AttributeMetaData} object from an URL.
304     *
305     * @param documentUrl
306     * {@link URL} to parse
307     * @see #parseAttributeMetaData(Element)
308     */
309 alfonx 420 public static AttributeMetadataMap loadAttributeMetaDataMap(
310 alfonx 400 final URL documentUrl) throws Exception {
311     Document document = SAX_BUILDER.build(documentUrl);
312     return parseAttributeMetaDataMap(document.getRootElement());
313     }
314 alfonx 244
315 alfonx 400 /**
316     * Creates an JDOM {@link Element} for the given {@link AttributeMetaData}
317     * object.
318     *
319     * @param amd
320     * meta data for one attribute
321     */
322     public static Element createAttributeMetaDataElement(
323     final AttributeMetaData amd) {
324     final Element element = new Element(ELEM_NAME_ATTRIBUTE, AMLURI);
325     element.setAttribute("col", String.valueOf(amd.getColIdx()));
326     element.setAttribute("visible", String.valueOf(amd.isVisible()));
327     element.setAttribute("unit", amd.getUnit());
328     // Creating a aml:name tag...
329     element.addContent(createTranslationElement("name", amd.getTitle()));
330     // Creating a aml:desc tag...
331     element.addContent(createTranslationElement("desc", amd.getDesc()));
332     return element;
333     }
334 alfonx 244
335 alfonx 400 /**
336     * Creates an JDOM {@link Element} for the given {@link AttributeMetaData}
337     * map.
338     *
339     * @param amdMap
340     * map of attribute meta data
341     */
342     public static Element createAttributeMetaDataMapElement(
343 alfonx 420 final AttributeMetadataMap amdMap) {
344 alfonx 400 final Element element = new Element(ELEM_NAME_AMD, AMLURI);
345     for (AttributeMetaData amd : amdMap.values())
346     element.addContent(createAttributeMetaDataElement(amd));
347     return element;
348     }
349 alfonx 244
350 alfonx 400 /**
351     * Saves a {@link AttributeMetaData AttributeMetaData-Map} to an URL.
352     *
353     * @param amdMap
354     * map of {@link AttributeMetaData}
355     * @param documentUrl
356     * {@link URL} to store the XML
357     */
358     public static void saveAttributeMetaDataMap(
359 alfonx 420 final AttributeMetadataMap amdMap, final URL documentUrl)
360 alfonx 400 throws Exception {
361     // Create XML-Document
362     final FileWriter out = new FileWriter(new File(documentUrl.toURI()));
363     XML_OUTPUTTER.output(createAttributeMetaDataMapElement(amdMap), out);
364     out.flush();
365     out.close();
366     }
367 alfonx 244
368 alfonx 400 /**
369     * Parses a {@link RasterLegendData} object from an JDOM-{@link Element}.
370     * This method works like {@link
371     * AMLImport#parseRasterLegendData(org.w3c.dom.Node}, but for JDOM.
372     *
373     * @param element
374     * {@link Element} to parse
375     */
376     public static RasterLegendData parseRasterLegendData(Element element) {
377 alfonx 244
378 alfonx 400 final boolean paintGaps = Boolean.valueOf(element
379     .getAttributeValue("paintGaps"));
380 alfonx 244
381 alfonx 400 RasterLegendData rld = new RasterLegendData(paintGaps);
382 alfonx 244
383 alfonx 400 for (Element childElement : (List<Element>) element.getChildren()) {
384     final String name = childElement.getName();
385     // Cancel if it's an attribute
386     if (childElement.getChildren().size() == 0)
387     continue;
388 alfonx 244
389 alfonx 400 if (name.equals(ELEM_NAME_RASTERLEGEND)) {
390     final String valueAttr = childElement
391     .getAttributeValue("value");
392     if (valueAttr == null)
393     throw new UnsupportedOperationException(
394     "Attribute 'value' missing for definition of <"
395     + ELEM_NAME_RASTERLEGEND + ">");
396     final double value = Double.valueOf(valueAttr);
397 alfonx 244
398 alfonx 400 // first and only item should be the label
399     final Element labelElement = childElement.getChild("label");
400     // id label element is missing, the translation is searched
401     // directly
402     // as childs of the rasterLegendItem element
403     Translation label = parseTranslation(labelElement != null ? labelElement
404     : childElement);
405     rld.put(value, label);
406     }
407     }
408 alfonx 244
409 alfonx 400 return rld;
410     }
411 alfonx 244
412 alfonx 400 /**
413     * Loads a {@link RasterLegendData} object from an URL.
414     *
415     * @param documentUrl
416     * {@link URL} to parse
417     * @see #parseAttributeMetaData(Element)
418     */
419     public static RasterLegendData loadRasterLegendData(final URL documentUrl)
420     throws Exception {
421     Document document = SAX_BUILDER.build(documentUrl);
422     return parseRasterLegendData(document.getRootElement());
423     }
424 alfonx 244
425 alfonx 400 /**
426     * Creates an JDOM {@link Element} for the given {@link RasterLegendData}
427     * map.
428     *
429     * @param rld
430     * raster legend data
431     */
432     public static Element createRasterLegendDataElement(
433     final RasterLegendData rld) {
434     final Element element = new Element(ELEM_NAME_RLD, AMLURI);
435     element.setAttribute("paintGaps", rld.isPaintGaps().toString());
436     for (Double key : rld.getSortedKeys()) {
437     Element item = new Element(ELEM_NAME_RASTERLEGEND, AMLURI);
438     item.setAttribute("value", key.toString());
439     item.addContent(createTranslationElement("label", rld.get(key)));
440     element.addContent(item);
441     }
442     return element;
443     }
444 alfonx 244
445 alfonx 400 /**
446     * Creates {@link RasterLegendData} from a {@link ColorMap}.
447     *
448     * @param colorMap
449     * a color map
450     * @param paintGaps
451     * indicated whether gaps are painted between the legend items
452     * @param digits
453     * number of digits the grid value classes (and legend) are
454     * rounded to (null means no round; >= 0 means digits after
455     * comma; < 0 means digits before comma)
456     */
457     public static RasterLegendData generateRasterLegendData(ColorMap colorMap,
458     boolean paintGaps, Integer digits) {
459     DecimalFormat decFormat = digits != null ? new DecimalFormat(SwingUtil
460     .getNumberFormatPattern(digits)) : null;
461     RasterLegendData rld = new RasterLegendData(paintGaps);
462     for (ColorMapEntry cme : colorMap.getColorMapEntries()) {
463     double value = StylingUtil.getQuantityFromColorMapEntry(cme);
464     String label = cme.getLabel();
465     // if no label is set (e.g. quantitative style),
466     // use the value as label
467     if (label == null || label.equals(""))
468     if (digits == null)
469     label = String.valueOf(value);
470     else
471     label = decFormat.format(LangUtil.round(value, digits));
472     rld.put(value, new Translation(" " + label));
473     }
474     return rld;
475     }
476 alfonx 244
477 alfonx 400 /**
478     * Creates {@link RasterLegendData} from the {@link ColorMap} of a style.
479     *
480     * @param style
481     * a raster style (must contain a {@link RasterSymbolizer})
482     * @param paintGaps
483     * indicated whether gaps are painted between the legend items
484     * @param digits
485     * number of digits the grid value classes (and legend) are
486     * rounded to (null means no round; >= 0 means digits after
487     * comma; < 0 means digits before comma)
488     */
489     public static RasterLegendData generateRasterLegendData(Style style,
490     boolean paintGaps, Integer digits) {
491     ColorMap colorMap = StylingUtil.getColorMapFromStyle(style);
492     if (colorMap == null)
493     throw new IllegalArgumentException(
494     "Color map can not be determined from style!");
495     return generateRasterLegendData(colorMap, paintGaps, digits);
496     }
497 alfonx 244
498 alfonx 400 /**
499     * Saves a {@link RasterLegendData} to an URL.
500     *
501     * @param rld
502     * raster legend data
503     * @param documentUrl
504     * {@link URL} to store the XML
505     */
506     public static void saveRasterLegendData(final RasterLegendData rld,
507     final URL documentUrl) throws Exception {
508     // Create XML-Document
509     final FileWriter out = new FileWriter(new File(documentUrl.toURI()));
510     XML_OUTPUTTER.output(createRasterLegendDataElement(rld), out);
511     out.flush();
512     out.close();
513     }
514 alfonx 244
515 alfonx 400 /**
516     * Parses a {@link Translation} object from an JDOM-{@link Element}. This
517     * method works like {@link AMLImport#parseTranslation(org.w3c.dom.Node},
518     * but for JDOM.
519     *
520     * @param element
521     * {@link Element} to parse
522     */
523     public final static Translation parseTranslation(final Element element) {
524     Translation trans = new Translation();
525 alfonx 244
526 alfonx 400 if (element == null)
527     return trans;
528 alfonx 244
529 alfonx 400 for (final Element translationElement : (List<Element>) element
530     .getChildren()) {
531     final String name = translationElement.getName();
532     if (name == null)
533     continue;
534 alfonx 244
535 alfonx 400 // lang attribute
536     String lang = translationElement.getAttributeValue("lang");
537     // set the default, if no language code is set
538     if (lang == null)
539     lang = Translation.DEFAULT_KEY;
540 alfonx 244
541 alfonx 400 final String translationText = translationElement.getValue();
542     if (translationText == null)
543     trans.put(lang, "");
544     else
545     trans.put(lang, translationText);
546     }
547 alfonx 244
548 alfonx 400 // if no <translation> is given, the value of the node should
549     // be used as a default translation
550     if (trans.size() == 0)
551     trans.put(Translation.DEFAULT_KEY, element.getValue());
552     // trans = new Translation(
553     // ((List<Element>)element.getChildren()).get(0).getValue() );
554 alfonx 244
555 alfonx 400 return trans;
556     }
557 alfonx 244
558 alfonx 400 /**
559     * Creates an JDOM {@link Element} for the given {@link Translation}.
560     *
561     * @param tagname
562     * Name of the Element
563     * @param translation
564     * Translation to store in the Element
565     */
566     public final static Element createTranslationElement(String tagname,
567     Translation translation) {
568     Element element = new Element(tagname, AMLURI);
569     if (translation == null)
570     throw new UnsupportedOperationException(
571     "Translation element can not be created from null!");
572 alfonx 244
573 alfonx 400 // If only a default translation is set, the <translation
574     // lang="..">..</tranlation>
575     // part is not used
576     if (translation.keySet().size() == 1
577     && translation.get(Translation.DEFAULT_KEY) != null) {
578     element.addContent(translation.get(Translation.DEFAULT_KEY));
579     return element;
580     }
581 alfonx 244
582 alfonx 400 // add a <translation lang="..">..</tranlation> part to the element for
583     // all languages
584     for (String lang : translation.keySet()) {
585     Element translationElement = new Element(ELEM_NAME_TRANSLATION,
586     AMLURI);
587     translationElement.setAttribute("lang", lang);
588     String translationString = translation.get(lang);
589     if (translationString == null)
590     translationString = "";
591     translationElement.addContent(translationString);
592     element.addContent(translationElement);
593     }
594 alfonx 244
595 alfonx 400 return element;
596     }
597 alfonx 244
598 alfonx 400 /**
599     * Sets a style to {@link StyledLayerInterface}.
600     *
601     * @param styledObject
602     * a styled object
603     * @param style
604     * a Style
605     */
606     public static void setStyledLayerStyle(StyledLayerInterface styledObject,
607     StyledLayerStyle<?> style) {
608     // set SLD style
609     styledObject.setStyle(style.getGeoObjectStyle());
610     // set meta data
611     if (styledObject instanceof StyledGridCoverageInterface
612     && (style.getMetaData() instanceof RasterLegendData || style
613     .getMetaData() == null)) {
614     RasterLegendData sourceRld = (RasterLegendData) style.getMetaData();
615     RasterLegendData destRld = ((StyledGridCoverageInterface) styledObject)
616     .getLegendMetaData();
617     if (destRld != null && sourceRld != null) {
618     destRld.setPaintGaps(sourceRld.isPaintGaps());
619     destRld.clear();
620     destRld.putAll(sourceRld);
621     }
622     return;
623     }
624     if (styledObject instanceof StyledFeatureCollectionInterface
625     && (style.getMetaData() instanceof Map || style.getMetaData() == null)) {
626 alfonx 420 AttributeMetadataMap sourceAmd = (AttributeMetadataMap) style
627 alfonx 400 .getMetaData();
628 alfonx 420 AttributeMetadataMap destAmd = ((StyledFeatureCollectionInterface) styledObject)
629 alfonx 400 .getAttributeMetaDataMap();
630     if (destAmd != null && sourceAmd != null) {
631     destAmd.clear();
632     destAmd.putAll(sourceAmd);
633     }
634     return;
635     }
636 alfonx 244
637 alfonx 400 throw new UnsupportedOperationException(
638     "Style is not compatible to object: "
639     + (style.getMetaData() == null ? null : style
640     .getMetaData().getClass().getSimpleName())
641     + " <-> "
642     + (styledObject == null ? null : styledObject
643     .getClass().getSimpleName()));
644     }
645 alfonx 244
646 alfonx 400 /**
647     * Returns the style a {@link StyledLayerInterface} as a
648     * {@link StyledLayerStyle}.
649     *
650     * @param styledObject
651     * a styled object
652     * @return {@code StyledLayerStyle<RasterLegendData>} for
653     * {@link StyledGridCoverageInterface} or {@code
654     * StyledLayerStyle<Map<Integer,AttributeMetaData>>} for
655     * {@link StyledFeatureCollectionInterface}
656     */
657     public static StyledLayerStyle<?> getStyledLayerStyle(
658     StyledLayerInterface styledObject) {
659     if (styledObject instanceof StyledGridCoverageInterface)
660     return getStyledLayerStyle((StyledGridCoverageInterface) styledObject);
661     if (styledObject instanceof StyledFeatureCollectionInterface)
662     return getStyledLayerStyle((StyledFeatureCollectionInterface) styledObject);
663     throw new UnsupportedOperationException(
664     "Unknown type of StyledLayerInterface: "
665     + (styledObject == null ? null : styledObject
666     .getClass().getSimpleName()));
667     }
668 alfonx 244
669 alfonx 400 /**
670     * Returns the style and raster meta data of a
671     * {@link StyledGridCoverageInterface} as a {@link StyledLayerStyle}.
672     *
673     * @param styledGC
674     * a styled grid coverage
675     */
676     public static StyledLayerStyle<RasterLegendData> getStyledLayerStyle(
677     StyledGridCoverageInterface styledGC) {
678     return new StyledLayerStyle<RasterLegendData>(styledGC.getStyle(),
679     styledGC.getLegendMetaData());
680     }
681 alfonx 244
682 alfonx 400 /**
683     * Returns the style and attribute meta data of a
684     * {@link StyledFeatureCollectionInterface} as a {@link StyledLayerStyle}.
685     *
686     * @param styledFC
687     * a styled feature collection
688     */
689     public static StyledLayerStyle<Map<Integer, AttributeMetaData>> getStyledLayerStyle(
690     StyledFeatureCollectionInterface styledFC) {
691     return new StyledLayerStyle<Map<Integer, AttributeMetaData>>(styledFC
692     .getStyle(), styledFC.getAttributeMetaDataMap());
693     }
694 alfonx 244
695 alfonx 400 /**
696     * Loads a {@linkplain Style SLD-Style} and {@linkplain RasterLegendData
697     * Raster-LegendData} for a given geo-object (raster) source. The SLD file
698     * must be present. A missing raster legend-data file is tolerated.
699     *
700     * @param geoObjectURL
701     * URL of the (already read) raster object
702     * @param sldExt
703     * file extention for the SLD file
704     * @param rldExt
705     * file extention for the raster legend-data file
706     * @return {@code null} in case of any error
707     */
708     public static StyledLayerStyle<RasterLegendData> loadStyledRasterStyle(
709     URL geoObjectURL, String sldExt, String rldExt) {
710     RasterLegendData metaData = null;
711     Style sldStyle = null;
712     try {
713     Style[] styles = StylingUtil.loadSLD(IOUtil.changeUrlExt(
714     geoObjectURL, sldExt));
715     // SLD must be present
716     if (styles == null || styles.length == 0)
717     return null;
718     sldStyle = styles[0];
719     } catch (Exception err) {
720     // SLD must be present
721     LangUtil.logDebugError(LOGGER, err);
722     return null;
723     }
724 alfonx 244
725 alfonx 400 try {
726     metaData = StyledLayerUtil.loadRasterLegendData(IOUtil
727     .changeUrlExt(geoObjectURL, rldExt));
728     } catch (FileNotFoundException err) {
729     // ignore missing raster legend data
730     } catch (Exception err) {
731     // any other error during legend data creation leads to error
732     LangUtil.logDebugError(LOGGER, err);
733     return null;
734     }
735     return new StyledLayerStyle<RasterLegendData>(sldStyle, metaData);
736     }
737 alfonx 244
738 alfonx 400 /**
739     * Loads a {@linkplain Style SLD-Style} from a {@code .sld} file and
740     * {@linkplain RasterLegendData Raster-LegendData} from a {@code .rld} file
741     * for a given geo-object (raster) source. The SLD file must be present. A
742     * missing raster legend-data file is tolerated.
743     *
744     * @param geoObjectURL
745     * URL of the (already read) raster object
746     * @param sldExt
747     * file extention for the SLD file
748     * @param rldExt
749     * file extention for the raster legend-data file
750     * @return {@code null} in case of any error
751     */
752     public static StyledLayerStyle<RasterLegendData> loadStyledRasterStyle(
753     URL geoObjectURL) {
754     return loadStyledRasterStyle(geoObjectURL, "sld", "rld");
755     }
756 alfonx 244
757 alfonx 400 /**
758     * Loads a {@linkplain Style SLD-Style} and a {@linkplain AttributeMetaData
759     * AttributeMetaData-Map} for a given geo-object (feature) source. The SLD
760     * file must be present. A missing attribute meta-data file is tolerated.
761     *
762     * @param geoObjectURL
763     * URL of the (already read) feature object
764     * @param sldExt
765     * file extention for the SLD file
766     * @param rldExt
767     * file extention for the raster legend-data file
768     * @return {@code null} in case of any error
769     */
770     public static StyledLayerStyle<Map<Integer, AttributeMetaData>> loadStyledFeatureStyle(
771     URL geoObjectURL, String sldExt, String rldExt) {
772     Map<Integer, AttributeMetaData> metaData = null;
773     Style sldStyle = null;
774     try {
775     Style[] styles = StylingUtil.loadSLD(IOUtil.changeUrlExt(
776     geoObjectURL, sldExt));
777     // SLD must be present
778     if (styles == null || styles.length == 0)
779     return null;
780     sldStyle = styles[0];
781     } catch (Exception err) {
782     // SLD must be present
783     LangUtil.logDebugError(LOGGER, err);
784     return null;
785     }
786 alfonx 244
787 alfonx 400 try {
788     metaData = StyledLayerUtil.loadAttributeMetaDataMap(IOUtil
789     .changeUrlExt(geoObjectURL, rldExt));
790     } catch (FileNotFoundException err) {
791     // ignore missing attribute meta data
792     } catch (Exception err) {
793     // any other error during meta data creation leads to error
794     LangUtil.logDebugError(LOGGER, err);
795     return null;
796     }
797 alfonx 244
798 alfonx 400 return new StyledLayerStyle<Map<Integer, AttributeMetaData>>(sldStyle,
799     metaData);
800     }
801 alfonx 244
802 alfonx 400 /**
803     * Loads a {@linkplain Style SLD-Style} from a {@code .sld} file and
804     * {@linkplain AttributeMetaData AttributeMetaData-Map} from a {@code .amd}
805     * file for a given geo-object (feature) source. The SLD file must be
806     * present. A missing attribute meta-data file is tolerated.
807     *
808     * @param geoObjectURL
809     * URL of the (already read) feature object
810     * @param sldExt
811     * file extention for the SLD file
812     * @param rldExt
813     * file extention for the raster legend-data file
814     * @return {@code null} in case of any error
815     */
816     public static StyledLayerStyle<Map<Integer, AttributeMetaData>> loadStyledFeatureStyle(
817     URL geoObjectURL) {
818     return loadStyledFeatureStyle(geoObjectURL, "sld", "amd");
819     }
820 alfonx 244
821 alfonx 400 /**
822     * Stores a {@linkplain Style SLD-Style} and {@linkplain RasterLegendData
823     * Raster-LegendData} for a given geo-object (raster) source.
824     *
825     * @param style
826     * style to save
827     * @param geoObjectURL
828     * URL of the raster object
829     * @param sldExt
830     * file extention for the SLD file
831     * @param mdExt
832     * file extention for the meta-data file
833     */
834     public static <T> void saveStyledLayerStyle(StyledLayerStyle<T> style,
835     URL geoObjectURL, String sldExt, String mdExt) throws Exception {
836     // Store the SLD
837     Style sldStyle = style.getGeoObjectStyle();
838     if (sldStyle != null) {
839     StylingUtil.saveStyleToSLD(sldStyle, IOUtil.changeFileExt(new File(
840     geoObjectURL.toURI()), sldExt));
841     }
842 alfonx 244
843 alfonx 400 // Store the meta data
844     T metaData = style.getMetaData();
845     if (metaData != null) {
846     if (metaData instanceof RasterLegendData) {
847     saveRasterLegendData((RasterLegendData) metaData, IOUtil
848     .changeUrlExt(geoObjectURL, mdExt));
849     // } else if ( metaData instanceof
850     // Map<Integer,AttributeMetaData> ) { // LEIDER NICHT
851     // KOMPILIERBAR!!
852     } else if (metaData instanceof Map) {
853     saveAttributeMetaDataMap(
854 alfonx 420 (AttributeMetadataMap) metaData, IOUtil
855 alfonx 400 .changeUrlExt(geoObjectURL, mdExt));
856     } else
857     throw new UnsupportedOperationException(
858     "Export for meta data not yet supported: "
859     + metaData.getClass().getSimpleName());
860     }
861     }
862 alfonx 244
863 alfonx 400 /**
864     * Stores the {@linkplain Style SLD-Style} to a {@code .sld} file and the
865     * meta data ({@link RasterLegendData} or {@link AttributeMetaData}) to a
866     * {@code .rld} or {@code .amd} file. for a given geo-object source.
867     *
868     * @param style
869     * style to save
870     * @param geoObjectURL
871     * URL of the (already read) raster object
872     */
873     public static void saveStyledLayerStyle(StyledLayerStyle<?> style,
874     URL geoObjectURL) throws Exception {
875     if (style.getMetaData() instanceof RasterLegendData)
876     saveStyledLayerStyle(style, geoObjectURL, "sld", "rld");
877     else
878     saveStyledLayerStyle(style, geoObjectURL, "sld", "amd");
879     }
880 alfonx 244
881 alfonx 397 /**
882     * Creates a {@link Box} that shows a legend for a list of
883     * {@link FeatureTypeStyle}s and a targeted featureType
884     *
885     * @param featureType
886     * If this a legend for Point, Polygon or Line?
887     * @param list
888     * The Styles to presented in this legend
889     *
890     * @author <a href="mailto:[email protected]">Stefan Alfons
891     * Kr&uuml;ger</a>
892     */
893     public static Box createLegendPanel(List<FeatureTypeStyle> list,
894     SimpleFeatureType featureType, int iconWidth, int iconHeight) {
895    
896     Box box = new Box(BoxLayout.Y_AXIS) {
897    
898     /**
899     * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot
900     * gemacht wird) wird. Dann werden wird der Hintergrund auf WEISS
901     * gesetzt.
902     *
903     * @author <a href="mailto:[email protected]">Stefan Alfons
904     * Kr&uuml;ger</a>
905     */
906     @Override
907     public void print(Graphics g) {
908     final Color orig = getBackground();
909     setBackground(Color.WHITE);
910     // wrap in try/finally so that we always restore the state
911     try {
912     super.print(g);
913     } finally {
914     setBackground(orig);
915     }
916     }
917     };
918    
919     for (FeatureTypeStyle ftStyle : list) {
920    
921     // One child-node for every rule
922     List<Rule> rules = ftStyle.rules();
923     for (Rule rule : rules) {
924    
925     /**
926     * Let's not create a hbox for Rules that only contain
927     * TextSymbolizers
928     */
929     if (StylingUtil.getTextSymbolizers(rule.getSymbolizers())
930     .size() == rule.getSymbolizers().length)
931     continue;
932    
933     Box hbox = new Box(BoxLayout.X_AXIS) {
934    
935     /**
936     * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein
937     * Screenshot gemacht wird) wird. Dann werden wird der
938     * Hintergrund auf WEISS gesetzt.
939     */
940     @Override
941     public void print(Graphics g) {
942     final Color orig = getBackground();
943     setBackground(Color.WHITE);
944     // wrap in try/finally so that we always restore the
945     // state
946     try {
947     super.print(g);
948     } finally {
949     setBackground(orig);
950     }
951     }
952     };
953    
954     /**
955     * The size of the legend Symbol is dependent on the size of the
956     * font.
957     */
958     final int fontHeight = new JLabel().getFontMetrics(
959     new JLabel().getFont()).getHeight();
960 alfonx 400
961 alfonx 397 final Dimension ICON_SIZE = new Dimension(iconWidth,
962     fontHeight > 5 ? fontHeight : iconHeight);
963    
964     // ****************************************************************************
965     // Create the actual icon
966     // ****************************************************************************
967     final BufferedImage imageForRule = LegendIconFeatureRenderer
968     .getInstance().createImageForRule(rule, featureType,
969     ICON_SIZE);
970    
971     // LOGGER.debug("Creating a new Legend Image for RUle name =
972     // "+rule.getName());
973    
974     ImageIcon legendIcon = new ImageIcon(imageForRule);
975    
976     final JLabel iconLabel = new JLabel(legendIcon);
977     hbox.setAlignmentX(0f);
978     hbox.add(iconLabel);
979     hbox.add(Box.createHorizontalStrut(3));
980    
981     Translation labelT = new Translation();
982 alfonx 409 labelT.fromOneLine(rule.getDescription().getTitle());
983 alfonx 397
984     final JLabel classTitleLabel = new JLabel(labelT.toString());
985     hbox.add(classTitleLabel);
986 alfonx 400 classTitleLabel.setLabelFor(iconLabel);
987 alfonx 397
988     box.add(hbox);
989    
990     }
991     }
992    
993     return box;
994     }
995    
996     /**
997 alfonx 400 * Creates a
998     *
999 alfonx 405 * @param styledRaster
1000 alfonx 400 * @param iconHeight
1001     * @param iconWidth
1002 alfonx 397 * @return
1003     */
1004 alfonx 405 public static Box createLegendPanel(StyledRasterInterface<?> styledRaster,
1005 alfonx 400 int iconWidth, int iconHeight) {
1006 alfonx 403
1007     /**
1008     * Determine whether a Style is responsible for the coloring
1009     */
1010     ColorModel colorModel = null;
1011 alfonx 405 if (!isStyleable(styledRaster)
1012 alfonx 406 || (isStyleable(styledRaster) && styledRaster.getStyle() == null)) {
1013 alfonx 405 colorModel = getColorModel(styledRaster);
1014 alfonx 403 }
1015    
1016 alfonx 405 RasterLegendData rasterLegendData = styledRaster.getLegendMetaData();
1017 alfonx 403 List<Double> legendRasterValues = rasterLegendData.getSortedKeys();
1018 alfonx 400 Map<Double, GridCoverage2D> sampleRasters = rasterLegendData
1019     .createSampleRasters();
1020    
1021     Box box = new Box(BoxLayout.Y_AXIS) {
1022    
1023     /**
1024     * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot
1025     * gemacht wird) wird. Dann werden wird der Hintergrund auf WEISS
1026     * gesetzt.
1027     */
1028     @Override
1029     public void print(Graphics g) {
1030     final Color orig = getBackground();
1031     setBackground(Color.WHITE);
1032     // wrap in try/finally so that we always restore the state
1033     try {
1034     super.print(g);
1035     } finally {
1036     setBackground(orig);
1037     }
1038     }
1039     };
1040    
1041     for (Double rValue : legendRasterValues) {
1042    
1043     /**
1044     *
1045     */
1046     Box hbox = new Box(BoxLayout.X_AXIS) {
1047    
1048     /**
1049     * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein
1050     * Screenshot gemacht wird) wird. Dann werden wird der
1051     * Hintergrund auf WEISS gesetzt.
1052     */
1053     @Override
1054     public void print(Graphics g) {
1055     final Color orig = getBackground();
1056     setBackground(Color.WHITE);
1057     // wrap in try/finally so that we always restore the
1058     // state
1059     try {
1060     super.print(g);
1061     } finally {
1062     setBackground(orig);
1063     }
1064     }
1065     };
1066    
1067     final Dimension ICON_SIZE = new Dimension(iconWidth,
1068     new JLabel().getFontMetrics(new JLabel().getFont())
1069     .getHeight() > 5 ? new JLabel().getFontMetrics(
1070     new JLabel().getFont()).getHeight() : iconHeight);
1071    
1072     // ****************************************************************************
1073     // Create the actual icon
1074     // ****************************************************************************
1075     BufferedImage buffImage = new BufferedImage(ICON_SIZE.width,
1076     ICON_SIZE.height, BufferedImage.TYPE_INT_ARGB);
1077     Graphics2D graphics = buffImage.createGraphics();
1078    
1079 alfonx 405 if (colorModel != null) {
1080    
1081 alfonx 403 try {
1082 alfonx 405 Object inData = null;
1083     switch (colorModel.getTransferType()) {
1084     case DataBuffer.TYPE_BYTE:
1085     inData = new byte[] { rValue.byteValue() };
1086     break;
1087     case DataBuffer.TYPE_USHORT:
1088     inData = new short[] { rValue.shortValue() };
1089     break;
1090     case DataBuffer.TYPE_INT:
1091     inData = new int[] { rValue.intValue() };
1092     break;
1093     case DataBuffer.TYPE_SHORT:
1094     inData = new short[] { rValue.shortValue() };
1095     break;
1096     case DataBuffer.TYPE_FLOAT:
1097     inData = new float[] { rValue.floatValue() };
1098     break;
1099     case DataBuffer.TYPE_DOUBLE:
1100     inData = new double[] { rValue.doubleValue() };
1101     break;
1102     default:
1103     inData = rValue.intValue();
1104     }
1105     final Color color = new Color(colorModel.getRGB(inData));
1106 alfonx 403 graphics.setBackground(color);
1107     graphics.setColor(color);
1108     graphics.fillRect(0, 0, ICON_SIZE.width, ICON_SIZE.height);
1109     } catch (Exception e) {
1110 alfonx 420 LOGGER.debug(
1111     "Dann nehmen wir halt den GridCoverageRenderer", e);
1112 alfonx 405 colorModel = null;
1113     }
1114     }
1115 alfonx 400
1116 alfonx 405 if (colorModel == null) {
1117 alfonx 400
1118 alfonx 405 /**
1119     * The coverage contains only one value of value rValue
1120     */
1121     GridCoverage2D sampleCov = sampleRasters.get(rValue);
1122     GridCoverageRenderer renderer;
1123     try {
1124     renderer = new GridCoverageRenderer(sampleCov
1125     .getCoordinateReferenceSystem(), JTSUtil
1126     .createEnvelope(sampleCov.getEnvelope()),
1127     new Rectangle(iconWidth, iconHeight),
1128     (AffineTransform) null);
1129     } catch (Exception e1) {
1130     throw new RuntimeException(
1131     "Creating the GridCoverageRenderer:", e1);
1132     }
1133 alfonx 403
1134 alfonx 405 /**
1135     * Iterate over all FeatureTypeStyles.
1136     */
1137     // for (FeatureTypeStyle ftStyle : styledGrid.getStyle()
1138     // .featureTypeStyles()) {
1139     // One child-node for every rule
1140     // List<Rule> rules = ftStyle.rules();
1141     // for (Rule rule : rules) {
1142     final Style style = styledRaster.getStyle();
1143     List<RasterSymbolizer> rSymbols = StylingUtil
1144     .getRasterSymbolizers(style);
1145    
1146     for (RasterSymbolizer symbolizer : rSymbols) {
1147     // LOGGER.debug("Creating a new Legend Image for RUle
1148     // name =
1149     // "+rule.getName());
1150     try {
1151     renderer.paint(graphics, sampleCov, symbolizer);
1152     } catch (Exception ee) {
1153     LOGGER.error("Unable to paint " + symbolizer
1154     + " into the legend image", ee);
1155 alfonx 403 }
1156 alfonx 405 // }
1157     // }
1158 alfonx 400 }
1159 alfonx 405 }
1160 alfonx 400
1161     ImageIcon legendIcon = new ImageIcon(buffImage);
1162    
1163     final JLabel iconLabel = new JLabel(legendIcon);
1164     hbox.setAlignmentX(0f);
1165     hbox.add(iconLabel);
1166     hbox.add(Box.createHorizontalStrut(3));
1167    
1168     Translation labelT = rasterLegendData.get(rValue);
1169     final JLabel classTitleLabel = new JLabel(labelT.toString());
1170     hbox.add(classTitleLabel);
1171     classTitleLabel.setLabelFor(iconLabel);
1172    
1173     box.add(hbox);
1174 alfonx 403
1175     if (rasterLegendData.getPaintGaps()) {
1176     iconLabel
1177     .setBorder(BorderFactory.createLineBorder(Color.black));
1178     box.add(Box.createVerticalStrut(3));
1179     }
1180    
1181 alfonx 400 }
1182    
1183     return box;
1184 alfonx 397 }
1185    
1186 alfonx 405 /**
1187     * Extracts the {@link ColorModel} of any {@link StyledRasterInterface}. May
1188     * return <code>null</code> if the geoobject can not be accessed.
1189     */
1190 alfonx 420 @SuppressWarnings("unchecked")
1191 alfonx 405 public static ColorModel getColorModel(StyledRasterInterface<?> styledGrid) {
1192     ColorModel colorModel = null;
1193     try {
1194     Object geoObject = styledGrid.getGeoObject();
1195     if (geoObject instanceof GridCoverage2D) {
1196     GridCoverage2D cov = (GridCoverage2D) geoObject;
1197     colorModel = cov.getRenderedImage().getColorModel();
1198 alfonx 419 } else if (styledGrid instanceof StyledRasterPyramidInterface) {
1199 alfonx 405
1200     Parameter readGG = new Parameter(
1201     AbstractGridFormat.READ_GRIDGEOMETRY2D);
1202    
1203     ReferencedEnvelope mapExtend = new org.geotools.geometry.jts.ReferencedEnvelope(
1204     styledGrid.getEnvelope(), styledGrid.getCrs());
1205    
1206     readGG.setValue(new GridGeometry2D(new GeneralGridEnvelope(
1207 alfonx 420 new Rectangle(0, 0, 1, 1)), mapExtend));
1208 alfonx 405
1209 alfonx 420 FeatureCollection<SimpleFeatureType, SimpleFeature> rFc = (FeatureCollection<SimpleFeatureType, SimpleFeature>) geoObject;
1210    
1211     final AbstractGridCoverage2DReader aReader = (AbstractGridCoverage2DReader) FeatureUtil
1212     .getWrappedGeoObject(rFc);
1213 alfonx 405 GridCoverage2D cov = (GridCoverage2D) aReader
1214     .read(new GeneralParameterValue[] { readGG });
1215     colorModel = cov.getRenderedImage().getColorModel();
1216     }
1217     } catch (Exception e) {
1218 alfonx 420 LOGGER.error("Error reading the colormodel from " + styledGrid, e);
1219 alfonx 405 return null;
1220     }
1221     return colorModel;
1222     }
1223    
1224     /**
1225     * @return <code>true</code> if a {@link RasterSymbolizer} can be applied
1226     * and will have an effect. Some rasters (e.g. GeoTIFF) can come
1227     * with their own {@link ColorModel} and will ignore any
1228     * {@link RasterSymbolizer} = SLD.
1229     */
1230     public static boolean isStyleable(StyledRasterInterface<?> styledRaster) {
1231     ColorModel colorModel = getColorModel(styledRaster);
1232    
1233     LOGGER.info("The colormodel of " + styledRaster.getTitle() + " is "
1234     + colorModel.getClass().getSimpleName());
1235    
1236     if (colorModel == null)
1237     return true;
1238     if (colorModel instanceof ComponentColorModel)
1239     return true;
1240     return false;
1241     }
1242 alfonx 244 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26