⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaultrasterlegendproducer.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* 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.vfny.geoserver.wms.responses;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

import org.geotools.feature.AttributeType;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.geometry.jts.LiteShape2;
import org.geotools.renderer.lite.StyledShapePainter;
import org.geotools.renderer.style.SLDStyleFactory;
import org.geotools.renderer.style.Style2D;
import org.geotools.styling.FeatureTypeStyle;
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.Style;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
import org.geotools.util.NumberRange;
import org.vfny.geoserver.wms.GetLegendGraphicProducer;
import org.vfny.geoserver.wms.WmsException;
import org.vfny.geoserver.wms.requests.GetLegendGraphicRequest;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;


/**
 * Template {@linkPlain
 * org.vfny.geoserver.responses.wms.GetLegendGraphicProducer} based on
 * GeoTools' {@link
 * http://svn.geotools.org/geotools/trunk/gt/module/main/src/org/geotools/renderer/lite/StyledShapePainter.java
 * StyledShapePainter} that produces a BufferedImage with the appropiate
 * legend graphic for a given GetLegendGraphic WMS request.
 *
 * <p>
 * It should be enough for a subclass to implement {@linkPlain
 * org.vfny.geoserver.responses.wms.GetLegendGraphicProducer#writeTo(OutputStream)}
 * and <code>getContentType()</code> in order to encode the BufferedImage
 * produced by this class to the appropiate output format.
 * </p>
 *
 * <p>
 * This class takes literally the fact that the arguments <code>WIDTH</code>
 * and <code>HEIGHT</code> are just <i>hints</i> about the desired dimensions
 * of the produced graphic, and the need to produce a legend graphic
 * representative enough of the SLD style for which it is being generated.
 * Thus, if no <code>RULE</code> parameter was passed and the style has more
 * than one applicable Rule for the actual scale factor, there will be
 * generated a legend graphic of the specified width, but with as many stacked
 * graphics as applicable rules were found, providing by this way a
 * representative enough legend.
 * </p>
 *
 * @author Gabriel Roldan, Axios Engineering
 * @version $Id: DefaultRasterLegendProducer.java 7746 2007-11-13 15:38:35Z aaime $
 */
public abstract class DefaultRasterLegendProducer implements GetLegendGraphicProducer {
    /** shared package's logger */
    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(DefaultRasterLegendProducer.class.getPackage()
                                                                                           .getName());

    /** Factory that will resolve symbolizers into rendered styles */
    private static final SLDStyleFactory styleFactory = new SLDStyleFactory();

    /** Tolerance used to compare doubles for equality */
    private static final double TOLERANCE = 1e-6;

    /**
     * Singleton shape painter to serve all legend requests. We can use a
     * single shape painter instance as long as it remains thread safe.
     */
    private static final StyledShapePainter shapePainter = new StyledShapePainter(null);

    /**
     * used to create sample point shapes with LiteShape (not lines nor
     * polygons)
     */
    private static final GeometryFactory geomFac = new GeometryFactory();

    /**
     * Default Legend graphics background color
     */
    public static final Color BG_COLOR = Color.WHITE;
    /**
     * Default label color
     */
    public static final Color FONT_COLOR = Color.BLACK;
    /**
     * Image observer to help in creating the stack like legend graphic from
     * the images created for each rule
     */
    private static final ImageObserver imgObs = new Canvas();

    /** padding percentaje factor at both sides of the legend. */
    private static final float hpaddingFactor = 0.15f;

    /** top & bottom padding percentaje factor for the legend */
    private static final float vpaddingFactor = 0.15f;

    /** The image produced at <code>produceLegendGraphic</code> */
    private BufferedImage legendGraphic;

    /**
     * set to <code>true</code> when <code>abort()</code> gets called,
     * indicates that the rendering of the legend graphic should stop
     * gracefully as soon as possible
     */
    private boolean renderingStopRequested;

