Skip to content
Permalink
Browse files

Preserve anchor point instead of delta

It's way easier to understand the concept
  • Loading branch information
m-kuhn committed Jan 5, 2020
1 parent e23089e commit e9d4e9fb12c6f6a92c38121218dc9fb181756578
@@ -1266,11 +1266,6 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La
double lblY = label->getY();

QgsLabelFeature *labelFeature = label->getFeaturePart()->feature();
if ( labelFeature->hasFixedPosition() )
{
lblX = labelFeature->fixedPosition().x();
lblY = labelFeature->fixedPosition().y();
}

HAlign hali = HAlign::Undefined;
VAlign vali = VAlign::Undefined;
@@ -1279,8 +1274,8 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La

if ( props.isActive( QgsPalLayerSettings::OffsetQuad ) )
{
lblX -= label->dX();
lblY -= label->dY();
lblX = labelFeature->anchorPosition().x();
lblY = labelFeature->anchorPosition().y();

const QVariant exprVal = props.value( QgsPalLayerSettings::OffsetQuad, expressionContext );
if ( exprVal.isValid() )
@@ -1335,8 +1330,8 @@ void QgsDxfExport::writeText( const QString &layer, const QString &text, pal::La

if ( props.isActive( QgsPalLayerSettings::Hali ) )
{
lblX -= label->dX();
lblY -= label->dY();
lblX = labelFeature->anchorPosition().x();
lblY = labelFeature->anchorPosition().y();

hali = HAlign::HLeft;
QVariant exprVal = props.value( QgsPalLayerSettings::Hali, expressionContext );
@@ -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;
@@ -115,22 +120,7 @@ void QgsLabelFeature::setObstacleSettings( const QgsLabelObstacleSettings &setti
mObstacleSettings = settings;
}

double QgsLabelFeature::dX() const
{
return mDX;
}

void QgsLabelFeature::setDX( double dX )
{
mDX = dX;
}

double QgsLabelFeature::dY() const
{
return mDY;
}

void QgsLabelFeature::setDY( double dY )
void QgsLabelFeature::setAnchorPosition( const QgsPointXY &anchorPosition )
{
mDY = dY;
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
@@ -434,47 +451,6 @@ class CORE_EXPORT QgsLabelFeature
*/
void setObstacleSettings( const QgsLabelObstacleSettings &settings );

/**
* The deltas (dX and dY) are the difference by which the fixed position deviates
* from the original position because of alignment.
*
* This can be used to restore the original position.
*
* \since QGIS 3.12
*/
double dX() const;

/**
* The deltas (dX and dY) are the difference by which the fixed position deviates
* from the original position because of alignment.
*
* This can be used to restore the original position.
*
* \since QGIS 3.12
*/
void setDX( double dX );

/**
* The deltas (dX and dY) are the difference by which the fixed position deviates
* from the original position because of alignment.
*
* This can be used to restore the original position.
*
* \since QGIS 3.12
*/
double dY() const;


/**
* The deltas (dX and dY) are the difference by which the fixed position deviates
* from the original position because of alignment.
*
* This can be used to restore the original position.
*
* \since QGIS 3.12
*/
void setDY( double dY );

protected:
//! Pointer to PAL layer (assigned when registered to PAL)
pal::Layer *mLayer = nullptr;
@@ -549,8 +525,7 @@ class CORE_EXPORT QgsLabelFeature

QgsLabelObstacleSettings mObstacleSettings;

double mDX = 0.0;
double mDY = 0.0;
QgsPointXY mAnchorPosition;
};

#endif // QGSLABELFEATURE_H
@@ -2012,6 +2012,7 @@ 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;
@@ -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,8 +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->setDX( xdiff );
lf->setDY( ydiff );
lf->setAnchorPosition( anchorPosition );
lf->setFeature( feature );
lf->setSymbol( symbol );
if ( !qgsDoubleNear( rotatedLabelX, 0.0 ) && !qgsDoubleNear( rotatedLabelY, 0.0 ) )
@@ -249,6 +249,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();
@@ -310,7 +312,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;
}

@@ -1615,7 +1617,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, false, LabelPosition::Quadrant::QuadrantOver, mLF->dX(), mLF->dY() ) );
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;
@@ -162,8 +160,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 )
@@ -323,16 +319,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 ( nextPart )
@@ -94,8 +94,7 @@ namespace pal
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 );
@@ -295,20 +294,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;
@@ -341,8 +326,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

0 comments on commit e9d4e9f

Please sign in to comment.
You can’t perform that action at this time.