// ********************************************************************** // //<copyright> // //BBN Technologies, a Verizon Company //10 Moulton Street //Cambridge, MA 02138 //(617) 873-8000 // //Copyright (C) BBNT Solutions LLC. All rights reserved. // //</copyright> //********************************************************************** // //$Source: ///cvs/darwars/ambush/aar/src/com/bbn/ambush/mission/MissionHandler.java,v //$ //$RCSfile: OMTextLabeler.java,v $ //$Revision: 1.4 $ //$Date: 2007/06/21 21:38:59 $ //$Author: dietrick $ // //********************************************************************** package com.bbn.openmap.omGraphics; import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; /** * A default implementation of OMLabeler that extends from OMText. One thing * going on with OMTextLabelers is that they are set to be non-rotating by * default, which means they preserve their set orientation even when the map * rotates. If you want them to rotate with the map, unset the * OMGraphicConstants.NO_ROTATE attribute, or set it to Boolean.FALSE. * * <pre> * Usage: * * OMTextLabeler label = new OMTextLabeler(labelString, OMText.JUSTIFY_CENTER); * omgraphic.putAttribute(OMGraphicConstants.LABEL, label); * </pre> * * @author dietrick */ public class OMTextLabeler extends OMText implements OMLabeler { public final static int ANCHOR_TOPLEFT = 0; public final static int ANCHOR_TOP = 1; public final static int ANCHOR_TOPRIGHT = 2; public final static int ANCHOR_LEFT = 3; public final static int ANCHOR_CENTER = 4; public final static int ANCHOR_RIGHT = 5; public final static int ANCHOR_BOTTOMLEFT = 6; public final static int ANCHOR_BOTTOM = 7; public final static int ANCHOR_BOTTOMRIGHT = 8; protected int anchor = ANCHOR_CENTER; /** * */ public OMTextLabeler(String stuff) { this(stuff, DEFAULT_FONT, JUSTIFY_LEFT); } /** * @param stuff * @param just */ public OMTextLabeler(String stuff, int just) { this(stuff, DEFAULT_FONT, just, ANCHOR_CENTER); } public OMTextLabeler(String stuff, int just, int loc) { this(stuff, DEFAULT_FONT, just, loc); } /** * @param stuff * @param font * @param just */ public OMTextLabeler(String stuff, Font font, int just) { this(stuff, font, just, ANCHOR_CENTER); } public OMTextLabeler(String stuff, Font font, int just, int loc) { setRenderType(RENDERTYPE_XY); setData(stuff); setFont(font); setJustify(just); setAnchor(loc); putAttribute(OMGraphicConstants.NO_ROTATE, Boolean.TRUE); } public void setLocation(GeneralPath gp) { if (gp != null) { Rectangle rect = gp.getBounds(); double x = rect.getX(); double y = rect.getY(); if (anchor == ANCHOR_TOP || anchor == ANCHOR_CENTER || anchor == ANCHOR_BOTTOM) { x += rect.getWidth() / 2; } else if (anchor == ANCHOR_TOPRIGHT || anchor == ANCHOR_RIGHT || anchor == ANCHOR_BOTTOMRIGHT) { x += rect.getWidth(); } if (anchor == ANCHOR_LEFT || anchor == ANCHOR_CENTER || anchor == ANCHOR_RIGHT) { y += rect.getHeight() / 2; } else if (anchor == ANCHOR_BOTTOMLEFT || anchor == ANCHOR_BOTTOM || anchor == ANCHOR_BOTTOMRIGHT) { y += rect.getHeight(); } setLocation(new Point((int) x, (int) y)); } } /* * (non-Javadoc) * @see * com.bbn.openmap.omGraphics.OMLabeler#setLocation(java.awt.geom.Point2D) */ public void setLocation(Point2D p) { polyBounds = null; setX((int) p.getX()); setY((int) p.getY()); setMapLocation(p); polyBounds = computeBounds(null); setNeedToRegenerate(false); } /* * (non-Javadoc) * @see com.bbn.openmap.omGraphics.OMLabeler#setLocation(int[][], int[][]) */ public void setLocation(int[] xpoints, int[] ypoints) { setLocation(getCenter(xpoints, ypoints)); } /** * Calculate the projected area of the poly. Algorithm used is from some * australian astronomy website =) * http://astronomy.swin.edu.au/~pbourke/geometry/polyarea */ protected static double calculateProjectedArea(int[] xpts, int[] ypts) { int j = 0; double area = 0.0; int npoints = xpts.length; for (int i = 0; i < npoints; ++i) { j = (i + 1) % npoints; area += xpts[i] * ypts[j]; area -= ypts[i] * xpts[j]; } return area / 2.0; } /** * Get the calculated center where the label string is drawn. Algorithm used * is from some australian astronomy website =) * http://astronomy.swin.edu.au/~pbourke/geometry/polyarea */ protected static Point getCenter(int[] xpts, int[] ypts) { int npoints = xpts.length; if (npoints == 1) { Point center = new Point(xpts[0], ypts[0]); return center; } if (npoints == 2) { // rmcneil - two points, A=0, div zero below int x; if (xpts[1] > xpts[0]) x = xpts[0] + ((xpts[1] - xpts[0]) / 2); else x = xpts[1] + ((xpts[0] - xpts[1]) / 2); int y; if (ypts[1] > ypts[0]) y = ypts[0] + ((ypts[1] - ypts[0]) / 2); else y = ypts[1] + ((ypts[0] - ypts[1]) / 2); Point center = new Point(x, y); return center; } double factor = 0; double cx = 0.0f; double cy = 0.0f; for (int i = 0; i < npoints; ++i) { int j = (i + 1) % npoints; factor = xpts[i] * ypts[j] - xpts[j] * ypts[i]; cx += (xpts[i] + xpts[j]) * factor; cy += (ypts[i] + ypts[j]) * factor; } double A = calculateProjectedArea(xpts, ypts); A *= 6.0; factor = 1.0 / A; // bbenyo: take the absolute value cause I was getting // negative values // for polys with all positive vertices // cx = Math.abs(cx * factor); // cy = Math.abs(cy * factor); // DFD and RS - let the area calculation return negative // values, and don't do this absolute value calculation. // Negative values get returned when the points are // counterclockwise, indicating holes. We may want labels // offscreen however, and the abs pushes them onscreen. cx *= factor; cy *= factor; Point center = new Point((int) Math.round(cx), (int) Math.round(cy)); return center; } public int getAnchor() { return anchor; } public void setAnchor(int anchor) { this.anchor = anchor; } public void restore(OMGeometry source) { super.restore(source); if (source instanceof OMTextLabeler) { OMTextLabeler labeler = (OMTextLabeler) source; this.anchor = labeler.anchor; } } }