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

Annotation of /trunk/src/skrueger/geotools/StyledLayerUtil.java

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26