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

📄 defaultrasterlegendproducer.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * @param g - the Graphics2D that will be used to render this label
     * @return a {@link BufferedImage} of the properly rendered label.
     */
    public static BufferedImage renderLabel(String label, Graphics2D g, GetLegendGraphicRequest req) {
        // We'll accept '/n' as a text string
        //to indicate a line break, as well as a traditional 'real' line-break in the XML.
        BufferedImage renderedLabel;
        Color labelColor = getLabelFontColor(req);
        if ((label.indexOf("\n") != -1) || (label.indexOf("\\n") != -1)) {
            //this is a label WITH line-breaks...we need to figure out it's height *and*
            //width, and then adjust the legend size accordingly
            Rectangle2D bounds = new Rectangle2D.Double(0, 0, 0, 0);
            ArrayList lineHeight = new ArrayList();
            // four backslashes... "\\" -> '\', so "\\\\n" -> '\' + '\' + 'n'
            final String realLabel = label.replaceAll("\\\\n", "\n");
            StringTokenizer st = new StringTokenizer(realLabel, "\n\r\f");

            while (st.hasMoreElements()) {
                final String token = st.nextToken();
                Rectangle2D thisLineBounds = g.getFontMetrics().getStringBounds(token, g);

                //if this is directly added as thisLineBounds.getHeight(), then there are rounding errors
                //because we can only DRAW fonts at discrete integer coords.
                final int thisLineHeight = (int) Math.ceil(thisLineBounds.getHeight());
                bounds.add(0, thisLineHeight + bounds.getHeight());
                bounds.add(thisLineBounds.getWidth(), 0);
                lineHeight.add(new Integer((int) Math.ceil(thisLineBounds.getHeight())));
            }

            //make the actual label image
            renderedLabel = new BufferedImage((int) Math.ceil(bounds.getWidth()),
                    (int) Math.ceil(bounds.getHeight()), BufferedImage.TYPE_INT_ARGB);

            st = new StringTokenizer(realLabel, "\n\r\f");

            Graphics2D rlg = renderedLabel.createGraphics();
            rlg.setColor(labelColor);
            rlg.setFont(g.getFont());
            rlg.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                g.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING));

            int y = 0 - g.getFontMetrics().getDescent();
            int c = 0;

            while (st.hasMoreElements()) {
                y += ((Integer) lineHeight.get(c++)).intValue();
                rlg.drawString(st.nextToken(), 0, y);
            }
        } else {
            //this is a traditional 'regular-old' label.  Just figure the
            //size and act accordingly.
            int height = (int) Math.ceil(g.getFontMetrics().getStringBounds(label, g).getHeight());
            int width = (int) Math.ceil(g.getFontMetrics().getStringBounds(label, g).getWidth());
            renderedLabel = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

            Graphics2D rlg = renderedLabel.createGraphics();
            rlg.setColor(labelColor);
            rlg.setFont(g.getFont());
            rlg.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                g.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING));
            rlg.drawString(label, 0, height - rlg.getFontMetrics().getDescent());
        }

        return renderedLabel;
    }

    /**
     * Returns a <code>java.awt.Shape</code> appropiate to render a legend
     * graphic given the symbolizer type and the legend dimensions.
     *
     * @param symbolizer the Symbolizer for whose type a sample shape will be
     *        created
     * @param legendWidth the requested width, in output units, of the legend
     *        graphic
     * @param legendHeight the requested height, in output units, of the legend
     *        graphic
     *
     * @return an appropiate Line2D, Rectangle2D or LiteShape(Point) for the
     *         symbolizer, wether it is a LineSymbolizer, a PolygonSymbolizer,
     *         or a Point ot Text Symbolizer
     *
     * @throws IllegalArgumentException if an unknown symbolizer impl was
     *         passed in.
     */
    private LiteShape2 getSampleShape(Symbolizer symbolizer, int legendWidth, int legendHeight) {
        LiteShape2 sampleShape;
        final float hpad = (legendWidth * hpaddingFactor);
        final float vpad = (legendHeight * vpaddingFactor);

        if (symbolizer instanceof LineSymbolizer) {
            if (this.sampleLine == null) {
                Coordinate[] coords = {
                        new Coordinate(hpad, legendHeight - vpad),
                        new Coordinate(legendWidth - hpad, vpad)
                    };
                LineString geom = geomFac.createLineString(coords);

                try {
                    this.sampleLine = new LiteShape2(geom, null, null, false);
                } catch (Exception e) {
                    this.sampleLine = null;
                }
            }

            sampleShape = this.sampleLine;
        } else if ((symbolizer instanceof PolygonSymbolizer)
                || (symbolizer instanceof RasterSymbolizer)) {
            if (this.sampleRect == null) {
                final float w = legendWidth - (2 * hpad);
                final float h = legendHeight - (2 * vpad);

                Coordinate[] coords = {
                        new Coordinate(hpad, vpad), new Coordinate(hpad, vpad + h),
                        new Coordinate(hpad + w, vpad + h), new Coordinate(hpad + w, vpad),
                        new Coordinate(hpad, vpad)
                    };
                LinearRing shell = geomFac.createLinearRing(coords);
                Polygon geom = geomFac.createPolygon(shell, null);

                try {
                    this.sampleRect = new LiteShape2(geom, null, null, false);
                } catch (Exception e) {
                    this.sampleRect = null;
                }
            }

            sampleShape = this.sampleRect;
        } else if (symbolizer instanceof PointSymbolizer || symbolizer instanceof TextSymbolizer) {
            if (this.samplePoint == null) {
                Coordinate coord = new Coordinate(legendWidth / 2, legendHeight / 2);

                try {
                    this.samplePoint = new LiteShape2(geomFac.createPoint(coord), null, null, false);
                } catch (Exception e) {
                    this.samplePoint = null;
                }
            }

            sampleShape = this.samplePoint;
        } else {
            throw new IllegalArgumentException("Unknown symbolizer: " + symbolizer);
        }

        return sampleShape;
    }

    /**
     * Creates a sample Feature instance in the hope that it can be used in the
     * rendering of the legend graphic.
     *
     * @param schema the schema for which to create a sample Feature instance
     *
     * @return
     *
     * @throws WmsException
     */
    private Feature createSampleFeature(FeatureType schema)
        throws WmsException {
        Feature sampleFeature;

        try {
            AttributeType[] atts = schema.getAttributeTypes();
            Object[] attributes = new Object[atts.length];

            for (int i = 0; i < atts.length; i++)
                attributes[i] = atts[i].createDefaultValue();

            sampleFeature = schema.create(attributes);
        } catch (IllegalAttributeException e) {
            e.printStackTrace();
            throw new WmsException(e);
        }

        return sampleFeature;
    }

    /**
     * Finds the applicable Rules for the given scale denominator.
     *
     * @param ftStyles
     * @param scaleDenominator
     *
     * @return
     */
    private Rule[] getApplicableRules(FeatureTypeStyle[] ftStyles, double scaleDenominator) {
        /**
         * Holds both the rules that apply and the ElseRule's if any, in the
         * order they appear
         */
        final List ruleList = new ArrayList();

        // get applicable rules at the current scale
        for (int i = 0; i < ftStyles.length; i++) {
            FeatureTypeStyle fts = ftStyles[i];
            Rule[] rules = fts.getRules();

            for (int j = 0; j < rules.length; j++) {
                Rule r = rules[j];

                if (isWithInScale(r, scaleDenominator)) {
                    ruleList.add(r);

                    /*
                     * I'm commented this out since I guess it has no sense
                     * for producing the legend, since wether or not the rule
                     * has an else filter, the legend is drawn only if the
                     * scale denominator lies inside the rule's scale range.
                              if (r.hasElseFilter()) {
                                  ruleList.add(r);
                              }
                     */
                }
            }
        }

        return (Rule[]) ruleList.toArray(new Rule[ruleList.size()]);
    }

    /**
     * Checks if a rule can be triggered at the current scale level
     *
     * @param r The rule
     * @param scaleDenominator the scale denominator to check if it is between
     *        the rule's scale range. -1 means that it allways is.
     *
     * @return true if the scale is compatible with the rule settings
     */
    private boolean isWithInScale(Rule r, double scaleDenominator) {
        return (scaleDenominator == -1)
        || (((r.getMinScaleDenominator() - TOLERANCE) <= scaleDenominator)
        && ((r.getMaxScaleDenominator() + TOLERANCE) > scaleDenominator));
    }

    /**
     * DOCUMENT ME!
     *
     * @return
     *
     * @throws IllegalStateException DOCUMENT ME!
     */
    public BufferedImage getLegendGraphic() {
        if (this.legendGraphic == null) {
            throw new IllegalStateException();
        }

        return this.legendGraphic;
    }

    /**
     * Asks the rendering to stop processing.
     */
    public void abort() {
        this.renderingStopRequested = true;
    }
}

⌨️ 快捷键说明

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