@@ -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 ;
@@ -1058,14 +1061,36 @@ int FeaturePart::createCurvedCandidatesAlongLine( QList< LabelPosition* >& lPos,
1058
1061
1059
1062
// average angle is calculated with respect to periodicity of angles
1060
1063
double angle_avg = atan2 ( sin_avg / li->char_num , cos_avg / li->char_num );
1061
- // displacement
1062
- if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) )
1063
- positions.append ( _createCurvedCandidate ( slp, angle_avg, mLF ->distLabel () + li->label_height / 2 ) );
1064
- if ( flags & FLAG_ON_LINE )
1065
- positions.append ( _createCurvedCandidate ( slp, angle_avg, 0 ) );
1066
- if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
1067
- positions.append ( _createCurvedCandidate ( slp, angle_avg, -li->label_height / 2 - mLF ->distLabel () ) );
1064
+ // displacement - we loop through 3 times, generating above, online then below line placements successively
1065
+ for ( int i = 0 ; i <= 2 ; ++i )
1066
+ {
1067
+ LabelPosition* p = nullptr ;
1068
+ if ( i == 0 && (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) ) )
1069
+ p = _createCurvedCandidate ( slp, angle_avg, mLF ->distLabel () + li->label_height / 2 );
1070
+ if ( i == 1 && flags & FLAG_ON_LINE )
1071
+ p = _createCurvedCandidate ( slp, angle_avg, 0 );
1072
+ if ( i == 2 && (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) ) )
1073
+ p = _createCurvedCandidate ( slp, angle_avg, -li->label_height / 2 - mLF ->distLabel () );
1074
+
1075
+ if ( p && mLF ->permissibleZonePrepared () )
1076
+ {
1077
+ bool within = true ;
1078
+ LabelPosition* currentPos = p;
1079
+ while ( within && currentPos )
1080
+ {
1081
+ within = GeomFunction::containsCandidate ( mLF ->permissibleZonePrepared (), currentPos->getX (), currentPos->getY (), currentPos->getWidth (), currentPos->getHeight (), currentPos->getAlpha () );
1082
+ currentPos = currentPos->getNextPart ();
1083
+ }
1084
+ if ( !within )
1085
+ {
1086
+ delete p;
1087
+ p = nullptr ;
1088
+ }
1089
+ }
1068
1090
1091
+ if ( p )
1092
+ positions.append ( p );
1093
+ }
1069
1094
// delete original candidate
1070
1095
delete slp;
1071
1096
}
@@ -1155,7 +1180,7 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
1155
1180
1156
1181
// fit in polygon only mode slows down calculation a lot, so if it's enabled
1157
1182
// then use a smaller limit for number of iterations
1158
- int maxTry = mLF ->layer ()-> fitInPolygonOnly () ? 7 : 10 ;
1183
+ int maxTry = mLF ->permissibleZonePrepared () ? 7 : 10 ;
1159
1184
1160
1185
do
1161
1186
{
@@ -1169,10 +1194,11 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
1169
1194
continue ;
1170
1195
}
1171
1196
1172
- if ( mLF ->layer ()->arrangement () == QgsPalLayerSettings::Horizontal && mLF ->layer ()-> fitInPolygonOnly () )
1197
+ if ( mLF ->layer ()->arrangement () == QgsPalLayerSettings::Horizontal && mLF ->permissibleZonePrepared () )
1173
1198
{
1174
1199
// check width/height of bbox is sufficient for label
1175
- if ( box->length < labelWidth || box->width < labelHeight )
1200
+ if ( mLF ->permissibleZone ().boundingBox ().width () < labelWidth ||
1201
+ mLF ->permissibleZone ().boundingBox ().height () < labelHeight )
1176
1202
{
1177
1203
// no way label can fit in this box, skip it
1178
1204
continue ;
@@ -1260,8 +1286,8 @@ int FeaturePart::createCandidatesForPolygon( QList< LabelPosition*>& lPos, Point
1260
1286
rx += box->x [0 ];
1261
1287
ry += box->y [0 ];
1262
1288
1263
- bool candidateAcceptable = ( mLF ->layer ()-> fitInPolygonOnly ()
1264
- ? mapShape-> containsLabelCandidate ( rx - dlx, ry - dly, labelWidth, labelHeight, alpha )
1289
+ bool candidateAcceptable = ( mLF ->permissibleZonePrepared ()
1290
+ ? GeomFunction::containsCandidate ( mLF -> permissibleZonePrepared (), rx - dlx, ry - dly, labelWidth, labelHeight, alpha )
1265
1291
: mapShape->containsPoint ( rx, ry ) );
1266
1292
if ( candidateAcceptable )
1267
1293
{
@@ -1350,9 +1376,9 @@ int FeaturePart::createCandidates( QList< LabelPosition*>& lPos,
1350
1376
double cx, cy;
1351
1377
mapShape->getCentroid ( cx, cy, mLF ->layer ()->centroidInside () );
1352
1378
if ( mLF ->layer ()->arrangement () == QgsPalLayerSettings::OverPoint )
1353
- createCandidatesOverPoint ( cx, cy, lPos, angle, mapShape );
1379
+ createCandidatesOverPoint ( cx, cy, lPos, angle );
1354
1380
else
1355
- createCandidatesAroundPoint ( cx, cy, lPos, angle, mapShape );
1381
+ createCandidatesAroundPoint ( cx, cy, lPos, angle );
1356
1382
break ;
1357
1383
case QgsPalLayerSettings::Line:
1358
1384
createCandidatesAlongLine ( lPos, mapShape );
0 commit comments