Skip to content

Commit 0bccdfe

Browse files
authoredJan 6, 2020
Merge pull request #33514 from m-kuhn/more-stable-dxf-export-alignment
[dxf export] Improve dxf alignment
2 parents 23f862b + 0eef197 commit 0bccdfe

File tree

9 files changed

+59
-54
lines changed

9 files changed

+59
-54
lines changed
 

‎src/core/dxf/qgsdxfexport.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,21 +1265,23 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
12651265
double lblX = label->getX();
12661266
double lblY = label->getY();
12671267

1268+
QgsLabelFeature *labelFeature = label->getFeaturePart()->feature();
1269+
12681270
HAlign hali = HAlign::Undefined;
12691271
VAlign vali = VAlign::Undefined;
12701272

12711273
const QgsPropertyCollection &props = layerSettings.dataDefinedProperties();
12721274

12731275
if ( props.isActive( QgsPalLayerSettings::OffsetQuad ) )
12741276
{
1277+
lblX = labelFeature->anchorPosition().x();
1278+
lblY = labelFeature->anchorPosition().y();
1279+
12751280
const QVariant exprVal = props.value( QgsPalLayerSettings::OffsetQuad, expressionContext );
12761281
if ( exprVal.isValid() )
12771282
{
12781283
int offsetQuad = exprVal.toInt();
12791284

1280-
lblX -= label->dX();
1281-
lblY -= label->dY();
1282-
12831285
switch ( offsetQuad )
12841286
{
12851287
case 0: // Above Left
@@ -1328,6 +1330,9 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
13281330

13291331
if ( props.isActive( QgsPalLayerSettings::Hali ) )
13301332
{
1333+
lblX = labelFeature->anchorPosition().x();
1334+
lblY = labelFeature->anchorPosition().y();
1335+
13311336
hali = HAlign::HLeft;
13321337
QVariant exprVal = props.value( QgsPalLayerSettings::Hali, expressionContext );
13331338
if ( exprVal.isValid() )
@@ -1344,8 +1349,6 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
13441349
}
13451350
}
13461351

1347-
std::unique_ptr<QFontMetricsF> labelFontMetrics( new QFontMetricsF( layerSettings.format().font() ) );
1348-
13491352
//vertical alignment
13501353
if ( props.isActive( QgsPalLayerSettings::Vali ) )
13511354
{

‎src/core/labeling/qgslabelfeature.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ QSizeF QgsLabelFeature::size( double angle ) const
8080
return ( angle >= 0.785398 && angle <= 2.35619 ) || ( angle >= 3.92699 && angle <= 5.49779 ) ? mRotatedSize : mSize;
8181
}
8282

83+
QgsPointXY QgsLabelFeature::anchorPosition() const
84+
{
85+
return mAnchorPosition;
86+
}
87+
8388
void QgsLabelFeature::setFeature( const QgsFeature &feature )
8489
{
8590
mFeature = feature;
@@ -114,3 +119,8 @@ void QgsLabelFeature::setObstacleSettings( const QgsLabelObstacleSettings &setti
114119
{
115120
mObstacleSettings = settings;
116121
}
122+
123+
void QgsLabelFeature::setAnchorPosition( const QgsPointXY &anchorPosition )
124+
{
125+
mAnchorPosition = anchorPosition;
126+
}

‎src/core/labeling/qgslabelfeature.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,26 @@ class CORE_EXPORT QgsLabelFeature
174174
void setHasFixedPosition( bool enabled ) { mHasFixedPosition = enabled; }
175175
//! Coordinates of the fixed position (relevant only if hasFixedPosition() returns TRUE)
176176
QgsPointXY fixedPosition() const { return mFixedPosition; }
177+
177178
//! Sets coordinates of the fixed position (relevant only if hasFixedPosition() returns TRUE)
178179
void setFixedPosition( const QgsPointXY &point ) { mFixedPosition = point; }
179180

181+
/**
182+
* In case of quadrand or aligned positioning, this is set to the anchor point.
183+
* This can be used for proper vector based output like DXF.
184+
*
185+
* \since QGIS 3.12
186+
*/
187+
QgsPointXY anchorPosition() const;
188+
189+
/**
190+
* In case of quadrand or aligned positioning, this is set to the anchor point.
191+
* This can be used for proper vector based output like DXF.
192+
*
193+
* \since QGIS 3.12
194+
*/
195+
void setAnchorPosition( const QgsPointXY &anchorPosition );
196+
180197
//! Whether the label should use a fixed angle instead of using angle from automatic placement
181198
bool hasFixedAngle() const { return mHasFixedAngle; }
182199
//! Sets whether the label should use a fixed angle instead of using angle from automatic placement
@@ -508,6 +525,7 @@ class CORE_EXPORT QgsLabelFeature
508525

509526
QgsLabelObstacleSettings mObstacleSettings;
510527

528+
QgsPointXY mAnchorPosition;
511529
};
512530

513531
#endif // QGSLABELFEATURE_H

‎src/core/labeling/qgspallabeling.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,6 +2012,11 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
20122012
bool ddXPos = false, ddYPos = false;
20132013
double quadOffsetX = 0.0, quadOffsetY = 0.0;
20142014
double offsetX = 0.0, offsetY = 0.0;
2015+
QgsPointXY anchorPosition = geom.centroid().asPoint();
2016+
2017+
//x/y shift in case of alignment
2018+
double xdiff = 0.0;
2019+
double ydiff = 0.0;
20152020

20162021
//data defined quadrant offset?
20172022
bool ddFixedQuad = false;
@@ -2168,10 +2173,6 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
21682173
angle = 0.0;
21692174
}
21702175

2171-
//x/y shift in case of alignment
2172-
double xdiff = 0.0;
2173-
double ydiff = 0.0;
2174-
21752176
//horizontal alignment
21762177
if ( mDataDefinedProperties.isActive( QgsPalLayerSettings::Hali ) )
21772178
{
@@ -2242,11 +2243,15 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
22422243
yPos = static_cast< const QgsPoint * >( ddPoint.constGet() )->y();
22432244
}
22442245

2246+
anchorPosition = QgsPointXY( xPos, yPos );
2247+
22452248
xPos += xdiff;
22462249
yPos += ydiff;
22472250
}
22482251
else
22492252
{
2253+
anchorPosition = QgsPointXY( xPos, yPos );
2254+
22502255
// only rotate non-pinned OverPoint placements until other placements are supported in pal::Feature
22512256
if ( dataDefinedRotation && placement != QgsPalLayerSettings::OverPoint )
22522257
{
@@ -2331,6 +2336,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
23312336

23322337
// feature to the layer
23332338
QgsTextLabelFeature *lf = new QgsTextLabelFeature( feature.id(), std::move( geos_geom_clone ), QSizeF( labelX, labelY ) );
2339+
lf->setAnchorPosition( anchorPosition );
23342340
lf->setFeature( feature );
23352341
lf->setSymbol( symbol );
23362342
if ( !qgsDoubleNear( rotatedLabelX, 0.0 ) && !qgsDoubleNear( rotatedLabelY, 0.0 ) )

‎src/core/labeling/qgstextlabelfeature.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
QgsTextLabelFeature::QgsTextLabelFeature( QgsFeatureId id, geos::unique_ptr geometry, QSizeF size )
2525
: QgsLabelFeature( id, std::move( geometry ), size )
26-
2726
{
2827
mDefinedFont = QFont();
2928
}

‎src/core/pal/feature.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ std::size_t FeaturePart::createCandidatesOverPoint( double x, double y, std::vec
298298
double xdiff = -labelW / 2.0;
299299
double ydiff = -labelH / 2.0;
300300

301+
feature()->setAnchorPosition( QgsPointXY( x, y ) );
302+
301303
if ( !qgsDoubleNear( mLF->quadOffset().x(), 0.0 ) )
302304
{
303305
xdiff += labelW / 2.0 * mLF->quadOffset().x();
@@ -359,7 +361,7 @@ std::size_t FeaturePart::createCandidatesOverPoint( double x, double y, std::vec
359361
}
360362
}
361363

362-
lPos.emplace_back( qgis::make_unique< LabelPosition >( id, lx, ly, labelW, labelH, angle, cost, this, false, quadrantFromOffset(), xdiff, ydiff ) );
364+
lPos.emplace_back( qgis::make_unique< LabelPosition >( id, lx, ly, labelW, labelH, angle, cost, this, false, quadrantFromOffset() ) );
363365
return nbp;
364366
}
365367

@@ -1701,7 +1703,7 @@ std::vector< std::unique_ptr< LabelPosition > > FeaturePart::createCandidates( P
17011703

17021704
if ( mLF->hasFixedPosition() )
17031705
{
1704-
lPos.emplace_back( qgis::make_unique< LabelPosition> ( 0, mLF->fixedPosition().x(), mLF->fixedPosition().y(), getLabelWidth( angle ), getLabelHeight( angle ), angle, 0.0, this ) );
1706+
lPos.emplace_back( qgis::make_unique< LabelPosition> ( 0, mLF->fixedPosition().x(), mLF->fixedPosition().y(), getLabelWidth( angle ), getLabelHeight( angle ), angle, 0.0, this, false, LabelPosition::Quadrant::QuadrantOver ) );
17051707
}
17061708
else
17071709
{

‎src/core/pal/labelposition.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
using namespace pal;
4242

43-
LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed, Quadrant quadrant, double dX, double dY )
43+
LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed, Quadrant quadrant )
4444
: id( id )
4545
, feature( feature )
4646
, probFeat( 0 )
@@ -55,8 +55,6 @@ LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h,
5555
, mCost( cost )
5656
, mHasObstacleConflict( false )
5757
, mUpsideDownCharCount( 0 )
58-
, mDx( dX )
59-
, mDy( dY )
6058
{
6159
type = GEOS_POLYGON;
6260
nbPoints = 4;
@@ -161,8 +159,6 @@ LabelPosition::LabelPosition( const LabelPosition &other )
161159
quadrant = other.quadrant;
162160
mHasObstacleConflict = other.mHasObstacleConflict;
163161
mUpsideDownCharCount = other.mUpsideDownCharCount;
164-
mDx = other.mDx;
165-
mDy = other.mDy;
166162
}
167163

168164
bool LabelPosition::isIn( double *bbox )
@@ -322,16 +318,6 @@ bool LabelPosition::isInConflictMultiPart( const LabelPosition *lp ) const
322318
return false; // no conflict found
323319
}
324320

325-
double LabelPosition::dY() const
326-
{
327-
return mDy;
328-
}
329-
330-
double LabelPosition::dX() const
331-
{
332-
return mDx;
333-
}
334-
335321
int LabelPosition::partCount() const
336322
{
337323
if ( mNextPart )

‎src/core/pal/labelposition.h

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,11 @@ namespace pal
8888
* \param feature labelpos owners
8989
* \param isReversed label is reversed
9090
* \param quadrant relative position of label to feature
91-
* \param dX the correction of the anchor point in x direction
92-
* \param dY the correction of the anchor point in y direction
9391
*/
9492
LabelPosition( int id, double x1, double y1,
9593
double w, double h,
9694
double alpha, double cost,
97-
FeaturePart *feature, bool isReversed = false, Quadrant quadrant = QuadrantOver,
98-
double dX = 0.0, double dY = 0.0 );
95+
FeaturePart *feature, bool isReversed = false, Quadrant quadrant = QuadrantOver );
9996

10097
//! Copy constructor
10198
LabelPosition( const LabelPosition &other );
@@ -305,20 +302,6 @@ namespace pal
305302
*/
306303
void insertIntoIndex( PalRtree<LabelPosition> &index );
307304

308-
/**
309-
* The offset of the anchor point in x direction.
310-
*
311-
* \since QGIS 3.12
312-
*/
313-
double dX() const;
314-
315-
/**
316-
* The offset of the anchor point in y direction.
317-
*
318-
* \since QGIS 3.12
319-
*/
320-
double dY() const;
321-
322305
protected:
323306

324307
int id;
@@ -353,8 +336,6 @@ namespace pal
353336
bool mHasObstacleConflict;
354337
bool mHasHardConflict = false;
355338
int mUpsideDownCharCount;
356-
double mDx = 0.0;
357-
double mDy = 0.0;
358339

359340
/**
360341
* Calculates the total number of parts for this label position

‎tests/src/core/testqgsdxfexport.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -554,13 +554,13 @@ void TestQgsDxfExport::testTextAlign()
554554
halignProp.setStaticValue( hali );
555555
props.setProperty( QgsPalLayerSettings::Hali, halignProp );
556556
QgsProperty posXProp = QgsProperty();
557-
posXProp.setExpressionString( QStringLiteral( "x($geometry)" ) );
557+
posXProp.setExpressionString( QStringLiteral( "x($geometry) + 1" ) );
558558
props.setProperty( QgsPalLayerSettings::PositionX, posXProp );
559559
QgsProperty valignProp = QgsProperty();
560560
valignProp.setStaticValue( vali );
561561
props.setProperty( QgsPalLayerSettings::Vali, valignProp );
562562
QgsProperty posYProp = QgsProperty();
563-
posXProp.setExpressionString( QStringLiteral( "y($geometry)" ) );
563+
posYProp.setExpressionString( QStringLiteral( "y($geometry) + 1" ) );
564564
props.setProperty( QgsPalLayerSettings::PositionY, posYProp );
565565
settings.setDataDefinedProperties( props );
566566

@@ -616,13 +616,13 @@ void TestQgsDxfExport::testTextAlign()
616616
"420\n"
617617
"**no check**\n"
618618
" 10\n"
619-
"REGEX ^2684679\\.39\\d*\n"
619+
"REGEX ^2684680\\.39\\d*\n"
620620
" 20\n"
621-
"REGEX ^1292182\\.52\\d*\n"
621+
"REGEX ^1292183\\.52\\d*\n"
622622
" 11\n"
623-
"REGEX ^2684679\\.39\\d*\n"
623+
"REGEX ^2684680\\.39\\d*\n"
624624
" 21\n"
625-
"REGEX ^1292182\\.52\\d*\n"
625+
"REGEX ^1292183\\.52\\d*\n"
626626
" 40\n"
627627
"**no check**\n"
628628
" 1\n"
@@ -1155,7 +1155,7 @@ bool TestQgsDxfExport::fileContainsText( const QString &path, const QString &tex
11551155
bool ok = false;
11561156
if ( searchLine.startsWith( QLatin1String( "REGEX " ) ) )
11571157
{
1158-
QRegularExpression re( searchLine.right( 7 ) );
1158+
QRegularExpression re( searchLine.mid( 6 ) );
11591159
if ( re.match( line ).hasMatch() )
11601160
ok = true;
11611161
}

0 commit comments

Comments
 (0)
Please sign in to comment.