org.mapfish.print.map.renderers.vector.PointRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.mapfish.print.map.renderers.vector.PointRenderer.java

Source

/*
 * Copyright (C) 2009  Camptocamp
 *
 * This file is part of MapFish Server
 *
 * MapFish Server is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MapFish Server is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with MapFish Server.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.mapfish.print.map.renderers.vector;

import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Coordinate;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Image;
import com.lowagie.text.DocumentException;
import org.mapfish.print.RenderingContext;
import org.mapfish.print.PDFUtils;
import org.mapfish.print.InvalidValueException;
import org.mapfish.print.config.ColorWrapper;
import org.mapfish.print.utils.PJsonObject;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.HashMap;

/**
 * Render point geometries. Support for the 3 OL stylings:
 * <ol>
 * <li>externalGraphic
 * <li>graphicName
 * <li>circle
 * </ol>
 */
public class PointRenderer extends GeometriesRenderer<Point> {

    private static final Map<String, float[]> SYMBOLS = new HashMap<String, float[]>();

    static {
        SYMBOLS.put("star", normalizeSymbol(new float[] { 350, 75, 379, 161, 469, 161, 397, 215, 423, 301, 350, 250,
                277, 301, 303, 215, 231, 161, 321, 161, 350, 75 }));
        SYMBOLS.put("cross", normalizeSymbol(
                new float[] { 4, 0, 6, 0, 6, 4, 10, 4, 10, 6, 6, 6, 6, 10, 4, 10, 4, 6, 0, 6, 0, 4, 4, 4, 4, 0 }));
        SYMBOLS.put("x", normalizeSymbol(new float[] { 0, 0, 25, 0, 50, 35, 75, 0, 100, 0, 65, 50, 100, 100, 75,
                100, 50, 65, 25, 100, 0, 100, 35, 50, 0, 0 }));
        SYMBOLS.put("square", normalizeSymbol(new float[] { 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 }));
        SYMBOLS.put("triangle", normalizeSymbol(new float[] { 0, 10, 10, 10, 5, 0, 0, 10 }));
    }

    private static float[] normalizeSymbol(float[] coords) {
        float minX = Float.MAX_VALUE;
        float maxX = -Float.MAX_VALUE;
        float minY = Float.MAX_VALUE;
        float maxY = -Float.MAX_VALUE;
        for (int i = 0; i < coords.length; i += 2) {
            float x = coords[i];
            float y = coords[i + 1];
            minX = Math.min(minX, x);
            maxX = Math.max(maxX, x);
            minY = Math.min(minY, y);
            maxY = Math.max(maxY, y);
        }
        float width = maxX - minX;
        float height = maxY - minY;
        for (int i = 0; i < coords.length; i += 2) {
            coords[i] = (coords[i] - minX) / width;
            coords[i + 1] = (coords[i + 1] - minY) / height;
        }
        return coords;
    }

    protected void renderImpl(RenderingContext context, PdfContentByte dc, PJsonObject style, Point geometry) {
        PdfGState state = new PdfGState();
        final Coordinate coordinate = geometry.getCoordinate();
        float pointRadius = style.optFloat("pointRadius", 4.0f);
        final float f = context.getStyleFactor();

        String graphicName = style.optString("graphicName");
        float width = style.optFloat("graphicWidth", pointRadius * 2.0f);
        float height = style.optFloat("graphicHeight", pointRadius * 2.0f);
        float offsetX = style.optFloat("graphicXOffset", -width / 2.0f);
        float offsetY = style.optFloat("graphicYOffset", -height / 2.0f);
        // See Feature/Vector.js for more information about labels
        String label = style.optString("label");
        String labelAlign = style.optString("labelAlign", "lb");
        /*
         * Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. 
         * Valid values for vertical alignment: "t"=top, "m"=middle, "b"=bottom.
         */
        float labelXOffset = style.optFloat("labelXOffset", (float) 0.0);
        float labelYOffset = style.optFloat("labelYOffset", (float) 0.0);
        String fontColor = style.optString("fontColor", "#000000");
        /* Supported itext fonts: COURIER, HELVETICA, TIMES_ROMAN */
        String fontFamily = style.optString("fontFamily", "HELVETICA");
        String fontSize = style.optString("fontSize", "12");
        String fontWeight = style.optString("fontWeight", "normal");

        if (style.optString("externalGraphic") != null) {
            float opacity = style.optFloat("graphicOpacity", style.optFloat("fillOpacity", 1.0f));
            state.setFillOpacity(opacity);
            state.setStrokeOpacity(opacity);
            dc.setGState(state);
            try {
                Image image = PDFUtils.createImage(context, width * f, height * f,
                        new URI(style.getString("externalGraphic")), 0.0f);
                image.setAbsolutePosition((float) coordinate.x + offsetX * f, (float) coordinate.y + offsetY * f);
                dc.addImage(image);
            } catch (BadElementException e) {
                context.addError(e);
            } catch (URISyntaxException e) {
                context.addError(e);
            } catch (DocumentException e) {
                context.addError(e);
            }

        } else if (graphicName != null && !graphicName.equalsIgnoreCase("circle")) {
            PolygonRenderer.applyStyle(context, dc, style, state);
            float[] symbol = SYMBOLS.get(graphicName);
            if (symbol == null) {
                throw new InvalidValueException("graphicName", graphicName);
            }
            dc.setGState(state);
            dc.moveTo((float) coordinate.x + symbol[0] * width * f + offsetX * f,
                    (float) coordinate.y + symbol[1] * height * f + offsetY * f);
            for (int i = 2; i < symbol.length - 2; i += 2) {
                dc.lineTo((float) coordinate.x + symbol[i] * width * f + offsetX * f,
                        (float) coordinate.y + symbol[i + 1] * height * f + offsetY * f);

            }
            dc.closePath();
            dc.fillStroke();

        } else if (label != null && label.length() > 0) {
            BaseFont bf = PDFUtils.getBaseFont(fontFamily, fontSize, fontWeight);
            float fontHeight = (float) Double.parseDouble(fontSize.toLowerCase().replaceAll("px", "")) * f;
            dc.setFontAndSize(bf, fontHeight);
            dc.setColorFill(ColorWrapper.convertColor(fontColor));
            state.setFillOpacity((float) 1.0);
            dc.setGState(state);
            dc.beginText();
            dc.setTextMatrix((float) coordinate.x + labelXOffset * f, (float) coordinate.y + labelYOffset * f);
            dc.setGState(state);
            dc.showTextAligned(PDFUtils.getHorizontalAlignment(labelAlign), label,
                    (float) coordinate.x + labelXOffset * f,
                    (float) coordinate.y + labelYOffset * f - PDFUtils.getVerticalOffset(labelAlign, fontHeight),
                    0);
            dc.endText();
        } else {
            PolygonRenderer.applyStyle(context, dc, style, state);
            dc.setGState(state);

            dc.circle((float) coordinate.x, (float) coordinate.y, pointRadius * f);
            dc.fillStroke();
        }
    }
}