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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26