Skip to content

Commit 34e2bea

Browse files
fritsvanveennyalldawson
authored andcommittedAug 17, 2016
'Using perimeter (curved)' labels on polygon layers will now respect 'Show upside-down labels' setting.
1 parent d6b419a commit 34e2bea

File tree

6 files changed

+169
-138
lines changed

6 files changed

+169
-138
lines changed
 

‎src/core/pal/feature.cpp

Lines changed: 127 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ int FeaturePart::createCandidatesAlongLineNearMidpoint( QList<LabelPosition*>& l
968968
}
969969

970970

971-
LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, double* path_distances, int orientation, int index, double distance )
971+
LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, double* path_distances, int& orientation, int index, double distance, bool& flip )
972972
{
973973
// Check that the given distance is on the given index and find the correct index and distance if not
974974
while ( distance < 0 && index > 1 )
@@ -995,10 +995,6 @@ LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, d
995995

996996
LabelInfo* li = mLF->curvedLabelInfo();
997997

998-
// Keep track of the initial index,distance incase we need to re-call get_placement_offset
999-
int initial_index = index;
1000-
double initial_distance = distance;
1001-
1002998
double string_height = li->label_height;
1003999
double old_x = path_positions->x[index-1];
10041000
double old_y = path_positions->y[index-1];
@@ -1018,14 +1014,18 @@ LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, d
10181014

10191015
LabelPosition* slp = nullptr;
10201016
LabelPosition* slp_tmp = nullptr;
1021-
// current_placement = placement_result()
10221017
double angle = atan2( -dy, dx );
10231018

10241019
bool orientation_forced = ( orientation != 0 ); // Whether the orientation was set by the caller
10251020
if ( !orientation_forced )
10261021
orientation = ( angle > 0.55 * M_PI || angle < -0.45 * M_PI ? -1 : 1 );
10271022

1028-
int upside_down_char_count = 0; // Count of characters that are placed upside down.
1023+
if ( !isUprightLabel() )
1024+
{
1025+
if ( orientation != 1 )
1026+
flip = true; // Report to the caller, that the orientation is flipped
1027+
orientation = 1;
1028+
}
10291029

10301030
for ( int i = 0; i < li->char_num; i++ )
10311031
{
@@ -1086,7 +1086,6 @@ LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, d
10861086

10871087
// Calculate angle from the start of the character to the end based on start_/end_ position
10881088
angle = atan2( start_y - end_y, end_x - start_x );
1089-
//angle = atan2(end_y-start_y, end_x-start_x);
10901089

10911090
// Test last_character_angle vs angle
10921091
// since our rendering angle has changed then check against our
@@ -1108,7 +1107,10 @@ LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, d
11081107
// and we're calculating the mean line here
11091108
double dist = 0.9 * li->label_height / 2;
11101109
if ( orientation < 0 )
1110+
{
11111111
dist = -dist;
1112+
flip = true;
1113+
}
11121114
start_x += dist * cos( angle + M_PI_2 );
11131115
start_y -= dist * sin( angle + M_PI_2 );
11141116

@@ -1137,36 +1139,15 @@ LabelPosition* FeaturePart::curvedPlacementAtOffset( PointSet* path_positions, d
11371139
slp_tmp->setNextPart( tmp );
11381140
slp_tmp = tmp;
11391141

1140-
//current_placement.add_node(ci.character,render_x, -render_y, render_angle);
1141-
//current_placement.add_node(ci.character,render_x - current_placement.starting_x, render_y - current_placement.starting_y, render_angle)
1142-
11431142
// Normalise to 0 <= angle < 2PI
1144-
while ( render_angle >= 2*M_PI ) render_angle -= 2 * M_PI;
1143+
while ( render_angle >= 2 * M_PI ) render_angle -= 2 * M_PI;
11451144
while ( render_angle < 0 ) render_angle += 2 * M_PI;
11461145

1147-
if ( render_angle > M_PI / 2 && render_angle < 1.5*M_PI )
1148-
upside_down_char_count++;
1146+
if ( render_angle > M_PI / 2 && render_angle < 1.5 * M_PI )
1147+
slp->incrementUpsideDownCharCount();
11491148
}
11501149
// END FOR
11511150

1152-
// If we placed too many characters upside down
1153-
if ( upside_down_char_count >= li->char_num / 2.0 )
1154-
{
1155-
// if we auto-detected the orientation then retry with the opposite orientation
1156-
if ( !orientation_forced )
1157-
{
1158-
orientation = -orientation;
1159-
delete slp;
1160-
slp = curvedPlacementAtOffset( path_positions, path_distances, orientation, initial_index, initial_distance );
1161-
}
1162-
else
1163-
{
1164-
// Otherwise we have failed to find a placement
1165-
delete slp;
1166-
return nullptr;
1167-
}
1168-
}
1169-
11701151
return slp;
11711152
}
11721153

@@ -1231,99 +1212,120 @@ int FeaturePart::createCurvedCandidatesAlongLine( QList< LabelPosition* >& lPos,
12311212
flags = FLAG_ON_LINE; // default flag
12321213
// placements may need to be reversed if using line position dependent orientation
12331214
// and the line has right-to-left direction
1234-
bool reversed = ( !( flags & FLAG_MAP_ORIENTATION ) ? isRightToLeft : false );
1215+
bool reversed = (( flags & FLAG_MAP_ORIENTATION ) ? isRightToLeft : false );
12351216

12361217
// an orientation of 0 means try both orientations and choose the best
12371218
int orientation = 0;
1238-
if ( !( flags & FLAG_MAP_ORIENTATION )
1239-
&& mLF->layer()->arrangement() == QgsPalLayerSettings::PerimeterCurved )
1219+
if ( !( flags & FLAG_MAP_ORIENTATION ) )
12401220
{
1241-
//... but if we are labeling the perimeter of a polygon and using line orientation flags,
1242-
// then we can only accept a single orientation, as we need to ensure that the labels fall
1243-
// inside or outside the polygon (and not mixed)
1221+
//... but if we are using line orientation flags, then we can only accept a single orientation,
1222+
// as we need to ensure that the labels fall inside or outside the polyline or polygon (and not mixed)
12441223
orientation = reversed ? -1 : 1;
12451224
}
12461225

12471226
// generate curved labels
12481227
for ( int i = 0; i*delta < total_distance; i++ )
12491228
{
1250-
LabelPosition* slp = curvedPlacementAtOffset( mapShape, path_distances, orientation, 1, i * delta );
1229+
bool flip = false;
1230+
bool orientation_forced = ( orientation != 0 ); // Whether the orientation was set by the caller
1231+
LabelPosition* slp = curvedPlacementAtOffset( mapShape, path_distances, orientation, 1, i * delta, flip );
1232+
if ( slp == nullptr )
1233+
continue;
12511234

1252-
if ( slp )
1235+
// If we placed too many characters upside down
1236+
if ( slp->upsideDownCharCount() >= li->char_num / 2.0 )
12531237
{
1254-
// evaluate cost
1255-
double angle_diff = 0.0, angle_last = 0.0, diff;
1256-
LabelPosition* tmp = slp;
1257-
double sin_avg = 0, cos_avg = 0;
1258-
while ( tmp )
1238+
// if we auto-detected the orientation then retry with the opposite orientation
1239+
if ( !orientation_forced )
12591240
{
1260-
if ( tmp != slp ) // not first?
1261-
{
1262-
diff = fabs( tmp->getAlpha() - angle_last );
1263-
if ( diff > 2*M_PI ) diff -= 2 * M_PI;
1264-
diff = qMin( diff, 2 * M_PI - diff ); // difference 350 deg is actually just 10 deg...
1265-
angle_diff += diff;
1266-
}
1241+
orientation = -orientation;
1242+
delete slp;
1243+
slp = curvedPlacementAtOffset( mapShape, path_distances, orientation, 1, i * delta, flip );
1244+
}
1245+
else if ( isUprightLabel() && !flip )
1246+
{
1247+
// Retry with the opposite orientation
1248+
orientation = -orientation;
1249+
delete slp;
1250+
slp = curvedPlacementAtOffset( mapShape, path_distances, orientation, 1, i * delta, flip );
1251+
}
1252+
}
1253+
if ( slp == nullptr )
1254+
continue;
12671255

1268-
sin_avg += sin( tmp->getAlpha() );
1269-
cos_avg += cos( tmp->getAlpha() );
1270-
angle_last = tmp->getAlpha();
1271-
tmp = tmp->getNextPart();
1256+
// evaluate cost
1257+
double angle_diff = 0.0, angle_last = 0.0, diff;
1258+
LabelPosition* tmp = slp;
1259+
double sin_avg = 0, cos_avg = 0;
1260+
while ( tmp )
1261+
{
1262+
if ( tmp != slp ) // not first?
1263+
{
1264+
diff = fabs( tmp->getAlpha() - angle_last );
1265+
if ( diff > 2*M_PI ) diff -= 2 * M_PI;
1266+
diff = qMin( diff, 2 * M_PI - diff ); // difference 350 deg is actually just 10 deg...
1267+
angle_diff += diff;
12721268
}
12731269

1274-
double angle_diff_avg = li->char_num > 1 ? ( angle_diff / ( li->char_num - 1 ) ) : 0; // <0, pi> but pi/8 is much already
1275-
double cost = angle_diff_avg / 100; // <0, 0.031 > but usually <0, 0.003 >
1276-
if ( cost < 0.0001 ) cost = 0.0001;
1270+
sin_avg += sin( tmp->getAlpha() );
1271+
cos_avg += cos( tmp->getAlpha() );
1272+
angle_last = tmp->getAlpha();
1273+
tmp = tmp->getNextPart();
1274+
}
1275+
1276+
double angle_diff_avg = li->char_num > 1 ? ( angle_diff / ( li->char_num - 1 ) ) : 0; // <0, pi> but pi/8 is much already
1277+
double cost = angle_diff_avg / 100; // <0, 0.031 > but usually <0, 0.003 >
1278+
if ( cost < 0.0001 ) cost = 0.0001;
12771279

1278-
// penalize positions which are further from the line's midpoint
1279-
double labelCenter = ( i * delta ) + getLabelWidth() / 2;
1280-
double costCenter = qAbs( total_distance / 2 - labelCenter ) / total_distance; // <0, 0.5>
1281-
cost += costCenter / 1000; // < 0, 0.0005 >
1282-
slp->setCost( cost );
1280+
// penalize positions which are further from the line's midpoint
1281+
double labelCenter = ( i * delta ) + getLabelWidth() / 2;
1282+
double costCenter = qAbs( total_distance / 2 - labelCenter ) / total_distance; // <0, 0.5>
1283+
cost += costCenter / 1000; // < 0, 0.0005 >
1284+
slp->setCost( cost );
12831285

1284-
// average angle is calculated with respect to periodicity of angles
1285-
double angle_avg = atan2( sin_avg / li->char_num, cos_avg / li->char_num );
1286-
// displacement - we loop through 3 times, generating above, online then below line placements successively
1287-
for ( int i = 0; i <= 2; ++i )
1286+
// average angle is calculated with respect to periodicity of angles
1287+
double angle_avg = atan2( sin_avg / li->char_num, cos_avg / li->char_num );
1288+
bool localreversed = flip ? !reversed : reversed;
1289+
// displacement - we loop through 3 times, generating above, online then below line placements successively
1290+
for ( int i = 0; i <= 2; ++i )
1291+
{
1292+
LabelPosition* p = nullptr;
1293+
if ( i == 0 && (( !localreversed && ( flags & FLAG_ABOVE_LINE ) ) || ( localreversed && ( flags & FLAG_BELOW_LINE ) ) ) )
1294+
p = _createCurvedCandidate( slp, angle_avg, mLF->distLabel() + li->label_height / 2 );
1295+
if ( i == 1 && flags & FLAG_ON_LINE )
12881296
{
1289-
LabelPosition* p = nullptr;
1290-
if ( i == 0 && (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) ) )
1291-
p = _createCurvedCandidate( slp, angle_avg, mLF->distLabel() + li->label_height / 2 );
1292-
if ( i == 1 && flags & FLAG_ON_LINE )
1293-
{
1294-
p = _createCurvedCandidate( slp, angle_avg, 0 );
1295-
p->setCost( p->cost() + 0.002 );
1296-
}
1297-
if ( i == 2 && (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) ) )
1297+
p = _createCurvedCandidate( slp, angle_avg, 0 );
1298+
p->setCost( p->cost() + 0.002 );
1299+
}
1300+
if ( i == 2 && (( !localreversed && ( flags & FLAG_BELOW_LINE ) ) || ( localreversed && ( flags & FLAG_ABOVE_LINE ) ) ) )
1301+
{
1302+
p = _createCurvedCandidate( slp, angle_avg, -li->label_height / 2 - mLF->distLabel() );
1303+
p->setCost( p->cost() + 0.001 );
1304+
}
1305+
1306+
if ( p && mLF->permissibleZonePrepared() )
1307+
{
1308+
bool within = true;
1309+
LabelPosition* currentPos = p;
1310+
while ( within && currentPos )
12981311
{
1299-
p = _createCurvedCandidate( slp, angle_avg, -li->label_height / 2 - mLF->distLabel() );
1300-
p->setCost( p->cost() + 0.001 );
1312+
within = GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), currentPos->getX(), currentPos->getY(), currentPos->getWidth(), currentPos->getHeight(), currentPos->getAlpha() );
1313+
currentPos = currentPos->getNextPart();
13011314
}
1302-
1303-
if ( p && mLF->permissibleZonePrepared() )
1315+
if ( !within )
13041316
{
1305-
bool within = true;
1306-
LabelPosition* currentPos = p;
1307-
while ( within && currentPos )
1308-
{
1309-
within = GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), currentPos->getX(), currentPos->getY(), currentPos->getWidth(), currentPos->getHeight(), currentPos->getAlpha() );
1310-
currentPos = currentPos->getNextPart();
1311-
}
1312-
if ( !within )
1313-
{
1314-
delete p;
1315-
p = nullptr;
1316-
}
1317+
delete p;
1318+
p = nullptr;
13171319
}
1318-
1319-
if ( p )
1320-
positions.append( p );
13211320
}
1322-
// delete original candidate
1323-
delete slp;
1321+
1322+
if ( p )
1323+
positions.append( p );
13241324
}
1325-
}
13261325

