/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2003-2008, Open Source Geospatial Foundation (OSGeo) * * This library 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; * version 2.1 of the License. * * This library 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. */ package org.geotools.renderer.style; // J2SE dependencies import java.awt.Composite; import java.awt.Shape; import java.awt.geom.Rectangle2D; import org.geotools.geometry.jts.TransformedShape; import org.geotools.resources.Classes; /** * Style to represent points as small filled and stroked shapes * * @author Andrea Aime * * * @source $URL$ * @version $Id$ */ public class MarkStyle2D extends PolygonStyle2D implements PointStyle2D { static boolean maxMarkSizeEnabled = Boolean.getBoolean("org.geotools.maxMarkSizeEnabled"); Shape shape; double size; float rotation; float displacementX; float displacementY; float anchorPointX = 0.5f; float anchorPointY = 0.5f; Composite composite; /** * Returns the shape rotation, in radians * * @return shape rotation, in radians */ public float getRotation() { return rotation; } /** * Returns the shape to be used to render the mark * */ public Shape getShape() { return shape; } /** * Returns a shape that can be used to draw the mark at the x, y coordinates * with appropriated rotation and size (according to the current style) * * @param x the x coordinate where the mark will be drawn * @param y the y coordinate where the mark will be drawn * * @return a shape that can be used to draw the mark */ public Shape getTransformedShape(float x, float y) { return getTransformedShape(x, y, 0, rotation); } /** * Returns a shape that can be used to draw the mark at the x, y coordinates with appropriated * rotation and size (according to the current style) * * @param x the x coordinate where the mark will be drawn * @param y the y coordinate where the mark will be drawn * @param baseRotation a custom rotation that will be applied before offsets * @param rotation the mark rotation * * @return a shape that can be used to draw the mark */ public Shape getTransformedShape(float x, float y, float baseRotation, float rotation) { if (shape != null) { Rectangle2D bounds = shape.getBounds2D(); double shapeSize = (maxMarkSizeEnabled ? Math.max(bounds.getWidth(), bounds.getHeight()) : bounds.getHeight()); double scale = size / shapeSize; TransformedShape ts = new TransformedShape(); ts.shape = shape; // shapes are already centered, we need to displace them only if the anchor is not 0.5 0.5 float dx = displacementX; float dy = displacementY; if (baseRotation != 0) { ts.translate(x, y); ts.rotate(baseRotation); ts.translate(dx, dy); } else { ts.translate(x + dx, y + dy); } ts.rotate(rotation); dx = (float) (bounds.getWidth() * scale * (0.5 - anchorPointX)); dy = (float) (bounds.getHeight() * scale * (anchorPointY - 0.5)); ts.translate(dx, dy); // flip the symbol to take into account the screen orientation // where the y grows from top to bottom ts.scale(scale, -scale); return ts; } else { return null; } } /** * Returns the size of the shape, in pixels * */ public double getSize() { return size; } /** * Sets the shape rotation, in radians * * @param f */ public void setRotation(float f) { rotation = f; } /** * Sets the shape to be used to render the mark * * @param shape */ public void setShape(Shape shape) { this.shape = shape; } /** * Sets the size of the shape, in pixels * * @param i */ public void setSize(double i) { size = i; } /** * Returns a string representation of this style. */ public String toString() { return Classes.getShortClassName(this) + '[' + shape + ']'; } public static boolean isMaxMarkSizeEnabled() { return maxMarkSizeEnabled; } /** * When true makes the mark scale itself to size using the max between the original * width and height, otherwise it defaults to the mark height (which has been the * original behavior of this class) * * @since 2.7.3 * * @param useMaxMarkSize */ public static void setMaxMarkSizeEnabled(boolean useMaxMarkSize) { MarkStyle2D.maxMarkSizeEnabled = useMaxMarkSize; } public float getDisplacementX() { return displacementX; } public void setDisplacementX(float displacementX) { this.displacementX = displacementX; } public float getDisplacementY() { return displacementY; } public void setDisplacementY(float displacementY) { this.displacementY = displacementY; } public float getAnchorPointX() { return anchorPointX; } public void setAnchorPointX(float anchorPointX) { this.anchorPointX = anchorPointX; } public float getAnchorPointY() { return anchorPointY; } public void setAnchorPointY(float anchorPointY) { this.anchorPointY = anchorPointY; } public Composite getComposite() { return composite; } public void setComposite(Composite composite) { this.composite = composite; } }