    /**
     * Just a holder to avoid creating many polygon shapes from inside
     * <code>getSampleShape()</code>
     */
    private LiteShape2 sampleRect;

    /**
     * Just a holder to avoid creating many line shapes from inside
     * <code>getSampleShape()</code>
     */
    private LiteShape2 sampleLine;

    /**
     * Just a holder to avoid creating many point shapes from inside
     * <code>getSampleShape()</code>
     */
    private LiteShape2 samplePoint;

    /**
     * Default constructor. Subclasses may provide its own with a String
     * parameter to establish its desired output format, if they support more
     * than one (e.g. a JAI based one)
     */
    public DefaultRasterLegendProducer() {
        super();
    }

    /**
     * Takes a GetLegendGraphicRequest and produces a BufferedImage that then
     * can be used by a subclass to encode it to the appropiate output format.
     *
     * @param request the "parsed" request, where "parsed" means that it's
     *        values are already validated so this method must not take care
     *        of verifying the requested layer exists and the like.
     *
     * @throws WmsException if there are problems creating a "sample" feature
     *         instance for the FeatureType <code>request</code> returns as
     *         the required layer (which should not occur).
     */
    public void produceLegendGraphic(GetLegendGraphicRequest request)
        throws WmsException {
        final Feature sampleFeature = createSampleFeature(request.getLayer());

        final Style gt2Style = request.getStyle();
        final FeatureTypeStyle[] ftStyles = gt2Style.getFeatureTypeStyles();

        final double scaleDenominator = request.getScale();

        final Rule[] applicableRules;

        if (request.getRule() != null) {
            applicableRules = new Rule[] { request.getRule() };
        } else {
            applicableRules = getApplicableRules(ftStyles, scaleDenominator);
        }

        final NumberRange scaleRange = new NumberRange(scaleDenominator, scaleDenominator);

        final int ruleCount = applicableRules.length;

        /**
         * A legend graphic is produced for each applicable rule. They're being
         * held here until the process is done and then painted on a "stack"
         * like legend.
         */
        final List /*<BufferedImage>*/ legendsStack = new ArrayList(ruleCount);

        final int w = request.getWidth();
        final int h = request.getHeight();

        final Color bgColor = getBackgroundColor(request);
        for (int i = 0; i < ruleCount; i++) {
            Symbolizer[] symbolizers = applicableRules[i].getSymbolizers();

            //BufferedImage image = prepareImage(w, h, request.isTransparent());
            final boolean transparent = request.isTransparent();
            final RenderedImage image = ImageUtils.createImage(w, h, (IndexColorModel)null, transparent);
            final Map hintsMap = new HashMap();
            Graphics2D graphics = ImageUtils.prepareTransparency(transparent, bgColor, image, hintsMap);
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            for (int sIdx = 0; sIdx < symbolizers.length; sIdx++) {
                Symbolizer symbolizer = symbolizers[sIdx];

                if (symbolizer instanceof RasterSymbolizer) {
                    BufferedImage imgShape;

                    try {
                        imgShape = ImageIO.read(new URL(request.getHttpServletRequest()
                                                               .getRequestURL()
                                    + "/../data/images/rasterLegend.png"));
                    } catch (MalformedURLException e) {
                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
                        throw new WmsException(e);
                    } catch (IOException e) {
                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
                        throw new WmsException(e);
                    }

                    graphics.drawImage(imgShape, 0, 0, w, h, null);
                } else {
                    Style2D style2d = styleFactory.createStyle(sampleFeature, symbolizer, scaleRange);
                    LiteShape2 shape = getSampleShape(symbolizer, w, h);

                    if (style2d != null) {
                        shapePainter.paint(graphics, shape, style2d, scaleDenominator);
                    }
                }
            }

            legendsStack.add(image);
        }

        //JD: changd legend behaviour, see GEOS-812
        //this.legendGraphic = scaleImage(mergeLegends(legendsStack), request);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -