mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-18 00:03:05 -04:00
[labeling] Fix curved labels sometimes placed below line even when
set to above line only
This commit is contained in:
parent
50315c4a33
commit
10c4bb9f9b
@ -998,22 +998,31 @@ LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, d
|
||||
double _distance = offsetAlongSegment;
|
||||
int endindex = index;
|
||||
|
||||
double startLabelX = 0;
|
||||
double startLabelY = 0;
|
||||
double endLabelX = 0;
|
||||
double endLabelY = 0;
|
||||
for ( int i = 0; i < li->char_num; i++ )
|
||||
{
|
||||
LabelInfo::CharacterInfo &ci = li->char_info[i];
|
||||
double 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 ) )
|
||||
double start_x, start_y;
|
||||
if ( !nextCharPosition( ci.width, path_distances[endindex], path_positions, endindex, _distance, start_x, start_y, endLabelX, endLabelY ) )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if ( i == 0 )
|
||||
{
|
||||
startLabelX = start_x;
|
||||
startLabelY = start_y;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the angle of the path segment under consideration
|
||||
double dx = path_positions->x[endindex] - path_positions->x[index];
|
||||
double dy = path_positions->y[endindex] - path_positions->y[index];
|
||||
double line_angle = std::atan2( -dy, dx );
|
||||
double dx = endLabelX - startLabelX;
|
||||
double dy = endLabelY - startLabelY;
|
||||
const double lineAngle = std::atan2( -dy, dx ) * 180 / M_PI;
|
||||
|
||||
bool isRightToLeft = ( line_angle > 0.55 * M_PI || line_angle < -0.45 * M_PI );
|
||||
bool isRightToLeft = ( lineAngle > 90 || lineAngle < -90 );
|
||||
reversed = isRightToLeft;
|
||||
orientation = isRightToLeft ? -1 : 1;
|
||||
}
|
||||
@ -1175,7 +1184,7 @@ int FeaturePart::createCurvedCandidatesAlongLine( QList< LabelPosition * > &lPos
|
||||
QLinkedList<LabelPosition *> positions;
|
||||
double delta = std::max( li->label_height, total_distance / mLF->layer()->pal->line_p );
|
||||
|
||||
unsigned long flags = mLF->layer()->arrangementFlags();
|
||||
pal::LineArrangementFlags flags = mLF->layer()->arrangementFlags();
|
||||
if ( flags == 0 )
|
||||
flags = FLAG_ON_LINE; // default flag
|
||||
|
||||
|
@ -56,6 +56,7 @@ class TestQgsLabelingEngine : public QObject
|
||||
void testTouchingParts();
|
||||
void testMergingLinesWithForks();
|
||||
void testCurvedLabelsWithTinySegments();
|
||||
void testCurvedLabelCorrectLinePlacement();
|
||||
void testLabelBoundary();
|
||||
void testLabelBlockingRegion();
|
||||
void testLabelRotationWithReprojection();
|
||||
@ -1037,6 +1038,72 @@ void TestQgsLabelingEngine::testCurvedLabelsWithTinySegments()
|
||||
QVERIFY( imageCheck( QStringLiteral( "label_curved_label_small_segments" ), img, 20 ) );
|
||||
}
|
||||
|
||||
void TestQgsLabelingEngine::testCurvedLabelCorrectLinePlacement()
|
||||
{
|
||||
// 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;
|
||||
settings.placementFlags = QgsPalLayerSettings::AboveLine | QgsPalLayerSettings::MapOrientation;
|
||||
settings.maxCurvedCharAngleIn = 99;
|
||||
settings.maxCurvedCharAngleOut = 99;
|
||||
|
||||
std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "LineString?crs=epsg:4326&field=id:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
|
||||
vl2->setRenderer( new QgsNullSymbolRenderer() );
|
||||
|
||||
QgsFeature f;
|
||||
f.setAttributes( QgsAttributes() << 1 );
|
||||
// Geometry which roughly curves around from "1 oclock" anticlockwise to 6 oclock.
|
||||
QgsGeometry g( QgsGeometry::fromWkt( QStringLiteral( "LineString (0.30541596873255172 0.3835845896147404, -0.08989391401451696 0.21831379117811278, -0.33668341708542704 -0.01619207146845336, -0.156895589056393 -0.20714684533780003, 0.02735901730876611 -0.21496370742601911)" ) ) );
|
||||
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 );
|
||||
|
||||
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_above_1" ), img, 20 ) );
|
||||
|
||||
// and below...
|
||||
settings.placementFlags = QgsPalLayerSettings::BelowLine | QgsPalLayerSettings::MapOrientation;
|
||||
vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary!
|
||||
|
||||
QgsMapRendererSequentialJob job2( mapSettings );
|
||||
job2.start();
|
||||
job2.waitForFinished();
|
||||
|
||||
img = job2.renderedImage();
|
||||
QVERIFY( imageCheck( QStringLiteral( "label_curved_label_below_1" ), img, 20 ) );
|
||||
}
|
||||
|
||||
void TestQgsLabelingEngine::testLabelBoundary()
|
||||
{
|
||||
// test that no labels are drawn outside of the specified label boundary
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
Loading…
x
Reference in New Issue
Block a user