24 #include <pal/feature.h>
25 #include <pal/layer.h>
26 #include <pal/palgeometry.h>
27 #include <pal/palexception.h>
28 #include <pal/problem.h>
29 #include <pal/labelposition.h>
35 #include <QApplication>
38 #include <QFontMetrics>
42 #include "diagram/qgsdiagram.h"
59 #include <QMessageBox>
68 qreal ltrSpacing = 0.0, qreal wordSpacing = 0.0,
bool curvedLabeling =
false )
75 , mFontMetrics( NULL )
76 , mLetterSpacing( ltrSpacing )
77 , mWordSpacing( wordSpacing )
78 , mCurvedLabeling( curvedLabeling )
81 mDefinedFont = QFont();
87 GEOSGeom_destroy( mG );
94 const GEOSGeometry* getGeosGeometry()
98 void releaseGeosGeometry(
const GEOSGeometry* )
103 const char* strId() {
return mStrId.data(); }
104 QString text() {
return mText; }
106 pal::LabelInfo* info( QFontMetricsF* fm,
const QgsMapToPixel* xform,
double fontScale,
double maxinangle,
double maxoutangle )
111 mFontMetrics =
new QFontMetricsF( *fm );
114 if ( maxinangle < 20.0 )
116 if ( 60.0 < maxinangle )
118 if ( maxoutangle > -20.0 )
120 if ( -95.0 > maxoutangle )
131 mInfo =
new pal::LabelInfo( mText.count(), ptSize.
y() - ptZero.
y(), maxinangle, maxoutangle );
132 for (
int i = 0; i < mText.count(); i++ )
134 mInfo->char_info[i].chr = mText[i].unicode();
138 charWidth = fm->width( mText[i] );
139 if ( mCurvedLabeling )
141 wordSpaceFix = qreal( 0.0 );
142 if ( mText[i] == QString(
" " )[0] )
146 wordSpaceFix = ( nxt < mText.count() && mText[nxt] != QString(
" " )[0] ) ? mWordSpacing : qreal( 0.0 );
148 if ( fm->width( QString( mText[i] ) ) - fm->width( mText[i] ) - mLetterSpacing != qreal( 0.0 ) )
151 wordSpaceFix -= mWordSpacing;
153 charWidth = fm->width( QString( mText[i] ) ) + wordSpaceFix;
157 mInfo->char_info[i].width = ptSize.
x() - ptZero.
x();
162 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& dataDefinedValues()
const {
return mDataDefinedValues; }
165 void setIsDiagram(
bool d ) { mIsDiagram = d; }
166 bool isDiagram()
const {
return mIsDiagram; }
168 void setIsPinned(
bool f ) { mIsPinned = f; }
169 bool isPinned()
const {
return mIsPinned; }
171 void setDefinedFont( QFont f ) { mDefinedFont = QFont( f ); }
172 QFont definedFont() {
return mDefinedFont; }
174 QFontMetricsF* getLabelFontMetrics() {
return mFontMetrics; }
176 void setDiagramAttributes(
const QgsAttributes& attrs,
const QgsFields* fields ) { mDiagramAttributes = attrs; mDiagramFields = fields; }
177 const QgsAttributes& diagramAttributes() {
return mDiagramAttributes; }
182 feature.
setFields( mDiagramFields,
false );
196 QFontMetricsF* mFontMetrics;
197 qreal mLetterSpacing;
199 bool mCurvedLabeling;
201 QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > mDataDefinedValues;
217 , mFeaturesToLabel( 0 )
218 , mFeatsSendingToPal( 0 )
230 blendMode = QPainter::CompositionMode_SourceOver;
588 int r = layer->
customProperty( property +
"R", QVariant( defaultColor.red() ) ).toInt();
589 int g = layer->
customProperty( property +
"G", QVariant( defaultColor.green() ) ).toInt();
590 int b = layer->
customProperty( property +
"B", QVariant( defaultColor.blue() ) ).toInt();
591 int a = withAlpha ? layer->
customProperty( property +
"A", QVariant( defaultColor.alpha() ) ).toInt() : 255;
592 return QColor( r, g, b, a );
606 if ( str.compare(
"Point", Qt::CaseInsensitive ) == 0
608 if ( str.compare(
"MapUnit", Qt::CaseInsensitive ) == 0
616 if ( str.compare(
"Lighten", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
617 if ( str.compare(
"Screen", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
618 if ( str.compare(
"Dodge", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
619 if ( str.compare(
"Addition", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
620 if ( str.compare(
"Darken", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
621 if ( str.compare(
"Multiply", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
622 if ( str.compare(
"Burn", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
623 if ( str.compare(
"Overlay", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
624 if ( str.compare(
"SoftLight", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
625 if ( str.compare(
"HardLight", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
626 if ( str.compare(
"Difference", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
627 if ( str.compare(
"Subtract", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
628 return QPainter::CompositionMode_SourceOver;
633 if ( str.compare(
"Miter", Qt::CaseInsensitive ) == 0 )
return Qt::MiterJoin;
634 if ( str.compare(
"Round", Qt::CaseInsensitive ) == 0 )
return Qt::RoundJoin;
635 return Qt::BevelJoin;
639 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
646 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i(
mDataDefinedNames );
647 while ( i.hasNext() )
655 const QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
662 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i(
mDataDefinedNames );
663 while ( i.hasNext() )
666 QString newPropertyName =
"labeling/dataDefined/" + i.value().first;
667 QVariant propertyValue = QVariant();
669 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it = propertyMap.find( i.key() );
670 if ( it != propertyMap.constEnd() )
678 QString field = dd->
field();
680 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
686 values << ( active ?
"1" :
"0" );
687 values << ( useExpr ?
"1" :
"0" );
690 if ( !values.isEmpty() )
692 propertyValue = QVariant( values.join(
"~~" ) );
698 if ( propertyValue.isValid() )
708 if ( layer->
customProperty( newPropertyName, QVariant() ).isValid() && i.value().second > -1 )
711 layer->
removeCustomProperty( QString(
"labeling/dataDefinedProperty" ) + QString::number( i.value().second ) );
718 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
720 QString newPropertyName =
"labeling/dataDefined/" +
mDataDefinedNames.value( p ).first;
721 QVariant newPropertyField = layer->
customProperty( newPropertyName, QVariant() );
723 QString ddString = QString();
724 if ( newPropertyField.isValid() )
726 ddString = newPropertyField.toString();
737 QString oldPropertyName =
"labeling/dataDefinedProperty" + QString::number( oldIndx );
738 QVariant oldPropertyField = layer->
customProperty( oldPropertyName, QVariant() );
740 if ( !oldPropertyField.isValid() )
747 int indx = oldPropertyField.toInt( &conversionOk );
757 if ( !oldIndicesToNames.isEmpty() )
759 ddString = oldIndicesToNames.value( indx );
764 if ( indx < fields.
size() )
766 ddString = fields.
at( indx ).
name();
771 if ( !ddString.isEmpty() )
784 if ( oldIndx == 16 || oldIndx == 17 )
795 if ( !ddString.isEmpty() && ddString != QString(
"0~~0~~~~" ) )
799 QStringList ddv = newStyleString.split(
"~~" );
802 propertyMap.insert( p, dd );
813 if ( layer->
customProperty(
"labeling" ).toString() != QString(
"pal" ) )
823 QFont appFont = QApplication::font();
835 fontFamily = appFont.family();
838 double fontSize = layer->
customProperty(
"labeling/fontSize" ).toDouble();
840 int fontWeight = layer->
customProperty(
"labeling/fontWeight" ).toInt();
841 bool fontItalic = layer->
customProperty(
"labeling/fontItalic" ).toBool();
842 textFont = QFont( fontFamily, fontSize, fontWeight, fontItalic );
846 textFont.setCapitalization(( QFont::Capitalization )layer->
customProperty(
"labeling/fontCapitals", QVariant( 0 ) ).toUInt() );
849 textFont.setLetterSpacing( QFont::AbsoluteSpacing, layer->
customProperty(
"labeling/fontLetterSpacing", QVariant( 0.0 ) ).toDouble() );
850 textFont.setWordSpacing( layer->
customProperty(
"labeling/fontWordSpacing", QVariant( 0.0 ) ).toDouble() );
872 double bufSize = layer->
customProperty(
"labeling/bufferSize", QVariant( 0.0 ) ).toDouble();
875 QVariant drawBuffer = layer->
customProperty(
"labeling/bufferDraw", QVariant() );
876 if ( drawBuffer.isValid() )
881 else if ( bufSize != 0.0 )
906 layer->
customProperty(
"labeling/shapeSizeY", QVariant( 0.0 ) ).toDouble() );
911 layer->
customProperty(
"labeling/shapeOffsetY", QVariant( 0.0 ) ).toDouble() );
914 layer->
customProperty(
"labeling/shapeRadiiY", QVariant( 0.0 ) ).toDouble() );
958 int scalemn = layer->
customProperty(
"labeling/scaleMin", QVariant( 0 ) ).toInt();
959 int scalemx = layer->
customProperty(
"labeling/scaleMax", QVariant( 0 ) ).toInt();
962 QVariant scalevis = layer->
customProperty(
"labeling/scaleVisibility", QVariant() );
963 if ( scalevis.isValid() )
969 else if ( scalemn > 0 || scalemx > 0 )
1124 bool active,
bool useExpr,
const QString& expr,
const QString& field )
1126 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
1130 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1140 else if ( !defaultVals )
1152 delete( it.value() );
1160 QString newValue = value;
1161 if ( !value.isEmpty() && !value.contains(
"~~" ) )
1168 newValue = values.join(
"~~" );
1176 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1186 QMap<QString, QString> map;
1187 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1190 return it.value()->toMap();
1203 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1219 QVariant result = QVariant();
1221 QString field = dd->
field();
1240 else if ( !useExpression && !field.isEmpty() )
1259 if ( result.isValid() )
1272 bool isActive =
false;
1273 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1276 isActive = it.value()->isActive();
1284 bool useExpression =
false;
1285 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1288 useExpression = it.value()->useExpression();
1291 return useExpression;
1315 double length = geom->
length();
1316 if ( length >= 0.0 )
1318 return ( length >= ( minSize * mapUnitsPerMM ) );
1323 double area = geom->
area();
1326 return ( sqrt( area ) >= ( minSize * mapUnitsPerMM ) );
1387 if ( exprVal.isValid() )
1389 wrapchr = exprVal.toString();
1393 if ( exprVal.isValid() )
1396 double size = exprVal.toDouble( &ok );
1405 if ( exprVal.isValid() )
1407 addDirSymb = exprVal.toBool();
1414 if ( exprVal.isValid() )
1416 leftDirSymb = exprVal.toString();
1420 if ( exprVal.isValid() )
1422 rightDirSymb = exprVal.toString();
1426 if ( exprVal.isValid() )
1429 int enmint = exprVal.toInt( &ok );
1439 if ( wrapchr.isEmpty() )
1441 wrapchr = QString(
"\n" );
1446 && ( !leftDirSymb.isEmpty() || !rightDirSymb.isEmpty() ) )
1448 QString dirSym = leftDirSymb;
1450 if ( fm->width( rightDirSymb ) > fm->width( dirSym ) )
1451 dirSym = rightDirSymb;
1455 text.append( dirSym );
1459 text.prepend( dirSym + wrapchr );
1463 double w = 0.0, h = 0.0;
1464 QStringList multiLineSplit = text.split( wrapchr );
1465 int lines = multiLineSplit.size();
1467 double labelHeight = fm->ascent() + fm->descent();
1469 h += fm->height() + ( double )(( lines - 1 ) * labelHeight * multilineH );
1472 for (
int i = 0; i < lines; ++i )
1474 double width = fm->width( multiLineSplit.at( i ) );
1483 labelX = qAbs( ptSize.
x() - ptZero.
x() );
1484 labelY = qAbs( ptSize.
y() - ptZero.
y() );
1502 QgsDebugMsgLevel( QString(
"exprVal Show:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1503 if ( !exprVal.toBool() )
1513 QgsDebugMsgLevel( QString(
"exprVal ScaleVisibility:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1514 useScaleVisibility = exprVal.toBool();
1517 if ( useScaleVisibility )
1523 QgsDebugMsgLevel( QString(
"exprVal MinScale:%1" ).arg( exprVal.toDouble() ), 4 );
1525 double mins = exprVal.toDouble( &conversionOk );
1535 minScale = 1 / qAbs( minScale );
1547 QgsDebugMsgLevel( QString(
"exprVal MaxScale:%1" ).arg( exprVal.toDouble() ), 4 );
1549 double maxs = exprVal.toDouble( &conversionOk );
1559 maxScale = 1 / qAbs( maxScale );
1575 QString units = exprVal.toString().trimmed();
1577 if ( !units.isEmpty() )
1584 double fontSize = labelFont.pointSizeF();
1587 QgsDebugMsgLevel( QString(
"exprVal Size:%1" ).arg( exprVal.toDouble() ), 4 );
1589 double size = exprVal.toDouble( &ok );
1595 if ( fontSize <= 0.0 )
1600 int fontPixelSize =
sizeToPixel( fontSize, context, fontunits,
true );
1602 if ( fontPixelSize < 1 )
1606 labelFont.setPixelSize( fontPixelSize );
1616 QgsDebugMsgLevel( QString(
"exprVal FontLimitPixel:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1617 useFontLimitPixelSize = exprVal.toBool();
1620 if ( useFontLimitPixelSize )
1626 int sizeInt = exprVal.toInt( &ok );
1627 QgsDebugMsgLevel( QString(
"exprVal FontMinPixel:%1" ).arg( sizeInt ), 4 );
1630 fontMinPixel = sizeInt;
1638 int sizeInt = exprVal.toInt( &ok );
1639 QgsDebugMsgLevel( QString(
"exprVal FontMaxPixel:%1" ).arg( sizeInt ), 4 );
1642 fontMaxPixel = sizeInt;
1646 if ( fontMinPixel > labelFont.pixelSize() || labelFont.pixelSize() > fontMaxPixel )
1677 QVariant result = exp->
evaluate( &f );
1683 labelText = result.toString();
1694 formatnum = exprVal.toBool();
1695 QgsDebugMsgLevel( QString(
"exprVal NumFormat:%1" ).arg( formatnum ?
"true" :
"false" ), 4 );
1706 int dInt = exprVal.toInt( &ok );
1708 if ( ok && dInt > 0 )
1710 decimalPlaces = dInt;
1718 signPlus = exprVal.toBool();
1719 QgsDebugMsgLevel( QString(
"exprVal NumPlusSign:%1" ).arg( signPlus ?
"true" :
"false" ), 4 );
1722 QVariant textV = QVariant( labelText );
1724 double d = textV.toDouble( &ok );
1727 QString numberFormat;
1728 if ( d > 0 && signPlus )
1730 numberFormat.append(
"+" );
1732 numberFormat.append(
"%1" );
1733 labelText = numberFormat.arg( d, 0,
'f', decimalPlaces );
1739 QFontMetricsF* labelFontMetrics =
new QFontMetricsF( labelFont );
1740 double labelX, labelY;
1746 double maxcharanglein = 20.0;
1747 double maxcharangleout = -20.0;
1757 QString ptstr = exprVal.toString().trimmed();
1758 QgsDebugMsgLevel( QString(
"exprVal CurvedCharAngleInOut:%1" ).arg( ptstr ), 4 );
1760 if ( !ptstr.isEmpty() )
1763 maxcharanglein = qBound( 20.0, (
double )maxcharanglePt.x(), 60.0 );
1764 maxcharangleout = qBound( 20.0, (
double )maxcharanglePt.y(), 95.0 );
1768 maxcharangleout = -( qAbs( maxcharangleout ) );
1786 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception" ).arg( f.
id() ), 4 );
1805 QString str = exprVal.toString().trimmed();
1808 if ( !str.isEmpty() )
1810 if ( str.compare(
"Visible", Qt::CaseInsensitive ) == 0 )
1812 wholeCentroid =
false;
1814 else if ( str.compare(
"Whole", Qt::CaseInsensitive ) == 0 )
1816 wholeCentroid =
true;
1829 bool do_clip =
false;
1830 if ( !centroidPoly || ( centroidPoly && !wholeCentroid ) )
1843 const GEOSGeometry* geos_geom = geom->
asGeos();
1845 if ( geos_geom == NULL )
1874 GEOSGeometry* geos_geom_clone = GEOSGeom_clone( geos_geom );
1877 bool dataDefinedPosition =
false;
1878 bool labelIsPinned =
false;
1879 bool layerDefinedRotation =
false;
1880 bool dataDefinedRotation =
false;
1881 double xPos = 0.0, yPos = 0.0,
angle = 0.0;
1882 bool ddXPos =
false, ddYPos =
false;
1883 double quadOffsetX = 0.0, quadOffsetY = 0.0;
1884 double offsetX = 0.0, offsetY = 0.0;
1891 int quadInt = exprVal.toInt( &ok );
1893 if ( ok && 0 <= quadInt && quadInt <= 8 )
1944 QString ptstr = exprVal.toString().trimmed();
1947 if ( !ptstr.isEmpty() )
1959 QString units = exprVal.toString().trimmed();
1961 if ( !units.isEmpty() )
1973 if ( !offinmapunits )
1975 offsetX *= mapUntsPerMM;
1981 if ( !offinmapunits )
1983 offsetY *= mapUntsPerMM;
1991 layerDefinedRotation =
true;
1999 double rotD = exprVal.toDouble( &ok );
2003 dataDefinedRotation =
true;
2010 xPos = exprVal.toDouble( &ddXPos );
2016 yPos = exprVal.toDouble( &ddYPos );
2019 if ( ddXPos && ddYPos )
2021 dataDefinedPosition =
true;
2022 labelIsPinned =
true;
2024 if ( layerDefinedRotation && !dataDefinedRotation )
2036 QString haliString = exprVal.toString();
2038 if ( haliString.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2040 xdiff -= labelX / 2.0;
2042 else if ( haliString.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2051 QString valiString = exprVal.toString();
2054 if ( valiString.compare(
"Bottom", Qt::CaseInsensitive ) != 0 )
2056 if ( valiString.compare(
"Top", Qt::CaseInsensitive ) == 0 )
2062 double descentRatio = labelFontMetrics->descent() / labelFontMetrics->height();
2063 if ( valiString.compare(
"Base", Qt::CaseInsensitive ) == 0 )
2065 ydiff -= labelY * descentRatio;
2069 double capHeightRatio = ( labelFontMetrics->boundingRect(
'H' ).height() + 1 + labelFontMetrics->descent() ) / labelFontMetrics->height();
2070 ydiff -= labelY * capHeightRatio;
2071 if ( valiString.compare(
"Half", Qt::CaseInsensitive ) == 0 )
2073 ydiff += labelY * ( capHeightRatio - descentRatio ) / 2.0;
2080 if ( dataDefinedRotation )
2083 double xd = xdiff * cos(
angle ) - ydiff * sin(
angle );
2084 double yd = xdiff * sin(
angle ) + ydiff * cos(
angle );
2100 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception on data-defined position" ).arg( f.
id() ), 4 );
2120 bool alwaysShow =
false;
2123 alwaysShow = exprVal.toBool();
2130 labelFont.letterSpacing(),
2131 labelFont.wordSpacing(),
2138 #if QT_VERSION >= 0x040800
2139 QgsDebugMsgLevel( QString(
"PAL font stored definedFont: %1, Style: %2" ).arg( labelFont.toString() ).arg( labelFont.styleName() ), 4 );
2146 if ( !
palLayer->registerFeature( lbl->
strId(), lbl, labelX, labelY, labelText.toUtf8().constData(),
2147 xPos, yPos, dataDefinedPosition,
angle, dataDefinedRotation,
2148 quadOffsetX, quadOffsetY, offsetX, offsetY, alwaysShow ) )
2151 catch ( std::exception &e )
2154 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( f.
id() ) + QString::fromLatin1( e.what() ), 4 );
2162 delete labelFontMetrics;
2167 double distance =
dist;
2171 double distD = exprVal.toDouble( &ok );
2182 QString units = exprVal.toString().trimmed();
2184 if ( !units.isEmpty() )
2190 if ( distance != 0 )
2192 if ( distinmapunit )
2200 feat->setDistLabel( qAbs(
ptOne.
x() - ptZero.
x() )* distance );
2204 QMap< DataDefinedProperties, QVariant >::const_iterator dIt =
dataDefinedValues.constBegin();
2220 QString dbgStr = QString(
"exprVal %1:" ).arg(
mDataDefinedNames.value( p ).first ) +
"%1";
2222 if ( valType == QString(
"bool" ) )
2224 bool bol = exprVal.toBool();
2229 if ( valType == QString(
"int" ) )
2232 int size = exprVal.toInt( &ok );
2241 if ( valType == QString(
"intpos" ) )
2244 int size = exprVal.toInt( &ok );
2247 if ( ok && size > 0 )
2253 if ( valType == QString(
"double" ) )
2256 double size = exprVal.toDouble( &ok );
2265 if ( valType == QString(
"doublepos" ) )
2268 double size = exprVal.toDouble( &ok );
2271 if ( ok && size > 0.0 )
2277 if ( valType == QString(
"rotation180" ) )
2280 double rot = exprVal.toDouble( &ok );
2284 if ( rot < -180.0 && rot >= -360 )
2288 if ( rot > 180.0 && rot <= 360 )
2292 if ( rot >= -180 && rot <= 180 )
2299 if ( valType == QString(
"transp" ) )
2302 int size = exprVal.toInt( &ok );
2304 if ( ok && size >= 0 && size <= 100 )
2310 if ( valType == QString(
"string" ) )
2312 QString str = exprVal.toString();
2318 if ( valType == QString(
"units" ) )
2320 QString unitstr = exprVal.toString().trimmed();
2323 if ( !unitstr.isEmpty() )
2329 if ( valType == QString(
"color" ) )
2331 QString colorstr = exprVal.toString().trimmed();
2335 if ( color.isValid() )
2341 if ( valType == QString(
"joinstyle" ) )
2343 QString joinstr = exprVal.toString().trimmed();
2346 if ( !joinstr.isEmpty() )
2352 if ( valType == QString(
"blendmode" ) )
2354 QString blendstr = exprVal.toString().trimmed();
2357 if ( !blendstr.isEmpty() )
2363 if ( valType == QString(
"pointf" ) )
2365 QString ptstr = exprVal.toString().trimmed();
2368 if ( !ptstr.isEmpty() )
2391 QString ddFontFamily(
"" );
2394 QString family = exprVal.toString().trimmed();
2397 if ( labelFont.family() != family )
2403 ddFontFamily = family;
2409 QString ddFontStyle(
"" );
2412 QString fontstyle = exprVal.toString().trimmed();
2413 QgsDebugMsgLevel( QString(
"exprVal Font style:%1" ).arg( fontstyle ), 4 );
2414 ddFontStyle = fontstyle;
2418 bool ddBold =
false;
2421 bool bold = exprVal.toBool();
2422 QgsDebugMsgLevel( QString(
"exprVal Font bold:%1" ).arg( bold ?
"true" :
"false" ), 4 );
2427 bool ddItalic =
false;
2430 bool italic = exprVal.toBool();
2431 QgsDebugMsgLevel( QString(
"exprVal Font italic:%1" ).arg( italic ?
"true" :
"false" ), 4 );
2438 QFont appFont = QApplication::font();
2439 bool newFontBuilt =
false;
2440 if ( ddBold || ddItalic )
2443 newFont = QFont( !ddFontFamily.isEmpty() ? ddFontFamily : labelFont.family() );
2444 newFontBuilt =
true;
2445 newFont.setBold( ddBold );
2446 newFont.setItalic( ddItalic );
2448 else if ( !ddFontStyle.isEmpty()
2449 && ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2451 if ( !ddFontFamily.isEmpty() )
2454 QFont styledfont =
mFontDB.font( ddFontFamily, ddFontStyle, appFont.pointSize() );
2455 if ( appFont != styledfont )
2457 newFont = styledfont;
2458 newFontBuilt =
true;
2465 else if ( !ddFontFamily.isEmpty() )
2467 if ( ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2471 if ( appFont != styledfont )
2473 newFont = styledfont;
2474 newFontBuilt =
true;
2479 newFont = QFont( ddFontFamily );
2480 newFontBuilt =
true;
2488 newFont.setPixelSize( labelFont.pixelSize() );
2489 newFont.setCapitalization( labelFont.capitalization() );
2490 newFont.setUnderline( labelFont.underline() );
2491 newFont.setStrikeOut( labelFont.strikeOut() );
2492 newFont.setWordSpacing( labelFont.wordSpacing() );
2493 newFont.setLetterSpacing( QFont::AbsoluteSpacing, labelFont.letterSpacing() );
2495 labelFont = newFont;
2499 double wordspace = labelFont.wordSpacing();
2503 double wspacing = exprVal.toDouble( &ok );
2504 QgsDebugMsgLevel( QString(
"exprVal FontWordSpacing:%1" ).arg( wspacing ), 4 );
2507 wordspace = wspacing;
2510 labelFont.setWordSpacing(
sizeToPixel( wordspace, context, fontunits,
false ) );
2513 double letterspace = labelFont.letterSpacing();
2517 double lspacing = exprVal.toDouble( &ok );
2518 QgsDebugMsgLevel( QString(
"exprVal FontLetterSpacing:%1" ).arg( lspacing ), 4 );
2521 letterspace = lspacing;
2524 labelFont.setLetterSpacing( QFont::AbsoluteSpacing,
sizeToPixel( letterspace, context, fontunits,
false ) );
2527 QFont::Capitalization fontcaps = labelFont.capitalization();
2530 QString fcase = exprVal.toString().trimmed();
2533 if ( !fcase.isEmpty() )
2535 if ( fcase.compare(
"NoChange", Qt::CaseInsensitive ) == 0 )
2537 fontcaps = QFont::MixedCase;
2539 else if ( fcase.compare(
"Upper", Qt::CaseInsensitive ) == 0 )
2541 fontcaps = QFont::AllUppercase;
2543 else if ( fcase.compare(
"Lower", Qt::CaseInsensitive ) == 0 )
2545 fontcaps = QFont::AllLowercase;
2547 else if ( fcase.compare(
"Capitalize", Qt::CaseInsensitive ) == 0 )
2549 fontcaps = QFont::Capitalize;
2552 if ( fontcaps != labelFont.capitalization() )
2554 labelFont.setCapitalization( fontcaps );
2562 bool strikeout = exprVal.toBool();
2563 QgsDebugMsgLevel( QString(
"exprVal Font strikeout:%1" ).arg( strikeout ?
"true" :
"false" ), 4 );
2564 labelFont.setStrikeOut( strikeout );
2570 bool underline = exprVal.toBool();
2571 QgsDebugMsgLevel( QString(
"exprVal Font underline:%1" ).arg( underline ?
"true" :
"false" ), 4 );
2572 labelFont.setUnderline( underline );
2596 drawBuffer = exprVal.toBool();
2608 bufrSize = exprVal.toDouble();
2615 bufTransp = exprVal.toInt();
2618 drawBuffer = ( drawBuffer && bufrSize > 0.0 && bufTransp < 100 );
2649 wrapchr = exprVal.toString();
2658 QString str = exprVal.toString().trimmed();
2659 QgsDebugMsgLevel( QString(
"exprVal MultiLineAlignment:%1" ).arg( str ), 4 );
2661 if ( !str.isEmpty() )
2666 if ( str.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2670 else if ( str.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2682 drawDirSymb = exprVal.toBool();
2696 QString str = exprVal.toString().trimmed();
2697 QgsDebugMsgLevel( QString(
"exprVal DirSymbPlacement:%1" ).arg( str ), 4 );
2699 if ( !str.isEmpty() )
2704 if ( str.compare(
"Above", Qt::CaseInsensitive ) == 0 )
2708 else if ( str.compare(
"Below", Qt::CaseInsensitive ) == 0 )
2731 drawShape = exprVal.toBool();
2743 shapeTransp = exprVal.toInt();
2746 drawShape = ( drawShape && shapeTransp < 100 );
2759 QString skind = exprVal.toString().trimmed();
2762 if ( !skind.isEmpty() )
2767 if ( skind.compare(
"Square", Qt::CaseInsensitive ) == 0 )
2771 else if ( skind.compare(
"Ellipse", Qt::CaseInsensitive ) == 0 )
2775 else if ( skind.compare(
"Circle", Qt::CaseInsensitive ) == 0 )
2779 else if ( skind.compare(
"SVG", Qt::CaseInsensitive ) == 0 )
2783 shapeKind = shpkind;
2792 QString svgfile = exprVal.toString().trimmed();
2793 QgsDebugMsgLevel( QString(
"exprVal ShapeSVGFile:%1" ).arg( svgfile ), 4 );
2804 QString stype = exprVal.toString().trimmed();
2807 if ( !stype.isEmpty() )
2812 if ( stype.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
2816 shpSizeType = sizType;
2825 ddShpSizeX = exprVal.toDouble();
2832 ddShpSizeY = exprVal.toDouble();
2838 && ( svgPath.isEmpty()
2839 || ( !svgPath.isEmpty()
2841 && ddShpSizeX == 0.0 ) ) )
2847 && ( ddShpSizeX == 0.0 || ddShpSizeY == 0.0 ) )
2869 QString rotstr = exprVal.toString().trimmed();
2870 QgsDebugMsgLevel( QString(
"exprVal ShapeRotationType:%1" ).arg( rotstr ), 4 );
2872 if ( !rotstr.isEmpty() )
2877 if ( rotstr.compare(
"Offset", Qt::CaseInsensitive ) == 0 )
2881 else if ( rotstr.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
2932 drawShadow = exprVal.toBool();
2944 shadowTransp = exprVal.toInt();
2951 shadowOffDist = exprVal.toDouble();
2958 shadowRad = exprVal.toDouble();
2961 drawShadow = ( drawShadow && shadowTransp < 100 && !( shadowOffDist == 0.0 && shadowRad == 0.0 ) );
2975 QString str = exprVal.toString().trimmed();
2978 if ( !str.isEmpty() )
2983 if ( str.compare(
"Text", Qt::CaseInsensitive ) == 0 )
2987 else if ( str.compare(
"Buffer", Qt::CaseInsensitive ) == 0 )
2991 else if ( str.compare(
"Background", Qt::CaseInsensitive ) == 0 )
3031 if ( unit ==
MapUnits && mapUnitsPerPixel > 0.0 )
3037 double ptsTomm = ( unit ==
Points ? 0.352778 : 1 );
3046 : mMapRenderer( NULL ), mPal( NULL )
3055 switch ( p.getSearch() )
3086 bool enabled =
false;
3087 if ( layer->
customProperty(
"labeling" ).toString() == QString(
"pal" ) )
3088 enabled = layer->
customProperty(
"labeling/enabled", QVariant(
false ) ).toBool();
3095 QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
3108 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::iterator it = lyr.
dataDefinedProperties.begin();
3111 delete( it.value() );
3132 if ( lyrTmp.fieldName.isEmpty() )
3138 if ( lyrTmp.isExpression )
3151 if ( fldIndex == -1 )
3182 if ( fldIndex != -1 )
3184 attrIndices.insert( fldIndex );
3189 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator dIt = lyr.
dataDefinedProperties.constBegin();
3201 QMap<QString, QVariant> exprParams;
3210 foreach ( QString name, cols )
3217 Arrangement arrangement;
3226 default: Q_ASSERT(
"unsupported placement" && 0 );
return 0;
3230 double priority = 1 - lyr.
priority / 10.0;
3231 double min_scale = -1, max_scale = -1;
3240 Layer* l =
mPal->addLayer( layer->
id().toUtf8().data(),
3241 min_scale, max_scale, arrangement,
3242 METER, priority, lyr.
obstacle,
true,
true,
3249 l->setLabelMode( lyr.
labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature );
3255 Layer::UpsideDownLabels upsdnlabels;
3261 default: Q_ASSERT(
"unsupported upside-down label setting" && 0 );
return 0;
3263 l->setUpsidedownLabels( upsdnlabels );
3328 Layer* l =
mPal->addLayer( layer->
id().append(
"d" ).toUtf8().data(), -1, -1, pal::Arrangement( s->
placement ), METER, s->
priority, s->
obstacle,
true, true );
3355 QHash<QgsVectorLayer*, QgsDiagramLayerSettings>::iterator layerIt =
mActiveDiagramLayers.find( layer );
3366 geom->
transform( *( layerIt.value().ct ) );
3369 const GEOSGeometry* geos_geom = geom->
asGeos();
3370 if ( geos_geom == 0 )
3380 layerIt.value().geometries.append( lbl );
3382 double diagramWidth = 0;
3383 double diagramHeight = 0;
3388 if ( diagSize.isValid() )
3390 diagramWidth = diagSize.width();
3391 diagramHeight = diagSize.height();
3399 int ddColX = layerIt.value().xPosColumn;
3400 int ddColY = layerIt.value().yPosColumn;
3401 double ddPosX = 0.0;
3402 double ddPosY = 0.0;
3403 bool ddPos = ( ddColX >= 0 && ddColY >= 0 );
3406 bool posXOk, posYOk;
3408 ddPosX = feat.
attribute( ddColX ).toDouble( &posXOk ) - diagramWidth / 2.0;
3409 ddPosY = feat.
attribute( ddColY ).toDouble( &posYOk ) - diagramHeight / 2.0;
3410 if ( !posXOk || !posYOk )
3427 if ( !layerIt.value().palLayer->registerFeature( lbl->
strId(), lbl, diagramWidth, diagramHeight,
"", ddPosX, ddPosY, ddPos ) )
3432 catch ( std::exception &e )
3435 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( feat.
id() ) + QString::fromLatin1( e.what() ), 4 );
3439 pal::Feature* palFeat = layerIt.value().palLayer->getFeature( lbl->
strId() );
3440 QgsPoint ptZero = layerIt.value().xform->toMapCoordinates( 0, 0 );
3441 QgsPoint ptOne = layerIt.value().xform->toMapCoordinates( 1, 0 );
3442 palFeat->setDistLabel( qAbs( ptOne.
x() - ptZero.
x() ) * layerIt.value().dist );
3460 case Chain: s = CHAIN;
break;
3464 case Falp: s = FALP;
break;
3466 mPal->setSearch( s );
3488 QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
3491 if ( lit.key() && lit.key()->id() == layerName )
3500 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3506 tmpLyr.
textColor = ddColor.value<QColor>();
3525 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3578 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3635 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3746 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3814 QPainter* painter = context.
painter();
3830 std::list<LabelPosition*>* labels;
3831 pal::Problem* problem;
3834 problem =
mPal->extractProblem( scale, bbox );
3836 catch ( std::exception& e )
3839 QgsDebugMsgLevel(
"PAL EXCEPTION :-( " + QString::fromLatin1( e.what() ), 4 );
3852 painter->setPen( QColor( 0, 0, 0, 64 ) );
3853 painter->setBrush( Qt::NoBrush );
3854 for (
int i = 0; i < problem->getNumFeatures(); i++ )
3856 for (
int j = 0; j < problem->getFeatureCandidateCount( i ); j++ )
3858 pal::LabelPosition* lp = problem->getFeatureCandidate( i, j );
3868 QgsDebugMsgLevel( QString(
"LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels->size() ), 4 );
3871 painter->setRenderHint( QPainter::Antialiasing );
3876 localp.begin( &localPict );
3877 double localdpi = ( localp.device()->logicalDpiX() + localp.device()->logicalDpiY() ) / 2;
3878 double contextdpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
3879 double dpiRatio = localdpi / contextdpi;
3883 std::list<LabelPosition*>::iterator it = labels->begin();
3884 for ( ; it != labels->end(); ++it )
3893 QString layerName = QString::fromUtf8(( *it )->getLayerName() );
3901 if ( dit.key() && dit.key()->id().append(
"d" ) == layerName )
3903 palGeometry->
feature( feature );
3905 dit.value().renderer->renderDiagram( feature, context, QPointF( outPt.
x(), outPt.
y() ) );
3913 QString layerId = layerName;
3928 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues = palGeometry->
dataDefinedValues();
3933 #if QT_VERSION >= 0x040800
3935 QgsDebugMsgLevel( QString(
"PAL font definedFont: %1, Style: %2" ).arg( dFont.toString() ).arg( dFont.styleName() ), 4 );
3990 QString labeltext = ((
QgsPalGeometry* )( *it )->getFeaturePart()->getUserGeometry() )->text();
3996 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
3998 QgsDebugMsgLevel( QString(
"LABELING draw: %1 ms" ).arg( t.elapsed() ), 4 );
4004 QHash<QgsVectorLayer*, QgsPalLayerSettings>::iterator lit;
4008 for ( QList<QgsPalGeometry*>::iterator git = lyr.
geometries.begin(); git != lyr.
geometries.end(); ++git )
4025 for ( QList<QgsPalGeometry*>::iterator git = dls.
geometries.begin(); git != dls.
geometries.end(); ++git )
4035 QList<QgsLabelPosition> positions;
4037 QList<QgsLabelPosition*> positionPointers;
4041 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
4042 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )
4053 QList<QgsLabelPosition> positions;
4055 QList<QgsLabelPosition*> positionPointers;
4059 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
4060 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )
4096 QgsPoint outPt2 = xform->
transform( lp->getX() + lp->getWidth(), lp->getY() + lp->getHeight() );
4099 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4100 painter->rotate( -lp->getAlpha() * 180 /
M_PI );
4101 QRectF rect( 0, 0, outPt2.
x() - outPt.
x(), outPt2.
y() - outPt.
y() );
4102 painter->drawRect( rect );
4106 rect.moveTo( outPt.
x(), outPt.
y() );
4110 if ( lp->getNextPart() )
4117 QPainter* painter = context.
painter();
4135 label->getY() + label->getHeight() / 2 );
4137 double xc = outPt2.
x() - outPt.
x();
4138 double yc = outPt2.
y() - outPt.
y();
4140 double angle = -label->getAlpha();
4141 double xd = xc * cos( angle ) - yc * sin( angle );
4142 double yd = xc * sin( angle ) + yc * cos( angle );
4144 centerPt.
setX( centerPt.
x() + xd );
4145 centerPt.
setY( centerPt.
y() + yd );
4148 component.
setSize(
QgsPoint( label->getWidth(), label->getHeight() ) );
4158 QString text = ((
QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();
4159 QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) );
4160 QFontMetricsF* labelfm = ((
QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->getLabelFontMetrics();
4162 QString wrapchr = !tmpLyr.
wrapChar.isEmpty() ? tmpLyr.
wrapChar : QString(
"\n" );
4168 bool prependSymb =
false;
4171 if ( label->getReversed() )
4186 prependSymb =
false;
4194 symb = symb + wrapchr;
4198 prependSymb =
false;
4199 symb = wrapchr + symb;
4204 txt.prepend( symb );
4214 QStringList multiLineList = txt.split( wrapchr );
4215 int lines = multiLineList.size();
4217 double labelWidest = 0.0;
4218 for (
int i = 0; i < lines; ++i )
4220 double labelWidth = labelfm->width( multiLineList.at( i ) );
4221 if ( labelWidth > labelWidest )
4223 labelWidest = labelWidth;
4227 double labelHeight = labelfm->ascent() + labelfm->descent();
4231 double ascentOffset = 0.25 * labelfm->ascent();
4233 for (
int i = 0; i < lines; ++i )
4236 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4237 painter->rotate( -label->getAlpha() * 180 /
M_PI );
4244 double xMultiLineOffset = 0.0;
4245 double labelWidth = labelfm->width( multiLineList.at( i ) );
4248 double labelWidthDiff = labelWidest - labelWidth;
4251 labelWidthDiff /= 2;
4253 xMultiLineOffset = labelWidthDiff;
4257 double yMultiLineOffset = ( lines - 1 - i ) * labelHeight * tmpLyr.
multilineHeight;
4258 painter->translate( QPointF( xMultiLineOffset, - ascentOffset - yMultiLineOffset ) );
4260 component.
setText( multiLineList.at( i ) );
4275 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4280 textp.begin( &textPict );
4281 textp.setPen( Qt::NoPen );
4283 textp.drawPath( path );
4298 painter->setCompositionMode( tmpLyr.
blendMode );
4306 painter->drawPicture( 0, 0, textPict );
4319 if ( label->getNextPart() )
4320 drawLabel( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
4327 QPainter* p = context.
painter();
4333 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4335 pen.setWidthF( penSize );
4341 tmpColor.setAlpha( 0 );
4347 buffp.begin( &buffPict );
4348 buffp.setPen( pen );
4349 buffp.setBrush( tmpColor );
4350 buffp.drawPath( path );
4373 p->drawPicture( 0, 0, buffPict );
4381 QPainter* p = context.
painter();
4382 double labelWidth = component.
size().
x(), labelHeight = component.
size().
y();
4412 double sizeOut = 0.0;
4421 if ( labelWidth >= labelHeight )
4422 sizeOut = labelWidth;
4423 else if ( labelHeight > labelWidth )
4424 sizeOut = labelHeight;
4429 sizeOut /= mmToMapUnits;
4443 map[
"size"] = QString::number( sizeOut );
4446 map[
"angle"] = QString::number( 0.0 );
4474 svgp.begin( &svgPict );
4493 svgShdwM->
renderPoint( QPointF( svgSize / 2, -svgSize / 2 ), svgShdwContext );
4510 p->translate( QPointF( xoff, yoff ) );
4512 p->translate( -svgSize / 2, svgSize / 2 );
4536 p->translate( QPointF( xoff, yoff ) );
4539 p->setCompositionMode( QPainter::CompositionMode_SourceOver );
4573 h = sqrt( pow( w, 2 ) + pow( h, 2 ) );
4579 h = h / sqrt( 2.0 ) * 2;
4580 w = w / sqrt( 2.0 ) * 2;
4592 QRectF rect( -w / 2.0, - h / 2.0, w, h );
4594 if ( rect.isNull() )
4598 p->translate( QPointF( component.
center().
x(), component.
center().
y() ) );
4602 p->translate( QPointF( xoff, yoff ) );
4611 pen.setWidthF( penSize );
4623 shapep.begin( &shapePict );
4624 shapep.setPen( pen );
4632 shapep.drawRoundedRect( rect, tmpLyr.
shapeRadii.x(), tmpLyr.
shapeRadii.y(), Qt::RelativeSize );
4638 shapep.drawRoundedRect( rect, xRadius, yRadius );
4644 shapep.drawEllipse( rect );
4668 p->drawPicture( 0, 0, shapePict );
4681 QPainter* p = context.
painter();
4682 double componentWidth = component.
size().
x(), componentHeight = component.
size().
y();
4683 double xOffset = component.
offset().
x(), yOffset = component.
offset().
y();
4690 radius = ( int )( radius + 0.5 );
4694 double blurBufferClippingScale = 3.75;
4695 int blurbuffer = ( radius > 17 ? 16 : radius ) * blurBufferClippingScale;
4697 QImage blurImg( componentWidth + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4698 componentHeight + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4699 QImage::Format_ARGB32_Premultiplied );
4703 int minBlurImgSize = 1;
4707 int maxBlurImgSize = 40000;
4708 if ( blurImg.isNull()
4709 || ( blurImg.width() < minBlurImgSize || blurImg.height() < minBlurImgSize )
4710 || ( blurImg.width() > maxBlurImgSize || blurImg.height() > maxBlurImgSize ) )
4713 blurImg.fill( QColor( Qt::transparent ).rgba() );
4715 if ( !pictp.begin( &blurImg ) )
4717 pictp.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4718 QPointF imgOffset( blurbuffer + pictbuffer + xOffset,
4719 blurbuffer + pictbuffer + componentHeight + yOffset );
4721 pictp.drawPicture( imgOffset,
4725 pictp.setCompositionMode( QPainter::CompositionMode_SourceIn );
4726 pictp.fillRect( blurImg.rect(), tmpLyr.
shadowColor );
4739 picti.begin( &blurImg );
4740 picti.setBrush( Qt::Dense7Pattern );
4741 QPen imgPen( QColor( 0, 0, 255, 255 ) );
4742 imgPen.setWidth( 1 );
4743 picti.setPen( imgPen );
4744 picti.setOpacity( 0.1 );
4745 picti.drawRect( 0, 0, blurImg.width(), blurImg.height() );
4761 QPointF transPt( -offsetDist * cos( angleRad +
M_PI / 2 ),
4762 -offsetDist * sin( angleRad +
M_PI / 2 ) );
4765 p->setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4772 double scale = ( double )tmpLyr.
shadowScale / 100.0;
4774 p->scale( scale, scale );
4779 p->translate( transPt );
4780 p->translate( -imgOffset.x(),
4782 p->drawImage( 0, 0, blurImg );
4790 p->setBrush( Qt::NoBrush );
4791 QPen imgPen( QColor( 255, 0, 0, 10 ) );
4792 imgPen.setWidth( 2 );
4793 imgPen.setStyle( Qt::DashLine );
4794 p->setPen( imgPen );
4795 p->scale( scale, scale );
4800 p->translate( transPt );
4801 p->translate( -imgOffset.x(),
4803 p->drawRect( 0, 0, blurImg.width(), blurImg.height() );
4808 p->setBrush( Qt::NoBrush );
4809 QPen componentRectPen( QColor( 0, 255, 0, 70 ) );
4810 componentRectPen.setWidth( 1 );
4815 p->setPen( componentRectPen );
4816 p->drawRect( QRect( -xOffset, -componentHeight - yOffset, componentWidth, componentHeight ) );
4827 "PAL",
"/SearchMethod", (
int )p.getSearch(), &saved ) );
4829 "PAL",
"/CandidatesPoint", p.getPointP(), &saved );
4831 "PAL",
"/CandidatesLine", p.getLineP(), &saved );
4833 "PAL",
"/CandidatesPolygon", p.getPolyP(), &saved );
4835 "PAL",
"/ShowingCandidates",
false, &saved );
4837 "PAL",
"/ShowingShadowRects",
false, &saved );
4839 "PAL",
"/ShowingAllLabels",
false, &saved );
4841 "PAL",
"/ShowingPartialsLabels", p.getShowPartial(), &saved );
bool checkMinimumSizeMM(const QgsRenderContext &ct, QgsGeometry *geom, double minSize) const
Checks if a feature is larger than a minimum size (in mm)
QgsFeatureId id() const
Get the feature id for this feature.
static QString encodeOutputUnit(QgsSymbolV2::OutputUnit unit)
QHash< QgsVectorLayer *, QgsPalLayerSettings > mActiveLayers
void calculateLabelSize(const QFontMetricsF *fm, QString text, double &labelX, double &labelY, QgsFeature *f=0)
const QgsMapToPixel * coordinateTransform()
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsPalLayerSettings & layer(const QString &layerName)
returns PAL layer settings for a registered layer
const QString & name() const
Gets the name of the field.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
void setRotationOffset(double rotation)
void setActive(bool active)
void registerFeature(QgsVectorLayer *layer, QgsFeature &f, const QgsRenderContext &context)
A rectangle specified with double values.
virtual QList< QgsLabelPosition > labelsWithinRect(const QgsRectangle &r)
return infos about labels within a given (map) rectangle
double maxCurvedCharAngleOut
QString leftDirectionSymbol
QgsExpression * expression
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
void dataDefinedShapeBackground(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
bool dataDefinedIsActive(QgsPalLayerSettings::DataDefinedProperties p) const
Whether data definition is active.
void dataDefinedTextStyle(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
A container class for data source field mapping or expression.
void writeDataDefinedPropertyMap(QgsVectorLayer *layer, const QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined * > &propertyMap)
virtual void drawLabel(pal::LabelPosition *label, QgsRenderContext &context, QgsPalLayerSettings &tmpLyr, DrawLabelType drawType, double dpiRatio=1.0)
drawLabel
double length()
get length of geometry using GEOS
virtual void clearActiveLayer(QgsVectorLayer *layer)
clears data defined objects from PAL layer settings for a registered layer
void addDataDefinedValue(QgsPalLayerSettings::DataDefinedProperties p, QVariant v)
void setNumCandidatePositions(int candPoint, int candLine, int candPolygon)
QgsExpression * expression()
const QgsPoint & offset()
virtual int addDiagramLayer(QgsVectorLayer *layer, QgsDiagramLayerSettings *s)
adds a diagram layer to the labeling engine
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
A class to query the labeling structure at a given point (small wraper around pal RTree class) ...
bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
double yMaximum() const
Get the y maximum value (top side of rectangle)
void setSearchMethod(Search s)
virtual void init(QgsMapRenderer *mr)
called when we're going to start with rendering
void loadEngineSettings()
load/save engine settings to project file
QPainter::CompositionMode bufferBlendMode
double rendererScale() const
double rotationOffset() const
QgsRectangle extent() const
returns current extent
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
QgsPoint transform(const QgsPoint &p) const
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
bool dataDefinedValEval(const QString &valType, QgsPalLayerSettings::DataDefinedProperties p, QVariant &exprVal)
bool mShowingPartialsLabels
QuadrantPosition quadOffset
#define FID_TO_STRING(fid)
virtual QList< QgsLabelPosition > labelsAtPosition(const QgsPoint &p)
return infos about labels at a given (map) position
void numCandidatePositions(int &candPoint, int &candLine, int &candPolygon)
QGis::GeometryType type()
Returns type of the vector.
static QPointF decodePoint(QString str)
Container of fields for a vector layer.
void setAttributes(const QgsAttributes &attrs)
void saveEngineSettings()
void readFromLayer(QgsVectorLayer *layer)
static QColor decodeColor(QString str)
QString expressionString() const
const QgsRectangle & extent() const
virtual void exit()
called when we're done with rendering
void dataDefinedDropShadow(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
QVariant dataDefinedValue(QgsPalLayerSettings::DataDefinedProperties p, QgsFeature &f, const QgsFields &fields) const
Get data defined property value from expression string or attribute field name.
void labelsInRect(const QgsRectangle &r, QList< QgsLabelPosition * > &posList)
Returns label position(s) in given rectangle.
void setIsDiagram(bool d)
MultiLineAlign multilineAlign
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
void setOffset(QgsPoint point)
void removeDataDefinedProperty(QgsPalLayerSettings::DataDefinedProperties p)
Set a property to static instead data defined.
double scaleFactor() const
static QgsSymbolLayerV2 * create(const QgsStringMap &properties=QgsStringMap())
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
double area()
get area of geometry using GEOS
A non GUI class for rendering a map layer set onto a QPainter.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=0) const
void parseTextStyle(QFont &labelFont, QgsPalLayerSettings::SizeUnit fontunits, const QgsRenderContext &context)
QHash< QgsVectorLayer *, QgsDiagramLayerSettings > mActiveDiagramLayers
QMap< QString, QString > QgsStringMap
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=0) const
double maxCurvedCharAngleIn
bool reverseDirectionSymbol
const QgsCoordinateTransform * transformation(const QgsMapLayer *layer) const
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
const GEOSGeometry * asGeos() const
Returns a geos geomtry.
static void drawLabelBackground(QgsRenderContext &context, QgsLabelComponent component, const QgsPalLayerSettings &tmpLyr)
Qt::PenJoinStyle bufferJoinStyle
void setRotation(double rotation)
Returns diagram settings for a feature.
void setDiagramAttributes(const QgsAttributes &attrs, const QgsFields *fields)
bool dataDefinedEvaluate(QgsPalLayerSettings::DataDefinedProperties p, QVariant &exprVal) const
Get data defined property value from expression string or attribute field name.
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
QgsMapRenderer * mMapRenderer
bool dataDefinedUseExpression(QgsPalLayerSettings::DataDefinedProperties p) const
Whether data definition is set to use an expression.
bool isGeosValid()
check validity using GEOS
Perform transforms between map coordinates and device coordinates.
void setUseExpression(bool use)
bool writeEntry(const QString &scope, const QString &key, bool value)
bool contains(const QgsPoint *p) const
Test for containment of a point (uses GEOS)
const QgsMapToPixel * xform
void dataDefinedTextBuffer(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
virtual void drawLabeling(QgsRenderContext &context)
called when the map is drawn and labels should be placed
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > & dataDefinedValues() const
void setScaleFactor(double factor)
virtual bool willUseLayer(QgsVectorLayer *layer)
called to find out whether the layer is used for labeling
QList< QgsPalGeometry * > geometries
void setFeatureId(QgsFeatureId id)
Set the feature id for this feature.
const QgsCoordinateTransform * ct
void parseTextFormatting()
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double rasterCompressFactor
double xMaximum() const
Get the x maximum value (right side of rectangle)
virtual QSizeF sizeMapUnits(const QgsFeature &feature, const QgsRenderContext &c)
Returns size of the diagram for a feature in map units.
#define QgsDebugMsgLevel(str, level)
bool bufferSizeInMapUnits
QgsPalLayerSettings mInvalidLayerSettings
SizeUnit shapeBorderWidthUnits
QMap< QgsPalLayerSettings::DataDefinedProperties, QPair< QString, int > > mDataDefinedNames
QPainter::CompositionMode blendMode
const QgsPoint & center()
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
static bool fontFamilyOnSystem(const QString &family)
Check whether font family is on system in a quick manner, which does not compare [foundry].
void setField(const QString &field)
int sizeToPixel(double size, const QgsRenderContext &c, SizeUnit unit, bool rasterfactor=false) const
Calculates pixel size (considering output size should be in pixel or map units, scale factors and opt...
QString updateDataDefinedString(const QString &value)
Convert old property value to new one as delimited values.
double scale() const
Scale denominator.
virtual QgsAttrPalIndexNameHash palAttributeIndexNames() const
Return list of indexes to names for QgsPalLabeling fix.
static void drawLabelShadow(QgsRenderContext &context, QgsLabelComponent component, const QgsPalLayerSettings &tmpLyr)
const QgsFields * fields() const
Get associated field map.
QStringList referencedColumns()
Get list of columns referenced by the expression.
void setExpressionParams(QMap< QString, QVariant > params)
static QString symbolNameToPath(QString name)
Get symbol's path from its name.
const QgsMapToPixel * xform
QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined * > dataDefinedProperties
Map of current data defined properties.
static void drawLabelBuffer(QgsRenderContext &context, QgsLabelComponent component, const QgsPalLayerSettings &tmpLyr)
void fromGeos(GEOSGeometry *geos)
Set the geometry, feeding in a geometry in GEOS format.
const QgsAttributes & attributes() const
void setPainter(QPainter *p)
double rasterScaleFactor() const
void setText(const QString &text)
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
bool removeEntry(const QString &scope, const QString &key)
remove the given key
void setDpiRatio(double ratio)
double mapUnitsPerPixel() const
Return current map units per pixel.
const QgsPoint & origin()
void removeCustomProperty(const QString &key)
Remove a custom property from layer.
QPainter::CompositionMode shapeBlendMode
void setPictureBuffer(double buffer)
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsDataDefined * dataDefinedProperty(QgsPalLayerSettings::DataDefinedProperties p)
Get a data defined property pointer.
SizeUnit shadowOffsetUnits
SizeUnit
Units used for option sizes, before being converted to rendered sizes.
Search searchMethod() const
QgsGeometry * intersection(QgsGeometry *geometry)
Returns a geometry representing the points shared by this geometry and other.
QMap< QString, QString > dataDefinedMap(QgsPalLayerSettings::DataDefinedProperties p) const
Get property value as separate values split into Qmap.
A class to represent a point geometry.
void setFields(const QgsFields *fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
static Qt::PenJoinStyle _decodePenJoinStyle(const QString &str)
Qt::PenJoinStyle shapeJoinStyle
unsigned int upsidedownLabels
bool useExpression() const
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
bool insertLabel(LabelPosition *labelPos, int featureId, const QString &layerName, const QString &labeltext, const QFont &labelfont, bool diagram=false, bool pinned=false)
Inserts label position.
static QPainter::CompositionMode _decodeBlendMode(const QString &str)
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
void renderPoint(const QPointF &point, QgsSymbolV2RenderContext &context)
static void _writeColor(QgsVectorLayer *layer, QString property, QColor color, bool withAlpha=true)
QgsPoint toMapCoordinatesF(double x, double y) const
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode Added in 1.9.
unsigned int placementFlags
QgsPoint toMapCoordinates(int x, int y) const
void setValid(bool validity)
Set the validity of the feature.
void setSize(QgsPoint point)
QString rightDirectionSymbol
QgsExpression * getLabelExpression()
Returns the QgsExpression for this label settings.
Contains information about the context of a rendering operation.
const QPicture * picture()
void clearEngineSettings()
void setPicture(QPicture *picture)
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
void setDataDefinedProperty(QgsPalLayerSettings::DataDefinedProperties p, bool active, bool useExpr, const QString &expr, const QString &field)
Set a property as data defined.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
void setDefinedFont(QFont f)
void drawLabelCandidateRect(pal::LabelPosition *lp, QPainter *painter, const QgsMapToPixel *xform)
static QgsPalLayerSettings::SizeUnit _decodeUnits(const QString &str)
QVector< QVariant > QgsAttributes
bool expressionIsPrepared() const
void readDataDefinedProperty(QgsVectorLayer *layer, QgsPalLayerSettings::DataDefinedProperties p, QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined * > &propertyMap)
virtual QgsLabelingEngineInterface * clone()
called when passing engine among map renderers
void label(const QgsPoint &p, QList< QgsLabelPosition * > &posList)
Returns label position(s) at a given point.
bool shadowRadiusAlphaOnly
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
static QgsProject * instance()
access to canonical QgsProject instance
virtual void clearActiveLayers()
clears all PAL layer settings for registered layers
void clear()
Removes and deletes all the entries.
virtual void registerDiagramFeature(QgsVectorLayer *layer, QgsFeature &feat, const QgsRenderContext &context=QgsRenderContext())
called for every diagram feature
void setMapToPixel(const QgsMapToPixel &mtp)
int size() const
Return number of items.
SizeUnit shadowRadiusUnits
static QgsGeometry * fromRect(const QgsRectangle &rect)
construct geometry from a rectangle
int transform(const QgsCoordinateTransform &ct)
Transform this geometry as described by CoordinateTranasform ct.
const QgsMapToPixel & mapToPixel() const
void writeToLayer(QgsVectorLayer *layer)
virtual void registerFeature(QgsVectorLayer *layer, QgsFeature &feat, const QgsRenderContext &context=QgsRenderContext())
hook called when drawing for every feature in a layer
virtual int prepareLayer(QgsVectorLayer *layer, QSet< int > &attrIndices, QgsRenderContext &ctx)
hook called when drawing layer before issuing select()
bool labelOffsetInMapUnits
double pictureBuffer() const
QPainter::CompositionMode shadowBlendMode
bool isExpression
Is this label made from a expression string eg FieldName || 'mm'.
void readDataDefinedPropertyMap(QgsVectorLayer *layer, QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined * > &propertyMap)
QList< QgsPalGeometry * > geometries
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode Added in 1.9.
Custom exception class for Coordinate Reference System related exceptions.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
QList< QgsLabelCandidate > mCandidates
Labeling engine interface.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
void setCenter(QgsPoint point)
SizeUnit shapeOffsetUnits
void setScale(double scale)
double scaleToPixelContext(double size, const QgsRenderContext &c, SizeUnit unit, bool rasterfactor=false) const
Calculates size (considering output size should be in pixel or map units, scale factors and optionall...
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
void feature(QgsFeature &feature)
QString parserErrorString() const
Returns parser error.
double xMinimum() const
Get the x minimum value (left side of rectangle)
const QgsCoordinateTransform * ct
QString evalErrorString() const
Returns evaluation error.
void setExpressionString(const QString &expr)
QHash< int, QString > QgsAttrPalIndexNameHash
static void blurImageInPlace(QImage &image, const QRect &rect, int radius, bool alphaOnly)
Blurs an image in place, e.g.
Maintains current state of more grainular and temporal values when creating/painting component parts ...
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=0, bool *match=0)
Check whether font family is on system.
pal::LabelInfo * info(QFontMetricsF *fm, const QgsMapToPixel *xform, double fontScale, double maxinangle, double maxoutangle)
QStringList referencedColumns(QgsVectorLayer *layer)
RotationType shapeRotationType
QMap< DataDefinedProperties, QVariant > dataDefinedValues
static QColor _readColor(QgsVectorLayer *layer, QString property, QColor defaultColor=Qt::black, bool withAlpha=true)
LinePlacementFlags placementFlags
const QgsFields * mCurFields
QgsLabelSearchTree * mLabelSearchTree
void setOrigin(QgsPoint point)
DirectionSymbols placeDirectionSymbol
void parseShapeBackground()
void dataDefinedTextFormatting(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)