Package org.geoserver.wms.responses.decoration

Source Code of org.geoserver.wms.responses.decoration.ScaleLineDecoration

/* 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.responses.decoration;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geotools.renderer.lite.RendererUtilities;
import org.geoserver.wms.responses.MapDecoration;
import org.vfny.geoserver.wms.WMSMapContext;

public class ScaleLineDecoration implements MapDecoration {
    /** A logger for this class. */
    private static final Logger LOGGER =
        org.geotools.util.logging.Logging.getLogger("org.geoserver.wms.responses");

    private static Map<String, Double>INCHES_PER_UNIT = new HashMap<String, Double> ();
    static {
      INCHES_PER_UNIT.put("inches", 1.0);
      INCHES_PER_UNIT.put("ft", 12.0);
      INCHES_PER_UNIT.put("mi", 63360.0);
      INCHES_PER_UNIT.put("m", 39.3701);
      INCHES_PER_UNIT.put("km", 39370.1);
      INCHES_PER_UNIT.put("dd", 4374754.0);
      INCHES_PER_UNIT.put("yd", 36.0);
  }
   
    public static final String topOutUnits = "km";
    public static final String topInUnits = "m";
    public static final String bottomOutUnits = "mi";
    public static final String bottomInUnits = "ft";
    public static final int suggestedWidth = 100;
   
    private float fontSize = 10;
    private float dpi = 25.4f / 0.28f; /// OGC Spec for SLD
    private float strokeWidth = 2;

    private Color bgcolor = Color.WHITE;
    private Color fgcolor = Color.BLACK;
   
    public void loadOptions(Map<String, String> options) {
      if (options.get("fontsize") != null) {
        try {
          this.fontSize = Float.parseFloat(options.get("fontsize"));
        } catch (Exception e) {
          this.LOGGER.log(Level.WARNING, "'fontsize' must be a float.", e);
        }
      }
     
      if (options.get("dpi") != null) {
        try {
          this.dpi = Float.parseFloat(options.get("dpi"));
        } catch (Exception e) {
          this.LOGGER.log(Level.WARNING, "'dpi' must be a float.", e);
        }
      }
     
      if (options.get("strokewidth") != null) {
        try {
          this.strokeWidth = Float.parseFloat(options.get("strokeWidth"));
        } catch (Exception e) {
          this.LOGGER.log(Level.WARNING, "'strokewidth' must be a float.", e);
        }
      }

        Color tmp = LegendDecoration.parseColor(options.get("bgcolor"));
        if (tmp != null) bgcolor = tmp;

        tmp = LegendDecoration.parseColor(options.get("fgcolor"));
        if (tmp != null) fgcolor = tmp;
    }

    public Dimension findOptimalSize(Graphics2D g2d, WMSMapContext mapContext){
      FontMetrics metrics = g2d.getFontMetrics(g2d.getFont());
      return new Dimension(
            suggestedWidth, 8 + (int)((metrics.getHeight() + metrics.getDescent()) * 2)
        );
    }
   
    public int getBarLength(double maxLength) {
      int digits = (int)(Math.log(maxLength) / Math.log(10));
      double pow10 = Math.pow(10, digits);
     
      // Find first character
      int firstCharacter = (int)(maxLength / pow10);
     
      int barLength;
      if (firstCharacter > 5) {
        barLength = 5;
      } else if (firstCharacter > 2) {
        barLength = 2;
      } else {
        barLength = 1;
      }
     
      return (int)(barLength * pow10);
    }

    public void paint(Graphics2D g2d, Rectangle paintArea, WMSMapContext mapContext)
    throws Exception {
      Color oldColor = g2d.getColor();
      Stroke oldStroke = g2d.getStroke();
      Font oldFont = g2d.getFont();
      Object oldAntialias = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
     
      // Set the font size.
      g2d.setFont(oldFont.deriveFont(this.fontSize));
     
      double scaleDenominator = RendererUtilities.calculateOGCScale(
            mapContext.getAreaOfInterest(),
            mapContext.getRequest().getWidth(),
            new HashMap()
        );
     
      String curMapUnits = "m";
     
      double normalizedScale = (scaleDenominator > 1.0)
            ? (1.0 / scaleDenominator)
            : scaleDenominator;
     
      double resolution = 1 / (normalizedScale * INCHES_PER_UNIT.get(curMapUnits) * this.dpi);
     
      int maxWidth = suggestedWidth;
     
      if (maxWidth > paintArea.getWidth()) {
        maxWidth = (int)paintArea.getWidth();
      }

        maxWidth = maxWidth - 6;
     
      double maxSizeData = maxWidth * resolution * INCHES_PER_UNIT.get(curMapUnits);
     
      String topUnits;
      String bottomUnits;
     
      if (maxSizeData > 100000) {
        topUnits = topOutUnits;
        bottomUnits = bottomOutUnits;
      } else {
        topUnits = topInUnits;
        bottomUnits = bottomInUnits;
      }
     
      double topMax = maxSizeData / INCHES_PER_UNIT.get(topUnits);
      double bottomMax = maxSizeData / INCHES_PER_UNIT.get(bottomUnits);
     
      int topRounded = this.getBarLength(topMax);
      int bottomRounded = this.getBarLength(bottomMax);
     
      topMax = topRounded / INCHES_PER_UNIT.get(curMapUnits) * INCHES_PER_UNIT.get(topUnits);
      bottomMax = bottomRounded / INCHES_PER_UNIT.get(curMapUnits) * INCHES_PER_UNIT.get(bottomUnits);
     
      int topPx = (int)(topMax / resolution);
        int bottomPx = (int)(bottomMax / resolution);
     
      int centerY = (int)paintArea.getCenterY();
      int leftX = (int)paintArea.getMinX() + ((int)paintArea.getWidth() - Math.max(topPx, bottomPx)) / 2;
     
      FontMetrics metrics = g2d.getFontMetrics(g2d.getFont());
      int prongHeight = (int)metrics.getHeight() + metrics.getDescent();
     
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);

        Rectangle frame = new Rectangle(
            leftX - 4, centerY - prongHeight - 4,
            Math.max(topPx, bottomPx) + 8, 8 + prongHeight * 2
        );

        g2d.setColor(bgcolor);
        g2d.fill(frame);;
       
        frame.height -= 1;
        frame.width -= 1;
      g2d.setColor(fgcolor);
        g2d.setStroke(new BasicStroke(1));
        g2d.draw(frame);
     
      g2d.setStroke(new BasicStroke(2));
     
      // Draw scale lines
      g2d.drawLine(leftX, centerY, leftX + topPx, centerY);
      g2d.drawLine(leftX, centerY, leftX + bottomPx, centerY);
     
      // Draw prongs
      g2d.drawLine(leftX, centerY + prongHeight, leftX, centerY - prongHeight);
      g2d.drawLine(leftX + topPx, centerY, leftX + topPx, centerY - prongHeight);
      g2d.drawLine(leftX + bottomPx, centerY, leftX + bottomPx, centerY + prongHeight);
     
      // Draw text
      String topText = topRounded + " " + topUnits;
      String bottomText = bottomRounded + " " + bottomUnits;

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAntialias);

        g2d.drawString(topText,
            leftX + (int)((topPx - metrics.stringWidth(topText)) / 2),
            centerY - prongHeight + metrics.getAscent()
        );
     
        g2d.drawString(bottomText,
            leftX + (int)((bottomPx - metrics.stringWidth(bottomText)) / 2),
            centerY + metrics.getHeight()
        );
       
      g2d.setColor(oldColor)
      g2d.setStroke(oldStroke);
      g2d.setFont(oldFont);
    }
}
TOP

Related Classes of org.geoserver.wms.responses.decoration.ScaleLineDecoration

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.