I'd like to report that, with the help of ESRI support, the solution to implement the adding of a line with an arrow head off a symbol to depict the symbol's direction of travel, or an angle with respect to north, that can be modified if the direction of travel changes was achieved. It can be accomplished without the need to create additional graphics, thus avoiding multiple graphic tracking off a single composite symbol. The code is below: /**
* Sets the direction of travel property on this symbol
*
* @param angle The direction of travel to set.
* @param angularUnit The units for the direction of travel.
*/
public void setDirectionOfTravel(double angle, AngularUnit angularUnit) {
this.symbols.remove(this.directionOfTravel);
this.symbols.remove(this.directionOfTravelGroundLine);
double radians = swapCompassHeadingAndTrigAngle(Code.RADIAN == angularUnit.getID() ? angle : angularUnit.convertToRadians(angle));
boolean isGround = 'G' == this.sic.charAt(2) || 'g' == this.sic.charAt(2);
if (isGround) {
//Battle dimension is Ground; draw line straight down behind frame
BufferedImage groundImage = new BufferedImage(DIRECTION_LINE_THICKNESS, DIRECTION_OF_MOVEMENT_LENGTH, BufferedImage.TYPE_INT_RGB);
Graphics2D g = groundImage.createGraphics();
g.setBackground(Color.BLACK);
this.directionOfTravelGroundLine = new PictureMarkerSymbol(groundImage);
this.directionOfTravelGroundLine.setOffsetY(DIRECTION_OF_MOVEMENT_LENGTH / -2);
this.symbols.add(0, this.directionOfTravelGroundLine);
this.updateSymbol();
}
//Draw arrow directly from center and on top of frame
double x = DIRECTION_OF_MOVEMENT_LENGTH * Math.cos(radians);
double y = DIRECTION_OF_MOVEMENT_LENGTH * Math.sin(radians);
BufferedImage directionImage = new BufferedImage(2 * DIRECTION_OF_MOVEMENT_LENGTH, 2 * DIRECTION_OF_MOVEMENT_LENGTH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = directionImage.createGraphics();
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(DIRECTION_LINE_THICKNESS));
g.drawLine(DIRECTION_OF_MOVEMENT_LENGTH,
DIRECTION_OF_MOVEMENT_LENGTH,
DIRECTION_OF_MOVEMENT_LENGTH + (int) Math.round(x),
DIRECTION_OF_MOVEMENT_LENGTH - (int) Math.round(y));
double firstArrowAngle = radians + Math.PI + DIRECTION_ARROWHEAD_ANGLE;
double firstArrowX = DIRECTION_ARROWHEAD_HEIGHT * Math.cos(firstArrowAngle);
double firstArrowY = DIRECTION_ARROWHEAD_HEIGHT * Math.sin(firstArrowAngle);
double secondArrowAngle = radians + Math.PI - DIRECTION_ARROWHEAD_ANGLE;
double secondArrowX = DIRECTION_ARROWHEAD_HEIGHT * Math.cos(secondArrowAngle);
double secondArrowY = DIRECTION_ARROWHEAD_HEIGHT * Math.sin(secondArrowAngle);
g.fillPolygon(new int[] {
DIRECTION_OF_MOVEMENT_LENGTH + (int) Math.round(x),
DIRECTION_OF_MOVEMENT_LENGTH + (int) Math.round(x) + (int) Math.round(firstArrowX),
DIRECTION_OF_MOVEMENT_LENGTH + (int) Math.round(x) + (int) Math.round(secondArrowX)},
new int[] {
DIRECTION_OF_MOVEMENT_LENGTH - (int) Math.round(y),
DIRECTION_OF_MOVEMENT_LENGTH - (int) Math.round(y) - (int) Math.round(firstArrowY),
DIRECTION_OF_MOVEMENT_LENGTH - (int) Math.round(y) - (int) Math.round(secondArrowY)},
3);
this.directionOfTravel = new PictureMarkerSymbol(directionImage);
if (isGround) {
this.directionOfTravel.setOffsetY(-1 * DIRECTION_OF_MOVEMENT_LENGTH);
}
this.symbols.add(this.directionOfTravel);
this.updateSymbol();
}
The above method is off a class that extends the composite symbol and, thus have access to all of list of symbols. The "updateSymbol" method simply removes and re-adds all enclosing symbols to the composite symbol, and updates its graphics layer using its graphic id. The "checking" of the "G" of the military symbol identification code determines if the composite symbol is that of a "Ground" entity, which, by standards, the arrowed line must comes off the bottom of the symbol and then to the direction of travel, whereas all others starts from the center of the symbol. The method uses images instead to "paint" the line and arrow to depict the desire look-and-feel. Note that, with the use of the composite symbol on screenshot of the variety are attached, additional missing labels can be implemented that are not currently seen or available using the message processor. The symbol image can also be modified to depict currency or status of symbols seen in military field systems.Excellent work, ESRI!