Skip to content
Permalink
Browse files

Option to preserve existing rotation values during freeze/thaw label …

…operations

- PAL layer setting for preserving existing rotation values
- Clean up field-mapping checks
  • Loading branch information
dakcarto committed Aug 8, 2012
1 parent 55628dd commit 6cfb0604237244b1588c9fb66af961b1517f6c53
@@ -140,6 +140,7 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM
mMinSizeSpinBox->setValue( lyr.minFeatureSize );
chkAddDirectionSymbol->setChecked( lyr.addDirectionSymbol );
wrapCharacterEdit->setText( lyr.wrapChar );
chkPreserveRotation->setChecked( lyr.preserveRotation );

bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 );
chkScaleBasedVisibility->setChecked( scaleBased );
@@ -323,6 +324,14 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
lyr.minFeatureSize = mMinSizeSpinBox->value();
lyr.fontSizeInMapUnits = ( mFontSizeUnitComboBox->currentIndex() == 1 );
lyr.wrapChar = wrapCharacterEdit->text();
if ( chkPreserveRotation->isChecked() )
{
lyr.preserveRotation = true;
}
else
{
lyr.preserveRotation = false;
}

//data defined labeling
setDataDefinedProperty( mSizeAttributeComboBox, QgsPalLayerSettings::Size, lyr );
@@ -600,11 +609,13 @@ void QgsLabelingGui::disableDataDefinedAlignment()
mVerticalAlignmentComboBox->setEnabled( false );
mRotationComboBox->setCurrentIndex( mRotationComboBox->findText( "" ) );
mRotationComboBox->setEnabled( false );
chkPreserveRotation->setEnabled( false );
}

void QgsLabelingGui::enableDataDefinedAlignment()
{
mHorizontalAlignmentComboBox->setEnabled( true );
mVerticalAlignmentComboBox->setEnabled( true );
mRotationComboBox->setEnabled( true );
chkPreserveRotation->setEnabled( true );
}
@@ -379,50 +379,28 @@ bool QgsMapToolFreezeLabels::freezeThawLabel( QgsVectorLayer* vlayer,
QgsDebugMsg( QString( "Label is diagram, skipping" ) );
return false;
}
// verify attribute table has proper fields setup
bool xColOk, yColOk, rColOk;
int xCol, yCol, rCol;

QVariant xColumn = vlayer->customProperty( "labeling/dataDefinedProperty9" );
if ( !xColumn.isValid() )
{
QgsDebugMsg( QString( "X column not set" ) );
return false;
}
xCol = xColumn.toInt( &xColOk );
if ( !xColOk )
{
QgsDebugMsg( QString( "X column not convertible to integer" ) );
return false;
}
// verify attribute table has x, y fields mapped
int xCol, yCol;
double xPosOrig, yPosOrig;
bool xSuccess, ySuccess;

QVariant yColumn = vlayer->customProperty( "labeling/dataDefinedProperty10" );
if ( !yColumn.isValid() )
{
QgsDebugMsg( QString( "Y column not set" ) );
return false;
}
yCol = yColumn.toInt( &yColOk );
if ( !yColOk )
if ( !dataDefinedPosition( vlayer, mCurrentLabelPos.featureId, xPosOrig, xSuccess, yPosOrig, ySuccess, xCol, yCol ) )
{
QgsDebugMsg( QString( "Y column not convertible to integer" ) );
QgsDebugMsg( QString( "Label X or Y column not mapped, skipping" ) );
return false;
}

// rotation field is optional, but will be used if available
bool hasRCol = true;
QVariant rColumn = vlayer->customProperty( "labeling/dataDefinedProperty14" );
if ( !rColumn.isValid() )
{
QgsDebugMsg( QString( "Rotation column not set" ) );
hasRCol = false;
}
rCol = rColumn.toInt( &rColOk );
if ( !rColOk )
{
QgsDebugMsg( QString( "Rotation column not convertible to integer" ) );
hasRCol = false;
}
// rotation field is optional, but will be used if available, unless data exists
int rCol;
bool rSuccess = false;
double defRot;

bool hasRCol = ( layerIsRotatable( vlayer, rCol )
&& dataDefinedRotation( vlayer, mCurrentLabelPos.featureId, defRot, rSuccess, true ) );

// get whether to preserve predefined rotation data during label freeze/thaw operations
bool preserveRot = preserveRotation();

