100916_data_defined_label_position.diff
| src/app/qgslabelinggui.h (Arbeitskopie) | ||
|---|---|---|
| 45 | 45 |
void updatePreview(); |
| 46 | 46 |
void updateOptions(); |
| 47 | 47 | |
| 48 |
void on_mXCoordinateComboBox_currentIndexChanged( const QString & text ); |
|
| 49 |
void on_mYCoordinateComboBox_currentIndexChanged( const QString & text ); |
|
| 50 | ||
| 48 | 51 |
protected: |
| 49 | 52 |
void populatePlacementMethods(); |
| 50 | 53 |
void populateFieldNames(); |
| ... | ... | |
| 57 | 60 |
private: |
| 58 | 61 |
QgsPalLabeling* mLBL; |
| 59 | 62 |
QgsVectorLayer* mLayer; |
| 63 | ||
| 64 |
void disableDataDefinedAlignment(); |
|
| 65 |
void enableDataDefinedAlignment(); |
|
| 60 | 66 |
}; |
| 61 | 67 | |
| 62 | 68 |
#endif |
| src/app/qgslabelinggui.cpp (Arbeitskopie) | ||
|---|---|---|
| 123 | 123 |
chkMergeLines->setChecked( lyr.mergeLines ); |
| 124 | 124 |
chkMultiLine->setChecked( lyr.multiLineLabels ); |
| 125 | 125 |
mMinSizeSpinBox->setValue( lyr.minFeatureSize ); |
| 126 |
chkAddDirectionSymbol->setChecked( lyr.addDirectionSymbol ); |
|
| 126 | 127 | |
| 127 | 128 |
bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 ); |
| 128 | 129 |
chkScaleBasedVisibility->setChecked( scaleBased ); |
| ... | ... | |
| 238 | 239 |
{
|
| 239 | 240 |
lyr.bufferSize = 0; |
| 240 | 241 |
} |
| 242 |
if ( chkAddDirectionSymbol->isChecked() ) |
|
| 243 |
{
|
|
| 244 |
lyr.addDirectionSymbol = true; |
|
| 245 |
} |
|
| 246 |
else |
|
| 247 |
{
|
|
| 248 |
lyr.addDirectionSymbol = false; |
|
| 249 |
} |
|
| 241 | 250 |
lyr.minFeatureSize = mMinSizeSpinBox->value(); |
| 242 | 251 | |
| 252 | ||
| 243 | 253 |
//data defined labeling |
| 244 | 254 |
setDataDefinedProperty( mSizeAttributeComboBox, QgsPalLayerSettings::Size, lyr ); |
| 245 | 255 |
setDataDefinedProperty( mColorAttributeComboBox, QgsPalLayerSettings::Color, lyr ); |
| ... | ... | |
| 250 | 260 |
setDataDefinedProperty( mFontFamilyAttributeComboBox, QgsPalLayerSettings::Family, lyr ); |
| 251 | 261 |
setDataDefinedProperty( mBufferSizeAttributeComboBox, QgsPalLayerSettings:: BufferSize, lyr ); |
| 252 | 262 |
setDataDefinedProperty( mBufferColorAttributeComboBox, QgsPalLayerSettings::BufferColor, lyr ); |
| 263 |
setDataDefinedProperty( mXCoordinateComboBox, QgsPalLayerSettings::PositionX, lyr ); |
|
| 264 |
setDataDefinedProperty( mYCoordinateComboBox, QgsPalLayerSettings::PositionY, lyr ); |
|
| 265 |
setDataDefinedProperty( mHorizontalAlignmentComboBox, QgsPalLayerSettings::Hali, lyr ); |
|
| 266 |
setDataDefinedProperty( mVerticalAlignmentComboBox, QgsPalLayerSettings::Vali, lyr ); |
|
| 253 | 267 | |
| 254 | 268 |
return lyr; |
| 255 | 269 |
} |
| ... | ... | |
| 308 | 322 |
comboList << mFontFamilyAttributeComboBox; |
| 309 | 323 |
comboList << mBufferSizeAttributeComboBox; |
| 310 | 324 |
comboList << mBufferColorAttributeComboBox; |
| 325 |
comboList << mXCoordinateComboBox; |
|
| 326 |
comboList << mYCoordinateComboBox; |
|
| 327 |
comboList << mHorizontalAlignmentComboBox; |
|
| 328 |
comboList << mVerticalAlignmentComboBox; |
|
| 311 | 329 | |
| 312 | 330 |
QList<QComboBox*>::iterator comboIt = comboList.begin(); |
| 313 | 331 |
for ( ; comboIt != comboList.end(); ++comboIt ) |
| ... | ... | |
| 335 | 353 |
setCurrentComboValue( mFontFamilyAttributeComboBox, s, QgsPalLayerSettings::Family ); |
| 336 | 354 |
setCurrentComboValue( mBufferSizeAttributeComboBox, s , QgsPalLayerSettings::BufferSize ); |
| 337 | 355 |
setCurrentComboValue( mBufferColorAttributeComboBox, s, QgsPalLayerSettings::BufferColor ); |
| 356 |
setCurrentComboValue( mXCoordinateComboBox, s, QgsPalLayerSettings::PositionX ); |
|
| 357 |
setCurrentComboValue( mYCoordinateComboBox, s, QgsPalLayerSettings::PositionY ); |
|
| 358 |
setCurrentComboValue( mHorizontalAlignmentComboBox, s, QgsPalLayerSettings::Hali ); |
|
| 359 |
setCurrentComboValue( mVerticalAlignmentComboBox, s, QgsPalLayerSettings::Vali ); |
|
| 338 | 360 |
} |
| 339 | 361 | |
| 340 | 362 |
void QgsLabelingGui::changeTextColor() |
| ... | ... | |
| 418 | 440 |
stackedOptions->setCurrentWidget( pageOptionsEmpty ); |
| 419 | 441 |
} |
| 420 | 442 |
} |
| 443 | ||
| 444 |
void QgsLabelingGui::on_mXCoordinateComboBox_currentIndexChanged( const QString & text ) |
|
| 445 |
{
|
|
| 446 |
if ( text.isEmpty() ) //no data defined alignment without data defined position |
|
| 447 |
{
|
|
| 448 |
disableDataDefinedAlignment(); |
|
| 449 |
} |
|
| 450 |
else if ( !mYCoordinateComboBox->currentText().isEmpty() ) |
|
| 451 |
{
|
|
| 452 |
enableDataDefinedAlignment(); |
|
| 453 |
} |
|
| 454 |
} |
|
| 455 | ||
| 456 |
void QgsLabelingGui::on_mYCoordinateComboBox_currentIndexChanged( const QString & text ) |
|
| 457 |
{
|
|
| 458 |
if ( text.isEmpty() ) //no data defined alignment without data defined position |
|
| 459 |
{
|
|
| 460 |
disableDataDefinedAlignment(); |
|
| 461 |
} |
|
| 462 |
else if ( !mXCoordinateComboBox->currentText().isEmpty() ) |
|
| 463 |
{
|
|
| 464 |
enableDataDefinedAlignment(); |
|
| 465 |
} |
|
| 466 |
} |
|
| 467 | ||
| 468 |
void QgsLabelingGui::disableDataDefinedAlignment() |
|
| 469 |
{
|
|
| 470 |
mHorizontalAlignmentComboBox->setCurrentIndex( mHorizontalAlignmentComboBox->findText( "" ) ); |
|
| 471 |
mHorizontalAlignmentComboBox->setEnabled( false ); |
|
| 472 |
mVerticalAlignmentComboBox->setCurrentIndex( mVerticalAlignmentComboBox->findText( "" ) ); |
|
| 473 |
mVerticalAlignmentComboBox->setEnabled( false ); |
|
| 474 |
} |
|
| 475 | ||
| 476 |
void QgsLabelingGui::enableDataDefinedAlignment() |
|
| 477 |
{
|
|
| 478 |
mHorizontalAlignmentComboBox->setEnabled( true ); |
|
| 479 |
mVerticalAlignmentComboBox->setEnabled( true ); |
|
| 480 |
} |
|
| src/core/qgspallabeling.cpp (Arbeitskopie) | ||
|---|---|---|
| 132 | 132 |
minFeatureSize = 0.0; |
| 133 | 133 |
vectorScaleFactor = 1.0; |
| 134 | 134 |
rasterCompressFactor = 1.0; |
| 135 |
addDirectionSymbol = false; |
|
| 135 | 136 |
} |
| 136 | 137 | |
| 137 | 138 |
QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s ) |
| ... | ... | |
| 156 | 157 |
minFeatureSize = s.minFeatureSize; |
| 157 | 158 |
vectorScaleFactor = s.vectorScaleFactor; |
| 158 | 159 |
rasterCompressFactor = s.rasterCompressFactor; |
| 160 |
addDirectionSymbol = s.addDirectionSymbol; |
|
| 159 | 161 | |
| 160 | 162 |
dataDefinedProperties = s.dataDefinedProperties; |
| 161 | 163 |
fontMetrics = NULL; |
| ... | ... | |
| 193 | 195 |
return; |
| 194 | 196 |
} |
| 195 | 197 | |
| 196 |
for ( int i = 0; i < 9; ++i )
|
|
| 198 |
for ( int i = 0; i < 13; ++i )
|
|
| 197 | 199 |
{
|
| 198 | 200 |
QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator it = propertyMap.find(( QgsPalLayerSettings::DataDefinedProperties )i ); |
| 199 | 201 |
QVariant propertyValue; |
| ... | ... | |
| 242 | 244 |
_readDataDefinedProperty( layer, QgsPalLayerSettings::Family, propertyMap ); |
| 243 | 245 |
_readDataDefinedProperty( layer, QgsPalLayerSettings::BufferSize, propertyMap ); |
| 244 | 246 |
_readDataDefinedProperty( layer, QgsPalLayerSettings::BufferColor, propertyMap ); |
| 247 |
_readDataDefinedProperty( layer, QgsPalLayerSettings::PositionX, propertyMap ); |
|
| 248 |
_readDataDefinedProperty( layer, QgsPalLayerSettings::PositionY, propertyMap ); |
|
| 249 |
_readDataDefinedProperty( layer, QgsPalLayerSettings::Hali, propertyMap ); |
|
| 250 |
_readDataDefinedProperty( layer, QgsPalLayerSettings::Vali, propertyMap ); |
|
| 245 | 251 |
} |
| 246 | 252 | |
| 247 | 253 |
void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer ) |
| ... | ... | |
| 269 | 275 |
labelPerPart = layer->customProperty( "labeling/labelPerPart" ).toBool(); |
| 270 | 276 |
mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool(); |
| 271 | 277 |
multiLineLabels = layer->customProperty( "labeling/multiLineLabels" ).toBool(); |
| 278 |
addDirectionSymbol = layer->customProperty( "labeling/addDirectionSymbol" ).toBool(); |
|
| 272 | 279 |
minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble(); |
| 273 | 280 |
_readDataDefinedPropertyMap( layer, dataDefinedProperties ); |
| 274 | 281 |
} |
| ... | ... | |
| 299 | 306 |
layer->setCustomProperty( "labeling/labelPerPart", labelPerPart ); |
| 300 | 307 |
layer->setCustomProperty( "labeling/mergeLines", mergeLines ); |
| 301 | 308 |
layer->setCustomProperty( "labeling/multiLineLabels", multiLineLabels ); |
| 309 |
layer->setCustomProperty( "labeling/addDirectionSymbol", addDirectionSymbol ); |
|
| 302 | 310 |
layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize ); |
| 303 | 311 |
_writeDataDefinedPropertyMap( layer, dataDefinedProperties ); |
| 304 | 312 |
} |
| ... | ... | |
| 358 | 366 |
return; |
| 359 | 367 |
} |
| 360 | 368 | |
| 369 |
if ( addDirectionSymbol && !multiLineLabels && placement == QgsPalLayerSettings::Line ) //consider the space needed for the direction symbol |
|
| 370 |
{
|
|
| 371 |
text.append( ">" ); |
|
| 372 |
} |
|
| 361 | 373 |
QRectF labelRect = fm->boundingRect( text ); |
| 362 | 374 |
double w, h; |
| 363 | 375 |
if ( !multiLineLabels ) |
| ... | ... | |
| 391 | 403 |
{
|
| 392 | 404 |
QString labelText = f.attributeMap()[fieldIndex].toString(); |
| 393 | 405 |
double labelX, labelY; // will receive label size |
| 406 |
QFont labelFont = textFont; |
|
| 394 | 407 | |
| 395 | 408 |
//data defined label size? |
| 396 | 409 |
QMap< DataDefinedProperties, int >::const_iterator it = dataDefinedProperties.find( QgsPalLayerSettings::Size ); |
| 397 | 410 |
if ( it != dataDefinedProperties.constEnd() ) |
| 398 | 411 |
{
|
| 399 |
QFont labelFont = textFont; |
|
| 400 | 412 |
//find out size |
| 401 | 413 |
QVariant size = f.attributeMap().value( *it ); |
| 402 | 414 |
if ( size.isValid() ) |
| ... | ... | |
| 430 | 442 |
return; |
| 431 | 443 |
} |
| 432 | 444 | |
| 445 |
//data defined position / alignment? |
|
| 446 |
bool dataDefinedPosition = false; |
|
| 447 |
double xPos, yPos; |
|
| 448 | ||
| 449 |
QMap< DataDefinedProperties, int >::const_iterator dPosXIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionX ); |
|
| 450 |
if ( dPosXIt != dataDefinedProperties.constEnd() ) |
|
| 451 |
{
|
|
| 452 |
QMap< DataDefinedProperties, int >::const_iterator dPosYIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionY ); |
|
| 453 |
if ( dPosYIt != dataDefinedProperties.constEnd() ) |
|
| 454 |
{
|
|
| 455 |
//data defined position |
|
| 456 |
dataDefinedPosition = true; |
|
| 457 |
xPos = f.attributeMap().value( *dPosXIt ).toDouble(); |
|
| 458 |
yPos = f.attributeMap().value( *dPosYIt ).toDouble(); |
|
| 459 | ||
| 460 |
//consider alignment settings (by adjusting xPos and yPos, which are lower/left in pal) |
|
| 461 | ||
| 462 |
//horizontal alignment |
|
| 463 |
QMap< DataDefinedProperties, int >::const_iterator haliIt = dataDefinedProperties.find( QgsPalLayerSettings::Hali ); |
|
| 464 |
if ( haliIt != dataDefinedProperties.end() ) |
|
| 465 |
{
|
|
| 466 |
QString haliString = f.attributeMap().value( *haliIt ).toString(); |
|
| 467 |
if ( haliString.compare( "Center", Qt::CaseInsensitive ) == 0 ) |
|
| 468 |
{
|
|
| 469 |
xPos -= labelX / 2.0; |
|
| 470 |
} |
|
| 471 |
else if ( haliString.compare( "Right", Qt::CaseInsensitive ) == 0 ) |
|
| 472 |
{
|
|
| 473 |
xPos -= labelX; |
|
| 474 |
} |
|
| 475 |
} |
|
| 476 | ||
| 477 |
//vertical alignment |
|
| 478 |
QMap< DataDefinedProperties, int >::const_iterator valiIt = dataDefinedProperties.find( QgsPalLayerSettings::Vali ); |
|
| 479 |
if ( valiIt != dataDefinedProperties.constEnd() ) |
|
| 480 |
{
|
|
| 481 |
QString valiString = f.attributeMap().value( *valiIt ).toString(); |
|
| 482 |
if ( valiString.compare( "Bottom", Qt::CaseInsensitive ) != 0 ) |
|
| 483 |
{
|
|
| 484 |
if ( valiString.compare( "Top", Qt::CaseInsensitive ) == 0 || valiString.compare( "Cap", Qt::CaseInsensitive ) == 0 ) |
|
| 485 |
{
|
|
| 486 |
yPos -= labelY; |
|
| 487 |
} |
|
| 488 |
else |
|
| 489 |
{
|
|
| 490 |
QFontMetrics labelFontMetrics( labelFont ); |
|
| 491 |
double descentRatio = labelFontMetrics.descent() / labelFontMetrics.height(); |
|
| 492 | ||
| 493 |
if ( valiString.compare( "Base", Qt::CaseInsensitive ) == 0 ) |
|
| 494 |
{
|
|
| 495 |
yPos -= labelY * descentRatio; |
|
| 496 |
} |
|
| 497 |
else if ( valiString.compare( "Half", Qt::CaseInsensitive ) == 0 ) |
|
| 498 |
{
|
|
| 499 |
yPos -= labelY * descentRatio; |
|
| 500 |
yPos -= labelY * 0.5 * ( 1 - descentRatio ); |
|
| 501 |
} |
|
| 502 |
} |
|
| 503 |
} |
|
| 504 |
} |
|
| 505 |
} |
|
| 506 |
} |
|
| 507 | ||
| 433 | 508 |
QgsPalGeometry* lbl = new QgsPalGeometry( f.id(), labelText, GEOSGeom_clone( geos_geom ) ); |
| 434 | 509 | |
| 435 | 510 |
// record the created geometry - it will be deleted at the end. |
| ... | ... | |
| 438 | 513 |
// register feature to the layer |
| 439 | 514 |
try |
| 440 | 515 |
{
|
| 441 |
if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData() ) ) |
|
| 516 |
if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData(), xPos, yPos, dataDefinedPosition ) )
|
|
| 442 | 517 |
return; |
| 443 | 518 |
} |
| 444 | 519 |
catch ( std::exception* e ) |
| ... | ... | |
| 871 | 946 |
QString text = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text(); |
| 872 | 947 |
QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) ); |
| 873 | 948 | |
| 949 |
//add the direction symbol if needed |
|
| 950 |
if ( !txt.isEmpty() && lyr.placement == QgsPalLayerSettings::Line && |
|
| 951 |
lyr.addDirectionSymbol && !lyr.multiLineLabels ) |
|
| 952 |
{
|
|
| 953 |
if ( label->getReversed() ) |
|
| 954 |
{
|
|
| 955 |
txt.prepend( "<" ); |
|
| 956 |
} |
|
| 957 |
else |
|
| 958 |
{
|
|
| 959 |
txt.append( ">" ); |
|
| 960 |
} |
|
| 961 |
} |
|
| 962 | ||
| 874 | 963 |
//QgsDebugMsg( "drawLabel " + QString::number( drawBuffer ) + " " + txt ); |
| 875 | 964 | |
| 876 | 965 |
QStringList multiLineList; |
| src/core/pal/feature.h (Arbeitskopie) | ||
|---|---|---|
| 86 | 86 | |
| 87 | 87 |
void setLabelInfo( LabelInfo* info ) { labelInfo = info; }
|
| 88 | 88 |
void setDistLabel( double dist ) { distlabel = dist; }
|
| 89 |
//Set label position of the feature to fixed x/y values |
|
| 90 |
void setFixedPosition( double x, double y ) { fixedPos = true; fixedPosX = x; fixedPosY = y;}
|
|
| 91 |
bool fixedPosition() const { return fixedPos; }
|
|
| 89 | 92 | |
| 90 | 93 |
protected: |
| 91 | 94 |
Layer *layer; |
| ... | ... | |
| 97 | 100 | |
| 98 | 101 |
char *uid; |
| 99 | 102 | |
| 103 |
bool fixedPos; //true in case of fixed position (only 1 candidate position with cost 0) |
|
| 104 |
double fixedPosX; |
|
| 105 |
double fixedPosY; |
|
| 106 | ||
| 100 | 107 |
// array of parts - possibly not necessary |
| 101 | 108 |
//int nPart; |
| 102 | 109 |
//FeaturePart** parts; |
| src/core/pal/labelposition.cpp (Arbeitskopie) | ||
|---|---|---|
| 54 | 54 | |
| 55 | 55 |
namespace pal |
| 56 | 56 |
{
|
| 57 |
LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature ) |
|
| 58 |
: id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 ) |
|
| 57 |
LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed )
|
|
| 58 |
: id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 ), reversed( isReversed )
|
|
| 59 | 59 |
{
|
| 60 | 60 | |
| 61 | 61 |
// alpha take his value bw 0 and 2*pi rad |
| src/core/pal/labelposition.h (Arbeitskopie) | ||
|---|---|---|
| 74 | 74 |
LabelPosition* nextPart; |
| 75 | 75 |
int partId; |
| 76 | 76 | |
| 77 |
//True if label direction is the same as line / polygon ring direction. |
|
| 78 |
//Could be used by the application to draw a directional arrow ('<' or '>')
|
|
| 79 |
//if the layer arrangement is P_LINE |
|
| 80 |
bool reversed; |
|
| 81 | ||
| 77 | 82 |
bool isInConflictSinglePart( LabelPosition* lp ); |
| 78 | 83 |
bool isInConflictMultiPart( LabelPosition* lp ); |
| 79 | 84 | |
| ... | ... | |
| 93 | 98 |
LabelPosition( int id, double x1, double y1, |
| 94 | 99 |
double w, double h, |
| 95 | 100 |
double alpha, double cost, |
| 96 |
FeaturePart *feature ); |
|
| 101 |
FeaturePart *feature, bool isReversed = false );
|
|
| 97 | 102 | |
| 98 | 103 |
/** copy constructor */ |
| 99 | 104 |
LabelPosition( const LabelPosition& other ); |
| ... | ... | |
| 190 | 195 |
* \return alpha to rotate text (in rad) |
| 191 | 196 |
*/ |
| 192 | 197 |
double getAlpha() const; |
| 198 |
bool getReversed() const { return reversed; }
|
|
| 193 | 199 | |
| 194 | 200 |
void print(); |
| 195 | 201 | |
| src/core/pal/layer.cpp (Arbeitskopie) | ||
|---|---|---|
| 226 | 226 | |
| 227 | 227 | |
| 228 | 228 | |
| 229 |
bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText ) |
|
| 229 |
bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText, |
|
| 230 |
double labelPosX, double labelPosY, bool fixedPos ) |
|
| 230 | 231 |
{
|
| 231 | 232 |
if ( !geom_id || label_x < 0 || label_y < 0 ) |
| 232 | 233 |
return false; |
| ... | ... | |
| 243 | 244 |
GEOSGeometry *the_geom = userGeom->getGeosGeometry(); |
| 244 | 245 | |
| 245 | 246 |
Feature* f = new Feature( this, geom_id, userGeom, label_x, label_y ); |
| 247 |
if ( fixedPos ) |
|
| 248 |
{
|
|
| 249 |
f->setFixedPosition( labelPosX, labelPosY ); |
|
| 250 |
} |
|
| 246 | 251 | |
| 247 | 252 |
bool first_feat = true; |
| 248 | 253 | |
| ... | ... | |
| 314 | 319 |
modMutex->unlock(); |
| 315 | 320 | |
| 316 | 321 |
// if using only biggest parts... |
| 317 |
if ( mode == LabelPerFeature && biggest_part != NULL )
|
|
| 322 |
if (( mode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL )
|
|
| 318 | 323 |
{
|
| 319 | 324 |
addFeaturePart( biggest_part, labelText ); |
| 320 | 325 |
first_feat = false; |
| src/core/pal/layer.h (Arbeitskopie) | ||
|---|---|---|
| 283 | 283 |
* @param label_x label width |
| 284 | 284 |
* @param label_y label height |
| 285 | 285 |
* @param userGeom user's geometry that implements the PalGeometry interface |
| 286 |
* @param labelPosX x position of the label (in case of fixed label position) |
|
| 287 |
* @param labelPosY y position of the label (in case of fixed label position) |
|
| 288 |
* @param fixedPos true if a single fixed position for this label is needed |
|
| 286 | 289 |
* |
| 287 | 290 |
* @throws PalException::FeatureExists |
| 288 | 291 |
* |
| 289 | 292 |
* @return true on success (i.e. valid geometry) |
| 290 | 293 |
*/ |
| 291 |
bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1, const char* labelText = NULL ); |
|
| 294 |
bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1, |
|
| 295 |
const char* labelText = NULL, double labelPosX = 0.0, double labelPosY = 0.0, bool fixedPos = false ); |
|
| 292 | 296 | |
| 293 | 297 |
/** return pointer to feature or NULL if doesn't exist */ |
| 294 | 298 |
Feature* getFeature( const char* geom_id ); |
| src/core/pal/feature.cpp (Arbeitskopie) | ||
|---|---|---|
| 61 | 61 |
namespace pal |
| 62 | 62 |
{
|
| 63 | 63 |
Feature::Feature( Layer* l, const char* geom_id, PalGeometry* userG, double lx, double ly ) |
| 64 |
: layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL ) |
|
| 64 |
: layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL ), fixedPos( false )
|
|
| 65 | 65 |
{
|
| 66 | 66 |
uid = new char[strlen( geom_id ) +1]; |
| 67 | 67 |
strcpy( uid, geom_id ); |
| ... | ... | |
| 599 | 599 |
reversed = ( alpha >= M_PI / 2 || alpha < -M_PI / 2 ); |
| 600 | 600 | |
| 601 | 601 |
if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) ) |
| 602 |
positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this ) ); // Line |
|
| 602 |
positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this, reversed ) ); // Line
|
|
| 603 | 603 |
if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) ) |
| 604 |
positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this ) ); // Line |
|
| 604 |
positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this, reversed ) ); // Line
|
|
| 605 | 605 |
if ( flags & FLAG_ON_LINE ) |
| 606 |
positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this ) ); // Line |
|
| 606 |
positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this, reversed ) ); // Line
|
|
| 607 | 607 |
} |
| 608 | 608 |
else if ( f->layer->arrangement == P_HORIZ ) |
| 609 | 609 |
{
|
| ... | ... | |
| 1245 | 1245 | |
| 1246 | 1246 |
double delta = bbox_max[0] - bbox_min[0]; |
| 1247 | 1247 | |
| 1248 |
switch ( type )
|
|
| 1248 |
if ( f->fixedPosition() )
|
|
| 1249 | 1249 |
{
|
| 1250 |
case GEOS_POINT: |
|
| 1251 |
if ( f->layer->getArrangement() == P_POINT_OVER ) |
|
| 1252 |
nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta ); |
|
| 1253 |
else |
|
| 1254 |
nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta ); |
|
| 1255 |
break; |
|
| 1256 |
case GEOS_LINESTRING: |
|
| 1257 |
if ( f->layer->getArrangement() == P_CURVED ) |
|
| 1258 |
nbp = setPositionForLineCurved( lPos, mapShape ); |
|
| 1259 |
else |
|
| 1260 |
nbp = setPositionForLine( scale, lPos, mapShape, delta ); |
|
| 1261 |
break; |
|
| 1250 |
nbp = 1; |
|
| 1251 |
*lPos = new LabelPosition *[nbp]; |
|
| 1252 |
( *lPos )[0] = new LabelPosition( 0, f->fixedPosX, f->fixedPosY, f->label_x, f->label_y, 0, 0.0, this ); |
|
| 1253 |
} |
|
| 1254 |
else |
|
| 1255 |
{
|
|
| 1256 |
switch ( type ) |
|
| 1257 |
{
|
|
| 1258 |
case GEOS_POINT: |
|
| 1259 |
if ( f->layer->getArrangement() == P_POINT_OVER ) |
|
| 1260 |
nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta ); |
|
| 1261 |
else |
|
| 1262 |
nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta ); |
|
| 1263 |
break; |
|
| 1264 |
case GEOS_LINESTRING: |
|
| 1265 |
if ( f->layer->getArrangement() == P_CURVED ) |
|
| 1266 |
nbp = setPositionForLineCurved( lPos, mapShape ); |
|
| 1267 |
else |
|
| 1268 |
nbp = setPositionForLine( scale, lPos, mapShape, delta ); |
|
| 1269 |
break; |
|
| 1262 | 1270 | |
| 1263 |
case GEOS_POLYGON: |
|
| 1264 |
switch ( f->layer->getArrangement() ) |
|
| 1265 |
{
|
|
| 1266 |
case P_POINT: |
|
| 1267 |
case P_POINT_OVER: |
|
| 1268 |
double cx, cy; |
|
| 1269 |
mapShape->getCentroid( cx, cy ); |
|
| 1270 |
if ( f->layer->getArrangement() == P_POINT_OVER ) |
|
| 1271 |
nbp = setPositionOverPoint( cx, cy, scale, lPos, delta ); |
|
| 1272 |
else |
|
| 1273 |
nbp = setPositionForPoint( cx, cy, scale, lPos, delta ); |
|
| 1274 |
break; |
|
| 1275 |
case P_LINE: |
|
| 1276 |
nbp = setPositionForLine( scale, lPos, mapShape, delta ); |
|
| 1277 |
break; |
|
| 1278 |
default: |
|
| 1279 |
nbp = setPositionForPolygon( scale, lPos, mapShape, delta ); |
|
| 1280 |
break; |
|
| 1281 |
} |
|
| 1271 |
case GEOS_POLYGON: |
|
| 1272 |
switch ( f->layer->getArrangement() ) |
|
| 1273 |
{
|
|
| 1274 |
case P_POINT: |
|
| 1275 |
case P_POINT_OVER: |
|
| 1276 |
double cx, cy; |
|
| 1277 |
mapShape->getCentroid( cx, cy ); |
|
| 1278 |
if ( f->layer->getArrangement() == P_POINT_OVER ) |
|
| 1279 |
nbp = setPositionOverPoint( cx, cy, scale, lPos, delta ); |
|
| 1280 |
else |
|
| 1281 |
nbp = setPositionForPoint( cx, cy, scale, lPos, delta ); |
|
| 1282 |
break; |
|
| 1283 |
case P_LINE: |
|
| 1284 |
nbp = setPositionForLine( scale, lPos, mapShape, delta ); |
|
| 1285 |
break; |
|
| 1286 |
default: |
|
| 1287 |
nbp = setPositionForPolygon( scale, lPos, mapShape, delta ); |
|
| 1288 |
break; |
|
| 1289 |
} |
|
| 1290 |
} |
|
| 1282 | 1291 |
} |
| 1283 | 1292 | |
| 1284 | 1293 |
int rnbp = nbp; |
| src/core/qgspallabeling.h (Arbeitskopie) | ||
|---|---|---|
| 83 | 83 |
Family, |
| 84 | 84 |
BufferSize, |
| 85 | 85 |
BufferColor, |
| 86 |
PositionX, //x-coordinate data defined label position |
|
| 87 |
PositionY, //y-coordinate data defined label position |
|
| 88 |
Hali, //horizontal alignment for data defined label position (Left, Center, Right) |
|
| 89 |
Vali //vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top) |
|
| 86 | 90 |
}; |
| 87 | 91 | |
| 88 | 92 |
QString fieldName; |
| ... | ... | |
| 103 | 107 |
bool mergeLines; |
| 104 | 108 |
bool multiLineLabels; //draw labels on multiple lines if they contain '\n' |
| 105 | 109 |
double minFeatureSize; // minimum feature size to be labelled (in mm) |
| 110 |
// Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring |
|
| 111 |
// Works only if Placement == Line |
|
| 112 |
bool addDirectionSymbol; |
|
| 106 | 113 | |
| 107 | 114 |
// called from register feature hook |
| 108 | 115 |
void calculateLabelSize( const QFontMetrics* fm, QString text, double& labelX, double& labelY ); |
| src/ui/qgslabelingguibase.ui (Arbeitskopie) | ||
|---|---|---|
| 678 | 678 |
</property> |
| 679 | 679 |
</widget> |
| 680 | 680 |
</item> |
| 681 |
<item row="7" column="0">
|
|
| 681 |
<item row="8" column="0">
|
|
| 682 | 682 |
<layout class="QHBoxLayout" name="horizontalLayout_19"> |
| 683 | 683 |
<item> |
| 684 | 684 |
<widget class="QLabel" name="label_19"> |
| ... | ... | |
| 696 | 696 |
</item> |
| 697 | 697 |
</layout> |
| 698 | 698 |
</item> |
| 699 |
<item row="8" column="0">
|
|
| 699 |
<item row="9" column="0">
|
|
| 700 | 700 |
<layout class="QHBoxLayout" name="horizontalLayout_20"> |
| 701 | 701 |
<item> |
| 702 | 702 |
<widget class="QCheckBox" name="chkNoObstacle"> |
| ... | ... | |
| 733 | 733 |
</item> |
| 734 | 734 |
</layout> |
| 735 | 735 |
</item> |
| 736 |
<item row="7" column="0"> |
|
| 737 |
<widget class="QCheckBox" name="chkAddDirectionSymbol"> |
|
| 738 |
<property name="text"> |
|
| 739 |
<string>add direction symbol</string> |
|
| 740 |
</property> |
|
| 741 |
</widget> |
|
| 742 |
</item> |
|
| 736 | 743 |
</layout> |
| 737 | 744 |
</widget> |
| 738 | 745 |
<widget class="QWidget" name="tab_4"> |
| 739 | 746 |
<attribute name="title"> |
| 740 | 747 |
<string>Data defined settings</string> |
| 741 | 748 |
</attribute> |
| 742 |
<layout class="QGridLayout" name="gridLayout_4">
|
|
| 749 |
<layout class="QGridLayout" name="gridLayout_3">
|
|
| 743 | 750 |
<item row="0" column="0"> |
| 744 | 751 |
<widget class="QGroupBox" name="mFontAttributePropertiesGroupBox"> |
| 745 | 752 |
<property name="sizePolicy"> |
| ... | ... | |
| 753 | 760 |
</property> |
| 754 | 761 |
<layout class="QGridLayout" name="gridLayout"> |
| 755 | 762 |
<item row="0" column="0"> |
| 756 |
<layout class="QGridLayout" name="gridLayout_11"> |
|
| 757 |
<item row="0" column="0"> |
|
| 758 |
<widget class="QLabel" name="mSizeLabel"> |
|
| 759 |
<property name="text"> |
|
| 760 |
<string>Size</string> |
|
| 761 |
</property> |
|
| 762 |
</widget> |
|
| 763 |
</item> |
|
| 764 |
<item row="0" column="1"> |
|
| 765 |
<widget class="QComboBox" name="mSizeAttributeComboBox"/> |
|
| 766 |
</item> |
|
| 767 |
<item row="2" column="0"> |
|
| 768 |
<widget class="QLabel" name="mBoldLabel"> |
|
| 769 |
<property name="text"> |
|
| 770 |
<string>Bold</string> |
|
| 771 |
</property> |
|
| 772 |
</widget> |
|
| 773 |
</item> |
|
| 774 |
<item row="2" column="1"> |
|
| 775 |
<widget class="QComboBox" name="mBoldAttributeComboBox"/> |
|
| 776 |
</item> |
|
| 777 |
<item row="1" column="1"> |
|
| 778 |
<widget class="QComboBox" name="mColorAttributeComboBox"/> |
|
| 779 |
</item> |
|
| 780 |
<item row="1" column="0"> |
|
| 781 |
<widget class="QLabel" name="mColorLabel"> |
|
| 782 |
<property name="text"> |
|
| 783 |
<string>Color</string> |
|
| 784 |
</property> |
|
| 785 |
</widget> |
|
| 786 |
</item> |
|
| 787 |
<item row="3" column="1"> |
|
| 788 |
<widget class="QComboBox" name="mItalicAttributeComboBox"/> |
|
| 789 |
</item> |
|
| 790 |
<item row="3" column="0"> |
|
| 791 |
<widget class="QLabel" name="mItalicLabel"> |
|
| 792 |
<property name="text"> |
|
| 793 |
<string>Italic</string> |
|
| 794 |
</property> |
|
| 795 |
</widget> |
|
| 796 |
</item> |
|
| 797 |
<item row="4" column="1"> |
|
| 798 |
<widget class="QComboBox" name="mUnderlineAttributeComboBox"/> |
|
| 799 |
</item> |
|
| 800 |
<item row="4" column="0"> |
|
| 801 |
<widget class="QLabel" name="mUnderlineLabel"> |
|
| 802 |
<property name="text"> |
|
| 803 |
<string>Underline</string> |
|
| 804 |
</property> |
|
| 805 |
</widget> |
|
| 806 |
</item> |
|
| 807 |
<item row="6" column="1"> |
|
| 808 |
<widget class="QComboBox" name="mFontFamilyAttributeComboBox"/> |
|
| 809 |
</item> |
|
| 810 |
<item row="6" column="0"> |
|
| 811 |
<widget class="QLabel" name="mFontFamilyLabel"> |
|
| 812 |
<property name="text"> |
|
| 813 |
<string>Font family</string> |
|
| 814 |
</property> |
|
| 815 |
</widget> |
|
| 816 |
</item> |
|
| 817 |
<item row="5" column="1"> |
|
| 818 |
<widget class="QComboBox" name="mStrikeoutAttributeComboBox"/> |
|
| 819 |
</item> |
|
| 820 |
<item row="5" column="0"> |
|
| 821 |
<widget class="QLabel" name="mStrikeoutLabel"> |
|
| 822 |
<property name="text"> |
|
| 823 |
<string>Strikeout</string> |
|
| 824 |
</property> |
|
| 825 |
</widget> |
|
| 826 |
</item> |
|
| 827 |
</layout> |
|
| 763 |
<widget class="QLabel" name="mSizeLabel"> |
|
| 764 |
<property name="text"> |
|
| 765 |
<string>Size</string> |
|
| 766 |
</property> |
|
| 767 |
</widget> |
|
| 828 | 768 |
</item> |
| 769 |
<item row="0" column="1"> |
|
| 770 |
<widget class="QComboBox" name="mSizeAttributeComboBox"/> |
|
| 771 |
</item> |
|
| 772 |
<item row="1" column="0"> |
|
| 773 |
<widget class="QLabel" name="mColorLabel"> |
|
| 774 |
<property name="text"> |
|
| 775 |
<string>Color</string> |
|
| 776 |
</property> |
|
| 777 |
</widget> |
|
| 778 |
</item> |
|
| 779 |
<item row="1" column="1"> |
|
| 780 |
<widget class="QComboBox" name="mColorAttributeComboBox"/> |
|
| 781 |
</item> |
|
| 782 |
<item row="2" column="0"> |
|
| 783 |
<widget class="QLabel" name="mBoldLabel"> |
|
| 784 |
<property name="text"> |
|
| 785 |
<string>Bold</string> |
|
| 786 |
</property> |
|
| 787 |
</widget> |
|
| 788 |
</item> |
|
| 789 |
<item row="2" column="1"> |
|
| 790 |
<widget class="QComboBox" name="mBoldAttributeComboBox"/> |
|
| 791 |
</item> |
|
| 792 |
<item row="3" column="0"> |
|
| 793 |
<widget class="QLabel" name="mItalicLabel"> |
|
| 794 |
<property name="text"> |
|
| 795 |
<string>Italic</string> |
|
| 796 |
</property> |
|
| 797 |
</widget> |
|
| 798 |
</item> |
|
| 799 |
<item row="3" column="1"> |
|
| 800 |
<widget class="QComboBox" name="mItalicAttributeComboBox"/> |
|
| 801 |
</item> |
|
| 802 |
<item row="4" column="0"> |
|
| 803 |
<widget class="QLabel" name="mUnderlineLabel"> |
|
| 804 |
<property name="text"> |
|
| 805 |
<string>Underline</string> |
|
| 806 |
</property> |
|
| 807 |
</widget> |
|
| 808 |
</item> |
|
| 809 |
<item row="4" column="1"> |
|
| 810 |
<widget class="QComboBox" name="mUnderlineAttributeComboBox"/> |
|
| 811 |
</item> |
|
| 812 |
<item row="5" column="0"> |
|
| 813 |
<widget class="QLabel" name="mStrikeoutLabel"> |
|
| 814 |
<property name="text"> |
|
| 815 |
<string>Strikeout</string> |
|
| 816 |
</property> |
|
| 817 |
</widget> |
|
| 818 |
</item> |
|
| 819 |
<item row="5" column="1"> |
|
| 820 |
<widget class="QComboBox" name="mStrikeoutAttributeComboBox"/> |
|
| 821 |
</item> |
|
| 822 |
<item row="6" column="0"> |
|
| 823 |
<widget class="QLabel" name="mFontFamilyLabel"> |
|
| 824 |
<property name="text"> |
|
| 825 |
<string>Font family</string> |
|
| 826 |
</property> |
|
| 827 |
</widget> |
|
| 828 |
</item> |
|
| 829 |
<item row="6" column="1"> |
|
| 830 |
<widget class="QComboBox" name="mFontFamilyAttributeComboBox"/> |
|
| 831 |
</item> |
|
| 829 | 832 |
</layout> |
| 830 | 833 |
</widget> |
| 831 | 834 |
</item> |
| ... | ... | |
| 834 | 837 |
<property name="title"> |
| 835 | 838 |
<string>Buffer properties</string> |
| 836 | 839 |
</property> |
| 837 |
<layout class="QGridLayout" name="gridLayout_3">
|
|
| 840 |
<layout class="QGridLayout" name="gridLayout_2">
|
|
| 838 | 841 |
<item row="0" column="0"> |
| 839 |
<layout class="QGridLayout" name="gridLayout_2"> |
|
| 840 |
<item row="0" column="0"> |
|
| 841 |
<widget class="QLabel" name="mBufferSizeLabel"> |
|
| 842 |
<property name="text"> |
|
| 843 |
<string>Buffer size</string> |
|
| 844 |
</property> |
|
| 845 |
</widget> |
|
| 846 |
</item> |
|
| 847 |
<item row="0" column="1"> |
|
| 848 |
<widget class="QComboBox" name="mBufferSizeAttributeComboBox"/> |
|
| 849 |
</item> |
|
| 850 |
<item row="1" column="0"> |
|
| 851 |
<widget class="QLabel" name="mBufferColorLabel"> |
|
| 852 |
<property name="text"> |
|
| 853 |
<string>Buffer color</string> |
|
| 854 |
</property> |
|
| 855 |
</widget> |
|
| 856 |
</item> |
|
| 857 |
<item row="1" column="1"> |
|
| 858 |
<widget class="QComboBox" name="mBufferColorAttributeComboBox"/> |
|
| 859 |
</item> |
|
| 860 |
</layout> |
|
| 842 |
<widget class="QLabel" name="mBufferSizeLabel"> |
|
| 843 |
<property name="text"> |
|
| 844 |
<string>Buffer size</string> |
|
| 845 |
</property> |
|
| 846 |
</widget> |
|
| 861 | 847 |
</item> |
| 848 |
<item row="0" column="1"> |
|
| 849 |
<widget class="QComboBox" name="mBufferSizeAttributeComboBox"/> |
|
| 850 |
</item> |
|
| 851 |
<item row="1" column="0"> |
|
| 852 |
<widget class="QLabel" name="mBufferColorLabel"> |
|
| 853 |
<property name="text"> |
|
| 854 |
<string>Buffer color</string> |
|
| 855 |
</property> |
|
| 856 |
</widget> |
|
| 857 |
</item> |
|
| 858 |
<item row="1" column="1"> |
|
| 859 |
<widget class="QComboBox" name="mBufferColorAttributeComboBox"/> |
|
| 860 |
</item> |
|
| 862 | 861 |
</layout> |
| 863 | 862 |
</widget> |
| 864 | 863 |
</item> |
| 865 | 864 |
<item row="2" column="0"> |
| 865 |
<widget class="QGroupBox" name="mPositionAttributeGroupBox"> |
|
| 866 |
<property name="title"> |
|
| 867 |
<string>Position</string> |
|
| 868 |
</property> |
|
| 869 |
<layout class="QGridLayout" name="gridLayout_4"> |
|
| 870 |
<item row="0" column="0"> |
|
| 871 |
<widget class="QLabel" name="mXCoordinateLabel"> |
|
| 872 |
<property name="text"> |
|
| 873 |
<string>X Coordinate</string> |
|
| 874 |
</property> |
|
| 875 |
</widget> |
|
| 876 |
</item> |
|
| 877 |
<item row="0" column="1"> |
|
| 878 |
<widget class="QComboBox" name="mXCoordinateComboBox"/> |
|
| 879 |
</item> |
|
| 880 |
<item row="1" column="0"> |
|
| 881 |
<widget class="QLabel" name="mYCoordinateLabel"> |
|
| 882 |
<property name="text"> |
|
| 883 |
<string>Y Coordinate</string> |
|
| 884 |
</property> |
|
| 885 |
</widget> |
|
| 886 |
</item> |
|
| 887 |
<item row="1" column="1"> |
|
| 888 |
<widget class="QComboBox" name="mYCoordinateComboBox"/> |
|
| 889 |
</item> |
|
| 890 |
<item row="2" column="0"> |
|
| 891 |
<widget class="QLabel" name="mHorizontalAlignmentLabel"> |
|
| 892 |
<property name="text"> |
|
| 893 |
<string>Horizontal alignment</string> |
|
| 894 |
</property> |
|
| 895 |
</widget> |
|
| 896 |
</item> |
|
| 897 |
<item row="2" column="1"> |
|
| 898 |
<widget class="QComboBox" name="mHorizontalAlignmentComboBox"/> |
|
| 899 |
</item> |
|
| 900 |
<item row="3" column="0"> |
|
| 901 |
<widget class="QLabel" name="mVerticalAlignmentLabel"> |
|
| 902 |
<property name="text"> |
|
| 903 |
<string>Vertical alignment</string> |
|
| 904 |
</property> |
|
| 905 |
</widget> |
|
| 906 |
</item> |
|
| 907 |
<item row="3" column="1"> |
|
| 908 |
<widget class="QComboBox" name="mVerticalAlignmentComboBox"/> |
|
| 909 |
</item> |
|
| 910 |
</layout> |
|
| 911 |
</widget> |
|
| 912 |
</item> |
|
| 913 |
<item row="3" column="0"> |
|
| 866 | 914 |
<spacer name="verticalSpacer"> |
| 867 | 915 |
<property name="orientation"> |
| 868 | 916 |
<enum>Qt::Vertical</enum> |