1326+
// delete original candidate
1327+
delete slp;
1328+
}
13271329

13281330
int nbp = positions.size();
13291331
for ( int i = 0; i < nbp; i++ )
@@ -1336,9 +1338,6 @@ int FeaturePart::createCurvedCandidatesAlongLine( QList< LabelPosition* >& lPos,
13361338
return nbp;
13371339
}
13381340

1339-
1340-
1341-
13421341
/*
13431342
* seg 2
13441343
* pt3 ____________pt2
@@ -1588,9 +1587,7 @@ int FeaturePart::createCandidates( QList< LabelPosition*>& lPos,
15881587
createCandidatesAroundPoint( x[0], y[0], lPos, angle );
15891588
break;
15901589
case GEOS_LINESTRING:
1591-
if ( mLF->layer()->arrangement() == QgsPalLayerSettings::Curved )
1592-
createCurvedCandidatesAlongLine( lPos, mapShape );
1593-
else if ( mLF->layer()->arrangement() == QgsPalLayerSettings::PerimeterCurved )
1590+
if ( mLF->layer()->isCurved() )
15941591
createCurvedCandidatesAlongLine( lPos, mapShape );
15951592
else
15961593
createCandidatesAlongLine( lPos, mapShape );
@@ -1774,3 +1771,28 @@ double FeaturePart::calculatePriority() const
17741771

17751772
return mLF->priority() >= 0 ? mLF->priority() : mLF->layer()->priority();
17761773
}
1774+
1775+
bool FeaturePart::isUprightLabel() const
1776+
{
1777+
bool uprightLabel = false;
1778+
1779+
switch ( mLF->layer()->upsidedownLabels() )
1780+
{
1781+
case Layer::Upright:
1782+
uprightLabel = true;
1783+
break;
1784+
case Layer::ShowDefined:
1785+
// upright only dynamic labels
1786+
if ( !hasFixedRotation() || ( !hasFixedPosition() && fixedAngle() == 0.0 ) )
1787+
{
1788+
uprightLabel = true;
1789+
}
1790+
break;
1791+
case Layer::ShowAll:
1792+
break;
1793+
default:
1794+
uprightLabel = true;
1795+
}
1796+
return uprightLabel;
1797+
}
1798+

‎src/core/pal/feature.h

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ namespace pal
178178
int createCandidatesAlongLineNearMidpoint( QList<LabelPosition *> &lPos, PointSet *mapShape, double initialCost = 0.0 );
179179

180180
LabelPosition* curvedPlacementAtOffset( PointSet* path_positions, double* path_distances,
181-
int orientation, int index, double distance );
181+
int& orientation, int index, double distance, bool& flip );
182182

183183
/** Generate curved candidates for line features.
184184
* @param lPos pointer to an array of candidates, will be filled by generated candidates
@@ -213,13 +213,28 @@ namespace pal
213213
double getLabelHeight() const { return mLF->size().height(); }
214214
double getLabelDistance() const { return mLF->distLabel(); }
215215

216-
bool getFixedRotation() { return mLF->hasFixedAngle(); }
217-
double getLabelAngle() { return mLF->fixedAngle(); }
218-
bool getFixedPosition() { return mLF->hasFixedPosition(); }
219-
bool getAlwaysShow() { return mLF->alwaysShow(); }
220-
bool isObstacle() { return mLF->isObstacle(); }
221-
double obstacleFactor() { return mLF->obstacleFactor(); }
222-
double repeatDistance() { return mLF->repeatDistance(); }
216+
//! Returns true if the feature's label has a fixed rotation
217+
bool hasFixedRotation() const { return mLF->hasFixedAngle(); }
218+
219+
//! Returns the fixed angle for the feature's label
220+
double fixedAngle() const { return mLF->fixedAngle(); }
221+
222+
//! Returns true if the feature's label has a fixed position
223+
bool hasFixedPosition() const { return mLF->hasFixedPosition(); }
224+
225+
//! Returns true if the feature's label should always been shown,
226+
//! even when it collides with other labels
227+
bool alwaysShow() const { return mLF->alwaysShow(); }
228+
229+
//! Returns true if the feature should act as an obstacle to labels
230+
bool isObstacle() const { return mLF->isObstacle(); }
231+
232+
//! Returns the feature's obstacle factor, which represents the penalty
233+
//! incurred for a label to overlap the feature
234+
double obstacleFactor() const { return mLF->obstacleFactor(); }
235+
236+
//! Returns the distance between repeating labels for this feature
237+
double repeatDistance() const { return mLF->repeatDistance(); }
223238

224239
//! Get number of holes (inner rings) - they are considered as obstacles
225240
int getNumSelfObstacles() const { return mHoles.count(); }
@@ -242,6 +257,8 @@ namespace pal
242257
*/
243258
double calculatePriority() const;
244259

