// **********************************************************************
//
//
//
//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;
}
}