mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-07 00:15:48 -04:00
Merge pull request #33514 from m-kuhn/more-stable-dxf-export-alignment
[dxf export] Improve dxf alignment
This commit is contained in:
commit
0bccdfe8de
@ -1265,6 +1265,8 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
|
||||
double lblX = label->getX();
|
||||
double lblY = label->getY();
|
||||
|
||||
QgsLabelFeature *labelFeature = label->getFeaturePart()->feature();
|
||||
|
||||
HAlign hali = HAlign::Undefined;
|
||||
VAlign vali = VAlign::Undefined;
|
||||
|
||||
@ -1272,14 +1274,14 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
|
||||
|
||||
if ( props.isActive( QgsPalLayerSettings::OffsetQuad ) )
|
||||
{
|
||||
lblX = labelFeature->anchorPosition().x();
|
||||
lblY = labelFeature->anchorPosition().y();
|
||||
|
||||
const QVariant exprVal = props.value( QgsPalLayerSettings::OffsetQuad, expressionContext );
|
||||
if ( exprVal.isValid() )
|
||||
{
|
||||
int offsetQuad = exprVal.toInt();
|
||||
|
||||
lblX -= label->dX();
|
||||
lblY -= label->dY();
|
||||
|
||||
switch ( offsetQuad )
|
||||
{
|
||||
case 0: // Above Left
|
||||
@ -1328,6 +1330,9 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
|
||||
|
||||
if ( props.isActive( QgsPalLayerSettings::Hali ) )
|
||||
{
|
||||
lblX = labelFeature->anchorPosition().x();
|
||||
lblY = labelFeature->anchorPosition().y();
|
||||
|
||||
hali = HAlign::HLeft;
|
||||
QVariant exprVal = props.value( QgsPalLayerSettings::Hali, expressionContext );
|
||||
if ( exprVal.isValid() )
|
||||
@ -1344,8 +1349,6 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<QFontMetricsF> labelFontMetrics( new QFontMetricsF( layerSettings.format().font() ) );
|
||||
|
||||
//vertical alignment
|
||||
if ( props.isActive( QgsPalLayerSettings::Vali ) )
|
||||
{
|
||||
|
@ -80,6 +80,11 @@ QSizeF QgsLabelFeature::size( double angle ) const
|
||||
return ( angle >= 0.785398 && angle <= 2.35619 ) || ( angle >= 3.92699 && angle <= 5.49779 ) ? mRotatedSize : mSize;
|
||||
}
|
||||
|
||||
QgsPointXY QgsLabelFeature::anchorPosition() const
|
||||
{
|
||||
return mAnchorPosition;
|
||||
}
|
||||
|
||||
void QgsLabelFeature::setFeature( const QgsFeature &feature )
|
||||
{
|
||||
mFeature = feature;
|
||||
@ -114,3 +119,8 @@ void QgsLabelFeature::setObstacleSettings( const QgsLabelObstacleSettings &setti
|
||||
{
|
||||
mObstacleSettings = settings;
|
||||
}
|
||||
|
||||
void QgsLabelFeature::setAnchorPosition( const QgsPointXY &anchorPosition )
|
||||
{
|
||||
mAnchorPosition = anchorPosition;
|
||||
}
|
||||
|
@ -174,9 +174,26 @@ class CORE_EXPORT QgsLabelFeature
|
||||
void setHasFixedPosition( bool enabled ) { mHasFixedPosition = enabled; }
|
||||
//! Coordinates of the fixed position (relevant only if hasFixedPosition() returns TRUE)
|
||||
QgsPointXY fixedPosition() const { return mFixedPosition; }
|
||||
|
||||
//! Sets coordinates of the fixed position (relevant only if hasFixedPosition() returns TRUE)
|
||||
void setFixedPosition( const QgsPointXY &point ) { mFixedPosition = point; }
|
||||
|
||||
/**
|
||||
* In case of quadrand or aligned positioning, this is set to the anchor point.
|
||||
* This can be used for proper vector based output like DXF.
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
QgsPointXY anchorPosition() const;
|
||||
|
||||
/**
|
||||
* In case of quadrand or aligned positioning, this is set to the anchor point.
|
||||
* This can be used for proper vector based output like DXF.
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
void setAnchorPosition( const QgsPointXY &anchorPosition );
|
||||
|
||||
//! Whether the label should use a fixed angle instead of using angle from automatic placement
|
||||
bool hasFixedAngle() const { return mHasFixedAngle; }
|
||||
//! Sets whether the label should use a fixed angle instead of using angle from automatic placement
|
||||
@ -508,6 +525,7 @@ class CORE_EXPORT QgsLabelFeature
|
||||
|
||||
QgsLabelObstacleSettings mObstacleSettings;
|
||||
|
||||
QgsPointXY mAnchorPosition;
|
||||
};
|
||||
|
||||
#endif // QGSLABELFEATURE_H
|
||||
|
@ -2012,6 +2012,11 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
|
||||
bool ddXPos = false, ddYPos = false;
|
||||
double quadOffsetX = 0.0, quadOffsetY = 0.0;
|
||||
double offsetX = 0.0, offsetY = 0.0;
|
||||
QgsPointXY anchorPosition = geom.centroid().asPoint();
|
||||
|
||||
//x/y shift in case of alignment
|
||||
double xdiff = 0.0;
|
||||
double ydiff = 0.0;
|
||||
|
||||
//data defined quadrant offset?
|
||||
bool ddFixedQuad = false;
|
||||
@ -2168,10 +2173,6 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
|
||||
angle = 0.0;
|
||||
}
|
||||
|
||||
//x/y shift in case of alignment
|
||||
double xdiff = 0.0;
|
||||
double ydiff = 0.0;
|
||||
|
||||
//horizontal alignment
|
||||
if ( mDataDefinedProperties.isActive( QgsPalLayerSettings::Hali ) )
|
||||
{
|
||||
@ -2242,11 +2243,15 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
|
||||
yPos = static_cast< const QgsPoint * >( ddPoint.constGet() )->y();
|
||||
}
|
||||
|
||||
anchorPosition = QgsPointXY( xPos, yPos );
|
||||
|
||||
xPos += xdiff;
|
||||
yPos += ydiff;
|
||||
}
|
||||
else
|
||||
{
|
||||
anchorPosition = QgsPointXY( xPos, yPos );
|
||||
|
||||
// only rotate non-pinned OverPoint placements until other placements are supported in pal::Feature
|
||||
if ( dataDefinedRotation && placement != QgsPalLayerSettings::OverPoint )
|
||||
{
|
||||
@ -2331,6 +2336,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
|
||||
|
||||
// feature to the layer
|
||||
QgsTextLabelFeature *lf = new QgsTextLabelFeature( feature.id(), std::move( geos_geom_clone ), QSizeF( labelX, labelY ) );
|
||||
lf->setAnchorPosition( anchorPosition );
|
||||
lf->setFeature( feature );
|
||||
lf->setSymbol( symbol );
|
||||
if ( !qgsDoubleNear( rotatedLabelX, 0.0 ) && !qgsDoubleNear( rotatedLabelY, 0.0 ) )
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
QgsTextLabelFeature::QgsTextLabelFeature( QgsFeatureId id, geos::unique_ptr geometry, QSizeF size )
|
||||
: QgsLabelFeature( id, std::move( geometry ), size )
|
||||
|
||||
{
|
||||
mDefinedFont = QFont();
|
||||
}
|
||||
|
@ -298,6 +298,8 @@ std::size_t FeaturePart::createCandidatesOverPoint( double x, double y, std::vec
|
||||
double xdiff = -labelW / 2.0;
|
||||
double ydiff = -labelH / 2.0;
|
||||
|
||||
feature()->setAnchorPosition( QgsPointXY( x, y ) );
|
||||
|
||||
if ( !qgsDoubleNear( mLF->quadOffset().x(), 0.0 ) )
|
||||
{
|
||||
xdiff += labelW / 2.0 * mLF->quadOffset().x();
|
||||
@ -359,7 +361,7 @@ std::size_t FeaturePart::createCandidatesOverPoint( double x, double y, std::vec
|
||||
}
|
||||
}
|
||||
|
||||
lPos.emplace_back( qgis::make_unique< LabelPosition >( id, lx, ly, labelW, labelH, angle, cost, this, false, quadrantFromOffset(), xdiff, ydiff ) );
|
||||
lPos.emplace_back( qgis::make_unique< LabelPosition >( id, lx, ly, labelW, labelH, angle, cost, this, false, quadrantFromOffset() ) );
|
||||
return nbp;
|
||||
}
|
||||
|
||||
@ -1701,7 +1703,7 @@ std::vector< std::unique_ptr< LabelPosition > > FeaturePart::createCandidates( P
|
||||
|
||||
if ( mLF->hasFixedPosition() )
|
||||
{
|
||||
lPos.emplace_back( qgis::make_unique< LabelPosition> ( 0, mLF->fixedPosition().x(), mLF->fixedPosition().y(), getLabelWidth( angle ), getLabelHeight( angle ), angle, 0.0, this ) );
|
||||
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 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
using namespace pal;
|
||||
|
||||
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 )
|
||||
LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed, Quadrant quadrant )
|
||||
: id( id )
|
||||
, feature( feature )
|
||||
, probFeat( 0 )
|
||||
@ -55,8 +55,6 @@ LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h,
|
||||
, mCost( cost )
|
||||
, mHasObstacleConflict( false )
|
||||
, mUpsideDownCharCount( 0 )
|
||||
, mDx( dX )
|
||||
, mDy( dY )
|
||||
{
|
||||
type = GEOS_POLYGON;
|
||||
nbPoints = 4;
|
||||
@ -161,8 +159,6 @@ LabelPosition::LabelPosition( const LabelPosition &other )
|
||||
quadrant = other.quadrant;
|
||||
mHasObstacleConflict = other.mHasObstacleConflict;
|
||||
mUpsideDownCharCount = other.mUpsideDownCharCount;
|
||||
mDx = other.mDx;
|
||||
mDy = other.mDy;
|
||||
}
|
||||
|
||||
bool LabelPosition::isIn( double *bbox )
|
||||
@ -322,16 +318,6 @@ bool LabelPosition::isInConflictMultiPart( const LabelPosition *lp ) const
|
||||
return false; // no conflict found
|
||||
}
|
||||
|
||||
double LabelPosition::dY() const
|
||||
{
|
||||
return mDy;
|
||||
}
|
||||
|
||||
double LabelPosition::dX() const
|
||||
{
|
||||
return mDx;
|
||||
}
|
||||
|
||||
int LabelPosition::partCount() const
|
||||
{
|
||||
if ( mNextPart )
|
||||
|
@ -88,14 +88,11 @@ namespace pal
|
||||
* \param feature labelpos owners
|
||||
* \param isReversed label is reversed
|
||||
* \param quadrant relative position of label to feature
|
||||
* \param dX the correction of the anchor point in x direction
|
||||
* \param dY the correction of the anchor point in y direction
|
||||
*/
|
||||
LabelPosition( int id, double x1, double y1,
|
||||
double w, double h,
|
||||
double alpha, double cost,
|
||||
FeaturePart *feature, bool isReversed = false, Quadrant quadrant = QuadrantOver,
|
||||
double dX = 0.0, double dY = 0.0 );
|
||||
FeaturePart *feature, bool isReversed = false, Quadrant quadrant = QuadrantOver );
|
||||
|
||||
//! Copy constructor
|
||||
LabelPosition( const LabelPosition &other );
|
||||
@ -305,20 +302,6 @@ namespace pal
|
||||
*/
|
||||
void insertIntoIndex( PalRtree<LabelPosition> &index );
|
||||
|
||||
/**
|
||||
* The offset of the anchor point in x direction.
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
double dX() const;
|
||||
|
||||
/**
|
||||
* The offset of the anchor point in y direction.
|
||||
*
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
double dY() const;
|
||||
|
||||
protected:
|
||||
|
||||
int id;
|
||||
@ -353,8 +336,6 @@ namespace pal
|
||||
bool mHasObstacleConflict;
|
||||
bool mHasHardConflict = false;
|
||||
int mUpsideDownCharCount;
|
||||
double mDx = 0.0;
|
||||
double mDy = 0.0;
|
||||
|
||||
/**
|
||||
* Calculates the total number of parts for this label position
|
||||
|
@ -554,13 +554,13 @@ void TestQgsDxfExport::testTextAlign()
|
||||
halignProp.setStaticValue( hali );
|
||||
props.setProperty( QgsPalLayerSettings::Hali, halignProp );
|
||||
QgsProperty posXProp = QgsProperty();
|
||||
posXProp.setExpressionString( QStringLiteral( "x($geometry)" ) );
|
||||
posXProp.setExpressionString( QStringLiteral( "x($geometry) + 1" ) );
|
||||
props.setProperty( QgsPalLayerSettings::PositionX, posXProp );
|
||||
QgsProperty valignProp = QgsProperty();
|
||||
valignProp.setStaticValue( vali );
|
||||
props.setProperty( QgsPalLayerSettings::Vali, valignProp );
|
||||
QgsProperty posYProp = QgsProperty();
|
||||
posXProp.setExpressionString( QStringLiteral( "y($geometry)" ) );
|
||||
posYProp.setExpressionString( QStringLiteral( "y($geometry) + 1" ) );
|
||||
props.setProperty( QgsPalLayerSettings::PositionY, posYProp );
|
||||
settings.setDataDefinedProperties( props );
|
||||
|
||||
@ -616,13 +616,13 @@ void TestQgsDxfExport::testTextAlign()
|
||||
"420\n"
|
||||
"**no check**\n"
|
||||
" 10\n"
|
||||
"REGEX ^2684679\\.39\\d*\n"
|
||||
"REGEX ^2684680\\.39\\d*\n"
|
||||
" 20\n"
|
||||
"REGEX ^1292182\\.52\\d*\n"
|
||||
"REGEX ^1292183\\.52\\d*\n"
|
||||
" 11\n"
|
||||
"REGEX ^2684679\\.39\\d*\n"
|
||||
"REGEX ^2684680\\.39\\d*\n"
|
||||
" 21\n"
|
||||
"REGEX ^1292182\\.52\\d*\n"
|
||||
"REGEX ^1292183\\.52\\d*\n"
|
||||
" 40\n"
|
||||
"**no check**\n"
|
||||
" 1\n"
|
||||
@ -1155,7 +1155,7 @@ bool TestQgsDxfExport::fileContainsText( const QString &path, const QString &tex
|
||||
bool ok = false;
|
||||
if ( searchLine.startsWith( QLatin1String( "REGEX " ) ) )
|
||||
{
|
||||
QRegularExpression re( searchLine.right( 7 ) );
|
||||
QRegularExpression re( searchLine.mid( 6 ) );
|
||||
if ( re.match( line ).hasMatch() )
|
||||
ok = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user