/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.wms.map;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.geotools.feature.FeatureTypes;
import org.geotools.styling.AnchorPoint;
import org.geotools.styling.ChannelSelection;
import org.geotools.styling.ColorMap;
import org.geotools.styling.ColorMapEntry;
import org.geotools.styling.ContrastEnhancement;
import org.geotools.styling.Displacement;
import org.geotools.styling.ExternalGraphic;
import org.geotools.styling.FeatureTypeConstraint;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.Fill;
import org.geotools.styling.Graphic;
import org.geotools.styling.Halo;
import org.geotools.styling.ImageOutline;
import org.geotools.styling.LinePlacement;
import org.geotools.styling.LineSymbolizer;
import org.geotools.styling.Mark;
import org.geotools.styling.NamedLayer;
import org.geotools.styling.OverlapBehavior;
import org.geotools.styling.PointPlacement;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.RasterSymbolizer;
import org.geotools.styling.Rule;
import org.geotools.styling.SelectedChannelType;
import org.geotools.styling.ShadedRelief;
import org.geotools.styling.Stroke;
import org.geotools.styling.Style;
import org.geotools.styling.StyleVisitor;
import org.geotools.styling.StyledLayer;
import org.geotools.styling.StyledLayerDescriptor;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
import org.geotools.styling.UserLayer;
import org.opengis.feature.type.FeatureType;
/**
* Extracts the active raster symbolizers, as long as there are some, and only raster symbolizers
* are available, without rendering transformations in place.
* In the case of mixed symbolizers it will return null
* TODO: extend this class so that it handles the case of other symbolizers applied after a raster
* symbolizer one (e.g., to draw a rectangle around a coverage)
*
* @author Andrea Aime
*
*/
public class RasterSymbolizerVisitor implements StyleVisitor {
double scaleDenominator;
FeatureType featureType;
List<RasterSymbolizer> symbolizers = new ArrayList<RasterSymbolizer>();
boolean otherSymbolizers = false;
boolean renderingTransformations = false;
public RasterSymbolizerVisitor(double scaleDenominator, FeatureType featureType) {
this.scaleDenominator = scaleDenominator;
this.featureType = featureType;
}
public void reset() {
symbolizers.clear();
otherSymbolizers = false;
renderingTransformations = false;
}
public List<RasterSymbolizer> getRasterSymbolizers() {
if(otherSymbolizers || renderingTransformations)
return Collections.emptyList();
else
return symbolizers;
}
public void visit(StyledLayerDescriptor sld) {
for (StyledLayer sl : sld.getStyledLayers()) {
if (sl instanceof UserLayer) {
((UserLayer) sl).accept(this);
} else if (sl instanceof NamedLayer) {
((NamedLayer) sl).accept(this);
}
}
}
public void visit(NamedLayer layer) {
for (Style s : layer.getStyles())
s.accept(this);
}
public void visit(UserLayer layer) {
for (Style s : layer.getUserStyles())
s.accept(this);
}
public void visit(FeatureTypeConstraint ftc) {
// nothing to do
}
public void visit(Style style) {
for (FeatureTypeStyle fts : style.featureTypeStyles()) {
if(fts.getTransformation() != null) {
renderingTransformations = true;
}
fts.accept(this);
}
}
public void visit(Rule rule) {
if (rule.getMinScaleDenominator() < scaleDenominator
&& rule.getMaxScaleDenominator() > scaleDenominator) {
for(Symbolizer s : rule.symbolizers())
s.accept(this);
}
}
public void visit(FeatureTypeStyle fts) {
// use the same logic as streaming renderer to decide if a fts is active
if((featureType.getName().getLocalPart() != null)
&& (featureType.getName().getLocalPart().equalsIgnoreCase(fts.getFeatureTypeName()) ||
FeatureTypes.isDecendedFrom(featureType, null, fts.getFeatureTypeName()))) {
for (Rule r : fts.rules())
r.accept(this);
}
}
public void visit(Fill fill) {
// nothing to do
}
public void visit(Stroke stroke) {
// nothing to do
}
public void visit(Symbolizer sym) {
if (sym instanceof RasterSymbolizer) {
visit((RasterSymbolizer) sym);
} else {
otherSymbolizers = true;
}
}
public void visit(PointSymbolizer ps) {
otherSymbolizers = true;
}
public void visit(LineSymbolizer line) {
otherSymbolizers = true;
}
public void visit(PolygonSymbolizer poly) {
otherSymbolizers = true;
}
public void visit(TextSymbolizer text) {
otherSymbolizers = true;
}
public void visit(RasterSymbolizer raster) {
this.symbolizers.add(raster);
}
public void visit(Graphic gr) {
// nothing to do
}
public void visit(Mark mark) {
// nothing to do
}
public void visit(ExternalGraphic exgr) {
// nothing to do
}
public void visit(PointPlacement pp) {
// nothing to do
}
public void visit(AnchorPoint ap) {
// nothing to do
}
public void visit(Displacement dis) {
// nothing to do
}
public void visit(LinePlacement lp) {
// nothing to do
}
public void visit(Halo halo) {
// nothing to do
}
public void visit(ColorMap colorMap) {
// nothing to do
}
public void visit(ColorMapEntry colorMapEntry) {
// nothing to do
}
public void visit(ContrastEnhancement contrastEnhancement) {
// nothing to do
}
public void visit(ImageOutline outline) {
// nothing to do
}
public void visit(ChannelSelection cs) {
// nothing to do
}
public void visit(OverlapBehavior ob) {
// nothing to do
}
public void visit(SelectedChannelType sct) {
// nothing to do
}
public void visit(ShadedRelief sr) {
// nothing to do
}
}