Package org.geoserver.wms.featureinfo

Source Code of org.geoserver.wms.featureinfo.DynamicSizeStyleExtractor

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wms.featureinfo;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.Icon;

import org.geotools.renderer.style.DynamicSymbolFactoryFinder;
import org.geotools.renderer.style.ExpressionExtractor;
import org.geotools.renderer.style.ExternalGraphicFactory;
import org.geotools.styling.ExternalGraphic;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.Fill;
import org.geotools.styling.Graphic;
import org.geotools.styling.LineSymbolizer;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.RasterSymbolizer;
import org.geotools.styling.Rule;
import org.geotools.styling.Stroke;
import org.geotools.styling.Style;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
import org.geotools.styling.visitor.DuplicatingStyleVisitor;
import org.geotools.util.logging.Logging;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.Literal;
import org.opengis.filter.expression.NilExpression;
import org.opengis.style.GraphicalSymbol;

/**
* Extract the portion of the style whose sizes depend on attribute values
*
* @author Andrea Aime - GeoSolutions
*/
class DynamicSizeStyleExtractor extends DuplicatingStyleVisitor {

    static final Logger LOGGER = Logging.getLogger(DynamicSizeStyleExtractor.class);

    boolean dynamic = false;

    public void visit(Rule rule) {
        super.visit(rule);
        Rule copy = (Rule) pages.peek();
        List<Symbolizer> nonNullCopies = new ArrayList<Symbolizer>();
        for (Symbolizer s : copy.symbolizers()) {
            if (s != null) {
                nonNullCopies.add(s);
            }
        }

        if (nonNullCopies.size() == 0) {
            pages.pop();
            pages.push(null);
        } else {
            copy.symbolizers().clear();
            copy.symbolizers().addAll(nonNullCopies);
        }
    }
   
    @Override
    public void visit(Fill fill) {
        // whatever goes on in a Fill does not affect the search area of fills
        boolean dynamicPrevious = false;
        try {
            super.visit(fill);
        } finally {
            dynamic = dynamicPrevious;
        }
    }

    @Override
    public void visit(FeatureTypeStyle fts) {
        super.visit(fts);
        FeatureTypeStyle copy = (FeatureTypeStyle) pages.peek();
        List<Rule> nonNullCopies = new ArrayList<Rule>();
        for (Rule r : copy.rules()) {
            if (r != null) {
                nonNullCopies.add(r);
            }
        }

        if (nonNullCopies.size() == 0) {
            pages.pop();
            pages.push(null);
        } else {
            copy.rules().clear();
            copy.rules().addAll(nonNullCopies);
        }
    }

    @Override
    public void visit(Style style) {
        super.visit(style);
        Style copy = (Style) pages.peek();
        List<FeatureTypeStyle> nonNullCopies = new ArrayList<FeatureTypeStyle>();
        for (FeatureTypeStyle ft : copy.featureTypeStyles()) {
            if (ft != null) {
                nonNullCopies.add(ft);
            }
        }

        if (nonNullCopies.size() == 0) {
            pages.pop();
            pages.push(null);
        } else {
            copy.featureTypeStyles().clear();
            copy.featureTypeStyles().addAll(nonNullCopies);
        }
    }

    @Override
    public void visit(LineSymbolizer line) {
        dynamic = false;
        super.visit(line);
        if (!dynamic) {
            pages.pop();
            pages.push(null);
        }
    }

    @Override
    public void visit(PolygonSymbolizer poly) {
        dynamic = false;
        super.visit(poly);
        if (!dynamic) {
            pages.pop();
            pages.push(null);
        }
    }

    @Override
    public void visit(PointSymbolizer ps) {
        dynamic = false;
        super.visit(ps);
        if (!dynamic) {
            pages.pop();
            pages.push(null);
        }
    }
   
    @Override
    public void visit(RasterSymbolizer raster) {
        // nothing to do, this style cannot make the buffer grow
        pages.push(null);
    }
   
    @Override
    public void visit(TextSymbolizer text) {
        // nothing to do, this style cannot make the buffer grow
        pages.push(null);
    }

    @Override
    public void visit(Graphic gr) {
        super.visit(gr);
        Expression sizeExpression = gr.getSize();
        if(!dynamic) {
            dynamic = !(sizeExpression != null && (sizeExpression instanceof Literal || sizeExpression instanceof NilExpression)) || hasDynamicGraphic(gr);
        }
    }

    private boolean hasDynamicGraphic(Graphic gr) {
        // not a fixed size, let's see if it has dynamic graphics inside
        for (GraphicalSymbol gs : gr.graphicalSymbols()) {
            if (gs instanceof ExternalGraphic) {
                ExternalGraphic eg = (ExternalGraphic) gs;
                try {
                    Icon icon = null;
                    if (eg.getInlineContent() != null) {
                        icon = eg.getInlineContent();
                    } else {
                        String location = eg.getLocation().toExternalForm();
                        // expand embedded cql expression
                        Expression expanded = ExpressionExtractor.extractCqlExpressions(location);
                        // if not a literal there is an attribute dependency
                        if (!(expanded instanceof Literal)) {
                            return true;
                        }

                        Iterator<ExternalGraphicFactory> it = DynamicSymbolFactoryFinder
                                .getExternalGraphicFactories();
                        while (it.hasNext()) {
                            try {
                                icon = it.next().getIcon(null, expanded, eg.getFormat(), 16);
                            } catch (Exception e) {
                                LOGGER.log(Level.FINE,
                                        "Error occurred evaluating external graphic", e);
                            }
                        }

                        // evaluate the icon if found, if not SLD asks us to go to the next one
                        // and thus we should ignore this one
                        if (icon != null) {
                            break;
                        }

                    }
                } catch (MalformedURLException e) {
                    LOGGER.log(Level.FINE,
                            "Failed to check graphics for attribute embedded in the path " + eg, e);
                }
            }

        }

        return false;
    }

    @Override
    public void visit(Stroke stroke) {
        super.visit(stroke);
        if (!(stroke.getWidth() instanceof Literal)) {
            dynamic = true;
        }
    }

}
TOP

Related Classes of org.geoserver.wms.featureinfo.DynamicSizeStyleExtractor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.