/[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 111 - (hide annotations)
Tue May 12 23:33:14 2009 UTC (15 years, 9 months ago) by alfonx
Original Path: trunk/src/skrueger/geotools/StyledMapUtil.java
File size: 29200 byte(s)
* Fixed some bugs with the SelectionListeners and the JMapPane. To make this work,  StyledFeatureLayerSelectionModel now extends StyledLayerSelectionModel<String>. So the selection is remembered as a Set of Feature-IDs. This change was needed, because Feature.java doesn't overwrite the equals method, and therefore the HashSet didn't function as expected.
* Added new Tools and BUttons to MapPaneToolBar.java to select features
* Changed a lot in MapPaneToolBar.java. It now allows to position Spaces, Actions and Tools via the ID field. (the new feature is to mix them)
* Fixed a bug in AV's ClickInfoPanel that would suddenly pop up an AtlasViewer if started from Geopublisher under special circumstances.
* Moving layers in the legend is using MapContext's move method instead of remove and insert.
* LayerPanel's remember* Maps now all have the MapLayer's ID as a key. 

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26