Skip to content

Commit

Permalink
[labeling] Fix curved labeling fails when line feature geometry
Browse files Browse the repository at this point in the history
begins with small segments

Fixes #28699
  • Loading branch information
nyalldawson committed May 30, 2019
1 parent fcacd00 commit 328b0af
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/core/pal/feature.cpp
Expand Up @@ -1000,7 +1000,7 @@ LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, d
{
LabelInfo::CharacterInfo &ci = li->char_info[i];
double start_x, start_y, end_x, end_y;
if ( !nextCharPosition( ci.width, path_distances[index], path_positions, endindex, _distance, start_x, start_y, end_x, end_y ) )
if ( !nextCharPosition( ci.width, path_distances[endindex], path_positions, endindex, _distance, start_x, start_y, end_x, end_y ) )
{
return nullptr;
}
Expand Down
56 changes: 56 additions & 0 deletions tests/src/core/testqgslabelingengine.cpp
Expand Up @@ -55,6 +55,7 @@ class TestQgsLabelingEngine : public QObject
void testAdjacentParts();
void testTouchingParts();
void testMergingLinesWithForks();
void testCurvedLabelsWithTinySegments();
void testLabelBoundary();
void testLabelBlockingRegion();
void testLabelRotationWithReprojection();
Expand Down Expand Up @@ -981,6 +982,61 @@ void TestQgsLabelingEngine::testMergingLinesWithForks()
QVERIFY( imageCheck( QStringLiteral( "label_multipart_touching_branches" ), img, 20 ) );
}

void TestQgsLabelingEngine::testCurvedLabelsWithTinySegments()
{
// test drawing curved labels when input linestring has many small segments
QgsPalLayerSettings settings;
setDefaultLabelParams( settings );

QgsTextFormat format = settings.format();
format.setSize( 20 );
format.setColor( QColor( 0, 0, 0 ) );
settings.setFormat( format );

settings.fieldName = QStringLiteral( "'XXXXXXXXXXXXXXXXXXXXXXXXXX'" );
settings.isExpression = true;
settings.placement = QgsPalLayerSettings::Curved;

std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "LineString?crs=epsg:3946&field=id:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
vl2->setRenderer( new QgsNullSymbolRenderer() );

QgsFeature f;
f.setAttributes( QgsAttributes() << 1 );
// our geometry starts with many small segments, followed by long ones
QgsGeometry g( QgsGeometry::fromWkt( QStringLiteral( "LineString (190000 5000010, 190100 5000000)" ) ) );
g = g.densifyByCount( 100 );
qgsgeometry_cast< QgsLineString * >( g.get() )->addVertex( QgsPoint( 190200, 5000000 ) );
f.setGeometry( g );
QVERIFY( vl2->dataProvider()->addFeature( f ) );

vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary!
vl2->setLabelsEnabled( true );

// make a fake render context
QSize size( 640, 480 );
QgsMapSettings mapSettings;
mapSettings.setDestinationCrs( vl2->crs() );

mapSettings.setOutputSize( size );
mapSettings.setExtent( g.boundingBox() );
mapSettings.setLayers( QList<QgsMapLayer *>() << vl2.get() );
mapSettings.setOutputDpi( 96 );
mapSettings.setFlag( QgsMapSettings::UseRenderingOptimization, false );

QgsLabelingEngineSettings engineSettings = mapSettings.labelingEngineSettings();
engineSettings.setFlag( QgsLabelingEngineSettings::UsePartialCandidates, false );
engineSettings.setFlag( QgsLabelingEngineSettings::DrawLabelRectOnly, true );
//engineSettings.setFlag( QgsLabelingEngineSettings::DrawCandidates, true );
mapSettings.setLabelingEngineSettings( engineSettings );

QgsMapRendererSequentialJob job( mapSettings );
job.start();
job.waitForFinished();

QImage img = job.renderedImage();
QVERIFY( imageCheck( QStringLiteral( "label_curved_label_small_segments" ), img, 20 ) );
}

void TestQgsLabelingEngine::testLabelBoundary()
{
// test that no labels are drawn outside of the specified label boundary
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 328b0af

Please sign in to comment.