public abstract class ALspDiscreteLabelingAlgorithm extends Object implements ILspLabelingAlgorithm
This abstract class implements an abstract algorithm that can be used to compute label
placements. It tries a discrete number of placements for each label. It does so by first
iterating over all representations using an Iterator
. While iterating over the
representations, the algorithm iterates over a discrete number of placements for each
representation. It does so by using an other Iterator
. Each time a placement is returned,
this placement is evaluated using an ILspLabelPlacementEvaluator
. If the evaluator approves the placement for the representation, it
is added to the list of placements to be painted.
This abstract class also makes sure that the representations are sorted using their priority.
This abstract implementation also makes sure that edited or sticky label locations 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 an ALspDiscreteLabelingAlgorithm
, these methods should be
implemented by creating an iterator or evaluator using the delegate algorithm, and returning a
wrapped iterator of evaluator. See also ALspDiscreteLabelingAlgorithmWrapper
.
This abstract class also stores a few statistics in the properties
of the ILspLabelingAlgorithm.LabelContext
. Algorithms can
choose to use these properties to implement certain features, like optimizations. The following
statistics are generated:
TOTAL_LABEL_COUNT_KEY
: the total amount of labels to be placed.LABEL_ATTEMPT_COUNT_KEY
: the amount of labels for which a placement was tried.CONSECUTIVE_LABEL_FAIL_COUNT_KEY
: the consecutive amount of labels for which no placement was found.CONSECUTIVE_LABEL_CONFLICT_FAIL_COUNT_KEY
: the consecutive amount of labels for which no placement was found due to conflicts in the ILspLabelConflictChecker
.LABEL_FAIL_COUNT_KEY
: the amount of labels for which the algorithm didn't find a placement.LABEL_CONFLICT_FAIL_COUNT_KEY
: the amount of labels for which the algorithm didn't find a placement due to conflicts in the ILspLabelConflictChecker
.LABEL_PLACED_COUNT_KEY
: the amount of labels for which the algorithm has found a placement.ILspLabelingAlgorithm.LabelContext
Modifier and Type | Field and Description |
---|---|
static String |
CONSECUTIVE_LABEL_CONFLICT_FAIL_COUNT_KEY
This key is used to store the consecutive amount of labels for which no placement was found
due to conflicts in the
ILspLabelConflictChecker . |
static String |
CONSECUTIVE_LABEL_FAIL_COUNT_KEY
This key is used to store the consecutive amount of labels for which no placement was found.
|
static String |
LABEL_ATTEMPT_COUNT_KEY
This key is used to store the amount of labels for which the algorithm has tried to find a
placement.
|
static String |
LABEL_CONFLICT_FAIL_COUNT_KEY
This key is used to store the total amount of labels for which the algorithms has failed to
find a placement due to a conflict in the
ILspLabelConflictChecker . |
static String |
LABEL_FAIL_COUNT_KEY
This key is used to store the total amount of labels for which the algorithm has failed to
find a placement.
|
static String |
LABEL_PLACED_COUNT_KEY
This key is used to store the total amount of labels for which the algorithm has found a
placement.
|
static String |
TOTAL_LABEL_COUNT_KEY
This key is used to store the total amount of labels placed by the algorithm.
|
Constructor and Description |
---|
ALspDiscreteLabelingAlgorithm() |
Modifier and Type | Method and Description |
---|---|
ALspDiscreteLabelingAlgorithm |
clone()
Makes
Object.clone() public. |
protected abstract Iterator<TLspLabelID> |
createLabelIterator(List<TLspLabelID> aLabels,
ILspLabelingAlgorithm.LabelContext aLabelContext,
ILspLabelConflictChecker aConflictChecker,
ILspView aView)
Creates a new
Iterator that iterates over the TLspLabelID s. |
protected abstract ILspLabelPlacementEvaluator |
createLabelPlacementEvaluator(List<TLspLabelID> aLabels,
ILspLabelingAlgorithm.LabelContext aLabelContext,
ILspLabelConflictChecker aConflictChecker,
ILspView aView)
Creates a new
ILspLabelPlacementEvaluator using the given parameters. |
protected abstract Iterator<TLspLabelPlacement> |
createLabelPlacementIterator(TLspLabelID aLabel,
ALspLabelLocations aCurrentLabelLocations,
ILspLabelingAlgorithm.LabelContext aLabelContext,
ILspLabelConflictChecker aConflictChecker,
ILspView aView)
Creates a new
Iterator that iterates over the TLspLabelPlacement s for
the given label. |
abstract double |
getQuality()
Returns the quality setting.
|
List<TLspLabelPlacement> |
placeLabels(List<TLspLabelID> aLabelIDs,
ILspLabelingAlgorithm.LabelContext aLabelContext,
ILspLabelConflictChecker aConflictChecker,
ILspView aView)
|
abstract void |
setQuality(double aQuality)
Sets the quality.
|
public static final String TOTAL_LABEL_COUNT_KEY
Integer
.public static final String LABEL_ATTEMPT_COUNT_KEY
Integer
.public static final String CONSECUTIVE_LABEL_FAIL_COUNT_KEY
5
.
When after that, a label placement succeeds, the property will be reset to 0
.
This amount is stored in the properties as an
Integer
.LABEL_FAIL_COUNT_KEY
,
Constant Field Valuespublic static final String CONSECUTIVE_LABEL_CONFLICT_FAIL_COUNT_KEY
ILspLabelConflictChecker
. E.g. when the last 5 attempts
to place a label failed, this property will be 5
. When after that, a label
placement succeeds, the property will be reset to 0
. This amount is stored in
the properties as an Integer
.public static final String LABEL_CONFLICT_FAIL_COUNT_KEY
ILspLabelConflictChecker
. This amount
is stored in the properties as an Integer
.public static final String LABEL_FAIL_COUNT_KEY
Integer
.public static final String LABEL_PLACED_COUNT_KEY
Integer
.public ALspDiscreteLabelingAlgorithm 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 abstract void setQuality(double aQuality)
Sets the quality. If the quality setting is high, the algorithm will try to place more
labels. If it is low, the algorithm will only try to place a small portion of the labels,
making label placement faster. Setting the quality to e.g. 0.5
can dramatically
improve the label placement performance in some cases.
E.g. it is possible that due to the quality setting, this algorithm will only try to place 10% of the labels. This may still result in high quality results, but this depends on the used data. In general, using a lower quality setting will still work well when the data (and its labels) are distributed uniformly over the screen.
By default, the quality is set to 1.0.
aQuality
- the new quality. This is a number in [0, 1].getQuality()
public abstract double getQuality()
setQuality(double)
public final List<TLspLabelPlacement> placeLabels(List<TLspLabelID> aLabelIDs, ILspLabelingAlgorithm.LabelContext aLabelContext, ILspLabelConflictChecker aConflictChecker, ILspView aView)
ILspLabelingAlgorithm
This method computes a list of label placements for the given
List
of labels. The returned label placements
should contain a valid label location and label bounds. They
should also point to their corresponding TLspLabelID
The returned List
of TLspLabelPlacement
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 visible in the
label placer
placeLabels
in interface ILspLabelingAlgorithm
aLabelIDs
- the labels to be placed.aLabelContext
- provides context information, such as priorities, PaintState, ...aConflictChecker
- the conflict checker that can be used to detect conflicts between labels.aView
- the view.protected abstract Iterator<TLspLabelID> createLabelIterator(List<TLspLabelID> aLabels, ILspLabelingAlgorithm.LabelContext aLabelContext, ILspLabelConflictChecker aConflictChecker, ILspView aView)
Iterator
that iterates over the TLspLabelID
s. The abstract algorithm will continue
iterating over TLspLabelID
s as long as Iterator.hasNext()
returns true
. When it returns false
, no more label placements will be
tried, and placeLabels
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.
Override this method to provide a custom implementation.
aLabels
- a list of labels that need to be placed.aLabelContext
- the label info object.aConflictChecker
- the conflict checker to be used when evaluating placements.aView
- the view.Iterator
that iterates over TLspLabelID
s.protected abstract Iterator<TLspLabelPlacement> createLabelPlacementIterator(TLspLabelID aLabel, ALspLabelLocations aCurrentLabelLocations, ILspLabelingAlgorithm.LabelContext aLabelContext, ILspLabelConflictChecker aConflictChecker, ILspView aView)
Iterator
that iterates over the TLspLabelPlacement
s for
the given label. The abstract algorithm will continue iterating over
TLspLabelPlacement
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 TLspLabelPlacement
should be
correctly initialized, that is it should at least be able to return a valid label location,
bounds rectangle and bounds rotation. It should also reference its corresponding
TLspLabelID
.
Override this method to provide a custom implementation.
aLabel
- the identifier for which an iterator should be created.aCurrentLabelLocations
- an ALspLabelLocations object containing locations for the
currently placed labels.aLabelContext
- the label info object.aConflictChecker
- the conflict checker to be used when evaluating placements.aView
- the view.Iterator
that iterates over TLspLabelPlacement
s.protected abstract ILspLabelPlacementEvaluator createLabelPlacementEvaluator(List<TLspLabelID> aLabels, ILspLabelingAlgorithm.LabelContext aLabelContext, ILspLabelConflictChecker aConflictChecker, ILspView aView)
ILspLabelPlacementEvaluator
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 placement will be used for its label, it will be added to the list of placed
representations, and it will be added to the given ILspLabelConflictChecker
. After
that, ILspLabelPlacementEvaluator.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 ILspLabelConflictChecker
. After that, ILspLabelPlacementEvaluator.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, ILspLabelPlacementEvaluator.noPlacementApplied
is called.PlacementResult.FAILED
: the abstract algorithm will immediately call ILspLabelPlacementEvaluator.noPlacementApplied
and will not try to find other placements for the label.Override this method to provide a custom implementation.
aLabels
- a list of labels.aLabelContext
- the label info object.aConflictChecker
- the conflict checker to be used when evaluating placements.aView
- the viewILspLabelPlacementEvaluator
.ILspLabelPlacementEvaluator