Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2012 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package gov.nasa.worldwind.symbology;
import com.jogamp.opengl.util.texture.*;
import com.jogamp.opengl.util.texture.awt.AWTTextureIO;
import gov.nasa.worldwind.*;
import gov.nasa.worldwind.avlist.*;
import gov.nasa.worldwind.drag.*;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.pick.*;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.util.*;
import com.jogamp.opengl.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
import java.util.List;
/**
* @author dcollins
* @version $Id: AbstractTacticalSymbol.java 2366 2014-10-02 23:16:31Z tgaskins $
*/
public abstract class AbstractTacticalSymbol extends WWObjectImpl implements TacticalSymbol, Movable, Draggable
{
protected static class IconSource
{
protected IconRetriever retriever;
protected String symbolId;
protected AVList retrieverParams;
public IconSource(IconRetriever retriever, String symbolId, AVList retrieverParams)
{
this.retriever = retriever;
this.symbolId = symbolId;
if (retrieverParams != null)
{
// If the specified parameters are non-null, then store a copy of the parameters in this key's params
// property to insulate it from changes made by the caller. This params list must not change after
// construction this key's properties must be immutable.
this.retrieverParams = new AVListImpl();
this.retrieverParams.setValues(retrieverParams);
}
}
public IconRetriever getRetriever()
{
return this.retriever;
}
public String getSymbolId()
{
return this.symbolId;
}
public AVList getRetrieverParams()
{
return this.retrieverParams;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
IconSource that = (IconSource) o;
if (this.retriever != null ? !this.retriever.equals(that.retriever)
: that.retriever != null)
return false;
if (this.symbolId != null ? !this.symbolId.equals(that.symbolId) : that.symbolId != null)
return false;
if (this.retrieverParams != null && that.retrieverParams != null)
{
Set> theseEntries = this.retrieverParams.getEntries();
Set> thoseEntries = that.retrieverParams.getEntries();
return theseEntries.equals(thoseEntries);
}
return (this.retrieverParams == null && that.retrieverParams == null);
}
@Override
public int hashCode()
{
int result = this.retriever != null ? this.retriever.hashCode() : 0;
result = 31 * result + (this.symbolId != null ? this.symbolId.hashCode() : 0);
result = 31 * result + (this.retrieverParams != null ? this.retrieverParams.getEntries().hashCode() : 0);
return result;
}
@Override
public String toString()
{
return this.symbolId;
}
}
// Use an IconKey as the texture's image source. The image source is what defines the contents of this texture,
// and is used as an address for the texture's contents in the cache.
protected static class IconTexture extends LazilyLoadedTexture
{
public IconTexture(IconSource imageSource)
{
super(imageSource);
}
public IconTexture(IconSource imageSource, boolean useMipMaps)
{
super(imageSource, useMipMaps);
}
protected boolean loadTextureData()
{
TextureData td = this.createIconTextureData();
if (td != null)
this.setTextureData(td);
return td != null;
}
protected TextureData createIconTextureData()
{
try
{
IconSource source = (IconSource) this.getImageSource();
BufferedImage image = source.getRetriever().createIcon(source.getSymbolId(),
source.getRetrieverParams());
if (image == null)
{
// IconRetriever returns null if the symbol identifier is not recognized, or if the parameter list
// specified an empty icon. In either case, we mark the texture initialization as having failed to
// suppress any further requests.
this.textureInitializationFailed = true;
return null;
}
return AWTTextureIO.newTextureData(Configuration.getMaxCompatibleGLProfile(), image,
this.isUseMipMaps());
}
catch (Exception e)
{
String msg = Logging.getMessage("Symbology.ExceptionRetrievingTacticalIcon", this.getImageSource());
Logging.logger().log(java.util.logging.Level.SEVERE, msg, e);
this.textureInitializationFailed = true; // Suppress subsequent requests for this tactical icon.
return null;
}
}
@Override
protected Runnable createRequestTask()
{
return new IconRequestTask(this);
}
protected static class IconRequestTask implements Runnable
{
protected final IconTexture texture;
protected IconRequestTask(IconTexture texture)
{
if (texture == null)
{
String message = Logging.getMessage("nullValue.TextureIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.texture = texture;
}
public void run()
{
if (Thread.currentThread().isInterrupted())
return; // the task was cancelled because it's a duplicate or for some other reason
if (this.texture.loadTextureData())
this.texture.notifyTextureLoaded();
}
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final IconRequestTask that = (IconRequestTask) o;
return this.texture != null ? this.texture.equals(that.texture) : that.texture == null;
}
public int hashCode()
{
return (this.texture != null ? this.texture.hashCode() : 0);
}
public String toString()
{
return this.texture.getImageSource().toString();
}
}
}
protected static class IconAtlasElement extends TextureAtlasElement
{
protected Point point;
/** Indicates the last time, in milliseconds, the element was requested or added. */
protected long lastUsed = System.currentTimeMillis();
public IconAtlasElement(TextureAtlas atlas, IconSource source)
{
super(atlas, source);
}
public Point getPoint()
{
return this.point;
}
public void setPoint(Point point)
{
this.point = point;
}
@Override
protected boolean loadImage()
{
BufferedImage image = this.createModifierImage();
if (image != null)
this.setImage(image);
return image != null;
}
protected BufferedImage createModifierImage()
{
try
{
IconSource source = (IconSource) this.getImageSource();
BufferedImage image = source.getRetriever().createIcon(source.getSymbolId(),
source.getRetrieverParams());
if (image == null)
{
// ModifierRetriever returns null if the modifier or its value is not recognized. In either case, we
// mark the image initialization as having failed to suppress any further requests.
this.imageInitializationFailed = true;
return null;
}
return image;
}
catch (Exception e)
{
String msg = Logging.getMessage("Symbology.ExceptionRetrievingGraphicModifier",
this.getImageSource());
Logging.logger().log(java.util.logging.Level.SEVERE, msg, e);
this.imageInitializationFailed = true; // Suppress subsequent requests for this modifier.
return null;
}
}
}
protected static class Label
{
protected String text;
protected Point point;
protected Font font;
protected Color color;
public Label(String text, Point point, Font font, Color color)
{
if (text == null)
{
String msg = Logging.getMessage("nullValue.StringIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (point == null)
{
String msg = Logging.getMessage("nullValue.PointIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (font == null)
{
String msg = Logging.getMessage("nullValue.FontIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (color == null)
{
String msg = Logging.getMessage("nullValue.ColorIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.text = text;
this.point = point;
this.font = font;
this.color = color;
}
public String getText()
{
return this.text;
}
public Point getPoint()
{
return this.point;
}
public Font getFont()
{
return this.font;
}
public Color getColor()
{
return this.color;
}
}
protected static class Line
{
protected Iterable extends Point2D> points;
public Line()
{
}
public Line(Iterable extends Point2D> points)
{
if (points == null)
{
String msg = Logging.getMessage("nullValue.IterableIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.points = points;
}
public Iterable extends Point2D> getPoints()
{
return points;
}
public void setPoints(Iterable extends Point2D> points)
{
this.points = points;
}
}
protected class OrderedSymbol implements OrderedRenderable
{
/**
* Per-frame Cartesian point corresponding to this symbol's position. Calculated each frame in {@link
* gov.nasa.worldwind.symbology.AbstractTacticalSymbol#computeSymbolPoints(gov.nasa.worldwind.render.DrawContext,
* gov.nasa.worldwind.symbology.AbstractTacticalSymbol.OrderedSymbol)}. Initially null.
*/
public Vec4 placePoint;
/**
* Per-frame screen point corresponding to the projection of the placePoint in the viewport (on the screen).
* Calculated each frame in {@link gov.nasa.worldwind.symbology.AbstractTacticalSymbol#computeSymbolPoints(gov.nasa.worldwind.render.DrawContext,
* gov.nasa.worldwind.symbology.AbstractTacticalSymbol.OrderedSymbol)}. Initially null.
*/
public Vec4 screenPoint;
/**
* Per-frame distance corresponding to the distance between the placePoint and the View's eye point. Used to
* order the symbol as an ordered renderable, and is returned by getDistanceFromEye. Calculated each frame in
* {@link gov.nasa.worldwind.symbology.AbstractTacticalSymbol#computeSymbolPoints(gov.nasa.worldwind.render.DrawContext,
* gov.nasa.worldwind.symbology.AbstractTacticalSymbol.OrderedSymbol)}. Initially 0.
*/
public double eyeDistance;
/**
* Per-frame screen scale indicating this symbol's x-scale relative to the screen offset. Calculated each frame
* in {@link #computeTransform(gov.nasa.worldwind.render.DrawContext, gov.nasa.worldwind.symbology.AbstractTacticalSymbol.OrderedSymbol)}.
* Initially 0.
*/
public double sx;
/**
* Per-frame screen scale indicating this symbol's y-scale relative to the screen offset. Calculated each frame
* in {@link #computeTransform(gov.nasa.worldwind.render.DrawContext, gov.nasa.worldwind.symbology.AbstractTacticalSymbol.OrderedSymbol)}.
* Initially 0.
*/
public double sy;
/**
* Per-frame screen offset indicating this symbol's x-offset relative to the screenPoint. Calculated each frame
* in {@link #computeTransform(gov.nasa.worldwind.render.DrawContext, gov.nasa.worldwind.symbology.AbstractTacticalSymbol.OrderedSymbol)}.
* Initially 0.
*/
public double dx;
/**
* Per-frame screen offset indicating this symbol's y-offset relative to the screenPoint. Calculated each frame
* in {@link #computeTransform(gov.nasa.worldwind.render.DrawContext, gov.nasa.worldwind.symbology.AbstractTacticalSymbol.OrderedSymbol)}.
* Initially 0.
*/
public double dy;
public Rectangle layoutRect;
public Rectangle screenRect;
/** iconRect with scaling applied, used to lay out text. */
public Rectangle iconRectScaled;
/** layoutRect with scaling applied, used to lay out text. */
public Rectangle layoutRectScaled;
@Override
public double getDistanceFromEye()
{
return this.eyeDistance;
}
@Override
public void pick(DrawContext dc, Point pickPoint)
{
AbstractTacticalSymbol.this.pick(dc, pickPoint, this);
}
@Override
public void render(DrawContext dc)
{
AbstractTacticalSymbol.this.drawOrderedRenderable(dc, this);
}
public boolean isEnableBatchRendering()
{
return AbstractTacticalSymbol.this.isEnableBatchRendering();
}
protected void doDrawOrderedRenderable(DrawContext dc, PickSupport pickCandidates)
{
AbstractTacticalSymbol.this.doDrawOrderedRenderable(dc, pickCandidates, this);
}
public boolean isEnableBatchPicking()
{
return AbstractTacticalSymbol.this.isEnableBatchPicking();
}
public Layer getPickLayer()
{
return AbstractTacticalSymbol.this.pickLayer;
}
}
/** Default unit format. */
public static final UnitsFormat DEFAULT_UNITS_FORMAT = new UnitsFormat();
/** The image file displayed while the icon is loading. */
public static final String LOADING_IMAGE_PATH =
Configuration.getStringValue("gov.nasa.worldwind.avkey.MilStd2525LoadingIconPath",
"images/doc-loading-128x128.png");
protected static final String LAYOUT_ABSOLUTE = "gov.nasa.worldwind.symbology.TacticalSymbol.LayoutAbsolute";
protected static final String LAYOUT_RELATIVE = "gov.nasa.worldwind.symbology.TacticalSymbol.LayoutRelative";
protected static final String LAYOUT_NONE = "gov.nasa.worldwind.symbology.TacticalSymbol.LayoutNone";
/**
* The default depth offset in device independent depth units: -8200. This value is configured to match the depth
* offset produced by existing screen elements such as PointPlacemark. This value was determined empirically.
*/
protected static final double DEFAULT_DEPTH_OFFSET = -8200;
protected static final long DEFAULT_MAX_TIME_SINCE_LAST_USED = 10000;
/**
* The default glyph texture atlas. This texture atlas holds all glyph images loaded by calls to
* layoutGlyphModifier. Initialized with initial dimensions of 1024x128 and maximum dimensions of
* 2048x2048. Configured to remove the least recently used texture elements when more space is needed.
*/
protected static final TextureAtlas DEFAULT_GLYPH_ATLAS = new TextureAtlas(1024, 128, 2048, 2048);
/**
* Maximum expected size of a symbol, used to estimate screen bounds for view frustum culling. This value is
* configured a bit higher than a symbol is likely to be drawn in practice to err on the side of not culling a
* symbol that is not visible, rather culling one that is visible.
*/
protected static final int MAX_SYMBOL_DIMENSION = 256;
/** The default number of label lines to expect when computing the minimum size of the text layout rectangle. */
protected static final int DEFAULT_LABEL_LINES = 5;
/** The attributes used if attributes are not specified. */
protected static TacticalSymbolAttributes defaultAttrs;
static
{
// Create and populate the default attributes.
defaultAttrs = new BasicTacticalSymbolAttributes();
defaultAttrs.setOpacity(BasicTacticalSymbolAttributes.DEFAULT_OPACITY);
defaultAttrs.setScale(BasicTacticalSymbolAttributes.DEFAULT_SCALE);
defaultAttrs.setTextModifierMaterial(BasicTacticalSymbolAttributes.DEFAULT_TEXT_MODIFIER_MATERIAL);
// Configure the atlas to remove old texture elements that are likely no longer used to make room for new
// modifiers when the atlas is full.
DEFAULT_GLYPH_ATLAS.setEvictOldElements(true);
}
/**
* Indicates whether this symbol is drawn when in view. true if this symbol is drawn when in view,
* otherwise false. Initially true.
*/
protected boolean visible = true;
/**
* Indicates whether this symbol is highlighted. true if this symbol is highlighted, otherwise
* false. Initially false.
*/
protected boolean highlighted;
/**
* Indicates this symbol's geographic position. See {@link #setPosition(gov.nasa.worldwind.geom.Position)} for a
* description of how tactical symbols interpret their position. Must be non-null, and is initialized during
* construction.
*/
protected Position position;
/**
* Indicates this symbol's altitude mode. See {@link #setAltitudeMode(int)} for a description of the valid altitude
* modes. Initially Worldwind.ABSOLUTE.
*/
protected int altitudeMode = WorldWind.ABSOLUTE;
/**
* Indicates whether this symbol draws its supplemental graphic modifiers. true if this symbol draws
* its graphic modifiers, otherwise false. Initially true.
*/
protected boolean showGraphicModifiers = true;
/**
* Indicates whether this symbol draws its supplemental text modifiers. true if this symbol draws its
* text modifiers, otherwise false. Initially true.
*/
protected boolean showTextModifiers = true;
/** Indicates an object to attach to the picked object list instead of this symbol. */
protected Object delegateOwner;
protected boolean enableBatchRendering = true;
protected boolean enableBatchPicking = true;
/** Indicates whether or not to display the implicit location modifier. */
protected boolean showLocation = true;
/** Indicates whether or not to display the implicit hostile indicator modifier. */
protected boolean showHostileIndicator;
/**
* Indicates the current text and graphic modifiers assigned to this symbol. This list of key-value pairs contains
* both the modifiers specified by the string identifier during construction, and those specified by calling {@link
* #setModifier(String, Object)}. Initialized to a new AVListImpl, and populated during construction from values in
* the string identifier and the modifiers list.
*/
protected AVList modifiers = new AVListImpl();
/**
* Modifiers active this frame. This list is determined by copying {@link #modifiers}, and applying changings in
* {@link #applyImplicitModifiers(gov.nasa.worldwind.avlist.AVList)}.
*/
protected AVList activeModifiers = new AVListImpl();
/**
* Indicates this symbol's normal (as opposed to highlight) attributes. May be null, indicating that
* the default attributes are used. Initially null.
*/
protected TacticalSymbolAttributes normalAttrs;
/**
* Indicates this symbol's highlight attributes. May be null, indicating that the default attributes
* are used. Initially null.
*/
protected TacticalSymbolAttributes highlightAttrs;
/**
* Indicates this symbol's currently active attributes. Updated in {@link #determineActiveAttributes}. Initialized
* to a new BasicTacticalSymbolAttributes.
*/
protected TacticalSymbolAttributes activeAttrs = new BasicTacticalSymbolAttributes();
protected Offset offset;
protected Offset iconOffset;
protected Size iconSize;
protected Double depthOffset;
protected IconRetriever iconRetriever;
protected IconRetriever modifierRetriever;
/**
* The frame used to calculate this symbol's per-frame values. Set to the draw context's frame number each frame.
* Initially -1.
*/
protected long frameNumber = -1;
protected OrderedSymbol thisFramesOrderedSymbol;
protected Rectangle iconRect;
/**
* Screen rect computed from the icon and static modifiers. This rectangle is cached and only recomputed when the
* icon or modifiers change.
*/
protected Rectangle staticScreenRect;
/**
* Layout rect computed from the icon and static modifiers. This rectangle is cached and only recomputed when the
* icon or modifiers change.
*/
protected Rectangle staticLayoutRect;
/** Indicates that one or more glyphs have not been resolved. */
protected boolean unresolvedGlyph;
protected List currentGlyphs = new ArrayList();
protected List