260+
//! Returns true if feature's label must be displayed upright
261+
bool isUprightLabel() const;
245262

246263
protected:
247264

‎src/core/pal/labelposition.cpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h,
6060
, quadrant( quadrant )
6161
, mCost( cost )
6262
, mHasObstacleConflict( false )
63+
, mUpsideDownCharCount( 0 )
6364
{
6465
type = GEOS_POLYGON;
6566
nbPoints = 4;
@@ -77,8 +78,6 @@ LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h,
7778

7879
double dx1, dx2, dy1, dy2;
7980

80-
double tx, ty;
81-
8281
dx1 = cos( this->alpha ) * w;
8382
dy1 = sin( this->alpha ) * w;
8483

@@ -98,32 +97,14 @@ LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h,
9897
y[3] = y1 + dy2;
9998

10099
// upside down ? (curved labels are always correct)
101-
if ( feature->layer()->arrangement() != QgsPalLayerSettings::Curved &&
102-
feature->layer()->arrangement() != QgsPalLayerSettings::PerimeterCurved &&
100+
if ( !feature->layer()->isCurved() &&
103101
this->alpha > M_PI / 2 && this->alpha <= 3*M_PI / 2 )
104102
{
105-
bool uprightLabel = false;
106-
107-
switch ( feature->layer()->upsidedownLabels() )
103+
if ( feature->isUprightLabel() )
108104
{
109-
case Layer::Upright:
110-
uprightLabel = true;
111-
break;
112-
case Layer::ShowDefined:
113-
// upright only dynamic labels
114-
if ( !feature->getFixedRotation() || ( !feature->getFixedPosition() && feature->getLabelAngle() == 0.0 ) )
115-
{
116-
uprightLabel = true;
117-
}
118-
break;
119-
case Layer::ShowAll:
120-
break;
121-
default:
122-
uprightLabel = true;
123-
}
105+
// Turn label upsidedown by inverting boundary points
106+
double tx, ty;
124107

125-
if ( uprightLabel )
126-
{
127108
tx = x[0];
128109
ty = y[0];
129110

@@ -184,6 +165,7 @@ LabelPosition::LabelPosition( const LabelPosition& other )
184165
reversed = other.reversed;
185166
quadrant = other.quadrant;
186167
mHasObstacleConflict = other.mHasObstacleConflict;
168+
mUpsideDownCharCount = other.mUpsideDownCharCount;
187169
}
188170

189171
bool LabelPosition::isIn( double *bbox )

‎src/core/pal/labelposition.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ namespace pal
228228
int getPartId() const { return partId; }
229229
void setPartId( int id ) { partId = id; }
230230

231+
//! Increases the count of upside down characters for this label position
232+
int incrementUpsideDownCharCount() { return ++mUpsideDownCharCount; }
233+
234+
//! Returns the number of upside down characters for this label position
235+
int upsideDownCharCount() const { return mUpsideDownCharCount; }
231236

232237
void removeFromIndex( RTree<LabelPosition*, double, 2, double> *index );
233238
void insertIntoIndex( RTree<LabelPosition*, double, 2, double> *index );
@@ -296,6 +301,7 @@ namespace pal
296301
private:
297302
double mCost;
298303
bool mHasObstacleConflict;
304+
int mUpsideDownCharCount;
299305

300306
/** Calculates the total number of parts for this label position
301307
*/

‎src/core/pal/layer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ namespace pal
9494
*/
9595
QgsPalLayerSettings::Placement arrangement() const { return mArrangement; }
9696

97+
/** Returns true if the layer has curved labels
98+
*/
99+
bool isCurved() const { return mArrangement == QgsPalLayerSettings::Curved || mArrangement == QgsPalLayerSettings::PerimeterCurved; }
100+
97101
/** Sets the layer's arrangement policy.
98102
* @param arrangement arrangement policy
99103
* @see arrangement

‎src/core/pal/problem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2268,7 +2268,7 @@ QList<LabelPosition*> * Problem::getSolution( bool returnInactive )
22682268
}
22692269
else if ( returnInactive
22702270
|| mLabelPositions.at( featStartId[i] )->getFeaturePart()->layer()->displayAll()
2271-
|| mLabelPositions.at( featStartId[i] )->getFeaturePart()->getAlwaysShow() )
2271+
|| mLabelPositions.at( featStartId[i] )->getFeaturePart()->alwaysShow() )
22722272
{
22732273
solList->push_back( mLabelPositions.at( featStartId[i] ) ); // unplaced label
22742274
}

12 commit comments

Comments
 (12)

fritsvanveen commented on Aug 25, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson
labels on wrong side of polygon
I have one layer, where the labels are shown on the wrong size of the polygon. They should be on the inside. Is there such a thing as an inverted polygon in a database? I've also drawn an inner glow, and that is shown correctly. I can see in QgsSymbol::renderFeature that a MultiPolygon is drawn, but that is also true for other layers, which are ok. I'm a bit at a loss here.

fritsvanveen commented on Aug 26, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson
2016-08-26 09_19_21-qgis 2 16 1-nodebo - test grenzen
2016-08-26 09_19_36-qgis 2 99 0 - test grenzend
I've attached some more examples. Only Katwijk is displayed correctly in 2.99.0, that is with labels inside the polygon. In 2.16.1 the polygons which are cutoff are also displayed with labels inside. Can you provide some hints how I can proceed to investigate this?
Oh, curved or straight labels exhibit the same problem.

nyalldawson commented on Aug 29, 2016

@nyalldawson
Collaborator

@fritsvanveen my usual approach here is to enable labels both above and below the line, and then enable the option to only draw labels which fit inside the polygon.

BTW - i've noticed since your last commit re upside down labels that many curved labels for line geometry layers are now drawn incorrectly upside down. Are you able to look into this?

fritsvanveen commented on Aug 29, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson Also for polygon layers. I'll look into it.

fritsvanveen commented on Sep 2, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson Just a quick update. The upsidedown bug is fixed. Variable 'orientation' should have been primed inside the for loop. However, with 'Line orientation dependent position' off, some labels are plotted on the wrong side of the line.

nyalldawson commented on Sep 3, 2016

@nyalldawson
Collaborator

@fritsvanveen great! is there an updated commit I should be looking at, or will you update the PR?

fritsvanveen commented on Sep 3, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson Not yet, let's wait until I fixed the other bug.

fritsvanveen commented on Sep 3, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson I'm confused about these lines in createCandidatesAlongLineNearStraightSegment

    // meaning of above/below may be reversed if using line position dependent orientation
    // and the line has right-to-left direction
    bool reversed = (( flags & FLAG_MAP_ORIENTATION ) ? isRightToLeft : false );

Should the comment not read 'using map orientation'

nyalldawson commented on Sep 3, 2016

@nyalldawson
Collaborator

Yes - sounds like that comment is wrong

fritsvanveen commented on Sep 4, 2016

@fritsvanveen
ContributorAuthor

fritsvanveen commented on Sep 4, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson Made another commit on my fork https://github.com/fritsvanveen/QGIS
Ik works now, but I want to clean up the code.

fritsvanveen commented on Sep 5, 2016

@fritsvanveen
ContributorAuthor

@nyalldawson Cleaned up code committed.

Please sign in to comment.