package org.geopublishing.atlasStyler.rulesLists; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.geopublishing.atlasStyler.ASUtil; import org.geopublishing.atlasStyler.RuleChangedEvent; import org.geotools.styling.ContrastEnhancement; import org.geotools.styling.FeatureTypeStyle; import org.geotools.styling.RasterSymbolizer; import org.geotools.styling.Rule; import org.geotools.styling.Symbolizer; import org.opengis.filter.Filter; import org.opengis.filter.expression.Expression; import org.opengis.style.ChannelSelection; import org.opengis.style.ContrastMethod; import org.opengis.style.SelectedChannelType; import de.schmitzm.geotools.FilterUtil; import de.schmitzm.geotools.styling.StyledRasterInterface; import de.schmitzm.geotools.styling.StylingUtil; /** * This RulesList styles three out of three or more band of a multiband-raster * as a RGB image. */ public class RasterRulesListRGB extends RasterRulesList { final static Logger log = Logger.getLogger(RasterRulesListRGB.class); private int[] channels = new int[3]; private ContrastMethod[] channelMethod = new ContrastMethod[3]; private Expression[] gammaValue = new Expression[3]; private ContrastMethod rsMethod = ContrastMethod.NONE;; private Expression rsGamma; public RasterRulesListRGB(StyledRasterInterface<?> styledRaster, boolean withDefaults) { super(RulesListType.RASTER_RGB, styledRaster); if (withDefaults) { channels[0] = 1; channels[1] = Math.min(2, getStyledRaster().getBandCount()); channels[2] = Math.min(3, getStyledRaster().getBandCount()); channelMethod[0] = ContrastMethod.NONE; channelMethod[1] = ContrastMethod.NONE; channelMethod[2] = ContrastMethod.NONE; } } @Override public void applyOpacity() { // Gibt nur eine Rule, wo die Opacity bei getRules gesetzt wird. } /** * 1-based * * red=1, green=2, blue=3 */ public int getChannel(int channel) { return channels[channel - 1]; } /** * 1-based * * @param channel * red=1, green=2, blue=3 */ public void setChannel(int channel, int value) { this.channels[channel - 1] = value; fireEvents(new RuleChangedEvent("Channel selection changed", this)); } /** * 1-based * * red=1, green=2, blue=3 */ public ContrastMethod getChannelMethod(int channel) { return channelMethod[channel - 1]; } /** * 1-based * * @param channel * red=1, green=2, blue=3 */ public void setChannelMethod(int channel, ContrastMethod contrastMethod) { if (contrastMethod == null) // Yes they really do use null to indicate // no // ContrastMethod is set channelMethod[channel - 1] = ContrastMethod.NONE; else channelMethod[channel - 1] = contrastMethod; fireEvents(new RuleChangedEvent("Contrastmethod for channel changed", this)); } /** * 1-based * * red=1, green=2, blue=3 */ public Expression getGammaValue(int channel) { if (gammaValue[channel - 1] == null) return FilterUtil.FILTER_FAC2.literal(1.0); // gammaValue of null // means no gammaValue // set. Default is 1.0 return gammaValue[channel - 1]; } public void setGammaValue(int channel, Double value) { gammaValue[channel - 1] = ff.literal(value); fireEvents(new RuleChangedEvent("GammaValue for channel changed", this)); } public Expression getRSGamma() { if (rsGamma == null) return FilterUtil.FILTER_FAC2.literal(1.0); return rsGamma; } public ContrastMethod getRSMethod() { return rsMethod; } public void setRSGamma(Double value) { rsGamma = ff.literal(value); fireEvents(new RuleChangedEvent( "GammaValue for RasterSymbolizer changed", this)); } public void setRSMethod(ContrastMethod contrastMethod) { if (contrastMethod == null) // Yes they really do use null to indicate // no ContrastMethod is set rsMethod = ContrastMethod.NONE; else rsMethod = contrastMethod; fireEvents(new RuleChangedEvent( "Contrastmethod for RasterSymbolizer changed", this)); } @Override public List<Rule> getRules() { RasterSymbolizer rs = StylingUtil.STYLE_BUILDER .createRasterSymbolizer(); if (getOpacity() != null) rs.setOpacity(ff.literal(getOpacity())); ContrastEnhancement rsCe = StylingUtil.STYLE_FACTORY .createContrastEnhancement(); // rsCe.setMethod(getRSMethod()); //does not work in geotools < 8.0 if (getRSMethod() == null || getRSMethod() == ContrastMethod.NONE) { // GT 2.7 does not know about NONE } else { // if (getRSMethod() == null) // rsCe.setType(FilterUtil.FILTER_FAC2.literal("NONE")); // else rsCe.setType(FilterUtil.FILTER_FAC2.literal(getRSMethod().name())); } rsCe.setGammaValue(getRSGamma()); ContrastEnhancement redCe = StylingUtil.STYLE_FACTORY .createContrastEnhancement(); redCe.setMethod(getChannelMethod(1)); redCe.setGammaValue(getGammaValue(1)); SelectedChannelType redT = StylingUtil.STYLE_FACTORY .createSelectedChannelType(String.valueOf(getChannel(1)), redCe); ContrastEnhancement greenCe = StylingUtil.STYLE_FACTORY .createContrastEnhancement(); greenCe.setMethod(getChannelMethod(2)); greenCe.setGammaValue(getGammaValue(2)); SelectedChannelType greenT = StylingUtil.STYLE_FACTORY .createSelectedChannelType(String.valueOf(getChannel(2)), greenCe); ContrastEnhancement blueCe = StylingUtil.STYLE_FACTORY .createContrastEnhancement(); blueCe.setMethod(getChannelMethod(3)); blueCe.setGammaValue(getGammaValue(3)); SelectedChannelType blueT = StylingUtil.STYLE_FACTORY .createSelectedChannelType(String.valueOf(getChannel(3)), blueCe); ChannelSelection cs = StylingUtil.STYLE_FACTORY.channelSelection(redT, greenT, blueT); if (getChannelMethod(1) != null && getChannelMethod(1) != ContrastMethod.NONE) ((ContrastEnhancement) cs.getRGBChannels()[0] .getContrastEnhancement()).setType(ff .literal(getChannelMethod(1).name())); if (getChannelMethod(2) != null && getChannelMethod(2) != ContrastMethod.NONE) ((ContrastEnhancement) cs.getRGBChannels()[1] .getContrastEnhancement()).setType(ff .literal(getChannelMethod(2).name())); if (getChannelMethod(3) != null && getChannelMethod(3) != ContrastMethod.NONE) ((ContrastEnhancement) cs.getRGBChannels()[2] .getContrastEnhancement()).setType(ff .literal(getChannelMethod(3).name())); rs.setChannelSelection(cs); rs.setContrastEnhancement(rsCe); /** * Rule mit dem oben erstellten Symbolizer zusammensetzen */ Rule rule = ASUtil.SB.createRule(rs); Filter filter = FilterUtil.ALLWAYS_TRUE_FILTER; // The order is important! This is parsed the reverse way. The last // thing added to the filter equals the first level in the XML. filter = addAbstractRlSettings(filter); rule.setFilter(filter); ArrayList<Rule> rList = new ArrayList<Rule>(); rList.add(rule); /** Saving the legend label */ rule.setTitle("TITLE" + getType().getTitle()); rule.setName("NAME" + getType().getTitle()); return rList; } @Override public void importRules(List<Rule> rules) { pushQuite(); try { if (rules.size() < 1) return; Rule r = rules.get(0); // Analyse the filters... parseAbstractRlSettings(r.getFilter()); for (Symbolizer s : r.getSymbolizers()) { if (s instanceof RasterSymbolizer) { RasterSymbolizer rs = (RasterSymbolizer) s; if (rs.getOpacity() != null) setOpacity(Double.valueOf(rs.getOpacity() .evaluate(null).toString())); setRSMethod(rs.getContrastEnhancement().getMethod()); if (rs.getContrastEnhancement().getGammaValue() == null) setRSGamma(1.0); else { setRSGamma(Double.valueOf(rs.getContrastEnhancement() .getGammaValue().toString())); } ChannelSelection cs = rs.getChannelSelection(); if (cs == null) continue; try { SelectedChannelType[] rgbChannels = cs.getRGBChannels(); setChannel(1, Integer.valueOf(rgbChannels[0] .getChannelName())); // null is returned when no method is specified if (rgbChannels[0].getContrastEnhancement().getMethod() != null) { setChannelMethod( 1, ContrastMethod.valueOf(rgbChannels[0] .getContrastEnhancement() .getMethod().name().toString())); } else { setChannelMethod(1, ContrastMethod.NONE); } if (rgbChannels[0].getContrastEnhancement() .getGammaValue() != null) { setGammaValue( 1, Double.valueOf(rgbChannels[0] .getContrastEnhancement() .getGammaValue().toString())); } else setGammaValue(1, 1.0); setChannel(2, Integer.valueOf(rgbChannels[1] .getChannelName())); if (rgbChannels[1].getContrastEnhancement().getMethod() != null) { setChannelMethod( 2, ContrastMethod.valueOf(rgbChannels[1] .getContrastEnhancement() .getMethod().name().toString())); } else { setChannelMethod(2, ContrastMethod.NONE); } if (rgbChannels[1].getContrastEnhancement() .getGammaValue() != null) { setGammaValue( 2, Double.valueOf(rgbChannels[1] .getContrastEnhancement() .getGammaValue().toString())); } else setGammaValue(2, 1.0); setChannel(3, Integer.valueOf(rgbChannels[2] .getChannelName())); if (rgbChannels[2].getContrastEnhancement().getMethod() != null) { setChannelMethod( 3, ContrastMethod.valueOf(rgbChannels[2] .getContrastEnhancement() .getMethod().name().toString())); } else { setChannelMethod(3, ContrastMethod.NONE); } if (rgbChannels[2].getContrastEnhancement() .getGammaValue() != null) { setGammaValue( 3, Double.valueOf(rgbChannels[2] .getContrastEnhancement() .getGammaValue().toString())); } else setGammaValue(2, 1.0); } catch (Exception e) { log.error("RGB channels didn't contain 3 channels??", e); continue; } return; } } } finally { popQuite(); } } @Override public void parseMetaInfoString(String metaInfoString, FeatureTypeStyle fts) { if (!metaInfoString.startsWith(getType().toString())) { // When importing a no ATlasStyler ColorMap return; } metaInfoString = metaInfoString .substring(getType().toString().length()); } }