package org.geotools.map.direct; import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.map.DirectLayer; import org.geotools.map.MapContent; import org.geotools.map.MapViewport; import org.geotools.util.Converters; /** * This is a simple watermark used to place a message (such as copyright information) onto a map. * * @author Jody * * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/render/src/main/java/org/geotools/map/direct/MessageDirectLayer.java $ */ public class MessageDirectLayer extends DirectLayer { /** * Message to be displayed. While it is perfectly alright to just use the getUserData() map we * are making use of an field here in order to verify the ability to fire events correctly when * the message is changed. */ private String message; /** * Key used to store optional color in getUserData() */ private static final String COLOR = "color"; /** * Key used to store x position in getUserData(). */ public static final String X = "x"; /** * Key used to store y position in getUserData() */ public static final String Y = "y"; public MessageDirectLayer(String message) { this.message = message; } @Override public void draw(Graphics2D graphics, MapContent map, MapViewport viewport) { if (viewport == null) { viewport = map.getViewport(); // use the map viewport if one has not been provided } if (viewport == null || viewport.getScreenArea() == null) { return; // renderer is not set up for use yet } if (message == null || message.length() == 0) { return; // no message to draw } Rectangle2D screen = rectangle2D(viewport.getScreenArea()); Double dx = Converters.convert(getUserData().get(X), Double.class); Double dy = Converters.convert(getUserData().get(Y), Double.class); if (dx == null) { dx = screen.getWidth(); } if (dy == null) { dy = screen.getHeight(); } FontMetrics fm = graphics.getFontMetrics(); Rectangle2D text = fm.getStringBounds(message, graphics); double x = position( screen.getX(), screen.getWidth(), dx, text.getWidth() ); double y = position( screen.getY(),screen.getHeight(), dy, text.getHeight() ); Color color = Converters.convert( getUserData().get(COLOR), Color.class ); Color previousColor = graphics.getColor(); try { if( color != null ){ graphics.setColor(color); } graphics.drawString( message, (float) x, (float) y ); } finally { if( color != null ){ graphics.setColor( previousColor ); } } } static double position(double x, double width, double dx, double span) { double ratio = dx / width; if (ratio < 0.3) { // left alignment return x + dx; } else if (ratio > 0.7) { // right alignment return x+dx-span; } else { // center alignment return x + dx - span/2.0; } } static Rectangle2D rectangle2D(Rectangle rectangle) { if (rectangle == null) { return null; } return new Rectangle2D.Double(rectangle.x, rectangle.y, rectangle.width, rectangle.height); } /** * Does not contribute a bounding box to the map. * * @return null */ @Override public ReferencedEnvelope getBounds() { return null; } }