Class TLcdContinuousDeclutteringLabelPainter
- All Implemented Interfaces:
ILcdGXYLayerLabelPainter
,ILcdGXYViewLabelPainter
,Serializable
,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:
- the labels tend to move to their desired label location. That location can be specified for all labels at once or for every label individually.
- sublabels are kept together, and will move as if they were one single label
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:
- Obstacles: dark green
- Labels: those that can be moved: orange. Those that cannot be moved (sticky): green.
- Direction of intended movement for the labels (drawn from the center outwards): yellow.
- Desired label location: small hollow black dot.
- Label anchor point: small hollow blue dot.
Notes:
- This class currently does not support rotated labels or obstacles.
- It assumes the
ILcdGXYLayer
s it works with implementILcdGXYEditableLabelsLayer
to be able to store the label locations. - It assumes the
ILcdGXYLabelPainter
of the layer implementsILcdGXYLabelPainter2
as it can only declutter labels if they can be placed freely, not when placement is limited to a fixed number of locations. - The bounds returned by the
ILcdGXYLabelPainter2
need to be independent of the location of the label for this algorithm to work well. Therefore the optionsetConsiderPinForBounds
ofTLcdGXYStampLabelPainter
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.- Since:
- 7.0
- See Also:
-
Field Summary
Fields inherited from interface com.luciad.view.gxy.ILcdGXYLayerLabelPainter
ALL, SELECTION
Fields inherited from interface com.luciad.view.gxy.ILcdGXYViewLabelPainter
ALL, SELECTION
-
Constructor Summary
ConstructorDescriptionDeprecated.Creates a newTLcdContinuousDeclutteringLabelPainter
, ready to use. -
Method Summary
Modifier and TypeMethodDescriptionvoid
addLabelObstacleProvider
(ILcdGXYLabelObstacleProvider aObstacleProvider) Deprecated.Adds the givenILcdGXYLabelObstacleProvider
.clone()
Deprecated.RedefinesObject.clone
to make it public.Deprecated.Returns the desired relative location.int
Deprecated.Returns the threshold priority for forced label painting.Deprecated.Returns the list of registeredILcdGXYLabelObstacleProvider
s.Deprecated.Returns the label priority provider.int
Deprecated.Returns the maximum declutter time.double
Deprecated.Returns the maximum label coverage ratio.Deprecated.Returns the scale ratio interval in which label locations are reused.boolean
Deprecated.Returns true if the selection is labeled.boolean
Deprecated.This method has been deprecated.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 givenILcdGXYLayer
on the givenILcdGXYView
, 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 variousILcdGXYLayer
of the givenILcdGXYView
, in the given mode.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 variousILcdGXYLayer
of the given Enumeration, on the givenILcdGXYView
, in the given mode.void
removeLabelObstacleProvider
(ILcdGXYLabelObstacleProvider aObstacleProvider) Deprecated.Removes the givenILcdGXYLabelObstacleProvider
.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.
-
Constructor Details
-
TLcdContinuousDeclutteringLabelPainter
public TLcdContinuousDeclutteringLabelPainter()Deprecated.Creates a newTLcdContinuousDeclutteringLabelPainter
, ready to use.
-
-
Method Details
-
setForcedPaintingThresholdPriority
public void setForcedPaintingThresholdPriority(int aPriority) Deprecated.Sets the threshold priority for forced label painting. The labels of objects with a priority value less than or equal to the threshold priority value will always be painted. The default value is-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)
).- Parameters:
aPriority
- the threshold priority for forced label painting.- See Also:
-
getForcedPaintingThresholdPriority
public int getForcedPaintingThresholdPriority()Deprecated.Returns the threshold priority for forced label painting.- Returns:
- the threshold priority for forced label painting.
- See Also:
-
setClassTraceOn
public static void setClassTraceOn(boolean aClassTraceOn) Deprecated.Enable/disable display of debug trace information for this class.- Parameters:
aClassTraceOn
- True to enable display of debug information.
-
setTraceOn
public void setTraceOn(boolean aTraceOn) Deprecated.Enable/disable display of debug trace information for this instance. Also draws some extra information on the view:- Obstacles: dark green
- Labels: those that can be moved: orange. Those that cannot be moved (sticky): green.
- Direction of intended movement for the labels (drawn from the center outwards): yellow.
- Desired label location: small hollow black dot.
- Label anchor point: small hollow blue dot.
- Parameters:
aTraceOn
- True to enable display of debug information.
-
isTraceOn
public boolean isTraceOn()Deprecated.This method has been deprecated. It is recommended to use the standard Java logging framework directly.Returnstrue
if tracing is enabled for this class.- Returns:
- true if tracing is enabled for this class, false otherwise.
-
getLabelPriorityProvider
Deprecated.Returns the label priority provider.- Returns:
- the label priority provider.
- See Also:
-
setLabelPriorityProvider
Deprecated.Sets the label priority provider, specifying the priority for individual labels. If a maximum label coverage is specified, the labels with lowest priority are dropped first. In the event labels overlap, those with higher priority are painted on top of labels with lower priority. So lower priority labels are the first candidates if labels need to be obscured.- Parameters:
aLabelPriorityProvider
- The priority provider to set.- See Also:
-
isSelectionLabeled
public boolean isSelectionLabeled()Deprecated.Returns true if the selection is labeled.- Returns:
- true if the selection is labeled.
- See Also:
-
setSelectionLabeled
public void setSelectionLabeled(boolean aSelectionLabeled) Deprecated.Sets if the selection should be labeled. Labeling the selection works independent from theILcdGXYLayer.isLabeled()
flag, so that even if labeling is disabled, selected objects can still be labeled.- Parameters:
aSelectionLabeled
- True to label the selection, false to only label the selection ifILcdGXYLayer.isLabeled()
returns true.
-
getMaxLabelCoverage
public double getMaxLabelCoverage()Deprecated.Returns the maximum label coverage ratio.- Returns:
- the maximum label coverage ratio.
- See Also:
-
setMaxLabelCoverage
public void setMaxLabelCoverage(double aMaximumLabelCoverage) Deprecated.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 toDouble.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.
- Parameters:
aMaximumLabelCoverage
- The maximum label coverage, must be larger than or equal to 0.- See Also:
-
addLabelObstacleProvider
Deprecated.Adds the givenILcdGXYLabelObstacleProvider
. Obstacle providers are used to provide the decluttering algorithm with obstacles: places where preferably no labels should be placed.- Parameters:
aObstacleProvider
- The provider to add.
-
removeLabelObstacleProvider
Deprecated.Removes the givenILcdGXYLabelObstacleProvider
.- Parameters:
aObstacleProvider
- The provider to remove.
-
getLabelObstacleProviders
Deprecated.Returns the list of registeredILcdGXYLabelObstacleProvider
s.- Returns:
- the list of registered
ILcdGXYLabelObstacleProvider
s.
-
getDesiredRelativeLocation
Deprecated.Returns the desired relative location.- Returns:
- the desired relative location.
- See Also:
-
setDesiredRelativeLocation
Deprecated.Sets the desired relative label location: the location the labels tend to move to. The location of the label is relative to the anchor point of the object it belongs to. So if for example the relative location is set tonew 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 alsoretrieveDesiredLabelLocation(java.awt.Graphics, com.luciad.view.gxy.ILcdGXYContext, java.lang.Object, int, int, java.awt.Point)
.- Parameters:
aDesiredRelativeLocation
- The desired location relative to the anchor point of the object.- See Also:
-
retrieveDesiredLabelLocation
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. The desired location is specified relative to the anchor point of the object, and it is the label anchor point that tends to move there. By default, aRelativeLocationSFCT is modified to equal the result ofgetDesiredRelativeLocation
. 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.- Parameters:
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.- See Also:
-
getMaxDeclutterTime
public int getMaxDeclutterTime()Deprecated.Returns the maximum declutter time.- Returns:
- the maximum declutter time.
- See Also:
-
setMaxDeclutterTime
public void setMaxDeclutterTime(int aMaxDeclutterTime) Deprecated.Sets the maximum time (in ms) that should be spend in decluttering the labels. Providing a smaller limit may cause label positioning to be less optimal. This time value is a hint, not a hard limit.- Parameters:
aMaxDeclutterTime
- The maximum time that can be spend in decluttering, in ms.
-
getReuseLocationsScaleRatioInterval
Deprecated.Returns the scale ratio interval in which label locations are reused.- Returns:
- the scale ratio interval in which label locations are reused.
- See Also:
-
setReuseLocationsScaleRatioInterval
Deprecated.Sets the scale ratio interval in which the label locations are reused. To avoid labels suddenly jumping from one location to another, the previous label locations are reused (as stored inALcdLabelLocations
). If large changes inscale
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 tonew 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 tonull
, label locations are never reused.- Parameters:
aReuseLocationsScaleRatioInterval
- The scale ratio interval.
-
paintLabel
public void paintLabel(Graphics aGraphics, ILcdGXYLayer aGXYLayer, ILcdGXYView aGXYView, int aLayerLabelPainterMode) Deprecated.Description copied from interface:ILcdGXYLayerLabelPainter
The implementation of this method shall define how to paint the labels of all the objects in the given
ILcdGXYLayer
on the givenILcdGXYView
, 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 anILcdGXYEditableLabelsLayer
, this method should inform theALcdLabelLocations
associated with that layer which labels have been drawn and which haven't been.- Specified by:
paintLabel
in interfaceILcdGXYLayerLabelPainter
- Parameters:
aGraphics
- TheGraphics
instance on which to paint the labels.aGXYLayer
- The layer for which to paint the labels. If this layer is an instance ofILcdGXYEditableLabelsLayer
, itsALcdLabelLocations
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 ofILcdGXYLayerLabelPainter.ALL
orILcdGXYLayerLabelPainter.SELECTION
- See Also:
-
clone
Deprecated.Description copied from interface:ILcdGXYLayerLabelPainter
RedefinesObject.clone
to make it public.- Specified by:
clone
in interfaceILcdGXYLayerLabelPainter
- Specified by:
clone
in interfaceILcdGXYViewLabelPainter
- Overrides:
clone
in classObject
-
paintLabel
Deprecated.Description copied from interface:ILcdGXYViewLabelPainter
The implementation of this method shall define how to paint the labels of all the objects in the variousILcdGXYLayer
of the givenILcdGXYView
, 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 theALcdLabelLocations
associated with that layer which labels have been drawn and which haven't been.- Specified by:
paintLabel
in interfaceILcdGXYViewLabelPainter
- Parameters:
aGraphics
- TheGraphics
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 ofILcdGXYEditableLabelsLayer
, 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 ofILcdGXYViewLabelPainter.ALL
orILcdGXYViewLabelPainter.SELECTION
- See Also:
-
paintLabel
public void paintLabel(Graphics aGraphics, Enumeration aGXYLayerEnumeration, ILcdGXYView aGXYView, int aMode) Deprecated.Description copied from interface:ILcdGXYViewLabelPainter
The implementation of this method shall define how to paint the labels of all the objects in the variousILcdGXYLayer
of the given Enumeration, on the givenILcdGXYView
, 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 theALcdLabelLocations
associated with that layer which labels have been drawn and which haven't been.- Specified by:
paintLabel
in interfaceILcdGXYViewLabelPainter
- Parameters:
aGraphics
- TheGraphics
instance on which to paint the labels.aGXYLayerEnumeration
- Only the labels for the layers contained in thisEnumeration
will be drawn.aGXYView
- The ILcdGXYView instance for which to paint the layers.aMode
- Determines which labels should be drawn. Should be one ofILcdGXYViewLabelPainter.ALL
orILcdGXYViewLabelPainter.SELECTION
- See Also:
-