@@ -227,7 +227,7 @@ LabelPosition::Quadrant FeaturePart::quadrantFromOffset() const
227
227
}
228
228
}
229
229
230
- int FeaturePart::createCandidatesOverPoint ( double x, double y, QList< LabelPosition*>& lPos, double angle, PointSet *mapShape )
230
+ int FeaturePart::createCandidatesOverPoint ( double x, double y, QList< LabelPosition*>& lPos, double angle )
231
231
{
232
232
int nbp = 1 ;
233
233
@@ -294,9 +294,9 @@ int FeaturePart::createCandidatesOverPoint( double x, double y, QList< LabelPosi
294
294
double lx = x + xdiff;
295
295
double ly = y + ydiff;
296
296
297
- if ( mapShape && type == GEOS_POLYGON && mLF ->layer ()-> fitInPolygonOnly () )
297
+ if ( mLF ->permissibleZonePrepared () )
298
298
{
299
- if ( !mapShape-> containsLabelCandidate ( lx, ly, labelW, labelH, angle ) )
299
+ if ( !GeomFunction::containsCandidate ( mLF -> permissibleZonePrepared (), lx, ly, labelW, labelH, angle ) )
300
300
{
301
301
return 0 ;
302
302
}
@@ -419,18 +419,20 @@ int FeaturePart::createCandidatesAtOrderedPositionsOverPoint( double x, double y
419
419
double labelX = referenceX + deltaX;
420
420
double labelY = referenceY + deltaY;
421
421
422
- lPos << new LabelPosition ( i, labelX, labelY, labelWidth, labelHeight, angle, cost, this , false , quadrant );
423
-
424
- // TODO - tweak
425
- cost += 0.001 ;
422
+ if ( ! mLF ->permissibleZonePrepared () || GeomFunction::containsCandidate ( mLF ->permissibleZonePrepared (), labelX, labelY, labelWidth, labelHeight, angle ) )
423
+ {
424
+ lPos << new LabelPosition ( i, labelX, labelY, labelWidth, labelHeight, angle, cost, this , false , quadrant );
425
+ // TODO - tweak
426
+ cost += 0.001 ;
427
+ }
426
428
427
429
++i;
428
430
}
429
431
430
432
return lPos.count ();
431
433
}
432
434
433
- int FeaturePart::createCandidatesAroundPoint ( double x, double y, QList< LabelPosition* >& lPos, double angle, PointSet *mapShape )
435
+ int FeaturePart::createCandidatesAroundPoint ( double x, double y, QList< LabelPosition* >& lPos, double angle )
434
436
{
435
437
double labelWidth = getLabelWidth ();
436
438
double labelHeight = getLabelHeight ();
@@ -547,9 +549,9 @@ int FeaturePart::createCandidatesAroundPoint( double x, double y, QList< LabelPo
547
549
cost = 0.0001 + 0.0020 * double ( icost ) / double ( numberCandidates - 1 );
548
550
549
551
550
- if ( mapShape && type == GEOS_POLYGON && mLF ->layer ()-> fitInPolygonOnly () )
552
+ if ( mLF ->permissibleZonePrepared () )
551
553
{
552
- if ( !mapShape-> containsLabelCandidate ( labelX, labelY, labelWidth, labelHeight, angle ) )
554
+ if ( !GeomFunction::containsCandidate ( mLF -> permissibleZonePrepared (), labelX, labelY, labelWidth, labelHeight, angle ) )
553
555
{
554
556
continue ;
555
557
}
@@ -698,17 +700,17 @@ int FeaturePart::createCandidatesAlongLine( QList< LabelPosition* >& lPos, Point
698
700
699
701
if ( aboveLine )
700
702
{
701
- if ( !mLF ->layer ()-> fitInPolygonOnly () || mapShape-> containsLabelCandidate ( bx + cos ( beta ) *distlabel, by + sin ( beta ) *distlabel, xrm, yrm, alpha ) )
703
+ if ( !mLF ->permissibleZonePrepared () || GeomFunction::containsCandidate ( mLF -> permissibleZonePrepared (), bx + cos ( beta ) *distlabel, by + sin ( beta ) *distlabel, xrm, yrm, alpha ) )
702
704
positions.append ( new LabelPosition ( i, bx + cos ( beta ) *distlabel, by + sin ( beta ) *distlabel, xrm, yrm, alpha, cost, this , isRightToLeft ) ); // Line
703
705
}
704
706
if ( belowLine )
705
707
{
706
- if ( !mLF ->layer ()-> fitInPolygonOnly () || mapShape-> containsLabelCandidate ( bx - cos ( beta ) *( distlabel + yrm ), by - sin ( beta ) *( distlabel + yrm ), xrm, yrm, alpha ) )
708
+ if ( !mLF ->permissibleZonePrepared () || GeomFunction::containsCandidate ( mLF -> permissibleZonePrepared (), bx - cos ( beta ) *( distlabel + yrm ), by - sin ( beta ) *( distlabel + yrm ), xrm, yrm, alpha ) )
707
709
positions.append ( new LabelPosition ( i, bx - cos ( beta ) *( distlabel + yrm ), by - sin ( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this , isRightToLeft ) ); // Line
708
710
}
709
711
if ( flags & FLAG_ON_LINE )
710
712
{
711
- if ( !mLF ->layer ()-> fitInPolygonOnly () || mapShape-> containsLabelCandidate ( bx - yrm*cos ( beta ) / 2 , by - yrm*sin ( beta ) / 2 , xrm, yrm, alpha ) )
713
+ if ( !mLF ->permissibleZonePrepared () || GeomFunction::containsCandidate ( mLF -> permissibleZonePrepared (), bx - yrm*cos ( beta ) / 2 , by - yrm*sin ( beta ) / 2 , xrm, yrm, alpha ) )
712
714
positions.append ( new LabelPosition ( i, bx - yrm*cos ( beta ) / 2 , by - yrm*sin ( beta ) / 2 , xrm, yrm, alpha, cost, this , isRightToLeft ) ); // Line
713
715
}
714
716
}
@@ -879,6 +881,7 @@ LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, d
879
881
delete slp;
880
882
return nullptr ;
881
883
}
884
+
882
885
// Shift the character downwards since the draw position is specified at the baseline
883
886
// and we're calculating the mean line here
884
887
double dist = 0.9 * li->label_height / 2 ;
@@ -1047,14 +1050,36 @@ int FeaturePart::createCurvedCandidatesAlongLine( QList< LabelPosition* >& lPos,
1047
1050
1048
1051
// average angle is calculated with respect to periodicity of angles
1049
1052
double angle_avg = atan2 ( sin_avg / li->char_num , cos_avg / li->char_num );
1050
- // displacement
1051
- if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) )
1052
- positions.append ( _createCurvedCandidate ( slp, angle_avg, mLF ->distLabel () + li->label_height / 2 ) );
1053
- if ( flags & FLAG_ON_LINE )
1054
- positions.append ( _createCurvedCandidate ( slp, angle_avg, 0 ) );
1055
- if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
1056
- positions.append ( _createCurvedCandidate ( slp, angle_avg, -li->label_height / 2 - mLF ->distLabel () ) );
1053
+ // displacement - we loop through 3 times, generating above, online then below line placements successively
1054
+ for ( int i = 0 ; i <= 2 ; ++i )
1055
+ {
1056
+ LabelPosition* p = nullptr ;
1057
+ if ( i == 0 && (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) ) )
1058
+ p = _createCurvedCandidate ( slp, angle_avg, mLF ->distLabel () + li->label_height / 2 );
1059
+ if ( i == 1 && flags & FLAG_ON_LINE )
1060
+ p = _createCurvedCandidate ( slp, angle_avg, 0 );
1061
+ if ( i == 2 && (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) ) )
1062
+ p = _createCurvedCandidate ( slp, angle_avg, -li->label_height / 2 - mLF ->distLabel () );
1063
+
1064
+ if ( p && mLF ->permissibleZonePrepared () )
1065
+ {
1066
+ bool within = true ;
1067
+ LabelPosition* currentPos = p;
1068
+ while ( within && currentPos )
1069
+ {
1070
+ within = GeomFunction::containsCandidate ( mLF ->permissibleZonePrepared (), currentPos->getX (), currentPos->getY (), currentPos->getWidth (), currentPos->getHeight (), currentPos->getAlpha () );
1071
+ currentPos = currentPos->getNextPart ();
1072
+ }
1073
+ if ( !within )
1074
+ {
1075
+ delete p;
1076
+ p = nullptr ;
1077
+ }
1078
+ }
1057
1079
1080
+ if ( p )
1081
+ positions.append ( p );
1082
+ }
1058
1083
// delete original candidate
1059
1084
delete slp;
1060
1085
}
@@ -1144,7 +1169,7 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
1144
1169
1145
1170
// fit in polygon only mode slows down calculation a lot, so if it's enabled
1146
1171
// then use a smaller limit for number of iterations
1147
- int maxTry = mLF ->layer ()-> fitInPolygonOnly () ? 7 : 10 ;
1172
+ int maxTry = mLF ->permissibleZonePrepared () ? 7 : 10 ;
1148
1173
1149
1174
do
1150
1175
{
@@ -1158,10 +1183,11 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
1158
1183
continue ;
1159
1184
}
1160
1185
1161
- if ( mLF ->layer ()->arrangement () == QgsPalLayerSettings::Horizontal && mLF ->layer ()-> fitInPolygonOnly () )
1186
+ if ( mLF ->layer ()->arrangement () == QgsPalLayerSettings::Horizontal && mLF ->permissibleZonePrepared () )
1162
1187
{
1163
1188
// check width/height of bbox is sufficient for label
1164
- if ( box->length < labelWidth || box->width < labelHeight )
1189
+ if ( mLF ->permissibleZone ().boundingBox ().width () < labelWidth ||
1190
+ mLF ->permissibleZone ().boundingBox ().height () < labelHeight )
1165
1191
{
1166
1192
// no way label can fit in this box, skip it
1167
1193
continue ;
@@ -1249,8 +1275,8 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
1249
1275
rx += box->x [0 ];
1250
1276
ry += box->y [0 ];
1251
1277
1252
- bool candidateAcceptable = ( mLF ->layer ()-> fitInPolygonOnly ()
1253
- ? mapShape-> containsLabelCandidate ( rx - dlx, ry - dly, labelWidth, labelHeight, alpha )
1278
+ bool candidateAcceptable = ( mLF ->permissibleZonePrepared ()
1279
+ ? GeomFunction::containsCandidate ( mLF -> permissibleZonePrepared (), rx - dlx, ry - dly, labelWidth, labelHeight, alpha )
1254
1280
: mapShape->containsPoint ( rx, ry ) );
1255
1281
if ( candidateAcceptable )
1256
1282
{
@@ -1337,9 +1363,9 @@ int FeaturePart::createCandidates( QList< LabelPosition*>& lPos,
1337
1363
double cx, cy;
1338
1364
mapShape->getCentroid ( cx, cy, mLF ->layer ()->centroidInside () );
1339
1365
if ( mLF ->layer ()->arrangement () == QgsPalLayerSettings::OverPoint )
1340
- createCandidatesOverPoint ( cx, cy, lPos, angle, mapShape );
1366
+ createCandidatesOverPoint ( cx, cy, lPos, angle );
1341
1367
else
1342
- createCandidatesAroundPoint ( cx, cy, lPos, angle, mapShape );
1368
+ createCandidatesAroundPoint ( cx, cy, lPos, angle );
1343
1369
break ;
1344
1370
case QgsPalLayerSettings::Line:
1345
1371
createCandidatesAlongLine ( lPos, mapShape );
0 commit comments