// edit attribute table
int fid = labelpos.featureId;
@@ -464,7 +442,7 @@ bool QgsMapToolFreezeLabels::freezeThawLabel( QgsVectorLayer* vlayer,
QgsDebugMsg( failedWrite );
return false;
}
if ( hasRCol )
if ( hasRCol && !preserveRot )
{
if ( !vlayer->changeAttributeValue( fid, rCol, labelR, false ) )
{
@@ -487,7 +465,7 @@ bool QgsMapToolFreezeLabels::freezeThawLabel( QgsVectorLayer* vlayer,
QgsDebugMsg( failedWrite );
return false;
}
if ( hasRCol )
if ( hasRCol && !preserveRot )
{
if ( !vlayer->changeAttributeValue( fid, rCol, QVariant(), false ) )
{
@@ -280,6 +280,19 @@ QFont QgsMapToolLabel::labelFontCurrentFeature()
return font;
}

bool QgsMapToolLabel::preserveRotation()
{
bool labelSettingsOk;
QgsPalLayerSettings& layerSettings = currentLabelSettings( &labelSettingsOk );

if ( labelSettingsOk )
{
return layerSettings.preserveRotation;
}

return true; // default, so there is no accidental data loss
}

bool QgsMapToolLabel::rotationPoint( QgsPoint& pos, bool ignoreUpsideDown )
{
QVector<QgsPoint> cornerPoints = mCurrentLabelPos.cornerPoints;
@@ -429,7 +442,7 @@ bool QgsMapToolLabel::layerIsRotatable( const QgsMapLayer* layer, int& rotationC
return true;
}

bool QgsMapToolLabel::dataDefinedRotation( QgsVectorLayer* vlayer, int featureId, double& rotation, bool& rotationSuccess )
bool QgsMapToolLabel::dataDefinedRotation( QgsVectorLayer* vlayer, int featureId, double& rotation, bool& rotationSuccess, bool ignoreXY )
{
rotationSuccess = false;
if ( !vlayer )
@@ -452,12 +465,15 @@ bool QgsMapToolLabel::dataDefinedRotation( QgsVectorLayer* vlayer, int featureId
QgsAttributeMap attributes = f.attributeMap();

//test, if data defined x- and y- values are not null. Otherwise, the position is determined by PAL and the rotation cannot be fixed
int xCol, yCol;
double x, y;
bool xSuccess, ySuccess;
if ( !dataDefinedPosition( vlayer, featureId, x, xSuccess, y, ySuccess, xCol, yCol ) || !xSuccess || !ySuccess )
if ( !ignoreXY )
{
return false;
int xCol, yCol;
double x, y;
bool xSuccess, ySuccess;
if ( !dataDefinedPosition( vlayer, featureId, x, xSuccess, y, ySuccess, xCol, yCol ) || !xSuccess || !ySuccess )
{
return false;
}
}

rotation = attributes[rotationCol].toDouble( &rotationSuccess );
@@ -93,6 +93,9 @@ class QgsMapToolLabel: public QgsMapTool
/**Returns the font for the current feature (considering default font and data defined properties*/
QFont labelFontCurrentFeature();

/**Returns whether to preserve predefined rotation data during label freeze/thaw operations*/
bool preserveRotation();

/**Get data defined position of a feature
@param vlayer vector layer
@param featureId feature identification integer
@@ -110,9 +113,10 @@ class QgsMapToolLabel: public QgsMapTool
@param featureId feature identification integer
@param rotation out: rotation value
@param rotationSuccess out: false if rotation value is NULL
@param ignoreXY ignore that x and y are required to be data-defined
@return true if data defined rotation is enabled on the layer
*/
bool dataDefinedRotation( QgsVectorLayer* vlayer, int featureId, double& rotation, bool& rotationSuccess );
bool dataDefinedRotation( QgsVectorLayer* vlayer, int featureId, double& rotation, bool& rotationSuccess, bool ignoreXY = false );

private:
QgsPalLayerSettings mInvalidLabelSettings;
@@ -154,22 +154,20 @@ void QgsMapToolMoveLabel::canvasReleaseEvent( QMouseEvent * e )
vlayer->changeAttributeValue( mCurrentLabelPos.featureId, yCol, yPosNew, false );

// set rotation to that of label, if data-defined and no rotation set yet
// handle case of initially set rotation column fields of 0 instead of NULL
// honor whether to preserve preexisting data on freeze
// must come after setting x and y positions
int rCol;
if ( !mCurrentLabelPos.isDiagram && !mCurrentLabelPos.isFrozen
if ( !mCurrentLabelPos.isDiagram
&& !mCurrentLabelPos.isFrozen
&& !preserveRotation()
&& layerIsRotatable( vlayer, rCol ) )
{
double labelRot = 0;
double defRot;
bool rSuccess;
if ( dataDefinedRotation( vlayer, mCurrentLabelPos.featureId, defRot, rSuccess ) )
{
labelRot = mCurrentLabelPos.rotation * 180 / M_PI;
if ( !rSuccess || ( rSuccess && defRot != labelRot ) )
{
vlayer->changeAttributeValue( mCurrentLabelPos.featureId, rCol, labelRot, false );
}
double labelRot = mCurrentLabelPos.rotation * 180 / M_PI;
vlayer->changeAttributeValue( mCurrentLabelPos.featureId, rCol, labelRot, false );
}
}
vlayer->endEditCommand();
@@ -163,6 +163,7 @@ QgsPalLayerSettings::QgsPalLayerSettings()
fontSizeInMapUnits = false;
distInMapUnits = false;
wrapChar = "";
preserveRotation = true;
}

QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
@@ -194,6 +195,7 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
fontSizeInMapUnits = s.fontSizeInMapUnits;
distInMapUnits = s.distInMapUnits;
wrapChar = s.wrapChar;
preserveRotation = s.preserveRotation;

dataDefinedProperties = s.dataDefinedProperties;
fontMetrics = NULL;
@@ -337,6 +339,7 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
fontSizeInMapUnits = layer->customProperty( "labeling/fontSizeInMapUnits" ).toBool();
distInMapUnits = layer->customProperty( "labeling/distInMapUnits" ).toBool();
wrapChar = layer->customProperty( "labeling/wrapChar" ).toString();
preserveRotation = layer->customProperty( "labeling/preserveRotation", QVariant( true ) ).toBool();
_readDataDefinedPropertyMap( layer, dataDefinedProperties );
}

@@ -376,6 +379,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )
layer->setCustomProperty( "labeling/fontSizeInMapUnits", fontSizeInMapUnits );
layer->setCustomProperty( "labeling/distInMapUnits", distInMapUnits );
layer->setCustomProperty( "labeling/wrapChar", wrapChar );
layer->setCustomProperty( "labeling/preserveRotation", preserveRotation );
_writeDataDefinedPropertyMap( layer, dataDefinedProperties );
}

@@ -161,6 +161,8 @@ class CORE_EXPORT QgsPalLayerSettings
/**Stores field indices for data defined layer properties*/
QMap< DataDefinedProperties, int > dataDefinedProperties;

bool preserveRotation; // preserve predefined rotation data during label freeze/thaw operations

/**Calculates pixel size (considering output size should be in pixel or map units, scale factors and oversampling)
@param size size to convert
@param c rendercontext
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>703</width>
<height>469</height>
<height>482</height>
</rect>
</property>
<property name="windowTitle">
@@ -463,8 +463,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>647</width>
<height>435</height>
<width>621</width>
<height>479</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_13">
@@ -924,9 +924,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>647</width>
<height>507</height>
<y>-289</y>
<width>618</width>
<height>599</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_11">
@@ -1050,6 +1050,26 @@
<string>Position</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="5" column="1">
<widget class="QComboBox" name="mRotationComboBox"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="mRotationLabel">
<property name="text">
<string>Rotation</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mLabelDistanceComboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mLabelDistanceLabel">
<property name="text">
<string>Label distance</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mXCoordinateLabel">
<property name="text">
@@ -1090,23 +1110,19 @@
<item row="4" column="1">
<widget class="QComboBox" name="mVerticalAlignmentComboBox"/>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="mRotationComboBox"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="mRotationLabel">
<property name="text">
<string>Rotation</string>
<item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="chkPreserveRotation">
<property name="toolTip">
<string>Uncheck to write labeling engine derived rotation on freeze and NULL on thaw</string>
</property>
<property name="styleSheet">
<string notr="true">margin-left: 12px;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mLabelDistanceComboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mLabelDistanceLabel">
<property name="text">
<string>Label distance</string>
<string>Preserve existing rotation values during label freeze/thaw operations</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>

0 comments on commit 6cfb060

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