@Deprecated public class TLcdContinuousDeclutteringLabelPainter extends Object implementsILcdGXYLayerLabelPainter,ILcdGXYViewLabelPainter, Cloneable
Implementation of ILcdGXYLayerLabelPainter
and
ILcdGXYViewLabelPainter
that offers continuously decluttered
labels, ideally suited for labeling moving objects (e.g., tracks). Please
note that this class delegates the actual painting of the labels to the
ILcdGXYLabelPainter2
set on the respective
ILcdGXYEditableLabelsLayer
.
When the objects move, the labels move along and avoid overlap in a continuous fashion by moving the labels around gently. The locations of the labels are not limited to a fixed number of possible locations, instead a label can be put everywhere on the map and there is no hard constraint on the distance between the label and the object. Instead, the following rules are applied:
Which labels are removed in the decluttering process is defined by the label coverage property. Which labels should be dropped first and which labels are drawn on top can be influenced by setting a priority provider. The default is to never drop any labels.
By adding obstacle providers, users of this class can ask this decluttering algorithm to avoid placing labels at certain locations.
During the decluttering process, labels are moved to new locations. These new
locations are stored in the label locations
associated with the layers (if they implement ILcdGXYEditableLabelsLayer
).
For smooth visual results, the ILcdGXYLayer/ILcdGXYView using this painter
should be refreshed regularly. This can for example be done by using the
TLcdSimulator
, or by refreshing the map using a timer, e.g.
Timer timer = new Timer( 50, new ActionListener() {
public void actionPerformed( ActionEvent e ) {
ILcdGXYView view = ...;
ILcdGXYLayer track_layer = ...;
view.invalidateGXYLayer( track_layer, true, this, "Invalidating track layer" );
}
}
} );
timer.setRepeats( true );
timer.start();
Using such a timer, it might be important with respect to performance to set
the correct number of background layers (see ILcdGXYView.getNumberOfCachedBackgroundLayers()
). The TLcdSimulator
does
this automatically (see TLcdSimulator.isManageNumberOfCachedBackgroundLayers()
).
For debugging purposes it can be very useful to enable logging on the 'trace' level, for example by adding this to your logging configuration file:
com.luciad.realtime.TLcdContinuousDeclutteringLabelPainter.level=FINESTIf logging is enabled, extra information is painted:
Notes:
ILcdGXYLayer
s it works with implement ILcdGXYEditableLabelsLayer
to be able to store the label locations.
ILcdGXYLabelPainter
of the layer implements
ILcdGXYLabelPainter2
as it can only declutter labels if they can be
placed freely, not when placement is limited to a fixed number of locations.
ILcdGXYLabelPainter2
need to
be independent of the location of the label for this algorithm to work well.
Therefore the option setConsiderPinForBounds
of
TLcdGXYStampLabelPainter
is not supported in combination with
this algorithm, as the pin varies in size depending on the label location.
ILcdGXYViewLabelPlacer
instead,
because it offers more implementations, better decluttering behavior, support for asynchronous
label placement, and easier customization.ALL, SELECTION
ALL, SELECTION
Constructor and Description |
---|
TLcdContinuousDeclutteringLabelPainter()
Deprecated.
Creates a new
TLcdContinuousDeclutteringLabelPainter , ready to use. |
Modifier and Type | Method and Description |
---|---|
void |
addLabelObstacleProvider(ILcdGXYLabelObstacleProvider aObstacleProvider)
Deprecated.
Adds the given
ILcdGXYLabelObstacleProvider . |
Object |
clone()
Deprecated.
Redefines
Object.clone to make it public. |
Point |
getDesiredRelativeLocation()
Deprecated.
Returns the desired relative location.
|
int |
getForcedPaintingThresholdPriority()
Deprecated.
Returns the threshold priority for forced label painting.
|
ILcdGXYLabelObstacleProvider[] |
getLabelObstacleProviders()
Deprecated.
Returns the list of registered
ILcdGXYLabelObstacleProvider s. |
ILcdGXYLabelPriorityProvider |
getLabelPriorityProvider()
Deprecated.
Returns the label priority provider.
|
int |
getMaxDeclutterTime()
Deprecated.
Returns the maximum declutter time.
|
double |
getMaxLabelCoverage()
Deprecated.
Returns the maximum label coverage ratio.
|
ILcdInterval |
getReuseLocationsScaleRatioInterval()
Deprecated.
Returns the scale ratio interval in which label locations are reused.
|
boolean |
isSelectionLabeled()
Deprecated.
Returns true if the selection is labeled.
|
boolean |
isTraceOn()
Deprecated.
This method has been deprecated. It is recommended to use the
standard Java logging framework directly.
|
void |
paintLabel(Graphics aGraphics,
Enumeration aGXYLayerEnumeration,
ILcdGXYView aGXYView,
int aMode)
Deprecated.
The implementation of this method shall define how to paint the labels of all the objects in
the various
ILcdGXYLayer of the given Enumeration, on the given
ILcdGXYView , in the given mode. |
void |
paintLabel(Graphics aGraphics,
ILcdGXYLayer aGXYLayer,
ILcdGXYView aGXYView,
int aLayerLabelPainterMode)
Deprecated.
The implementation of this method shall define how to paint the labels of all the objects in
the given
ILcdGXYLayer on the given ILcdGXYView , in the given mode. |
void |
paintLabel(Graphics aGraphics,
ILcdGXYView aGXYView,
int aViewLabelPainterMode)
Deprecated.
The implementation of this method shall define how to paint the labels of all the objects in
the various
ILcdGXYLayer of the given ILcdGXYView , in the given mode. |
void |
removeLabelObstacleProvider(ILcdGXYLabelObstacleProvider aObstacleProvider)
Deprecated.
Removes the given
ILcdGXYLabelObstacleProvider . |
protected void |
retrieveDesiredLabelLocation(Graphics aGraphics,
ILcdGXYContext aGXYContext,
Object aObject,
int aLabelIndex,
int aSubLabelIndex,
Point aRelativeLocationSFCT)
Deprecated.
Retrieves the desired label location for the given object, label and sub
label index.
|
static void |
setClassTraceOn(boolean aClassTraceOn)
Deprecated.
Enable/disable display of debug trace information for this class.
|
void |
setDesiredRelativeLocation(Point aDesiredRelativeLocation)
Deprecated.
Sets the desired relative label location: the location the labels tend to move to.
|
void |
setForcedPaintingThresholdPriority(int aPriority)
Deprecated.
Sets the threshold priority for forced label painting.
|
void |
setLabelPriorityProvider(ILcdGXYLabelPriorityProvider aLabelPriorityProvider)
Deprecated.
Sets the label priority provider, specifying the priority for individual labels.
|
void |
setMaxDeclutterTime(int aMaxDeclutterTime)
Deprecated.
Sets the maximum time (in ms) that should be spend in decluttering the
labels.
|
void |
setMaxLabelCoverage(double aMaximumLabelCoverage)
Deprecated.
Sets the maximum label coverage ratio.
|
void |
setReuseLocationsScaleRatioInterval(ILcdInterval aReuseLocationsScaleRatioInterval)
Deprecated.
Sets the scale ratio interval in which the label locations are reused.
|
void |
setSelectionLabeled(boolean aSelectionLabeled)
Deprecated.
Sets if the selection should be labeled.
|
void |
setTraceOn(boolean aTraceOn)
Deprecated.
Enable/disable display of debug trace information for this instance.
|
public TLcdContinuousDeclutteringLabelPainter()
TLcdContinuousDeclutteringLabelPainter
, ready to use.public void setForcedPaintingThresholdPriority(int aPriority)
-1
, in which case no forced painting is done.
Because of the threshold priority for forced label painting it is possible that the
maximum label coverage constraint is violated (see setMaxLabelCoverage(double)
).
aPriority
- the threshold priority for forced label painting.getForcedPaintingThresholdPriority()
public int getForcedPaintingThresholdPriority()
setForcedPaintingThresholdPriority(int)
public static void setClassTraceOn(boolean aClassTraceOn)
aClassTraceOn
- True to enable display of debug information.public void setTraceOn(boolean aTraceOn)
aTraceOn
- True to enable display of debug information.public boolean isTraceOn()
true
if tracing is enabled for this class.public ILcdGXYLabelPriorityProvider getLabelPriorityProvider()
setLabelPriorityProvider(com.luciad.view.gxy.ILcdGXYLabelPriorityProvider)
public void setLabelPriorityProvider(ILcdGXYLabelPriorityProvider aLabelPriorityProvider)
aLabelPriorityProvider
- The priority provider to set.setMaxLabelCoverage(double)
public boolean isSelectionLabeled()
setSelectionLabeled(boolean)
public void setSelectionLabeled(boolean aSelectionLabeled)
ILcdGXYLayer.isLabeled()
flag, so that even
if labeling is disabled, selected objects can still be labeled.aSelectionLabeled
- True to label the selection, false to only label the selection
if ILcdGXYLayer.isLabeled()
returns true.public double getMaxLabelCoverage()
setMaxLabelCoverage(double)
public void setMaxLabelCoverage(double aMaximumLabelCoverage)
Sets the maximum label coverage ratio. It controls when to start dropping labels if the view contains too many of them.
It is defined as the surface used by the labels (approximated by their bounds)
divided by the total surface of the ILcdGXYView
, so typical values are in the
range of ]0,1]. To for example start dropping labels if more than 30% of the view would be
covered by labels, set this property to 0.3. A value of for example 2 means the labels can
use the available screen space twice (so a lot of overlap). Set it to
Double.MAX_VALUE
to never drop any labels (the default value).
The label surfaces are approximated by their bounds.
Labels with the lowest priority are dropped first. Selected labels will get 'ultimate' priority, in that they are dropped as the last ones.
aMaximumLabelCoverage
- The maximum label coverage, must be larger than or equal to 0.setLabelPriorityProvider(com.luciad.view.gxy.ILcdGXYLabelPriorityProvider)
public void addLabelObstacleProvider(ILcdGXYLabelObstacleProvider aObstacleProvider)
ILcdGXYLabelObstacleProvider
. Obstacle providers are used
to provide the decluttering algorithm with obstacles: places where preferably no
labels should be placed.aObstacleProvider
- The provider to add.public void removeLabelObstacleProvider(ILcdGXYLabelObstacleProvider aObstacleProvider)
ILcdGXYLabelObstacleProvider
.aObstacleProvider
- The provider to remove.public ILcdGXYLabelObstacleProvider[] getLabelObstacleProviders()
ILcdGXYLabelObstacleProvider
s.ILcdGXYLabelObstacleProvider
s.public Point getDesiredRelativeLocation()
setDesiredRelativeLocation(java.awt.Point)
public void setDesiredRelativeLocation(Point aDesiredRelativeLocation)
new Point( 10, 10 )
, all labels (that is, their anchors)
tend to move to an offset of (10, 10) to the object they belong to.
See also retrieveDesiredLabelLocation(java.awt.Graphics, com.luciad.view.gxy.ILcdGXYContext, java.lang.Object, int, int, java.awt.Point)
.aDesiredRelativeLocation
- The desired location relative to the anchor point of the object.ILcdGXYPainter.anchorPointSFCT(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext, java.awt.Point)
,
ILcdGXYLabelPainter2.labelAnchorPointSFCT(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext, java.awt.Point)
protected void retrieveDesiredLabelLocation(Graphics aGraphics, ILcdGXYContext aGXYContext, Object aObject, int aLabelIndex, int aSubLabelIndex, Point aRelativeLocationSFCT)
getDesiredRelativeLocation
.
Override this method to specify the desired location differently for every
label. This for example can be used to avoid that labels would like to be
at the location where a track is heading to.aGraphics
- The graphics involved in the paint operation.aGXYContext
- The context containing the layer, the view and the transformations.aObject
- The object.aLabelIndex
- The label index, 0 if no ILcdGXYMultiLabelPainter is used.aSubLabelIndex
- The sub label index, 0 if no ILcdGXYMultiLabelPainter is used.aRelativeLocationSFCT
- The location this method adapts as a side effect, relative to the anchor point
of the object.ILcdGXYPainter.anchorPointSFCT(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext, java.awt.Point)
,
ILcdGXYLabelPainter2.labelAnchorPointSFCT(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext, java.awt.Point)
public int getMaxDeclutterTime()
setMaxDeclutterTime(int)
public void setMaxDeclutterTime(int aMaxDeclutterTime)
aMaxDeclutterTime
- The maximum time that can be spend in decluttering, in ms.public ILcdInterval getReuseLocationsScaleRatioInterval()
setReuseLocationsScaleRatioInterval(com.luciad.util.ILcdInterval)
public void setReuseLocationsScaleRatioInterval(ILcdInterval aReuseLocationsScaleRatioInterval)
ALcdLabelLocations
).
If large changes in
scale
occur (e.g., zooming
in/out), trying to reuse those locations is no longer useful as visual
contact with the labels is lost anyway. Using this interval, one can
specify for which scale changes the label locations should be reused,
using a lower and an upper ratio.
For example setting this value to new TLcdInterval(0.8, 1.2)
means that the label locations are reused if new scale (e.g., after
zooming) divided by the old scale (e.g., before zooming) is within the
interval [0.8, 1.2].
If this interval is set to null
, label locations are never
reused.aReuseLocationsScaleRatioInterval
- The scale ratio interval.public void paintLabel(Graphics aGraphics, ILcdGXYLayer aGXYLayer, ILcdGXYView aGXYView, int aLayerLabelPainterMode)
ILcdGXYLayerLabelPainter
The implementation of this method shall define how to paint the labels of all the objects in
the given ILcdGXYLayer
on the given ILcdGXYView
, in the given mode.
Here one can implement various smart algorithms to check whether or not to paint a label at a
certain location.
If aGXYLayer
is an ILcdGXYEditableLabelsLayer
, this method should
inform the ALcdLabelLocations
associated with that layer which labels have been
drawn and which haven't been.
paintLabel
in interface ILcdGXYLayerLabelPainter
aGraphics
- The Graphics
instance on which to paint the labels.aGXYLayer
- The layer for which to paint the labels. If this layer is an
instance of ILcdGXYEditableLabelsLayer
, its
ALcdLabelLocations
should be informed of which
labels have been drawn and which haven't.aGXYView
- The view in which the layer is contained.aLayerLabelPainterMode
- Determines which labels should be painted. Should be one of
ILcdGXYLayerLabelPainter.ALL
or ILcdGXYLayerLabelPainter.SELECTION
ILcdGXYEditableLabelsLayer
,
ALcdLabelLocations.setPainted(java.lang.Object, int, int, com.luciad.view.ILcdView, boolean, int)
public Object clone()
ILcdGXYLayerLabelPainter
Object.clone
to make it public.clone
in interface ILcdGXYLayerLabelPainter
clone
in interface ILcdGXYViewLabelPainter
clone
in class Object
public void paintLabel(Graphics aGraphics, ILcdGXYView aGXYView, int aViewLabelPainterMode)
ILcdGXYViewLabelPainter
ILcdGXYLayer
of the given ILcdGXYView
, in the given mode.
Here one can implement various smart algorithms to check whether or not to paint a label at a
certain location.
If any layer for which labels are painted is an ILcdGXYEditableLabelsLayer
,
this method should inform the ALcdLabelLocations
associated with that layer which
labels have been drawn and which haven't been.
paintLabel
in interface ILcdGXYViewLabelPainter
aGraphics
- The Graphics
instance on which to paint the
labels.aGXYView
- The view for which to paint the labels. If labels are drawn for
a layer that is an instance of ILcdGXYEditableLabelsLayer
,
its ALcdLabelLocations instance should be informed of which
labels have been drawn and which haven't been.aViewLabelPainterMode
- Determines which labels should be drawn. Should be one of
ILcdGXYViewLabelPainter.ALL
or
ILcdGXYViewLabelPainter.SELECTION
ILcdGXYEditableLabelsLayer
,
ALcdLabelLocations.setPainted(java.lang.Object, int, int, com.luciad.view.ILcdView, boolean, int)
public void paintLabel(Graphics aGraphics, Enumeration aGXYLayerEnumeration, ILcdGXYView aGXYView, int aMode)
ILcdGXYViewLabelPainter
ILcdGXYLayer
of the given Enumeration, on the given
ILcdGXYView
, in the given mode. Here one can implement various smart algorithms to
check whether or not to paint a label at a certain location.
If any layer for which labels are painted is an ILcdGXYEditableLabelsLayer
,
this method should inform the ALcdLabelLocations
associated with that layer which
labels have been drawn and which haven't been.
paintLabel
in interface ILcdGXYViewLabelPainter
aGraphics
- The Graphics
instance on which to paint the
labels.aGXYLayerEnumeration
- Only the labels for the layers contained in this
Enumeration
will be drawn.aGXYView
- The ILcdGXYView instance for which to paint the layers.aMode
- Determines which labels should be drawn. Should be one of
ILcdGXYViewLabelPainter.ALL
or
ILcdGXYViewLabelPainter.SELECTION
ILcdGXYEditableLabelsLayer
,
ALcdLabelLocations.setPainted(java.lang.Object, int, int, com.luciad.view.ILcdView, boolean, int)