1 |
package skrueger.geotools; |
package skrueger.geotools; |
2 |
|
|
3 |
|
import java.io.File; |
4 |
|
import java.io.FileNotFoundException; |
5 |
|
import java.io.FileWriter; |
6 |
|
import java.net.URL; |
7 |
import java.text.DecimalFormat; |
import java.text.DecimalFormat; |
|
import java.util.Map; |
|
8 |
import java.util.HashMap; |
import java.util.HashMap; |
9 |
import java.util.List; |
import java.util.List; |
10 |
import java.net.URL; |
import java.util.Map; |
11 |
|
import java.util.SortedMap; |
12 |
|
import java.util.TreeMap; |
13 |
|
|
14 |
import org.geotools.feature.FeatureCollection; |
import org.apache.log4j.Logger; |
|
import org.geotools.map.MapLayer; |
|
|
import org.geotools.map.DefaultMapLayer; |
|
15 |
import org.geotools.coverage.grid.GridCoverage2D; |
import org.geotools.coverage.grid.GridCoverage2D; |
16 |
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; |
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; |
17 |
import org.geotools.data.FeatureSource; |
import org.geotools.feature.FeatureCollection; |
18 |
|
import org.geotools.map.DefaultMapLayer; |
19 |
|
import org.geotools.map.MapLayer; |
20 |
import org.geotools.styling.ColorMap; |
import org.geotools.styling.ColorMap; |
21 |
import org.geotools.styling.ColorMapEntry; |
import org.geotools.styling.ColorMapEntry; |
22 |
|
import org.geotools.styling.RasterSymbolizer; |
23 |
import org.geotools.styling.Style; |
import org.geotools.styling.Style; |
|
|
|
|
import org.apache.log4j.Logger; |
|
|
|
|
|
import org.jdom.Element; |
|
24 |
import org.jdom.Document; |
import org.jdom.Document; |
25 |
|
import org.jdom.Element; |
26 |
import org.jdom.input.SAXBuilder; |
import org.jdom.input.SAXBuilder; |
27 |
import org.jdom.output.XMLOutputter; |
import org.jdom.output.XMLOutputter; |
28 |
|
|
29 |
import schmitzm.geotools.styling.StylingUtil; |
import schmitzm.geotools.styling.StylingUtil; |
|
import skrueger.AttributeMetaData; |
|
|
import skrueger.RasterLegendData; |
|
|
import skrueger.i8n.Translation; |
|
30 |
import schmitzm.io.IOUtil; |
import schmitzm.io.IOUtil; |
|
import java.io.File; |
|
|
import java.io.FileNotFoundException; |
|
31 |
import schmitzm.lang.LangUtil; |
import schmitzm.lang.LangUtil; |
32 |
import schmitzm.swing.SwingUtil; |
import schmitzm.swing.SwingUtil; |
33 |
|
import skrueger.AttributeMetaData; |
34 |
import java.io.FileWriter; |
import skrueger.RasterLegendData; |
35 |
|
import skrueger.i8n.Translation; |
36 |
|
|
37 |
/** |
/** |
38 |
* This class provides static helper methods for dealing with |
* This class provides static helper methods for dealing with |
39 |
* {@link StyledMapInterface} stuff. |
* {@link StyledLayerInterface} stuff. |
40 |
* @author <a href="mailto:[email protected]">Martin Schmitz</a> (University of Bonn/Germany) |
* @author <a href="mailto:[email protected]">Martin Schmitz</a> (University of Bonn/Germany) |
41 |
* @version 1.0 |
* @version 1.0 |
42 |
*/ |
*/ |
43 |
public class StyledMapUtil { |
public class StyledLayerUtil { |
44 |
private static final Logger LOGGER = Logger.getLogger(StyledMapUtil.class.getName()); |
private static final Logger LOGGER = Logger.getLogger(StyledLayerUtil.class.getName()); |
45 |
private static final SAXBuilder SAX_BUILDER = new SAXBuilder(); |
private static final SAXBuilder SAX_BUILDER = new SAXBuilder(); |
46 |
private static final XMLOutputter XML_OUTPUTTER = new XMLOutputter(); |
private static final XMLOutputter XML_OUTPUTTER = new XMLOutputter(); |
47 |
|
|
60 |
|
|
61 |
/** |
/** |
62 |
* Creates a Geotools {@link MapLayer} from an object. If the object is a |
* Creates a Geotools {@link MapLayer} from an object. If the object is a |
63 |
* {@link StyledMapInterface} then its sytle is used. In case of direct |
* {@link StyledLayerInterface} then its sytle is used. In case of direct |
64 |
* Geotools objects ({@link GridCoverage2D}, {@link AbstractGridCoverage2DReader}, |
* Geotools objects ({@link GridCoverage2D}, {@link AbstractGridCoverage2DReader}, |
65 |
* {@link FeatureCollection}) a default style is generated. |
* {@link FeatureCollection}) a default style is generated. |
66 |
* @param object an Object |
* @param object an Object |
72 |
|
|
73 |
/** |
/** |
74 |
* Creates a Geotools {@link MapLayer} from an object. If the object is a |
* Creates a Geotools {@link MapLayer} from an object. If the object is a |
75 |
* {@link StyledMapInterface} then its sytle is used. In case of direct |
* {@link StyledLayerInterface} then its sytle is used. In case of direct |
76 |
* Geotools objects ({@link GridCoverage2D}, {@link AbstractGridCoverage2DReader}, |
* Geotools objects ({@link GridCoverage2D}, {@link AbstractGridCoverage2DReader}, |
77 |
* {@link FeatureCollection}) a default style is generated. |
* {@link FeatureCollection}) a default style is generated. |
78 |
* @param object an Object |
* @param object an Object |
82 |
public static MapLayer createMapLayer(Object object, Style forcedStyle) throws Exception { |
public static MapLayer createMapLayer(Object object, Style forcedStyle) throws Exception { |
83 |
MapLayer layer = null; |
MapLayer layer = null; |
84 |
Style style = null; |
Style style = null; |
85 |
if ( object instanceof StyledMapInterface ) { |
if ( object instanceof StyledLayerInterface ) { |
86 |
style = ((StyledMapInterface<?>)object).getStyle(); |
style = ((StyledLayerInterface<?>)object).getStyle(); |
87 |
object = ((StyledMapInterface<?>)object).getGeoObject(); |
object = ((StyledLayerInterface<?>)object).getGeoObject(); |
88 |
} |
} |
89 |
if ( forcedStyle != null ) |
if ( forcedStyle != null ) |
90 |
style = forcedStyle; |
style = forcedStyle; |
105 |
} |
} |
106 |
|
|
107 |
/** |
/** |
108 |
* Creates an default instance of {@link StyledMapInterface} for a Geotools |
* Creates an default instance of {@link StyledLayerInterface} for a Geotools |
109 |
* object ({@link GridCoverage2D}, {@link FeatureCollection}) with a default |
* object ({@link GridCoverage2D}, {@link FeatureCollection}) with a default |
110 |
* style. |
* style. |
111 |
* @param object an Object |
* @param object an Object |
112 |
* @param title title for the object |
* @param title title for the object |
113 |
* @exception UnsupportedOperationException if {@code null} is given as object or an error occurs during creation |
* @exception UnsupportedOperationException if {@code null} is given as object or an error occurs during creation |
114 |
*/ |
*/ |
115 |
public static StyledMapInterface<?> createStyledMap(Object object, String title) { |
public static StyledLayerInterface<?> createStyledLayer(Object object, String title) { |
116 |
return createStyledMap(object, title, null); |
return createStyledLayer(object, title, null); |
117 |
} |
} |
118 |
|
|
119 |
/** |
/** |
120 |
* Creates an default instance of {@link StyledMapInterface} for a Geotools |
* Creates an default instance of {@link StyledLayerInterface} for a Geotools |
121 |
* object ({@link GridCoverage2D}, {@link FeatureCollection}) with a given |
* object ({@link GridCoverage2D}, {@link FeatureCollection}) with a given |
122 |
* style. |
* style. |
123 |
* @param object an Object |
* @param object an Object |
125 |
* @param style style and meta data for the object |
* @param style style and meta data for the object |
126 |
* @exception UnsupportedOperationException if {@code null} is given as object or an error occurs during creation |
* @exception UnsupportedOperationException if {@code null} is given as object or an error occurs during creation |
127 |
*/ |
*/ |
128 |
public static StyledMapInterface<?> createStyledMap(Object object, String title, StyledMapStyle style) { |
public static StyledLayerInterface<?> createStyledLayer(Object object, String title, StyledLayerStyle style) { |
129 |
StyledMapInterface<?> styledObject = null; |
StyledLayerInterface<?> styledLayer = null; |
130 |
|
|
131 |
String id = (title != null) ? title : "defaultID"; |
String id = (title != null) ? title : "defaultID"; |
132 |
|
|
133 |
if ( object instanceof GridCoverage2D ) |
if ( object instanceof GridCoverage2D ) |
134 |
styledObject = new StyledGridCoverage( |
styledLayer = new StyledGridCoverage( |
135 |
(GridCoverage2D)object, |
(GridCoverage2D)object, |
136 |
id, |
id, |
137 |
title, |
title, |
138 |
style |
style |
139 |
); |
); |
140 |
else if ( object instanceof AbstractGridCoverage2DReader ) |
else if ( object instanceof AbstractGridCoverage2DReader ) |
141 |
styledObject = new StyledGridCoverageReader( |
styledLayer = new StyledGridCoverageReader( |
142 |
(AbstractGridCoverage2DReader)object, |
(AbstractGridCoverage2DReader)object, |
143 |
id, |
id, |
144 |
title, |
title, |
145 |
style |
style |
146 |
); |
); |
147 |
else if ( object instanceof FeatureCollection ) |
else if ( object instanceof FeatureCollection ) |
148 |
styledObject = new StyledFeatureCollection( |
styledLayer = new StyledFeatureCollection( |
149 |
(FeatureCollection)object, |
(FeatureCollection)object, |
150 |
id, |
id, |
151 |
title, |
title, |
152 |
style |
style |
153 |
); |
); |
154 |
|
|
155 |
if ( styledObject == null ) |
if ( styledLayer == null ) |
156 |
throw new UnsupportedOperationException("Can not create StyledMapInterface object from "+(object == null ? "null" : object.getClass())); |
throw new UnsupportedOperationException("Can not create StyledLayerInterface object from "+(object == null ? "null" : object.getClass())); |
157 |
|
|
158 |
return styledObject; |
return styledLayer; |
159 |
} |
} |
160 |
|
|
161 |
/** |
/** |
162 |
|
* Return only the visible or invisible entries of an AttributeMetaData-Map. |
163 |
|
* @param amdMap AttributeMetaData-Map |
164 |
|
* @param visible indicated whether the visible or invisible entries are |
165 |
|
* returned |
166 |
|
*/ |
167 |
|
public static SortedMap<Integer,AttributeMetaData> getVisibleAttributeMetaData(Map<Integer,AttributeMetaData> amdMap, boolean visible) { |
168 |
|
SortedMap<Integer,AttributeMetaData> filteredMap = new TreeMap<Integer,AttributeMetaData>(); |
169 |
|
for (AttributeMetaData amd : amdMap.values()) |
170 |
|
if ( amd.isVisible() ) |
171 |
|
filteredMap.put(amd.getColIdx(), amd); |
172 |
|
|
173 |
|
return filteredMap; |
174 |
|
} |
175 |
|
|
176 |
|
|
177 |
|
/** |
178 |
* Parses a {@link AttributeMetaData} object from an JDOM-{@link Element}. |
* Parses a {@link AttributeMetaData} object from an JDOM-{@link Element}. |
179 |
* This method works like {@link AMLImport#parseDataAttribute(org.w3c.dom.Node}, |
* This method works like {@link AMLImport#parseDataAttribute(org.w3c.dom.Node}, |
180 |
* but for JDOM. |
* but for JDOM. |
464 |
|
|
465 |
|
|
466 |
/** |
/** |
467 |
* Sets a style to {@link StyledMapInterface}. |
* Sets a style to {@link StyledLayerInterface}. |
468 |
* @param styledObject a styled object |
* @param styledObject a styled object |
469 |
* @param style a Style |
* @param style a Style |
470 |
*/ |
*/ |
471 |
public static void setStyledMapStyle(StyledMapInterface styledObject, StyledMapStyle<?> style) { |
public static void setStyledLayerStyle(StyledLayerInterface styledObject, StyledLayerStyle<?> style) { |
472 |
// set SLD style |
// set SLD style |
473 |
styledObject.setStyle( style.getGeoObjectStyle() ); |
styledObject.setStyle( style.getGeoObjectStyle() ); |
474 |
// set meta data |
// set meta data |
501 |
} |
} |
502 |
|
|
503 |
/** |
/** |
504 |
* Returns the style a {@link StyledMapInterface} as a {@link StyledMapStyle}. |
* Returns the style a {@link StyledLayerInterface} as a {@link StyledLayerStyle}. |
505 |
* @param styledObject a styled object |
* @param styledObject a styled object |
506 |
* @return {@code StyledMapStyle<RasterLegendData>} for {@link StyledGridCoverageInterface} |
* @return {@code StyledLayerStyle<RasterLegendData>} for {@link StyledGridCoverageInterface} |
507 |
* or {@code StyledMapStyle<Map<Integer,AttributeMetaData>>} for |
* or {@code StyledLayerStyle<Map<Integer,AttributeMetaData>>} for |
508 |
* {@link StyledFeatureCollectionInterface} |
* {@link StyledFeatureCollectionInterface} |
509 |
*/ |
*/ |
510 |
public static StyledMapStyle<?> getStyledMapStyle(StyledMapInterface styledObject) { |
public static StyledLayerStyle<?> getStyledLayerStyle(StyledLayerInterface styledObject) { |
511 |
if ( styledObject instanceof StyledGridCoverageInterface ) |
if ( styledObject instanceof StyledGridCoverageInterface ) |
512 |
return getStyledMapStyle( (StyledGridCoverageInterface)styledObject ); |
return getStyledLayerStyle( (StyledGridCoverageInterface)styledObject ); |
513 |
if ( styledObject instanceof StyledFeatureCollectionInterface ) |
if ( styledObject instanceof StyledFeatureCollectionInterface ) |
514 |
return getStyledMapStyle( (StyledFeatureCollectionInterface)styledObject ); |
return getStyledLayerStyle( (StyledFeatureCollectionInterface)styledObject ); |
515 |
throw new UnsupportedOperationException("Unknown type of StyledMapInterface: "+(styledObject == null ? null : styledObject.getClass().getSimpleName())); |
throw new UnsupportedOperationException("Unknown type of StyledLayerInterface: "+(styledObject == null ? null : styledObject.getClass().getSimpleName())); |
516 |
} |
} |
517 |
|
|
518 |
/** |
/** |
519 |
* Returns the style and raster meta data of a {@link StyledGridCoverageInterface} |
* Returns the style and raster meta data of a {@link StyledGridCoverageInterface} |
520 |
* as a {@link StyledMapStyle}. |
* as a {@link StyledLayerStyle}. |
521 |
* @param styledGC a styled grid coverage |
* @param styledGC a styled grid coverage |
522 |
*/ |
*/ |
523 |
public static StyledMapStyle<RasterLegendData> getStyledMapStyle(StyledGridCoverageInterface styledGC) { |
public static StyledLayerStyle<RasterLegendData> getStyledLayerStyle(StyledGridCoverageInterface styledGC) { |
524 |
return new StyledMapStyle<RasterLegendData>( |
return new StyledLayerStyle<RasterLegendData>( |
525 |
styledGC.getStyle(), |
styledGC.getStyle(), |
526 |
styledGC.getLegendMetaData() |
styledGC.getLegendMetaData() |
527 |
); |
); |
529 |
|
|
530 |
/** |
/** |
531 |
* Returns the style and attribute meta data of a {@link StyledFeatureCollectionInterface} |
* Returns the style and attribute meta data of a {@link StyledFeatureCollectionInterface} |
532 |
* as a {@link StyledMapStyle}. |
* as a {@link StyledLayerStyle}. |
533 |
* @param styledFC a styled feature collection |
* @param styledFC a styled feature collection |
534 |
*/ |
*/ |
535 |
public static StyledMapStyle<Map<Integer,AttributeMetaData>> getStyledMapStyle(StyledFeatureCollectionInterface styledFC) { |
public static StyledLayerStyle<Map<Integer,AttributeMetaData>> getStyledLayerStyle(StyledFeatureCollectionInterface styledFC) { |
536 |
return new StyledMapStyle<Map<Integer,AttributeMetaData>>( |
return new StyledLayerStyle<Map<Integer,AttributeMetaData>>( |
537 |
styledFC.getStyle(), |
styledFC.getStyle(), |
538 |
styledFC.getAttributeMetaDataMap() |
styledFC.getAttributeMetaDataMap() |
539 |
); |
); |
548 |
* @param rldExt file extention for the raster legend-data file |
* @param rldExt file extention for the raster legend-data file |
549 |
* @return {@code null} in case of any error |
* @return {@code null} in case of any error |
550 |
*/ |
*/ |
551 |
public static StyledMapStyle<RasterLegendData> loadStyledRasterStyle(URL geoObjectURL, String sldExt, String rldExt) { |
public static StyledLayerStyle<RasterLegendData> loadStyledRasterStyle(URL geoObjectURL, String sldExt, String rldExt) { |
552 |
RasterLegendData metaData = null; |
RasterLegendData metaData = null; |
553 |
Style sldStyle = null; |
Style sldStyle = null; |
554 |
try { |
try { |
565 |
} |
} |
566 |
|
|
567 |
try { |
try { |
568 |
metaData = StyledMapUtil.loadRasterLegendData( IOUtil.changeUrlExt(geoObjectURL,rldExt) ); |
metaData = StyledLayerUtil.loadRasterLegendData( IOUtil.changeUrlExt(geoObjectURL,rldExt) ); |
569 |
} catch (FileNotFoundException err) { |
} catch (FileNotFoundException err) { |
570 |
// ignore missing raster legend data |
// ignore missing raster legend data |
571 |
} catch (Exception err) { |
} catch (Exception err) { |
573 |
LangUtil.logDebugError(LOGGER,err); |
LangUtil.logDebugError(LOGGER,err); |
574 |
return null; |
return null; |
575 |
} |
} |
576 |
return new StyledMapStyle<RasterLegendData>(sldStyle, metaData); |
return new StyledLayerStyle<RasterLegendData>(sldStyle, metaData); |
577 |
} |
} |
578 |
|
|
579 |
/** |
/** |
586 |
* @param rldExt file extention for the raster legend-data file |
* @param rldExt file extention for the raster legend-data file |
587 |
* @return {@code null} in case of any error |
* @return {@code null} in case of any error |
588 |
*/ |
*/ |
589 |
public static StyledMapStyle<RasterLegendData> loadStyledRasterStyle(URL geoObjectURL) { |
public static StyledLayerStyle<RasterLegendData> loadStyledRasterStyle(URL geoObjectURL) { |
590 |
return loadStyledRasterStyle(geoObjectURL, "sld", "rld"); |
return loadStyledRasterStyle(geoObjectURL, "sld", "rld"); |
591 |
} |
} |
592 |
|
|
599 |
* @param rldExt file extention for the raster legend-data file |
* @param rldExt file extention for the raster legend-data file |
600 |
* @return {@code null} in case of any error |
* @return {@code null} in case of any error |
601 |
*/ |
*/ |
602 |
public static StyledMapStyle<Map<Integer,AttributeMetaData>> loadStyledFeatureStyle(URL geoObjectURL, String sldExt, String rldExt) { |
public static StyledLayerStyle<Map<Integer,AttributeMetaData>> loadStyledFeatureStyle(URL geoObjectURL, String sldExt, String rldExt) { |
603 |
Map<Integer,AttributeMetaData> metaData = null; |
Map<Integer,AttributeMetaData> metaData = null; |
604 |
Style sldStyle = null; |
Style sldStyle = null; |
605 |
try { |
try { |
615 |
} |
} |
616 |
|
|
617 |
try { |
try { |
618 |
metaData = StyledMapUtil.loadAttributeMetaDataMap( IOUtil.changeUrlExt(geoObjectURL,rldExt) ); |
metaData = StyledLayerUtil.loadAttributeMetaDataMap( IOUtil.changeUrlExt(geoObjectURL,rldExt) ); |
619 |
} catch (FileNotFoundException err) { |
} catch (FileNotFoundException err) { |
620 |
// ignore missing attribute meta data |
// ignore missing attribute meta data |
621 |
} catch (Exception err) { |
} catch (Exception err) { |
624 |
return null; |
return null; |
625 |
} |
} |
626 |
|
|
627 |
return new StyledMapStyle<Map<Integer,AttributeMetaData>>(sldStyle, metaData); |
return new StyledLayerStyle<Map<Integer,AttributeMetaData>>(sldStyle, metaData); |
628 |
} |
} |
629 |
|
|
630 |
/** |
/** |
637 |
* @param rldExt file extention for the raster legend-data file |
* @param rldExt file extention for the raster legend-data file |
638 |
* @return {@code null} in case of any error |
* @return {@code null} in case of any error |
639 |
*/ |
*/ |
640 |
public static StyledMapStyle<Map<Integer,AttributeMetaData>> loadStyledFeatureStyle(URL geoObjectURL) { |
public static StyledLayerStyle<Map<Integer,AttributeMetaData>> loadStyledFeatureStyle(URL geoObjectURL) { |
641 |
return loadStyledFeatureStyle(geoObjectURL, "sld", "amd"); |
return loadStyledFeatureStyle(geoObjectURL, "sld", "amd"); |
642 |
} |
} |
643 |
|
|
649 |
* @param sldExt file extention for the SLD file |
* @param sldExt file extention for the SLD file |
650 |
* @param mdExt file extention for the meta-data file |
* @param mdExt file extention for the meta-data file |
651 |
*/ |
*/ |
652 |
public static <T> void saveStyledMapStyle(StyledMapStyle<T> style, URL geoObjectURL, String sldExt, String mdExt) throws Exception { |
public static <T> void saveStyledLayerStyle(StyledLayerStyle<T> style, URL geoObjectURL, String sldExt, String mdExt) throws Exception { |
653 |
// Store the SLD |
// Store the SLD |
654 |
Style sldStyle = style.getGeoObjectStyle(); |
Style sldStyle = style.getGeoObjectStyle(); |
655 |
if ( sldStyle != null ) { |
if ( sldStyle != null ) { |
689 |
* @param style style to save |
* @param style style to save |
690 |
* @param geoObjectURL URL of the (already read) raster object |
* @param geoObjectURL URL of the (already read) raster object |
691 |
*/ |
*/ |
692 |
public static void saveStyledMapStyle(StyledMapStyle<?> style, URL geoObjectURL) throws Exception { |
public static void saveStyledLayerStyle(StyledLayerStyle<?> style, URL geoObjectURL) throws Exception { |
693 |
if ( style.getMetaData() instanceof RasterLegendData ) |
if ( style.getMetaData() instanceof RasterLegendData ) |
694 |
saveStyledMapStyle(style,geoObjectURL, "sld", "rld"); |
saveStyledLayerStyle(style,geoObjectURL, "sld", "rld"); |
695 |
else |
else |
696 |
saveStyledMapStyle(style,geoObjectURL, "sld", "amd"); |
saveStyledLayerStyle(style,geoObjectURL, "sld", "amd"); |
697 |
} |
} |
698 |
|
|
699 |
} |
} |