/[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 315 - (hide annotations)
Wed Aug 26 11:03:27 2009 UTC (15 years, 6 months ago) by mojays
File size: 30018 byte(s)
Branch created from SCHMITZM 1.0 (rev 313) to switch to gt2-2.6.x.
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     import java.io.File;
33     import java.io.FileNotFoundException;
34     import java.io.FileWriter;
35     import java.net.URL;
36     import java.text.DecimalFormat;
37     import java.util.HashMap;
38     import java.util.List;
39     import java.util.Map;
40     import java.util.SortedMap;
41     import java.util.TreeMap;
42    
43     import org.apache.log4j.Logger;
44     import org.geotools.coverage.grid.GridCoverage2D;
45     import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
46     import org.geotools.feature.FeatureCollection;
47     import org.geotools.map.DefaultMapLayer;
48     import org.geotools.map.MapLayer;
49     import org.geotools.styling.ColorMap;
50     import org.geotools.styling.ColorMapEntry;
51     import org.geotools.styling.RasterSymbolizer;
52     import org.geotools.styling.Style;
53     import org.jdom.Document;
54     import org.jdom.Element;
55     import org.jdom.input.SAXBuilder;
56     import org.jdom.output.XMLOutputter;
57    
58     import schmitzm.geotools.styling.StylingUtil;
59     import schmitzm.io.IOUtil;
60     import schmitzm.lang.LangUtil;
61     import schmitzm.swing.SwingUtil;
62     import skrueger.AttributeMetaData;
63     import skrueger.RasterLegendData;
64     import skrueger.i8n.Translation;
65    
66     /**
67     * This class provides static helper methods for dealing with
68     * {@link StyledLayerInterface} stuff.
69     * @author <a href="mailto:[email protected]">Martin Schmitz</a> (University of Bonn/Germany)
70     * @version 1.0
71     */
72     public class StyledLayerUtil {
73     private static final Logger LOGGER = Logger.getLogger(StyledLayerUtil.class.getName());
74     private static final SAXBuilder SAX_BUILDER = new SAXBuilder();
75     private static final XMLOutputter XML_OUTPUTTER = new XMLOutputter();
76    
77     /** URL for Atlas XML schema */
78     public static final String AMLURI = "http://www.wikisquare.de/AtlasML";
79     /** Name of the XML Element for the attribute meta data map */
80     public static final String ELEM_NAME_AMD = "attributeMetaData";
81     /** Name of the XML Element for the raster legend data */
82     public static final String ELEM_NAME_RLD = "rasterLegendData";
83     /** Name of the XML Element for an attribute meta data map entry */
84     public static final String ELEM_NAME_ATTRIBUTE = "dataAttribute";
85     /** Name of the XML Element for an raster legend data entry */
86     public static final String ELEM_NAME_RASTERLEGEND = "rasterLegendItem";
87     /** Name of the XML Element for a translation */
88     public static final String ELEM_NAME_TRANSLATION = "translation";
89    
90     /**
91     * Creates a Geotools {@link MapLayer} from an object. If the object is a
92     * {@link StyledLayerInterface} then its sytle is used. In case of direct
93     * Geotools objects ({@link GridCoverage2D}, {@link AbstractGridCoverage2DReader},
94     * {@link FeatureCollection}) a default style is generated.
95     * @param object an Object
96     * @exception Exception if {@code null} is given as object or an error occurs during layer creation
97     */
98     public static MapLayer createMapLayer(Object object) throws Exception {
99     return createMapLayer(object,null);
100     }
101    
102     /**
103     * Creates a Geotools {@link MapLayer} from an object. If the object is a
104     * {@link StyledLayerInterface} then its sytle is used. In case of direct
105     * Geotools objects ({@link GridCoverage2D}, {@link AbstractGridCoverage2DReader},
106     * {@link FeatureCollection}) a default style is generated.
107     * @param object an Object
108     * @param forcedStyle (SLD-)Style to force for the object
109     * @exception Exception if {@code null} is given as object or an error occurs during layer creation
110     */
111     public static MapLayer createMapLayer(Object object, Style forcedStyle) throws Exception {
112     MapLayer layer = null;
113     Style style = null;
114     if ( object instanceof StyledLayerInterface ) {
115     style = ((StyledLayerInterface<?>)object).getStyle();
116     object = ((StyledLayerInterface<?>)object).getGeoObject();
117     }
118     if ( forcedStyle != null )
119     style = forcedStyle;
120     if ( style == null )
121     style = StylingUtil.createDefaultStyle(object);
122    
123     if (object instanceof GridCoverage2D)
124     layer = new DefaultMapLayer( (GridCoverage2D) object, style);
125     if (object instanceof AbstractGridCoverage2DReader)
126     layer = new DefaultMapLayer( (AbstractGridCoverage2DReader) object, style);
127     if (object instanceof FeatureCollection)
128     layer = new DefaultMapLayer( (FeatureCollection) object, style);
129    
130     if ( layer == null )
131     throw new Exception("Can not create MapLayer from "+(object == null ? "null" : object.getClass()));
132    
133     return layer;
134     }
135    
136     /**
137     * Creates an default instance of {@link StyledLayerInterface} for a Geotools
138     * object ({@link GridCoverage2D}, {@link FeatureCollection}) with a default
139     * style.
140     * @param object an Object
141     * @param title title for the object
142     * @exception UnsupportedOperationException if {@code null} is given as object or an error occurs during creation
143     */
144     public static StyledLayerInterface<?> createStyledLayer(Object object, String title) {
145     return createStyledLayer(object, title, null);
146     }
147    
148     /**
149     * Creates an default instance of {@link StyledLayerInterface} for a Geotools
150     * object ({@link GridCoverage2D}, {@link FeatureCollection}) with a given
151     * style.
152     * @param object an Object
153     * @param title title for the object
154     * @param style style and meta data for the object
155     * @exception UnsupportedOperationException if {@code null} is given as object or an error occurs during creation
156     */
157     public static StyledLayerInterface<?> createStyledLayer(Object object, String title, StyledLayerStyle style) {
158     StyledLayerInterface<?> styledLayer = null;
159    
160     String id = (title != null) ? title : "defaultID";
161    
162     if ( object instanceof GridCoverage2D )
163     styledLayer = new StyledGridCoverage(
164     (GridCoverage2D)object,
165     id,
166     title,
167     style
168     );
169     else if ( object instanceof AbstractGridCoverage2DReader )
170     styledLayer = new StyledGridCoverageReader(
171     (AbstractGridCoverage2DReader)object,
172     id,
173     title,
174     style
175     );
176     else if ( object instanceof FeatureCollection )
177     styledLayer = new StyledFeatureCollection(
178     (FeatureCollection)object,
179     id,
180     title,
181     style
182     );
183    
184     if ( styledLayer == null )
185     throw new UnsupportedOperationException("Can not create StyledLayerInterface object from "+(object == null ? "null" : object.getClass()));
186    
187     return styledLayer;
188     }
189    
190     /**
191     * Return only the visible or invisible entries of an AttributeMetaData-Map.
192     * @param amdMap AttributeMetaData-Map
193     * @param visible indicated whether the visible or invisible entries are
194     * returned
195     */
196     public static SortedMap<Integer,AttributeMetaData> getVisibleAttributeMetaData(Map<Integer,AttributeMetaData> amdMap, boolean visible) {
197     SortedMap<Integer,AttributeMetaData> filteredMap = new TreeMap<Integer,AttributeMetaData>();
198     for (AttributeMetaData amd : amdMap.values())
199     if ( amd.isVisible() )
200     filteredMap.put(amd.getColIdx(), amd);
201    
202     return filteredMap;
203     }
204    
205    
206     /**
207     * Parses a {@link AttributeMetaData} object from an JDOM-{@link Element}.
208     * This method works like {@link AMLImport#parseDataAttribute(org.w3c.dom.Node},
209     * but for JDOM.
210     * @param element {@link Element} to parse
211     */
212     public static AttributeMetaData parseAttributeMetaData(final Element element) {
213     final Integer col = Integer.valueOf(element.getAttributeValue("col"));
214     final Boolean visible = Boolean.valueOf(element.getAttributeValue("visible"));
215     final String unit = element.getAttributeValue("unit");
216    
217     Translation name = new Translation();
218     Translation desc = new Translation();
219     for (final Element childElement : (List<Element>)element.getChildren()) {
220     if (childElement.getName() == null)
221     continue;
222    
223     if (childElement.getName().equals("name"))
224     name = parseTranslation(childElement);
225     else if (childElement.getName().equals("desc"))
226     desc = parseTranslation(childElement);
227     }
228     return new AttributeMetaData(col, visible, name, desc, unit);
229     }
230    
231     /**
232     * Parses a {@link AttributeMetaData} map from an JDOM-{@link Element}
233     * with {@code <attribute>}-childs.
234     * @param element {@link Element} to parse
235     */
236     public static Map<Integer,AttributeMetaData> parseAttributeMetaDataMap(final Element element) {
237     HashMap<Integer,AttributeMetaData> metaData = new HashMap<Integer,AttributeMetaData>();
238     List<Element> attributesElements = element.getChildren( ELEM_NAME_ATTRIBUTE );
239     for (Element attibuteElement : attributesElements)
240     {
241     AttributeMetaData attrMetaData = parseAttributeMetaData( attibuteElement );
242     metaData.put( attrMetaData.getColIdx(), attrMetaData );
243     }
244     return metaData;
245     }
246    
247     /**
248     * Loads a {@link AttributeMetaData} object from an URL.
249     * @param documentUrl {@link URL} to parse
250     * @see #parseAttributeMetaData(Element)
251     */
252     public static Map<Integer,AttributeMetaData> loadAttributeMetaDataMap(final URL documentUrl) throws Exception {
253     Document document = SAX_BUILDER.build(documentUrl);
254     return parseAttributeMetaDataMap( document.getRootElement() );
255     }
256    
257     /**
258     * Creates an JDOM {@link Element} for the given {@link AttributeMetaData}
259     * object.
260     * @param amd meta data for one attribute
261     */
262     public static Element createAttributeMetaDataElement(final AttributeMetaData amd) {
263     final Element element = new Element( ELEM_NAME_ATTRIBUTE , AMLURI);
264     element.setAttribute("col", String.valueOf( amd.getColIdx() ) );
265     element.setAttribute("visible", String.valueOf( amd.isVisible() ) );
266     element.setAttribute("unit", amd.getUnit() );
267     // Creating a aml:name tag...
268     element.addContent( createTranslationElement("name", amd.getTitle()) );
269     // Creating a aml:desc tag...
270     element.addContent( createTranslationElement("desc", amd.getDesc()) );
271     return element;
272     }
273    
274     /**
275     * Creates an JDOM {@link Element} for the given {@link AttributeMetaData}
276     * map.
277     * @param amdMap map of attribute meta data
278     */
279     public static Element createAttributeMetaDataMapElement(final Map<Integer,AttributeMetaData> amdMap) {
280     final Element element = new Element( ELEM_NAME_AMD , AMLURI);
281     for (AttributeMetaData amd : amdMap.values())
282     element.addContent( createAttributeMetaDataElement( amd ) );
283     return element;
284     }
285    
286     /**
287     * Saves a {@link AttributeMetaData AttributeMetaData-Map} to an URL.
288     * @param amdMap map of {@link AttributeMetaData}
289     * @param documentUrl {@link URL} to store the XML
290     */
291     public static void saveAttributeMetaDataMap(final Map<Integer,AttributeMetaData> amdMap, final URL documentUrl) throws Exception {
292     // Create XML-Document
293     final FileWriter out = new FileWriter( new File(documentUrl.toURI()) );
294     XML_OUTPUTTER.output(
295     createAttributeMetaDataMapElement(amdMap),
296     out
297     );
298     out.flush();
299     out.close();
300     }
301    
302    
303    
304     /**
305     * Parses a {@link RasterLegendData} object from an JDOM-{@link Element}.
306     * This method works like {@link AMLImport#parseRasterLegendData(org.w3c.dom.Node},
307     * but for JDOM.
308     * @param element {@link Element} to parse
309     */
310     public static RasterLegendData parseRasterLegendData(Element element) {
311    
312     final boolean paintGaps = Boolean.valueOf( element.getAttributeValue("paintGaps") );
313    
314     RasterLegendData rld = new RasterLegendData(paintGaps);
315    
316     for ( Element childElement : (List<Element>)element.getChildren() ) {
317     final String name = childElement.getName();
318     // Cancel if it's an attribute
319     if ( childElement.getChildren().size() == 0 )
320     continue;
321    
322     if (name.equals( ELEM_NAME_RASTERLEGEND )) {
323     final String valueAttr = childElement.getAttributeValue("value");
324     if ( valueAttr == null )
325     throw new UnsupportedOperationException("Attribute 'value' missing for definition of <"+ELEM_NAME_RASTERLEGEND+">");
326     final double value = Double.valueOf(valueAttr);
327    
328     // first and only item should be the label
329     final Element labelElement = childElement.getChild("label");
330     // id label element is missing, the translation is searched directly
331     // as childs of the rasterLegendItem element
332     Translation label = parseTranslation( labelElement != null ? labelElement : childElement );
333     rld.put(value, label);
334     }
335     }
336    
337     return rld;
338     }
339    
340     /**
341     * Loads a {@link RasterLegendData} object from an URL.
342     * @param documentUrl {@link URL} to parse
343     * @see #parseAttributeMetaData(Element)
344     */
345     public static RasterLegendData loadRasterLegendData(final URL documentUrl) throws Exception {
346     Document document = SAX_BUILDER.build(documentUrl);
347     return parseRasterLegendData( document.getRootElement() );
348     }
349    
350     /**
351     * Creates an JDOM {@link Element} for the given {@link RasterLegendData}
352     * map.
353     * @param rld raster legend data
354     */
355     public static Element createRasterLegendDataElement(final RasterLegendData rld) {
356     final Element element = new Element( ELEM_NAME_RLD , AMLURI);
357     element.setAttribute("paintGaps", rld.isPaintGaps().toString());
358     for (Double key : rld.getSortedKeys()) {
359     Element item = new Element( ELEM_NAME_RASTERLEGEND, AMLURI);
360     item.setAttribute("value", key.toString());
361     item.addContent( createTranslationElement("label", rld.get(key)) );
362     element.addContent(item);
363     }
364     return element;
365     }
366    
367     /**
368     * Creates {@link RasterLegendData} from a {@link ColorMap}.
369     * @param colorMap a color map
370     * @param paintGaps indicated whether gaps are painted between the legend items
371     * @param digits number of digits the grid value classes (and legend) are
372     * rounded to (null means no round; >= 0 means digits after comma;
373     * < 0 means digits before comma) */
374     public static RasterLegendData generateRasterLegendData(ColorMap colorMap, boolean paintGaps, Integer digits) {
375     DecimalFormat decFormat = digits != null ? new DecimalFormat( SwingUtil.getNumberFormatPattern(digits) ) : null;
376     RasterLegendData rld = new RasterLegendData(paintGaps);
377     for (ColorMapEntry cme : colorMap.getColorMapEntries())
378     {
379     double value = StylingUtil.getQuantityFromColorMapEntry(cme);
380     String label = cme.getLabel();
381     // if no label is set (e.g. quantitative style),
382     // use the value as label
383     if ( label == null || label.equals("") )
384     if ( digits == null )
385     label = String.valueOf(value);
386     else
387     label = decFormat.format( LangUtil.round(value, digits) );
388     rld.put( value, new Translation(" "+label) );
389     }
390     return rld;
391     }
392    
393     /**
394     * Creates {@link RasterLegendData} from the {@link ColorMap} of a style.
395     * @param style a raster style (must contain a {@link RasterSymbolizer})
396     * @param paintGaps indicated whether gaps are painted between the legend items
397     * @param digits number of digits the grid value classes (and legend) are
398     * rounded to (null means no round; >= 0 means digits after comma;
399     * < 0 means digits before comma) */
400     public static RasterLegendData generateRasterLegendData(Style style, boolean paintGaps, Integer digits) {
401     ColorMap colorMap = StylingUtil.getColorMapFromStyle(style);
402     if ( colorMap == null)
403     throw new IllegalArgumentException("Color map can not be determined from style!");
404     return generateRasterLegendData(colorMap, paintGaps, digits);
405     }
406    
407     /**
408     * Saves a {@link RasterLegendData} to an URL.
409     * @param rld raster legend data
410     * @param documentUrl {@link URL} to store the XML
411     */
412     public static void saveRasterLegendData(final RasterLegendData rld, final URL documentUrl) throws Exception {
413     // Create XML-Document
414     final FileWriter out = new FileWriter( new File(documentUrl.toURI()) );
415     XML_OUTPUTTER.output(
416     createRasterLegendDataElement(rld),
417     out
418     );
419     out.flush();
420     out.close();
421     }
422    
423     /**
424     * Parses a {@link Translation} object from an JDOM-{@link Element}.
425     * This method works like {@link AMLImport#parseTranslation(org.w3c.dom.Node},
426     * but for JDOM.
427     * @param element {@link Element} to parse
428     */
429     public final static Translation parseTranslation(final Element element) {
430     Translation trans = new Translation();
431    
432     if (element == null)
433     return trans;
434    
435     for (final Element translationElement : (List<Element>)element.getChildren()) {
436     final String name = translationElement.getName();
437     if (name == null)
438     continue;
439    
440     // lang attribute
441     String lang = translationElement.getAttributeValue("lang");
442     // set the default, if no language code is set
443     if ( lang == null )
444     lang = Translation.DEFAULT_KEY;
445    
446     final String translationText = translationElement.getValue();
447     if (translationText == null)
448     trans.put(lang, "");
449     else
450     trans.put(lang, translationText);
451     }
452    
453     // if no <translation> is given, the value of the node should
454     // be used as a default translation
455     if (trans.size() == 0)
456     trans.put( Translation.DEFAULT_KEY, element.getValue() );
457     // trans = new Translation( ((List<Element>)element.getChildren()).get(0).getValue() );
458    
459     return trans;
460     }
461    
462     /**
463     * Creates an JDOM {@link Element} for the given {@link Translation}.
464     * @param tagname Name of the Element
465     * @param translation Translation to store in the Element
466     */
467     public final static Element createTranslationElement(String tagname, Translation translation) {
468     Element element = new Element(tagname, AMLURI);
469     if ( translation == null )
470     throw new UnsupportedOperationException("Translation element can not be created from null!");
471    
472     // If only a default translation is set, the <translation lang="..">..</tranlation>
473     // part is not used
474     if (translation.keySet().size() == 1 && translation.get(Translation.DEFAULT_KEY) != null) {
475     element.addContent( translation.get(Translation.DEFAULT_KEY) );
476     return element;
477     }
478    
479     // add a <translation lang="..">..</tranlation> part to the element for
480     // all languages
481     for (String lang : translation.keySet()) {
482     Element translationElement = new Element( ELEM_NAME_TRANSLATION , AMLURI);
483     translationElement.setAttribute("lang", lang);
484     String translationString = translation.get(lang);
485     if (translationString == null)
486     translationString = "";
487     translationElement.addContent( translationString );
488     element.addContent(translationElement);
489     }
490    
491     return element;
492     }
493    
494    
495     /**
496     * Sets a style to {@link StyledLayerInterface}.
497     * @param styledObject a styled object
498     * @param style a Style
499     */
500     public static void setStyledLayerStyle(StyledLayerInterface styledObject, StyledLayerStyle<?> style) {
501     // set SLD style
502     styledObject.setStyle( style.getGeoObjectStyle() );
503     // set meta data
504     if ( styledObject instanceof StyledGridCoverageInterface &&
505     (style.getMetaData() instanceof RasterLegendData || style.getMetaData() == null) ) {
506     RasterLegendData sourceRld = (RasterLegendData)style.getMetaData();
507     RasterLegendData destRld = ((StyledGridCoverageInterface)styledObject).getLegendMetaData();
508     if ( destRld != null && sourceRld != null ) {
509     destRld.setPaintGaps(sourceRld.isPaintGaps());
510     destRld.clear();
511     destRld.putAll( sourceRld );
512     }
513     return;
514     }
515     if ( styledObject instanceof StyledFeatureCollectionInterface &&
516     (style.getMetaData() instanceof Map || style.getMetaData() == null) ) {
517     Map<Integer, AttributeMetaData> sourceAmd = (Map<Integer, AttributeMetaData>)style.getMetaData();
518     Map<Integer, AttributeMetaData> destAmd = ((StyledFeatureCollectionInterface)styledObject).getAttributeMetaDataMap();
519     if ( destAmd != null && sourceAmd != null ) {
520     destAmd.clear();
521     destAmd.putAll( sourceAmd );
522     }
523     return;
524     }
525    
526     throw new UnsupportedOperationException("Style is not compatible to object: " +
527     (style.getMetaData() == null ? null : style.getMetaData().getClass().getSimpleName()) +
528     " <-> " +
529     (styledObject == null ? null : styledObject.getClass().getSimpleName()));
530     }
531    
532     /**
533     * Returns the style a {@link StyledLayerInterface} as a {@link StyledLayerStyle}.
534     * @param styledObject a styled object
535     * @return {@code StyledLayerStyle<RasterLegendData>} for {@link StyledGridCoverageInterface}
536     * or {@code StyledLayerStyle<Map<Integer,AttributeMetaData>>} for
537     * {@link StyledFeatureCollectionInterface}
538     */
539     public static StyledLayerStyle<?> getStyledLayerStyle(StyledLayerInterface styledObject) {
540     if ( styledObject instanceof StyledGridCoverageInterface )
541     return getStyledLayerStyle( (StyledGridCoverageInterface)styledObject );
542     if ( styledObject instanceof StyledFeatureCollectionInterface )
543     return getStyledLayerStyle( (StyledFeatureCollectionInterface)styledObject );
544     throw new UnsupportedOperationException("Unknown type of StyledLayerInterface: "+(styledObject == null ? null : styledObject.getClass().getSimpleName()));
545     }
546    
547     /**
548     * Returns the style and raster meta data of a {@link StyledGridCoverageInterface}
549     * as a {@link StyledLayerStyle}.
550     * @param styledGC a styled grid coverage
551     */
552     public static StyledLayerStyle<RasterLegendData> getStyledLayerStyle(StyledGridCoverageInterface styledGC) {
553     return new StyledLayerStyle<RasterLegendData>(
554     styledGC.getStyle(),
555     styledGC.getLegendMetaData()
556     );
557     }
558    
559     /**
560     * Returns the style and attribute meta data of a {@link StyledFeatureCollectionInterface}
561     * as a {@link StyledLayerStyle}.
562     * @param styledFC a styled feature collection
563     */
564     public static StyledLayerStyle<Map<Integer,AttributeMetaData>> getStyledLayerStyle(StyledFeatureCollectionInterface styledFC) {
565     return new StyledLayerStyle<Map<Integer,AttributeMetaData>>(
566     styledFC.getStyle(),
567     styledFC.getAttributeMetaDataMap()
568     );
569     }
570    
571     /**
572     * Loads a {@linkplain Style SLD-Style} and {@linkplain RasterLegendData Raster-LegendData}
573     * for a given geo-object (raster) source. The SLD file must be present. A missing
574     * raster legend-data file is tolerated.
575     * @param geoObjectURL URL of the (already read) raster object
576     * @param sldExt file extention for the SLD file
577     * @param rldExt file extention for the raster legend-data file
578     * @return {@code null} in case of any error
579     */
580     public static StyledLayerStyle<RasterLegendData> loadStyledRasterStyle(URL geoObjectURL, String sldExt, String rldExt) {
581     RasterLegendData metaData = null;
582     Style sldStyle = null;
583     try {
584     Style[] styles = StylingUtil.loadSLD(IOUtil.changeUrlExt(geoObjectURL, sldExt));
585     // SLD must be present
586     if ( styles == null || styles.length == 0 )
587     return null;
588     sldStyle = styles[0];
589     }
590     catch (Exception err) {
591     // SLD must be present
592     LangUtil.logDebugError(LOGGER,err);
593     return null;
594     }
595    
596     try {
597     metaData = StyledLayerUtil.loadRasterLegendData( IOUtil.changeUrlExt(geoObjectURL,rldExt) );
598     } catch (FileNotFoundException err) {
599     // ignore missing raster legend data
600     } catch (Exception err) {
601     // any other error during legend data creation leads to error
602     LangUtil.logDebugError(LOGGER,err);
603     return null;
604     }
605     return new StyledLayerStyle<RasterLegendData>(sldStyle, metaData);
606     }
607    
608     /**
609     * Loads a {@linkplain Style SLD-Style} from a {@code .sld} file and
610     * {@linkplain RasterLegendData Raster-LegendData} from a {@code .rld} file
611     * for a given geo-object (raster) source. The SLD file must be present. A missing
612     * raster legend-data file is tolerated.
613     * @param geoObjectURL URL of the (already read) raster object
614     * @param sldExt file extention for the SLD file
615     * @param rldExt file extention for the raster legend-data file
616     * @return {@code null} in case of any error
617     */
618     public static StyledLayerStyle<RasterLegendData> loadStyledRasterStyle(URL geoObjectURL) {
619     return loadStyledRasterStyle(geoObjectURL, "sld", "rld");
620     }
621    
622     /**
623     * Loads a {@linkplain Style SLD-Style} and a {@linkplain AttributeMetaData AttributeMetaData-Map}
624     * for a given geo-object (feature) source. The SLD file must be present. A missing
625     * attribute meta-data file is tolerated.
626     * @param geoObjectURL URL of the (already read) feature object
627     * @param sldExt file extention for the SLD file
628     * @param rldExt file extention for the raster legend-data file
629     * @return {@code null} in case of any error
630     */
631     public static StyledLayerStyle<Map<Integer,AttributeMetaData>> loadStyledFeatureStyle(URL geoObjectURL, String sldExt, String rldExt) {
632     Map<Integer,AttributeMetaData> metaData = null;
633     Style sldStyle = null;
634     try {
635     Style[] styles = StylingUtil.loadSLD(IOUtil.changeUrlExt(geoObjectURL, sldExt));
636     // SLD must be present
637     if ( styles == null || styles.length == 0 )
638     return null;
639     sldStyle = styles[0];
640     } catch (Exception err) {
641     // SLD must be present
642     LangUtil.logDebugError(LOGGER,err);
643     return null;
644     }
645    
646     try {
647     metaData = StyledLayerUtil.loadAttributeMetaDataMap( IOUtil.changeUrlExt(geoObjectURL,rldExt) );
648     } catch (FileNotFoundException err) {
649     // ignore missing attribute meta data
650     } catch (Exception err) {
651     // any other error during meta data creation leads to error
652     LangUtil.logDebugError(LOGGER,err);
653     return null;
654     }
655    
656     return new StyledLayerStyle<Map<Integer,AttributeMetaData>>(sldStyle, metaData);
657     }
658    
659     /**
660     * Loads a {@linkplain Style SLD-Style} from a {@code .sld} file and
661     * {@linkplain AttributeMetaData AttributeMetaData-Map} from a {@code .amd} file
662     * for a given geo-object (feature) source. The SLD file must be present. A missing
663     * attribute meta-data file is tolerated.
664     * @param geoObjectURL URL of the (already read) feature object
665     * @param sldExt file extention for the SLD file
666     * @param rldExt file extention for the raster legend-data file
667     * @return {@code null} in case of any error
668     */
669     public static StyledLayerStyle<Map<Integer,AttributeMetaData>> loadStyledFeatureStyle(URL geoObjectURL) {
670     return loadStyledFeatureStyle(geoObjectURL, "sld", "amd");
671     }
672    
673     /**
674     * Stores a {@linkplain Style SLD-Style} and {@linkplain RasterLegendData Raster-LegendData}
675     * for a given geo-object (raster) source.
676     * @param style style to save
677     * @param geoObjectURL URL of the raster object
678     * @param sldExt file extention for the SLD file
679     * @param mdExt file extention for the meta-data file
680     */
681     public static <T> void saveStyledLayerStyle(StyledLayerStyle<T> style, URL geoObjectURL, String sldExt, String mdExt) throws Exception {
682     // Store the SLD
683     Style sldStyle = style.getGeoObjectStyle();
684     if ( sldStyle != null ) {
685     StylingUtil.saveStyleToSLD(
686     sldStyle,
687     IOUtil.changeFileExt(
688     new File(geoObjectURL.toURI()),
689     sldExt
690     )
691     );
692     }
693    
694     // Store the meta data
695     T metaData = style.getMetaData();
696     if ( metaData != null ) {
697     if ( metaData instanceof RasterLegendData ) {
698     saveRasterLegendData(
699     (RasterLegendData)metaData,
700     IOUtil.changeUrlExt(geoObjectURL,mdExt)
701     );
702     // } else if ( metaData instanceof Map<Integer,AttributeMetaData> ) { // LEIDER NICHT KOMPILIERBAR!!
703     } else if ( metaData instanceof Map ) {
704     saveAttributeMetaDataMap(
705     (Map<Integer,AttributeMetaData>)metaData,
706     IOUtil.changeUrlExt(geoObjectURL,mdExt)
707     );
708     } else
709     throw new UnsupportedOperationException("Export for meta data not yet supported: "+metaData.getClass().getSimpleName());
710     }
711     }
712    
713     /**
714     * Stores the {@linkplain Style SLD-Style} to a {@code .sld} file and
715     * the meta data ({@link RasterLegendData} or {@link AttributeMetaData})
716     * to a {@code .rld} or {@code .amd} file.
717     * for a given geo-object source.
718     * @param style style to save
719     * @param geoObjectURL URL of the (already read) raster object
720     */
721     public static void saveStyledLayerStyle(StyledLayerStyle<?> style, URL geoObjectURL) throws Exception {
722     if ( style.getMetaData() instanceof RasterLegendData )
723     saveStyledLayerStyle(style,geoObjectURL, "sld", "rld");
724     else
725     saveStyledLayerStyle(style,geoObjectURL, "sld", "amd");
726     }
727    
728     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26