[QGIS Commit] r14423 - in trunk/qgis/src: app core core/pal ui
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed Oct 20 16:23:52 EDT 2010
Author: wonder
Date: 2010-10-20 13:23:52 -0700 (Wed, 20 Oct 2010)
New Revision: 14423
Modified:
trunk/qgis/src/app/qgslabelinggui.cpp
trunk/qgis/src/app/qgslabelinggui.h
trunk/qgis/src/core/pal/feature.cpp
trunk/qgis/src/core/pal/feature.h
trunk/qgis/src/core/pal/labelposition.cpp
trunk/qgis/src/core/pal/labelposition.h
trunk/qgis/src/core/pal/layer.cpp
trunk/qgis/src/core/pal/layer.h
trunk/qgis/src/core/qgspallabeling.cpp
trunk/qgis/src/core/qgspallabeling.h
trunk/qgis/src/ui/qgslabelingguibase.ui
Log:
[FEATURE] Data defined label position in new labeling - from Marco Hugentobler.
Modified: trunk/qgis/src/app/qgslabelinggui.cpp
===================================================================
--- trunk/qgis/src/app/qgslabelinggui.cpp 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/app/qgslabelinggui.cpp 2010-10-20 20:23:52 UTC (rev 14423)
@@ -123,6 +123,7 @@
chkMergeLines->setChecked( lyr.mergeLines );
chkMultiLine->setChecked( lyr.multiLineLabels );
mMinSizeSpinBox->setValue( lyr.minFeatureSize );
+ chkAddDirectionSymbol->setChecked( lyr.addDirectionSymbol );
bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 );
chkScaleBasedVisibility->setChecked( scaleBased );
@@ -139,7 +140,19 @@
btnTextColor->setColor( lyr.textColor );
btnBufferColor->setColor( lyr.bufferColor );
- updateFont( lyr.textFont );
+
+ if ( lyr.fontSizeInMapUnits )
+ {
+ mFontSizeUnitComboBox->setCurrentIndex( 1 );
+ }
+ else
+ {
+ mFontSizeUnitComboBox->setCurrentIndex( 0 );
+ }
+
+ QFont textFont = lyr.textFont;
+ updateFont( textFont );
+ mFontSizeSpinBox->setValue( textFont.pointSizeF() );
updateUi();
updateOptions();
@@ -238,8 +251,18 @@
{
lyr.bufferSize = 0;
}
+ if ( chkAddDirectionSymbol->isChecked() )
+ {
+ lyr.addDirectionSymbol = true;
+ }
+ else
+ {
+ lyr.addDirectionSymbol = false;
+ }
lyr.minFeatureSize = mMinSizeSpinBox->value();
+ lyr.fontSizeInMapUnits = ( mFontSizeUnitComboBox->currentIndex() == 1 );
+
//data defined labeling
setDataDefinedProperty( mSizeAttributeComboBox, QgsPalLayerSettings::Size, lyr );
setDataDefinedProperty( mColorAttributeComboBox, QgsPalLayerSettings::Color, lyr );
@@ -250,6 +273,12 @@
setDataDefinedProperty( mFontFamilyAttributeComboBox, QgsPalLayerSettings::Family, lyr );
setDataDefinedProperty( mBufferSizeAttributeComboBox, QgsPalLayerSettings:: BufferSize, lyr );
setDataDefinedProperty( mBufferColorAttributeComboBox, QgsPalLayerSettings::BufferColor, lyr );
+ setDataDefinedProperty( mXCoordinateComboBox, QgsPalLayerSettings::PositionX, lyr );
+ setDataDefinedProperty( mYCoordinateComboBox, QgsPalLayerSettings::PositionY, lyr );
+ setDataDefinedProperty( mHorizontalAlignmentComboBox, QgsPalLayerSettings::Hali, lyr );
+ setDataDefinedProperty( mVerticalAlignmentComboBox, QgsPalLayerSettings::Vali, lyr );
+ setDataDefinedProperty( mLabelDistanceComboBox, QgsPalLayerSettings::LabelDistance, lyr );
+ setDataDefinedProperty( mRotationComboBox, QgsPalLayerSettings::Rotation, lyr );
return lyr;
}
@@ -308,6 +337,12 @@
comboList << mFontFamilyAttributeComboBox;
comboList << mBufferSizeAttributeComboBox;
comboList << mBufferColorAttributeComboBox;
+ comboList << mXCoordinateComboBox;
+ comboList << mYCoordinateComboBox;
+ comboList << mHorizontalAlignmentComboBox;
+ comboList << mVerticalAlignmentComboBox;
+ comboList << mLabelDistanceComboBox;
+ comboList << mRotationComboBox;
QList<QComboBox*>::iterator comboIt = comboList.begin();
for ( ; comboIt != comboList.end(); ++comboIt )
@@ -335,6 +370,12 @@
setCurrentComboValue( mFontFamilyAttributeComboBox, s, QgsPalLayerSettings::Family );
setCurrentComboValue( mBufferSizeAttributeComboBox, s , QgsPalLayerSettings::BufferSize );
setCurrentComboValue( mBufferColorAttributeComboBox, s, QgsPalLayerSettings::BufferColor );
+ setCurrentComboValue( mXCoordinateComboBox, s, QgsPalLayerSettings::PositionX );
+ setCurrentComboValue( mYCoordinateComboBox, s, QgsPalLayerSettings::PositionY );
+ setCurrentComboValue( mHorizontalAlignmentComboBox, s, QgsPalLayerSettings::Hali );
+ setCurrentComboValue( mVerticalAlignmentComboBox, s, QgsPalLayerSettings::Vali );
+ setCurrentComboValue( mLabelDistanceComboBox, s, QgsPalLayerSettings::LabelDistance );
+ setCurrentComboValue( mRotationComboBox, s, QgsPalLayerSettings::Rotation );
}
void QgsLabelingGui::changeTextColor()
@@ -352,14 +393,21 @@
bool ok;
QFont font = QFontDialog::getFont( &ok, lblFontPreview->font(), this );
if ( ok )
+ {
updateFont( font );
+ }
+ mFontSizeSpinBox->setValue( font.pointSizeF() );
}
void QgsLabelingGui::updateFont( QFont font )
{
- lblFontName->setText( QString( "%1, %2 %3" ).arg( font.family() ).arg( font.pointSize() ).arg( tr( "pt" ) ) );
+ QString fontSizeUnitString = tr( "pt" );
+ if ( mFontSizeUnitComboBox->currentIndex() == 1 )
+ {
+ fontSizeUnitString = tr( "map units" );
+ }
+ lblFontName->setText( QString( "%1, %2 %3" ).arg( font.family() ).arg( font.pointSize() ).arg( fontSizeUnitString ) );
lblFontPreview->setFont( font );
-
updatePreview();
}
@@ -418,3 +466,57 @@
stackedOptions->setCurrentWidget( pageOptionsEmpty );
}
}
+
+void QgsLabelingGui::on_mFontSizeSpinBox_valueChanged( double d )
+{
+ QFont font = lblFontPreview->font();
+ font.setPointSizeF( d );
+ lblFontPreview->setFont( font );
+ updateFont( font );
+}
+
+void QgsLabelingGui::on_mFontSizeUnitComboBox_currentIndexChanged( int index )
+{
+ updateFont( lblFontPreview->font() );
+}
+
+void QgsLabelingGui::on_mXCoordinateComboBox_currentIndexChanged( const QString & text )
+{
+ if ( text.isEmpty() ) //no data defined alignment without data defined position
+ {
+ disableDataDefinedAlignment();
+ }
+ else if ( !mYCoordinateComboBox->currentText().isEmpty() )
+ {
+ enableDataDefinedAlignment();
+ }
+}
+
+void QgsLabelingGui::on_mYCoordinateComboBox_currentIndexChanged( const QString & text )
+{
+ if ( text.isEmpty() ) //no data defined alignment without data defined position
+ {
+ disableDataDefinedAlignment();
+ }
+ else if ( !mXCoordinateComboBox->currentText().isEmpty() )
+ {
+ enableDataDefinedAlignment();
+ }
+}
+
+void QgsLabelingGui::disableDataDefinedAlignment()
+{
+ mHorizontalAlignmentComboBox->setCurrentIndex( mHorizontalAlignmentComboBox->findText( "" ) );
+ mHorizontalAlignmentComboBox->setEnabled( false );
+ mVerticalAlignmentComboBox->setCurrentIndex( mVerticalAlignmentComboBox->findText( "" ) );
+ mVerticalAlignmentComboBox->setEnabled( false );
+ mRotationComboBox->setCurrentIndex( mRotationComboBox->findText( "" ) );
+ mRotationComboBox->setEnabled( false );
+}
+
+void QgsLabelingGui::enableDataDefinedAlignment()
+{
+ mHorizontalAlignmentComboBox->setEnabled( true );
+ mVerticalAlignmentComboBox->setEnabled( true );
+ mRotationComboBox->setEnabled( true );
+}
Modified: trunk/qgis/src/app/qgslabelinggui.h
===================================================================
--- trunk/qgis/src/app/qgslabelinggui.h 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/app/qgslabelinggui.h 2010-10-20 20:23:52 UTC (rev 14423)
@@ -45,6 +45,11 @@
void updatePreview();
void updateOptions();
+ void on_mFontSizeSpinBox_valueChanged( double d );
+ void on_mFontSizeUnitComboBox_currentIndexChanged( int index );
+ void on_mXCoordinateComboBox_currentIndexChanged( const QString & text );
+ void on_mYCoordinateComboBox_currentIndexChanged( const QString & text );
+
protected:
void populatePlacementMethods();
void populateFieldNames();
@@ -57,6 +62,9 @@
private:
QgsPalLabeling* mLBL;
QgsVectorLayer* mLayer;
+
+ void disableDataDefinedAlignment();
+ void enableDataDefinedAlignment();
};
#endif
Modified: trunk/qgis/src/core/pal/feature.cpp
===================================================================
--- trunk/qgis/src/core/pal/feature.cpp 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/feature.cpp 2010-10-20 20:23:52 UTC (rev 14423)
@@ -61,7 +61,7 @@
namespace pal
{
Feature::Feature( Layer* l, const char* geom_id, PalGeometry* userG, double lx, double ly )
- : layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL )
+ : layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL ), fixedPos( false ), fixedRotation( false )
{
uid = new char[strlen( geom_id ) +1];
strcpy( uid, geom_id );
@@ -599,11 +599,11 @@
reversed = ( alpha >= M_PI / 2 || alpha < -M_PI / 2 );
if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) )
- positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this ) ); // Line
+ positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this, reversed ) ); // Line
if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
- positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this ) ); // Line
+ positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this, reversed ) ); // Line
if ( flags & FLAG_ON_LINE )
- positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this ) ); // Line
+ positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this, reversed ) ); // Line
}
else if ( f->layer->arrangement == P_HORIZ )
{
@@ -1245,40 +1245,54 @@
double delta = bbox_max[0] - bbox_min[0];
- switch ( type )
+ if ( f->fixedPosition() )
{
- case GEOS_POINT:
- if ( f->layer->getArrangement() == P_POINT_OVER )
- nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta );
- else
- nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta );
- break;
- case GEOS_LINESTRING:
- if ( f->layer->getArrangement() == P_CURVED )
- nbp = setPositionForLineCurved( lPos, mapShape );
- else
- nbp = setPositionForLine( scale, lPos, mapShape, delta );
- break;
+ nbp = 1;
+ *lPos = new LabelPosition *[nbp];
+ double angle = 0.0;
+ if ( f->fixedRotation )
+ {
+ angle = f->fixedAngle;
+ }
+ ( *lPos )[0] = new LabelPosition( 0, f->fixedPosX, f->fixedPosY, f->label_x, f->label_y, angle, 0.0, this );
+ }
+ else
+ {
+ switch ( type )
+ {
+ case GEOS_POINT:
+ if ( f->layer->getArrangement() == P_POINT_OVER )
+ nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta );
+ else
+ nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta );
+ break;
+ case GEOS_LINESTRING:
+ if ( f->layer->getArrangement() == P_CURVED )
+ nbp = setPositionForLineCurved( lPos, mapShape );
+ else
+ nbp = setPositionForLine( scale, lPos, mapShape, delta );
+ break;
- case GEOS_POLYGON:
- switch ( f->layer->getArrangement() )
- {
- case P_POINT:
- case P_POINT_OVER:
- double cx, cy;
- mapShape->getCentroid( cx, cy );
- if ( f->layer->getArrangement() == P_POINT_OVER )
- nbp = setPositionOverPoint( cx, cy, scale, lPos, delta );
- else
- nbp = setPositionForPoint( cx, cy, scale, lPos, delta );
- break;
- case P_LINE:
- nbp = setPositionForLine( scale, lPos, mapShape, delta );
- break;
- default:
- nbp = setPositionForPolygon( scale, lPos, mapShape, delta );
- break;
- }
+ case GEOS_POLYGON:
+ switch ( f->layer->getArrangement() )
+ {
+ case P_POINT:
+ case P_POINT_OVER:
+ double cx, cy;
+ mapShape->getCentroid( cx, cy );
+ if ( f->layer->getArrangement() == P_POINT_OVER )
+ nbp = setPositionOverPoint( cx, cy, scale, lPos, delta );
+ else
+ nbp = setPositionForPoint( cx, cy, scale, lPos, delta );
+ break;
+ case P_LINE:
+ nbp = setPositionForLine( scale, lPos, mapShape, delta );
+ break;
+ default:
+ nbp = setPositionForPolygon( scale, lPos, mapShape, delta );
+ break;
+ }
+ }
}
int rnbp = nbp;
Modified: trunk/qgis/src/core/pal/feature.h
===================================================================
--- trunk/qgis/src/core/pal/feature.h 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/feature.h 2010-10-20 20:23:52 UTC (rev 14423)
@@ -86,6 +86,11 @@
void setLabelInfo( LabelInfo* info ) { labelInfo = info; }
void setDistLabel( double dist ) { distlabel = dist; }
+ //Set label position of the feature to fixed x/y values
+ void setFixedPosition( double x, double y ) { fixedPos = true; fixedPosX = x; fixedPosY = y;}
+ bool fixedPosition() const { return fixedPos; }
+ //Set label rotation to fixed value
+ void setFixedAngle( double a ) { fixedRotation = true; fixedAngle = a; }
protected:
Layer *layer;
@@ -97,6 +102,13 @@
char *uid;
+ bool fixedPos; //true in case of fixed position (only 1 candidate position with cost 0)
+ double fixedPosX;
+ double fixedPosY;
+ //Fixed (e.g. data defined) angle only makes sense together with fixed position
+ bool fixedRotation;
+ double fixedAngle; //fixed angle value (in rad)
+
// array of parts - possibly not necessary
//int nPart;
//FeaturePart** parts;
Modified: trunk/qgis/src/core/pal/labelposition.cpp
===================================================================
--- trunk/qgis/src/core/pal/labelposition.cpp 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/labelposition.cpp 2010-10-20 20:23:52 UTC (rev 14423)
@@ -54,8 +54,8 @@
namespace pal
{
- LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature )
- : id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 )
+ LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed )
+ : id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 ), reversed( isReversed )
{
// alpha take his value bw 0 and 2*pi rad
Modified: trunk/qgis/src/core/pal/labelposition.h
===================================================================
--- trunk/qgis/src/core/pal/labelposition.h 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/labelposition.h 2010-10-20 20:23:52 UTC (rev 14423)
@@ -74,6 +74,11 @@
LabelPosition* nextPart;
int partId;
+ //True if label direction is the same as line / polygon ring direction.
+ //Could be used by the application to draw a directional arrow ('<' or '>')
+ //if the layer arrangement is P_LINE
+ bool reversed;
+
bool isInConflictSinglePart( LabelPosition* lp );
bool isInConflictMultiPart( LabelPosition* lp );
@@ -93,7 +98,7 @@
LabelPosition( int id, double x1, double y1,
double w, double h,
double alpha, double cost,
- FeaturePart *feature );
+ FeaturePart *feature, bool isReversed = false );
/** copy constructor */
LabelPosition( const LabelPosition& other );
@@ -190,6 +195,7 @@
* \return alpha to rotate text (in rad)
*/
double getAlpha() const;
+ bool getReversed() const { return reversed; }
void print();
Modified: trunk/qgis/src/core/pal/layer.cpp
===================================================================
--- trunk/qgis/src/core/pal/layer.cpp 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/layer.cpp 2010-10-20 20:23:52 UTC (rev 14423)
@@ -226,7 +226,8 @@
- bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText )
+ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText,
+ double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle )
{
if ( !geom_id || label_x < 0 || label_y < 0 )
return false;
@@ -245,6 +246,14 @@
GEOSGeometry *the_geom = userGeom->getGeosGeometry();
Feature* f = new Feature( this, geom_id, userGeom, label_x, label_y );
+ if ( fixedPos )
+ {
+ f->setFixedPosition( labelPosX, labelPosY );
+ }
+ if ( fixedAngle )
+ {
+ f->setFixedAngle( angle );
+ }
bool first_feat = true;
@@ -316,7 +325,7 @@
modMutex->unlock();
// if using only biggest parts...
- if ( mode == LabelPerFeature && biggest_part != NULL )
+ if (( mode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL )
{
addFeaturePart( biggest_part, labelText );
first_feat = false;
Modified: trunk/qgis/src/core/pal/layer.h
===================================================================
--- trunk/qgis/src/core/pal/layer.h 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/layer.h 2010-10-20 20:23:52 UTC (rev 14423)
@@ -283,12 +283,16 @@
* @param label_x label width
* @param label_y label height
* @param userGeom user's geometry that implements the PalGeometry interface
+ * @param labelPosX x position of the label (in case of fixed label position)
+ * @param labelPosY y position of the label (in case of fixed label position)
+ * @param fixedPos true if a single fixed position for this label is needed
*
* @throws PalException::FeatureExists
*
* @return true on success (i.e. valid geometry)
*/
- bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1, const char* labelText = NULL );
+ bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1,
+ const char* labelText = NULL, double labelPosX = 0.0, double labelPosY = 0.0, bool fixedPos = false, double angle = 0.0, bool fixedAngle = false );
/** return pointer to feature or NULL if doesn't exist */
Feature* getFeature( const char* geom_id );
Modified: trunk/qgis/src/core/qgspallabeling.cpp
===================================================================
--- trunk/qgis/src/core/qgspallabeling.cpp 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/qgspallabeling.cpp 2010-10-20 20:23:52 UTC (rev 14423)
@@ -132,6 +132,8 @@
minFeatureSize = 0.0;
vectorScaleFactor = 1.0;
rasterCompressFactor = 1.0;
+ addDirectionSymbol = false;
+ fontSizeInMapUnits = false;
}
QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
@@ -156,6 +158,8 @@
minFeatureSize = s.minFeatureSize;
vectorScaleFactor = s.vectorScaleFactor;
rasterCompressFactor = s.rasterCompressFactor;
+ addDirectionSymbol = s.addDirectionSymbol;
+ fontSizeInMapUnits = s.fontSizeInMapUnits;
dataDefinedProperties = s.dataDefinedProperties;
fontMetrics = NULL;
@@ -193,7 +197,7 @@
return;
}
- for ( int i = 0; i < 9; ++i )
+ for ( int i = 0; i < 15; ++i )
{
QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator it = propertyMap.find(( QgsPalLayerSettings::DataDefinedProperties )i );
QVariant propertyValue;
@@ -242,6 +246,12 @@
_readDataDefinedProperty( layer, QgsPalLayerSettings::Family, propertyMap );
_readDataDefinedProperty( layer, QgsPalLayerSettings::BufferSize, propertyMap );
_readDataDefinedProperty( layer, QgsPalLayerSettings::BufferColor, propertyMap );
+ _readDataDefinedProperty( layer, QgsPalLayerSettings::PositionX, propertyMap );
+ _readDataDefinedProperty( layer, QgsPalLayerSettings::PositionY, propertyMap );
+ _readDataDefinedProperty( layer, QgsPalLayerSettings::Hali, propertyMap );
+ _readDataDefinedProperty( layer, QgsPalLayerSettings::Vali, propertyMap );
+ _readDataDefinedProperty( layer, QgsPalLayerSettings::LabelDistance, propertyMap );
+ _readDataDefinedProperty( layer, QgsPalLayerSettings::Rotation, propertyMap );
}
void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
@@ -269,7 +279,9 @@
labelPerPart = layer->customProperty( "labeling/labelPerPart" ).toBool();
mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
multiLineLabels = layer->customProperty( "labeling/multiLineLabels" ).toBool();
+ addDirectionSymbol = layer->customProperty( "labeling/addDirectionSymbol" ).toBool();
minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble();
+ fontSizeInMapUnits = layer->customProperty( "labeling/fontSizeInMapUnits" ).toBool();
_readDataDefinedPropertyMap( layer, dataDefinedProperties );
}
@@ -299,7 +311,9 @@
layer->setCustomProperty( "labeling/labelPerPart", labelPerPart );
layer->setCustomProperty( "labeling/mergeLines", mergeLines );
layer->setCustomProperty( "labeling/multiLineLabels", multiLineLabels );
+ layer->setCustomProperty( "labeling/addDirectionSymbol", addDirectionSymbol );
layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize );
+ layer->setCustomProperty( "labeling/fontSizeInMapUnits", fontSizeInMapUnits );
_writeDataDefinedPropertyMap( layer, dataDefinedProperties );
}
@@ -358,6 +372,10 @@
return;
}
+ if ( addDirectionSymbol && !multiLineLabels && placement == QgsPalLayerSettings::Line ) //consider the space needed for the direction symbol
+ {
+ text.append( ">" );
+ }
QRectF labelRect = fm->boundingRect( text );
double w, h;
if ( !multiLineLabels )
@@ -391,12 +409,12 @@
{
QString labelText = f.attributeMap()[fieldIndex].toString();
double labelX, labelY; // will receive label size
+ QFont labelFont = textFont;
//data defined label size?
QMap< DataDefinedProperties, int >::const_iterator it = dataDefinedProperties.find( QgsPalLayerSettings::Size );
if ( it != dataDefinedProperties.constEnd() )
{
- QFont labelFont = textFont;
//find out size
QVariant size = f.attributeMap().value( *it );
if ( size.isValid() )
@@ -406,7 +424,7 @@
{
return;
}
- labelFont.setPointSize( sizeToPixel( sizeDouble, context ) );
+ labelFont.setPixelSize( sizeToPixel( sizeDouble, context ) );
}
QFontMetrics labelFontMetrics( labelFont );
calculateLabelSize( &labelFontMetrics, labelText, labelX, labelY );
@@ -430,6 +448,88 @@
return;
}
+ //data defined position / alignment / rotation?
+ bool dataDefinedPosition = false;
+ bool dataDefinedRotation = false;
+ double xPos, yPos, angle;
+
+ QMap< DataDefinedProperties, int >::const_iterator dPosXIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionX );
+ if ( dPosXIt != dataDefinedProperties.constEnd() )
+ {
+ QMap< DataDefinedProperties, int >::const_iterator dPosYIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionY );
+ if ( dPosYIt != dataDefinedProperties.constEnd() )
+ {
+ //data defined position
+ dataDefinedPosition = true;
+ xPos = f.attributeMap().value( *dPosXIt ).toDouble();
+ yPos = f.attributeMap().value( *dPosYIt ).toDouble();
+
+ //x/y shift in case of alignment
+ double xdiff = 0;
+ double ydiff = 0;
+
+ //horizontal alignment
+ QMap< DataDefinedProperties, int >::const_iterator haliIt = dataDefinedProperties.find( QgsPalLayerSettings::Hali );
+ if ( haliIt != dataDefinedProperties.end() )
+ {
+ QString haliString = f.attributeMap().value( *haliIt ).toString();
+ if ( haliString.compare( "Center", Qt::CaseInsensitive ) == 0 )
+ {
+ xdiff -= labelX / 2.0;
+ }
+ else if ( haliString.compare( "Right", Qt::CaseInsensitive ) == 0 )
+ {
+ xdiff -= labelX;
+ }
+ }
+
+ //vertical alignment
+ QMap< DataDefinedProperties, int >::const_iterator valiIt = dataDefinedProperties.find( QgsPalLayerSettings::Vali );
+ if ( valiIt != dataDefinedProperties.constEnd() )
+ {
+ QString valiString = f.attributeMap().value( *valiIt ).toString();
+ if ( valiString.compare( "Bottom", Qt::CaseInsensitive ) != 0 )
+ {
+ if ( valiString.compare( "Top", Qt::CaseInsensitive ) == 0 || valiString.compare( "Cap", Qt::CaseInsensitive ) == 0 )
+ {
+ ydiff -= labelY;
+ }
+ else
+ {
+ QFontMetrics labelFontMetrics( labelFont );
+ double descentRatio = labelFontMetrics.descent() / labelFontMetrics.height();
+
+ if ( valiString.compare( "Base", Qt::CaseInsensitive ) == 0 )
+ {
+ ydiff -= labelY * descentRatio;
+ }
+ else if ( valiString.compare( "Half", Qt::CaseInsensitive ) == 0 )
+ {
+ ydiff -= labelY * descentRatio;
+ ydiff -= labelY * 0.5 * ( 1 - descentRatio );
+ }
+ }
+ }
+ }
+
+ //data defined rotation?
+ QMap< DataDefinedProperties, int >::const_iterator rotIt = dataDefinedProperties.find( QgsPalLayerSettings::Rotation );
+ if ( rotIt != dataDefinedProperties.constEnd() )
+ {
+ dataDefinedRotation = true;
+ angle = f.attributeMap().value( *rotIt ).toDouble() * M_PI / 180;
+ //adjust xdiff and ydiff because the hali/vali point needs to be the rotation center
+ double xd = xdiff * cos( angle ) - ydiff * sin( angle );
+ double yd = xdiff * sin( angle ) + ydiff * cos( angle );
+ xdiff = xd;
+ ydiff = yd;
+ }
+
+ yPos += ydiff;
+ xPos += xdiff;
+ }
+ }
+
QgsPalGeometry* lbl = new QgsPalGeometry( f.id(), labelText, GEOSGeom_clone( geos_geom ) );
// record the created geometry - it will be deleted at the end.
@@ -438,7 +538,8 @@
// register feature to the layer
try
{
- if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData() ) )
+ if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData(),
+ xPos, yPos, dataDefinedPosition, angle, dataDefinedRotation ) )
return;
}
catch ( std::exception* e )
@@ -452,9 +553,20 @@
feat->setLabelInfo( lbl->info( fontMetrics, xform, rasterCompressFactor ) );
// TODO: allow layer-wide feature dist in PAL...?
- if ( dist != 0 )
- feat->setDistLabel( fabs( ptOne.x() - ptZero.x() )* dist * vectorScaleFactor );
+ //data defined label-feature distance?
+ double distance = dist;
+ QMap< DataDefinedProperties, int >::const_iterator dDistIt = dataDefinedProperties.find( QgsPalLayerSettings::LabelDistance );
+ if ( dDistIt != dataDefinedProperties.constEnd() )
+ {
+ distance = f.attributeMap().value( *dDistIt ).toDouble();
+ }
+
+ if ( distance != 0 )
+ {
+ feat->setDistLabel( fabs( ptOne.x() - ptZero.x() )* distance * vectorScaleFactor );
+ }
+
//add parameters for data defined labeling to QgsPalGeometry
QMap< DataDefinedProperties, int >::const_iterator dIt = dataDefinedProperties.constBegin();
for ( ; dIt != dataDefinedProperties.constEnd(); ++dIt )
@@ -465,9 +577,17 @@
int QgsPalLayerSettings::sizeToPixel( double size, const QgsRenderContext& c ) const
{
- // set font size from points to output size
- double pixelSize = 0.3527 * size * c.scaleFactor() * c.rasterScaleFactor() + 0.5;
- return ( int )pixelSize;
+ double pixelSize;
+ if ( fontSizeInMapUnits )
+ {
+ pixelSize = size / c.mapToPixel().mapUnitsPerPixel() * c.rasterScaleFactor();
+ }
+ else //font size in points
+ {
+ // set font size from points to output size
+ pixelSize = 0.3527 * size * c.scaleFactor() * c.rasterScaleFactor();
+ }
+ return ( int )( pixelSize + 0.5 );
}
@@ -730,7 +850,7 @@
QVariant dataDefinedSize = palGeometry->dataDefinedValues().value( QgsPalLayerSettings::Size );
if ( dataDefinedSize.isValid() )
{
- fontForLabel.setPointSize( lyr.sizeToPixel( dataDefinedSize.toDouble(), context ) );
+ fontForLabel.setPixelSize( lyr.sizeToPixel( dataDefinedSize.toDouble(), context ) );
}
//font color
QVariant dataDefinedColor = palGeometry->dataDefinedValues().value( QgsPalLayerSettings::Color );
@@ -871,6 +991,20 @@
QString text = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();
QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) );
+ //add the direction symbol if needed
+ if ( !txt.isEmpty() && lyr.placement == QgsPalLayerSettings::Line &&
+ lyr.addDirectionSymbol && !lyr.multiLineLabels )
+ {
+ if ( label->getReversed() )
+ {
+ txt.prepend( "<" );
+ }
+ else
+ {
+ txt.append( ">" );
+ }
+ }
+
//QgsDebugMsg( "drawLabel " + QString::number( drawBuffer ) + " " + txt );
QStringList multiLineList;
@@ -913,7 +1047,7 @@
painter->restore();
if ( label->getNextPart() )
- drawLabel( label->getNextPart(), painter, f, c, xform, drawBuffer );
+ drawLabel( label->getNextPart(), painter, f, c, xform, bufferSize, bufferColor, drawBuffer );
}
}
Modified: trunk/qgis/src/core/qgspallabeling.h
===================================================================
--- trunk/qgis/src/core/qgspallabeling.h 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/qgspallabeling.h 2010-10-20 20:23:52 UTC (rev 14423)
@@ -83,6 +83,12 @@
Family,
BufferSize,
BufferColor,
+ PositionX, //x-coordinate data defined label position
+ PositionY, //y-coordinate data defined label position
+ Hali, //horizontal alignment for data defined label position (Left, Center, Right)
+ Vali, //vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
+ LabelDistance,
+ Rotation //data defined rotation (only usefull in connection with data defined position)
};
QString fieldName;
@@ -103,6 +109,10 @@
bool mergeLines;
bool multiLineLabels; //draw labels on multiple lines if they contain '\n'
double minFeatureSize; // minimum feature size to be labelled (in mm)
+ // Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring
+ // Works only if Placement == Line
+ bool addDirectionSymbol;
+ bool fontSizeInMapUnits; //true if font size is in map units (otherwise in points)
// called from register feature hook
void calculateLabelSize( const QFontMetrics* fm, QString text, double& labelX, double& labelY );
@@ -130,7 +140,7 @@
/**Stores field indices for data defined layer properties*/
QMap< DataDefinedProperties, int > dataDefinedProperties;
- /**Calculates pixel size (considering scale factors and oversampling)
+ /**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
@return font pixel size*/
Modified: trunk/qgis/src/ui/qgslabelingguibase.ui
===================================================================
--- trunk/qgis/src/ui/qgslabelingguibase.ui 2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/ui/qgslabelingguibase.ui 2010-10-20 20:23:52 UTC (rev 14423)
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>496</width>
- <height>659</height>
+ <width>504</width>
+ <height>686</height>
</rect>
</property>
<property name="windowTitle">
@@ -396,7 +396,7 @@
</item>
</layout>
</item>
- <item row="1" column="0">
+ <item row="2" column="0">
<widget class="QLabel" name="label_29">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -412,7 +412,7 @@
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_16">
<item>
<widget class="QgsColorButton" name="btnTextColor">
@@ -445,7 +445,7 @@
</item>
</layout>
</item>
- <item row="2" column="0">
+ <item row="3" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Buffer</string>
@@ -455,7 +455,7 @@
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_17">
<item>
<widget class="QCheckBox" name="chkBuffer">
@@ -512,7 +512,7 @@
</item>
</layout>
</item>
- <item row="4" column="0">
+ <item row="5" column="0">
<widget class="QLabel" name="label_33">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -528,8 +528,14 @@
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="5" column="1">
<widget class="QgsLabelPreview" name="lblFontPreview">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="minimumSize">
<size>
<width>30</width>
@@ -544,13 +550,45 @@
</property>
</widget>
</item>
- <item row="3" column="0" colspan="2">
+ <item row="4" column="0" colspan="2">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="mFontSizeLabel">
+ <property name="text">
+ <string>Font size</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QDoubleSpinBox" name="mFontSizeSpinBox">
+ <property name="maximum">
+ <double>999999999.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="mFontSizeUnitComboBox">
+ <item>
+ <property name="text">
+ <string>In points</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>In map units</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
</item>
@@ -678,7 +716,7 @@
</property>
</widget>
</item>
- <item row="7" column="0">
+ <item row="8" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_19">
<item>
<widget class="QLabel" name="label_19">
@@ -696,7 +734,7 @@
</item>
</layout>
</item>
- <item row="8" column="0">
+ <item row="9" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_20">
<item>
<widget class="QCheckBox" name="chkNoObstacle">
@@ -733,13 +771,20 @@
</item>
</layout>
</item>
+ <item row="7" column="0">
+ <widget class="QCheckBox" name="chkAddDirectionSymbol">
+ <property name="text">
+ <string>add direction symbol</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Data defined settings</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout_4">
+ <layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QGroupBox" name="mFontAttributePropertiesGroupBox">
<property name="sizePolicy">
@@ -753,79 +798,75 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
- <layout class="QGridLayout" name="gridLayout_11">
- <item row="0" column="0">
- <widget class="QLabel" name="mSizeLabel">
- <property name="text">
- <string>Size</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="mSizeAttributeComboBox"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="mBoldLabel">
- <property name="text">
- <string>Bold</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QComboBox" name="mBoldAttributeComboBox"/>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="mColorAttributeComboBox"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="mColorLabel">
- <property name="text">
- <string>Color</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QComboBox" name="mItalicAttributeComboBox"/>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="mItalicLabel">
- <property name="text">
- <string>Italic</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QComboBox" name="mUnderlineAttributeComboBox"/>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="mUnderlineLabel">
- <property name="text">
- <string>Underline</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QComboBox" name="mFontFamilyAttributeComboBox"/>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="mFontFamilyLabel">
- <property name="text">
- <string>Font family</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QComboBox" name="mStrikeoutAttributeComboBox"/>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="mStrikeoutLabel">
- <property name="text">
- <string>Strikeout</string>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QLabel" name="mSizeLabel">
+ <property name="text">
+ <string>Size</string>
+ </property>
+ </widget>
</item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="mSizeAttributeComboBox"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="mColorLabel">
+ <property name="text">
+ <string>Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="mColorAttributeComboBox"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="mBoldLabel">
+ <property name="text">
+ <string>Bold</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="mBoldAttributeComboBox"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="mItalicLabel">
+ <property name="text">
+ <string>Italic</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="mItalicAttributeComboBox"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="mUnderlineLabel">
+ <property name="text">
+ <string>Underline</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="mUnderlineAttributeComboBox"/>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="mStrikeoutLabel">
+ <property name="text">
+ <string>Strikeout</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="mStrikeoutAttributeComboBox"/>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="mFontFamilyLabel">
+ <property name="text">
+ <string>Font family</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QComboBox" name="mFontFamilyAttributeComboBox"/>
+ </item>
</layout>
</widget>
</item>
@@ -834,35 +875,100 @@
<property name="title">
<string>Buffer properties</string>
</property>
- <layout class="QGridLayout" name="gridLayout_3">
+ <layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="mBufferSizeLabel">
- <property name="text">
- <string>Buffer size</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="mBufferSizeAttributeComboBox"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="mBufferColorLabel">
- <property name="text">
- <string>Buffer color</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="mBufferColorAttributeComboBox"/>
- </item>
- </layout>
+ <widget class="QLabel" name="mBufferSizeLabel">
+ <property name="text">
+ <string>Buffer size</string>
+ </property>
+ </widget>
</item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="mBufferSizeAttributeComboBox"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="mBufferColorLabel">
+ <property name="text">
+ <string>Buffer color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="mBufferColorAttributeComboBox"/>
+ </item>
</layout>
</widget>
</item>
<item row="2" column="0">
+ <widget class="QGroupBox" name="mPositionAttributeGroupBox">
+ <property name="title">
+ <string>Position</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="0">
+ <widget class="QLabel" name="mXCoordinateLabel">
+ <property name="text">
+ <string>X Coordinate</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="mXCoordinateComboBox"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="mYCoordinateLabel">
+ <property name="text">
+ <string>Y Coordinate</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="mYCoordinateComboBox"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="mHorizontalAlignmentLabel">
+ <property name="text">
+ <string>Horizontal alignment</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="mHorizontalAlignmentComboBox"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="mVerticalAlignmentLabel">
+ <property name="text">
+ <string>Vertical alignment</string>
+ </property>
+ </widget>
+ </item>
+ <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>
+ </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>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
More information about the QGIS-commit
mailing list