Instead of just considering the "candidate furthest from the polygon
rings" as the best, also consider that candidates closer to the
overall polygon centroid are better than those further from the centroid.
I.e. if two candidates are similarish distances from a ring, pick the
one closer to the centroid instead of the one further from the centroid
(even if that further one is a tiny bit more distant from a ring)
Instead of basing the initial dx/dy for the grid-based polygon candidate
generation on the size of the label itself, instead use either the
engine setting for polygon label density OR try and infer this from the
maximum number of candidates to generate for the polygon.
This avoids numerous issues with the label-size based approach:
- small labels (e.g. 1-2 digit labels) would generate a HUGE number of candidates
because the initial dx/dy were very small
- large labels would generate very few candidates, giving few options for
placement within these polygons (due to initially large dx/dy)
- by generating much more candidates then desired for small labels,
all the candidates further from the polygon centers would be culled
at a later step, meaning that the only candidates available for the
labeling problem solving would be clustered around a very small area
of the polygon (instead of distributed over the whole polygon)
1. Remove redundant sort operations
2. Rename classes and methods for clarity
3. Don't overwrite polygon candidate costs with new costs based solely
on the ring distance cost -- instead just increase the existing cost
by the ring distance cost, so that already calculated costs such as
obstacle overlap costs aren't lost
4. Remove unused code
Seems to be trimming the candidate list early and artificially
resetting all candidate costs if they are too high?
I believe this code is wrong, or has been made redundant by other
changes to the logic of the labeling engine. At this stage we have
not completely calculated the costs for label candidates, so
sorting and truncating the candidate list here is premature and potentially
removes nice candidates.
Avoids crashes caused by super-heavy labeling jobs, where a huge
number of candidates causes the rtree to branch out to a level
where the leaf size becomes comparable to float epsilon values
Candidates furthest from any obstacles were being preferred, even
when this resulted in labels being located around the edges of polygon
features.
The correct logic should be only to consider direct overlaps of the
candidate with an obstacle as a conflict, and if a candidate does
NOT overlap and obstacles then we rely on the "put labels furthest
from edges as possible" rule.
to be placed on the maximum number of point, line and polygon candidates
which are generated for label features
These settings are set via the core\rendering\label_candidates_limit_*
settings, and allow for global limits to be set on the maximum number
of candidates allowed for label features. Placing these limits can
improve map rendering time, at the expense of worse label placement or
potentially missing map labels. (By default no global limit is set, which
means the labeling engine auto calculates the limit or uses the project
level settings)
The intended use case is for server administrators who are seeking for
maximum rendering speed to globally set these limits, causing them to
apply to all projects without the need for project-specific tweaks.
settings and logic
The previous approach of a single fixed value which applied to ALL line and ALL polygon
features was... not ideal. It meant that all line features would be assigned the same
number of candidates, regardless of length. So a road of length 1 cm on the rendered
map would have an identical number of candidates as a 30cm road covering the length of the
whole map!! This resulted in both a lot of wasted calculations (generating a ridiculous
number of candidates for small lines at barely discernable distances from each other)
AND an insufficient number of candidates for lengthy features (resulting in worse label
placement for these features).
(The situation was similar, but even worse for polygons)
Now, the setting is reworked to "Number of line candidates per cm" and "number of
polygon candidates per cm2". This means that small features get much less candidates,
and large features get much more features! Both a win for map rendering speed in many
circumstances AND good cartography... now that's a nice Christmas gift for QGIS :)