// ********************************************************************** // // // //BBN Technologies, a Verizon Company //10 Moulton Street //Cambridge, MA 02138 //(617) 873-8000 // //Copyright (C) BBNT Solutions LLC. All rights reserved. // // //********************************************************************** // //$Source: ///cvs/darwars/ambush/aar/src/com/bbn/ambush/mission/MissionHandler.java,v //$ //$RCSfile: OMTextLabelerTracing.java,v $ //$Revision: 1.3 $ //$Date: 2006/08/09 21:04:14 $ //$Author: dietrick $ // //********************************************************************** package com.bbn.openmap.omGraphics; import com.bbn.openmap.proj.ProjMath; import com.bbn.openmap.util.DataBounds; import com.bbn.openmap.util.Debug; import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.Graphics; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import java.util.Vector; /** * A default implementation of OMLabeler that extends from OMText. * * @author dietrick */ public class OMTextLabelerTracing extends OMTextLabeler { protected OMGraphic labeledGraphic; protected boolean labeledIsClosed; protected boolean hideLabel; // ------------------------------------------------------ public void setLabeledGraphic(OMGraphic lo) { labeledGraphic = lo;} /** * */ public OMTextLabelerTracing(OMGraphic lo, String stuff) { this(lo, stuff, DEFAULT_FONT, JUSTIFY_LEFT); } /** * @param stuff * @param just */ public OMTextLabelerTracing(OMGraphic lo, String stuff, int just) { this(lo, stuff, DEFAULT_FONT, just, ANCHOR_CENTER); } public OMTextLabelerTracing(OMGraphic lo, String stuff, int just, int loc) { this(lo, stuff, DEFAULT_FONT, just, loc); } /** * @param stuff * @param font * @param just */ public OMTextLabelerTracing(OMGraphic lo, String stuff, Font font, int just) { this(lo, stuff, font, just, ANCHOR_CENTER); } public OMTextLabelerTracing(OMGraphic lo, String stuff, Font font, int just, int loc) { super(stuff, font, just, loc); setLabeledGraphic(lo); labeledIsClosed = false; } 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.Point) */ public void setLocation(Point p) { super.setLocation(p); } /* * (non-Javadoc) * * @see com.bbn.openmap.omGraphics.OMLabeler#setLocation(int[][], * int[][]) */ private static float rotangle = ProjMath.degToRad(45.0f); public void setLocation(int[] xpoints, int[] ypoints) { // Is we closed (Polygon) ?? /* if(xpoints.length > 1 && xpoints[0] == xpoints[xpoints.length-1] && ypoints[0] == ypoints[ypoints.length-1]) { labeledIsClosed = true;} */ hideLabel = false; Point center = new Point(); if(xpoints.length > 1 && findCenterandBounds(xpoints, ypoints, center)) { setLocation(center); } else { super.setLocation(xpoints, ypoints);} } //------------------------------------------------------ private boolean needPrepForRender = false; public synchronized void render(Graphics g) { try { if(needPrepForRender) { prepareForRender(g); needPrepForRender = false; // computeBounds(); } super.render(g); } catch(Exception e) { Debug.output("Cought "+e); } } public static float computeRotation(float x1, float y1, float x2, float y2) { float retVal = 0.0f; // DataBounds ext = calculateLineExt(xpoints, ypoints); // int idx = findClosest(center.x, center.y, xpoints, ypoints); // ext. float my, mx; try { //(float)rect.width / rect.height; my = (float)(y1 - y2); mx = (float)(x1 - x2); my = (float)Math.atan2(mx, my); if(my != 0.0f) { retVal = my;} } catch(Exception e) { retVal = 0.0f; } return retVal; } //------------------------------------------------------ private static float rotationLimit = ProjMath.degToRad(90.0f); private static float rotationAdj = ProjMath.degToRad(180.0f); //------------------------------------------------------ protected boolean findCenterandBounds(int[] xpts, int[] ypts, Point center) { boolean retVal = false; int j = 0; int[] segmentlens = new int[xpts.length]; int segcurr = 0; int segmentlength =0, segmentstart=0; int[] longestsegment = null; int longestsegmentlength =0; int longestsegmentstart =0; int longestsegmentend =0; int totsegmentlen =0; DataBounds currbounding = new DataBounds(); DataBounds longestSegmBounding = currbounding; boolean colsesegm = false; // Find bounding box and longest segment int i =0; do { if(xpts[i] > -1 && ypts[i] > -1 ) { currbounding.add(xpts[i], ypts[i]); if(segmentstart > -1 && i > 0) { if(xpts[i] == xpts[i-1]) // Vert/Horiz { segmentlens[segcurr] = Math.abs(ypts[i-1] - ypts[i]); } else if(ypts[i] == ypts[i-1]) // Vert/Horiz { segmentlens[segcurr] = Math.abs(xpts[i-1] - xpts[i]); } else // Pythagoras { segmentlens[segcurr] = (int) Math.hypot(Math.abs(xpts[i-1] - xpts[i]), Math.abs(ypts[i-1] - ypts[i])); } segmentlength += segmentlens[segcurr]; totsegmentlen += segmentlens[segcurr]; segcurr++; } else { segmentstart = i;} colsesegm = false; } // valid segment else { colsesegm = true;} if(colsesegm || xpts.length == (i+1)) { if(segmentlength > 0) { // Save longest Segment length if(longestsegmentlength < segmentlength) { longestsegment = new int[segcurr]; System.arraycopy(segmentlens, 0, longestsegment, 0, segcurr); longestsegmentstart = segmentstart; longestsegmentend = i; longestsegmentlength = segmentlength; longestSegmBounding = currbounding; } segcurr =0; } segmentstart = -1; segmentlength =0; currbounding = new DataBounds(); } ++i; } while(i < xpts.length) ; // Segmentstart must be larger than 0, otherwise, no visible segment // i is the centerpoint of the longest segment if(totsegmentlen > 10) { // Find Center of line(Length) int halfdist = (int) longestsegmentlength/ 2; for(i = 0; halfdist > 0 && i < longestsegment.length; i++) { halfdist -= segmentlens[i]; } int loc = longestsegmentstart+i; // if(loc // if( try { // Set midpoint center.x = (xpts[loc-1] + xpts[loc])/2; center.y = (ypts[loc-1] + ypts[loc])/2; } catch(Exception e) {Debug.output("ComputeLocation: ["+this.getData()+"] "+ e ); } if(longestsegmentlength > 50) { //Debug.output("ComputeLocation: ["+this.getData()+"] "+ loc +" @ ("+xpts[loc-1]+", "+ ypts[loc-1] +"), ("+xpts[loc]+", "+ ypts[loc]+")"); // float rotangle = computeRotation(longestSegmBounding); float rotangle = 0.0f; // rotangle = computeRotation(xpts[loc-1], ypts[loc-1], // xpts[loc], ypts[loc]); rotangle = computeRotation(ypts[loc-1], xpts[loc-1], ypts[loc], xpts[loc]); if(rotangle != 0.0f) { //rotangle +=rotationAdj; if(rotangle < -rotationLimit) { rotangle += rotationAdj;} else if(rotangle > rotationLimit) { rotangle -= rotationAdj;} setRotationAngle(rotangle); needPrepForRender =true; //Debug.output("ComputeLocation: ["+this.getData()+"] "+ i +" @ "+center+", Rot:"+ProjMath.radToDeg(rotangle)+". "); } retVal = true; hideLabel = false; } else { hideLabel = true;} } else { hideLabel = true;} return retVal; } /** * Calls super.setShape(), but also checks the attributes for a * label and moves the label accordingly. The label will be placed * in the center of the bounding box around the path. */ public void setShape(GeneralPath gp) { if(labeledIsClosed) { super.setShape(gp); } } /** * Computes the bounding polygon. Sets the cache field * polyBounds. * * @see #polyBounds */ protected void computeBounds_Junk() { if(!labeledIsClosed) { GeneralPath gp = labeledGraphic.getShape(); if(gp != null) { /* Rectangle rect = gp.getBounds(); float aspect = (float)rect.width / rect.height; if(rect.width > 1.0) { setRotationAngle(aspect); } */ super.setShape(gp); } } super.computeBounds(); // this.setLocation(); } /** * Renders the text onto the given graphics. Sets the cache field * fm. * * @param g the java.awt.Graphics to put the string on. * * @see #fm */ /* public synchronized void render(Graphics g) { if(getNeedToRegenerate() && !labeledIsClosed) {setRotationAngle(computeRotation(labeledGraphic));} super.render(g); } */ /* protected void renderString(Graphics g, String string, int x, int y) { if(!labeledIsClosed) { GeneralPath gp = labeledGraphic.getShape(); if(gp != null) { Rectangle rect = gp.getBounds(); float aspect = (float)rect.width / rect.height; if(rect.width > 1.0) { setRotationAngle(aspect); } } } super.renderString(g, string, x, y); } */ /** * Get the visibility variable. * * @return boolean */ public boolean isVisible() { boolean retVal = labeledGraphic.isVisible() && super.isVisible(); if(retVal && hideLabel) { retVal = false;} return retVal; } }