public abstract class ALcdGXYDiscretePlacementsLabelingAlgorithm extends Object implements ILcdGXYLabelingAlgorithm
Iterator
. While iterating over the labels,
the algorithm iterates over a discrete number of label placements for each label. It does
so by using an Iterator
. Each time a label placement is returned, this placement
is evaluated using an ILcdLabelPlacementEvaluator
. If the evaluator approves the
placement for the label, it is added to the list of label placements to be painted.
This abstract class also makes sure that the labels are sorted using their priority (see
TLcdCollectedLabelInfo.PRIORITY_KEY
).
This abstract implementation also makes sure that the label offset functionality is correctly
handled (see TLcdLabelLocation.getParentLabel()
, TLcdLabelLocation.getAnchorPoint
).
So classes implementing this abstract labeling algorithm should just place their labels relative
to the object anchor point (with no anchor point and parent label specified in the TLcdLabelLocation), and
this class will make sure they are offset correctly.
This abstract implementation also makes sure that edited or sticky labels are correctly handled. So implementations of this abstract algorithm should not try to handle sticky or edited labels themselves.
When implementing this abstract algorithm, the following methods should be implemented :
When wrapping anALcdGXYDiscretePlacementsLabelingAlgorithm
, these methods should
be implemented by creating an iterator or evaluator using the delegate algorithm, and returning
a wrapped iterator of evaluator.Constructor and Description |
---|
ALcdGXYDiscretePlacementsLabelingAlgorithm() |
Modifier and Type | Method and Description |
---|---|
ALcdGXYDiscretePlacementsLabelingAlgorithm |
clone()
Makes
Object.clone() public. |
TLcdCollectedLabelInfoList |
collectLabelInfo(List<TLcdLabelIdentifier> aLabelsToCollect,
Graphics aGraphics,
ILcdGXYView aGXYView)
This method returns a
TLcdCollectedLabelInfoList object based
on the given list of TLcdLabelIdentifier s. |
List<TLcdLabelPlacement> |
computeLabelPlacements(TLcdCollectedLabelInfoList aLabelInfoList,
ILcdLabelConflictChecker aLabelConflictChecker,
ILcdGXYView aView)
This method computes a list of
TLcdLabelPlacement s using the given
TLcdCollectedLabelInfoList . |
protected abstract Iterator<TLcdCollectedLabelInfo> |
createLabelIterator(TLcdCollectedLabelInfoList aLabelInfoList,
ILcdLabelConflictChecker aBoundsConflictChecker,
ILcdGXYView aView)
Creates a new
Iterator that iterates over the TLcdCollectedLabelInfo s. |
protected abstract ILcdLabelPlacementEvaluator |
createLabelPlacementEvaluator(TLcdCollectedLabelInfoList aLabelInfoList,
ILcdLabelConflictChecker aBoundsConflictChecker,
ILcdGXYView aView)
Creates a new
ILcdLabelPlacementEvaluator using the given parameters. |
protected abstract Iterator<TLcdLabelPlacement> |
createLabelPlacementIterator(TLcdCollectedLabelInfo aLabel,
TLcdCollectedLabelInfoList aLabelInfoList,
ILcdLabelConflictChecker aBoundsConflictChecker,
ILcdGXYView aView)
Creates a new
Iterator that iterates over the TLcdLabelPlacement s
for the given label. |
public ALcdGXYDiscretePlacementsLabelingAlgorithm()
public ALcdGXYDiscretePlacementsLabelingAlgorithm clone()
ILcdCloneable
Makes Object.clone()
public.
java.lang.Object
, it can be implemented like this:
public Object clone() {
try {
return super.clone();
} catch ( CloneNotSupportedException e ) {
// Cannot happen: extends from Object and implements Cloneable (see also Object.clone)
throw new RuntimeException( e );
}
}
clone
in interface ILcdCloneable
clone
in class Object
Object.clone()
public TLcdCollectedLabelInfoList collectLabelInfo(List<TLcdLabelIdentifier> aLabelsToCollect, Graphics aGraphics, ILcdGXYView aGXYView)
ILcdGXYLabelingAlgorithm
TLcdCollectedLabelInfoList
object based
on the given list of TLcdLabelIdentifier
s. The returned
TLcdCollectedLabelInfoList
should contain a TLcdCollectedLabelInfo
object for each label that should be placed.
Each TLcdCollectedLabelInfo
should also contain all information needed by
computeLabelPlacements
to place the labels. In order to enable
correct asynchronous label placing, all calls to the layer and the (label) painters should be
done in this method. The results should then be stored in the info objects.
It is possible that the returned TLcdCollectedLabelInfoList
doesn't contain a
TLcdCollectedLabelInfo
object for every given TLcdLabelIdentifier
.
In that case the missing labels are not placed.
collectLabelInfo
in interface ILcdGXYLabelingAlgorithm
aLabelsToCollect
- the labels for which a TLcdCollectedLabelInfoList
should
be created.aGraphics
- the graphics.aGXYView
- the view.TLcdCollectedLabelInfoList
which contains all the information needed to
place the labels.public final List<TLcdLabelPlacement> computeLabelPlacements(TLcdCollectedLabelInfoList aLabelInfoList, ILcdLabelConflictChecker aLabelConflictChecker, ILcdGXYView aView)
TLcdLabelPlacement
s using the given
TLcdCollectedLabelInfoList
. The returned label placements
should contain a valid TLcdLabelLocation
and label bounds. They should also point
to their corresponding TLcdCollectedLabelInfo
, which in turn should point to its
corresponding TLcdCollectedLabeledObjectInfo
.
The given TLcdCollectedLabelInfoList
should always be an object created or returned
by collectLabelInfo
.
The returned List
of TLcdLabelPlacement
s contains label placements
that are either visible or invisible. When a placement is present in the list, it means that
the location should be stored. When a placement in the list is marked as visible, it means that
its location should be marked as to-be-painted.
The labels should by preference be placed in the order in which the labels are returned by
TLcdCollectedLabelInfoList.getLabels()
.
This method implements an abstract algorithm to create labels. It tries a discrete number of placements for each label. It first creates a label iterator, looping over all labels to be handled. For each such label, a label placement iterator is created to iterate over label placements. A label placement is then evaluated by a label placement evaluator and possibly added to the list of placed labels.
The implementation of this method first sorts all labels using the priorities set in the label. It then creates the label iterator and label placement evaluator using the sorted labels and then executes the abstract algorithm using them. During the algorithm, label placement iterators are created for each processed label.
computeLabelPlacements
in interface ILcdGXYLabelingAlgorithm
aLabelInfoList
- the info object that contains all information needed to place the labels.aLabelConflictChecker
- the bounds conflict checker that can be used to detect conflicts between labels.aView
- the view.createLabelIterator
,
createLabelPlacementIterator
,
createLabelPlacementEvaluator
protected abstract Iterator<TLcdCollectedLabelInfo> createLabelIterator(TLcdCollectedLabelInfoList aLabelInfoList, ILcdLabelConflictChecker aBoundsConflictChecker, ILcdGXYView aView)
Iterator
that iterates over the TLcdCollectedLabelInfo
s.
The abstract labeling algorithm will continue iterating over TLcdCollectedLabelInfo
s
as long as Iterator.hasNext()
returns true
. When it returns false
,
no more labels will be tried, and computeLabelPlacements
returns.
Iterator.hasNext()
should always be called before calling Iterator.next()
, and
if it returns true
, Iterator.next()
should never return null
.
The implementation of this method should be as independent as possible. It should not rely on
createLabelPlacementIterator
or
createLabelPlacementEvaluator
.
Not respecting this might result in unexpected behaviour when wrapping or extending this class.
The returned TLcdCollectedLabelInfo
should be correctly initialized, i.e. it should
contain all information needed to create valid TLcdLabelPlacement
s using
createLabelPlacementIterator
. It should also always point
to its corresponding TLcdCollectedLabeledObjectInfo
.
Override this method to provide a custom implementation.
aLabelInfoList
- the label infos object that contains all information needed to place the labels.aBoundsConflictChecker
- the bounds conflict checker to be used when evaluating label placements.aView
- the view.Iterator
that iterates over TLcdCollectedLabelInfo
s.protected abstract Iterator<TLcdLabelPlacement> createLabelPlacementIterator(TLcdCollectedLabelInfo aLabel, TLcdCollectedLabelInfoList aLabelInfoList, ILcdLabelConflictChecker aBoundsConflictChecker, ILcdGXYView aView)
Iterator
that iterates over the TLcdLabelPlacement
s
for the given label. The abstract labeling algorithm will continue iterating over
TLcdLabelPlacement
s as long as Iterator.hasNext()
returns true
.
When it returns false
, a new label will be tried. Iterator.hasNext()
should
always be called before calling Iterator.next()
, and if it returns true
,
Iterator.next()
should never return null
.
The implementation of this method should be as independent as possible. It should not rely on
createLabelIterator
or createLabelPlacementEvaluator
.
Not respecting this might result in unexpected behaviour when wrapping or extending this class.
The returned TLcdLabelPlacement
should be correctly initialized, i.e. it should at
least be able to return a valid label location, bounds rectangle and bounds rotation. It should
also reference its corresponding TLcdCollectedLabelInfo
.
Override this method to provide a custom implementation.
aLabel
- the label for which an iterator should be created.aLabelInfoList
- the info object that contains all information needed to place the labels.aBoundsConflictChecker
- the bounds conflict checker to be used when evaluating label placements.aView
- the view.Iterator
that iterates over TLcdLabelPlacement
s.protected abstract ILcdLabelPlacementEvaluator createLabelPlacementEvaluator(TLcdCollectedLabelInfoList aLabelInfoList, ILcdLabelConflictChecker aBoundsConflictChecker, ILcdGXYView aView)
ILcdLabelPlacementEvaluator
using the given parameters. It evaluates
the placements returned by createLabelPlacementIterator
,
and returns a PlacementResult
to denote if the placement should be used for its
label or not.
The following actions are undertaken for the following placement results :
PlacementResult.SUCCESS
:
the given label placement will be used for its label, it will be added to the list of placed
labels, and it will be added to the given ILcdLabelConflictChecker
. After that,
ILcdLabelPlacementEvaluator.placementApplied
will be called and no more placements are tried for the label.PlacementResult.FALLBACK
:
the abstract algorithm will try to find an other placements which returns
PlacementResult.SUCCESS
.
When no such placement is found, this placement will be added to the list of placed labels,
and it will be added to the given ILcdLabelConflictChecker
. After that,
ILcdLabelPlacementEvaluator.placementApplied
will be called.PlacementResult.TRY_NEW_PLACEMENT
:
the abstract algorithm will try to find an other placement which returns
PlacementResult.SUCCESS
or
PlacementResult.FALLBACK
.
When no such placement is found, ILcdLabelPlacementEvaluator.noPlacementApplied
is called.PlacementResult.FAILED
: the
abstract algorithm will immediately call ILcdLabelPlacementEvaluator.noPlacementApplied
and will not try to find other placements for the label.Override this method to provide a custom implementation.
aLabelInfoList
- the info object that contains all information needed to place the labels.aBoundsConflictChecker
- the bounds conflict checker to be used when evaluating label placements.aView
- the viewILcdLabelPlacementEvaluator