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>
83 qreal ltrSpacing = 0.0, qreal wordSpacing = 0.0,
bool curvedLabeling =
false )
90 , mFontMetrics( NULL )
91 , mLetterSpacing( ltrSpacing )
92 , mWordSpacing( wordSpacing )
93 , mCurvedLabeling( curvedLabeling )
96 mDefinedFont = QFont();
102 GEOSGeom_destroy( mG );
109 const GEOSGeometry* getGeosGeometry()
113 void releaseGeosGeometry(
const GEOSGeometry* )
118 const char* strId() {
return mStrId.data(); }
119 QString text() {
return mText; }
121 pal::LabelInfo* info( QFontMetricsF* fm,
const QgsMapToPixel* xform,
double fontScale,
double maxinangle,
double maxoutangle )
126 mFontMetrics =
new QFontMetricsF( *fm );
129 if ( maxinangle < 20.0 )
131 if ( 60.0 < maxinangle )
133 if ( maxoutangle > -20.0 )
135 if ( -95.0 > maxoutangle )
146 mInfo =
new pal::LabelInfo( mText.count(), ptSize.
y() - ptZero.
y(), maxinangle, maxoutangle );
147 for (
int i = 0; i < mText.count(); i++ )
149 mInfo->char_info[i].chr = mText[i].unicode();
153 charWidth = fm->width( mText[i] );
154 if ( mCurvedLabeling )
156 wordSpaceFix = qreal( 0.0 );
157 if ( mText[i] == QString(
" " )[0] )
161 wordSpaceFix = ( nxt < mText.count() && mText[nxt] != QString(
" " )[0] ) ? mWordSpacing : qreal( 0.0 );
163 if ( fm->width( QString( mText[i] ) ) - fm->width( mText[i] ) - mLetterSpacing != qreal( 0.0 ) )
166 wordSpaceFix -= mWordSpacing;
168 charWidth = fm->width( QString( mText[i] ) ) + wordSpaceFix;
172 mInfo->char_info[i].width = ptSize.
x() - ptZero.
x();
177 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& dataDefinedValues()
const {
return mDataDefinedValues; }
180 void setIsDiagram(
bool d ) { mIsDiagram = d; }
181 bool isDiagram()
const {
return mIsDiagram; }
183 void setIsPinned(
bool f ) { mIsPinned = f; }
184 bool isPinned()
const {
return mIsPinned; }
186 void setDefinedFont( QFont f ) { mDefinedFont = QFont( f ); }
187 QFont definedFont() {
return mDefinedFont; }
189 QFontMetricsF* getLabelFontMetrics() {
return mFontMetrics; }
191 void setDiagramAttributes(
const QgsAttributes& attrs,
const QgsFields* fields ) { mDiagramAttributes = attrs; mDiagramFields = fields; }
192 const QgsAttributes& diagramAttributes() {
return mDiagramAttributes; }
197 feature.
setFields( mDiagramFields,
false );
211 QFontMetricsF* mFontMetrics;
212 qreal mLetterSpacing;
214 bool mCurvedLabeling;
216 QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > mDataDefinedValues;
232 , mFeaturesToLabel( 0 )
233 , mFeatsSendingToPal( 0 )
245 blendMode = QPainter::CompositionMode_SourceOver;
631 int r = layer->
customProperty( property +
"R", QVariant( defaultColor.red() ) ).toInt();
632 int g = layer->
customProperty( property +
"G", QVariant( defaultColor.green() ) ).toInt();
633 int b = layer->
customProperty( property +
"B", QVariant( defaultColor.blue() ) ).toInt();
634 int a = withAlpha ? layer->
customProperty( property +
"A", QVariant( defaultColor.alpha() ) ).toInt() : 255;
635 return QColor( r, g, b, a );
649 if ( str.compare(
"Point", Qt::CaseInsensitive ) == 0
651 if ( str.compare(
"MapUnit", Qt::CaseInsensitive ) == 0
659 if ( str.compare(
"Lighten", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
660 if ( str.compare(
"Screen", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
661 if ( str.compare(
"Dodge", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
662 if ( str.compare(
"Addition", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
663 if ( str.compare(
"Darken", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
664 if ( str.compare(
"Multiply", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
665 if ( str.compare(
"Burn", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
666 if ( str.compare(
"Overlay", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
667 if ( str.compare(
"SoftLight", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
668 if ( str.compare(
"HardLight", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
669 if ( str.compare(
"Difference", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
670 if ( str.compare(
"Subtract", Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
671 return QPainter::CompositionMode_SourceOver;
676 if ( str.compare(
"Miter", Qt::CaseInsensitive ) == 0 )
return Qt::MiterJoin;
677 if ( str.compare(
"Round", Qt::CaseInsensitive ) == 0 )
return Qt::RoundJoin;
678 return Qt::BevelJoin;
682 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
689 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i(
mDataDefinedNames );
690 while ( i.hasNext() )
698 const QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
705 QMapIterator<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > i(
mDataDefinedNames );
706 while ( i.hasNext() )
709 QString newPropertyName =
"labeling/dataDefined/" + i.value().first;
710 QVariant propertyValue = QVariant();
712 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it = propertyMap.find( i.key() );
713 if ( it != propertyMap.constEnd() )
721 QString field = dd->
field();
723 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
729 values << ( active ?
"1" :
"0" );
730 values << ( useExpr ?
"1" :
"0" );
733 if ( !values.isEmpty() )
735 propertyValue = QVariant( values.join(
"~~" ) );
741 if ( propertyValue.isValid() )
751 if ( layer->
customProperty( newPropertyName, QVariant() ).isValid() && i.value().second > -1 )
754 layer->
removeCustomProperty( QString(
"labeling/dataDefinedProperty" ) + QString::number( i.value().second ) );
761 QMap < QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > & propertyMap )
763 QString newPropertyName =
"labeling/dataDefined/" +
mDataDefinedNames.value( p ).first;
764 QVariant newPropertyField = layer->
customProperty( newPropertyName, QVariant() );
766 QString ddString = QString();
767 if ( newPropertyField.isValid() )
769 ddString = newPropertyField.toString();
780 QString oldPropertyName =
"labeling/dataDefinedProperty" + QString::number( oldIndx );
781 QVariant oldPropertyField = layer->
customProperty( oldPropertyName, QVariant() );
783 if ( !oldPropertyField.isValid() )
790 int indx = oldPropertyField.toInt( &conversionOk );
800 if ( !oldIndicesToNames.isEmpty() )
802 ddString = oldIndicesToNames.value( indx );
807 if ( indx < fields.
size() )
809 ddString = fields.
at( indx ).
name();
814 if ( !ddString.isEmpty() )
827 if ( oldIndx == 16 || oldIndx == 17 )
838 if ( !ddString.isEmpty() && ddString != QString(
"0~~0~~~~" ) )
842 QStringList ddv = newStyleString.split(
"~~" );
845 propertyMap.insert( p, dd );
856 if ( layer->
customProperty(
"labeling" ).toString() != QString(
"pal" ) )
873 QFont appFont = QApplication::font();
885 fontFamily = appFont.family();
888 double fontSize = layer->
customProperty(
"labeling/fontSize" ).toDouble();
892 int fontWeight = layer->
customProperty(
"labeling/fontWeight" ).toInt();
893 bool fontItalic = layer->
customProperty(
"labeling/fontItalic" ).toBool();
894 textFont = QFont( fontFamily, fontSize, fontWeight, fontItalic );
898 textFont.setCapitalization(( QFont::Capitalization )layer->
customProperty(
"labeling/fontCapitals", QVariant( 0 ) ).toUInt() );
901 textFont.setLetterSpacing( QFont::AbsoluteSpacing, layer->
customProperty(
"labeling/fontLetterSpacing", QVariant( 0.0 ) ).toDouble() );
902 textFont.setWordSpacing( layer->
customProperty(
"labeling/fontWordSpacing", QVariant( 0.0 ) ).toDouble() );
924 double bufSize = layer->
customProperty(
"labeling/bufferSize", QVariant( 0.0 ) ).toDouble();
927 QVariant drawBuffer = layer->
customProperty(
"labeling/bufferDraw", QVariant() );
928 if ( drawBuffer.isValid() )
933 else if ( bufSize != 0.0 )
960 layer->
customProperty(
"labeling/shapeSizeY", QVariant( 0.0 ) ).toDouble() );
967 layer->
customProperty(
"labeling/shapeOffsetY", QVariant( 0.0 ) ).toDouble() );
972 layer->
customProperty(
"labeling/shapeRadiiY", QVariant( 0.0 ) ).toDouble() );
1033 int scalemn = layer->
customProperty(
"labeling/scaleMin", QVariant( 0 ) ).toInt();
1034 int scalemx = layer->
customProperty(
"labeling/scaleMax", QVariant( 0 ) ).toInt();
1037 QVariant scalevis = layer->
customProperty(
"labeling/scaleVisibility", QVariant() );
1038 if ( scalevis.isValid() )
1044 else if ( scalemn > 0 || scalemx > 0 )
1224 bool active,
bool useExpr,
const QString& expr,
const QString& field )
1226 bool defaultVals = ( !active && !useExpr && expr.isEmpty() && field.isEmpty() );
1230 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1240 else if ( !defaultVals )
1252 delete( it.value() );
1260 QString newValue = value;
1261 if ( !value.isEmpty() && !value.contains(
"~~" ) )
1268 newValue = values.join(
"~~" );
1276 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1286 QMap<QString, QString> map;
1287 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1290 return it.value()->toMap();
1303 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1319 QVariant result = QVariant();
1321 QString field = dd->
field();
1340 else if ( !useExpression && !field.isEmpty() )
1359 if ( result.isValid() )
1372 bool isActive =
false;
1373 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1376 isActive = it.value()->isActive();
1384 bool useExpression =
false;
1385 QMap< DataDefinedProperties, QgsDataDefined* >::const_iterator it =
dataDefinedProperties.find( p );
1388 useExpression = it.value()->useExpression();
1391 return useExpression;
1415 double length = geom->
length();
1416 if ( length >= 0.0 )
1418 return ( length >= ( minSize * mapUnitsPerMM ) );
1423 double area = geom->
area();
1426 return ( sqrt( area ) >= ( minSize * mapUnitsPerMM ) );
1487 if ( exprVal.isValid() )
1489 wrapchr = exprVal.toString();
1493 if ( exprVal.isValid() )
1496 double size = exprVal.toDouble( &ok );
1505 if ( exprVal.isValid() )
1507 addDirSymb = exprVal.toBool();
1514 if ( exprVal.isValid() )
1516 leftDirSymb = exprVal.toString();
1520 if ( exprVal.isValid() )
1522 rightDirSymb = exprVal.toString();
1526 if ( exprVal.isValid() )
1529 int enmint = exprVal.toInt( &ok );
1539 if ( wrapchr.isEmpty() )
1541 wrapchr = QString(
"\n" );
1546 && ( !leftDirSymb.isEmpty() || !rightDirSymb.isEmpty() ) )
1548 QString dirSym = leftDirSymb;
1550 if ( fm->width( rightDirSymb ) > fm->width( dirSym ) )
1551 dirSym = rightDirSymb;
1555 text.append( dirSym );
1559 text.prepend( dirSym + wrapchr );
1563 double w = 0.0, h = 0.0;
1564 QStringList multiLineSplit = text.split( wrapchr );
1565 int lines = multiLineSplit.size();
1567 double labelHeight = fm->ascent() + fm->descent();
1569 h += fm->height() + ( double )(( lines - 1 ) * labelHeight * multilineH );
1572 for (
int i = 0; i < lines; ++i )
1574 double width = fm->width( multiLineSplit.at( i ) );
1583 labelX = qAbs( ptSize.
x() - ptZero.
x() );
1584 labelY = qAbs( ptSize.
y() - ptZero.
y() );
1600 QgsDebugMsgLevel( QString(
"exprVal Show:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1601 if ( !exprVal.toBool() )
1611 QgsDebugMsgLevel( QString(
"exprVal ScaleVisibility:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1612 useScaleVisibility = exprVal.toBool();
1615 if ( useScaleVisibility )
1621 QgsDebugMsgLevel( QString(
"exprVal MinScale:%1" ).arg( exprVal.toDouble() ), 4 );
1623 double mins = exprVal.toDouble( &conversionOk );
1633 minScale = 1 / qAbs( minScale );
1645 QgsDebugMsgLevel( QString(
"exprVal MaxScale:%1" ).arg( exprVal.toDouble() ), 4 );
1647 double maxs = exprVal.toDouble( &conversionOk );
1657 maxScale = 1 / qAbs( maxScale );
1673 QString units = exprVal.toString().trimmed();
1675 if ( !units.isEmpty() )
1682 double fontSize = labelFont.pointSizeF();
1685 QgsDebugMsgLevel( QString(
"exprVal Size:%1" ).arg( exprVal.toDouble() ), 4 );
1687 double size = exprVal.toDouble( &ok );
1693 if ( fontSize <= 0.0 )
1700 if ( fontPixelSize < 1 )
1704 labelFont.setPixelSize( fontPixelSize );
1714 QgsDebugMsgLevel( QString(
"exprVal FontLimitPixel:%1" ).arg( exprVal.toBool() ?
"true" :
"false" ), 4 );
1715 useFontLimitPixelSize = exprVal.toBool();
1718 if ( useFontLimitPixelSize )
1724 int sizeInt = exprVal.toInt( &ok );
1725 QgsDebugMsgLevel( QString(
"exprVal FontMinPixel:%1" ).arg( sizeInt ), 4 );
1728 fontMinPixel = sizeInt;
1736 int sizeInt = exprVal.toInt( &ok );
1737 QgsDebugMsgLevel( QString(
"exprVal FontMaxPixel:%1" ).arg( sizeInt ), 4 );
1740 fontMaxPixel = sizeInt;
1744 if ( fontMinPixel > labelFont.pixelSize() || labelFont.pixelSize() > fontMaxPixel )
1775 QVariant result = exp->
evaluate( &f );
1781 labelText = result.isNull() ?
"" : result.toString();
1786 labelText = v.isNull() ?
"" : v.toString();
1793 formatnum = exprVal.toBool();
1794 QgsDebugMsgLevel( QString(
"exprVal NumFormat:%1" ).arg( formatnum ?
"true" :
"false" ), 4 );
1805 int dInt = exprVal.toInt( &ok );
1807 if ( ok && dInt > 0 )
1809 decimalPlaces = dInt;
1817 signPlus = exprVal.toBool();
1818 QgsDebugMsgLevel( QString(
"exprVal NumPlusSign:%1" ).arg( signPlus ?
"true" :
"false" ), 4 );
1821 QVariant textV( labelText );
1823 double d = textV.toDouble( &ok );
1826 QString numberFormat;
1827 if ( d > 0 && signPlus )
1829 numberFormat.append(
"+" );
1831 numberFormat.append(
"%1" );
1832 labelText = numberFormat.arg( d, 0,
'f', decimalPlaces );
1838 QFontMetricsF* labelFontMetrics =
new QFontMetricsF( labelFont );
1839 double labelX, labelY;
1845 double maxcharanglein = 20.0;
1846 double maxcharangleout = -20.0;
1856 QString ptstr = exprVal.toString().trimmed();
1857 QgsDebugMsgLevel( QString(
"exprVal CurvedCharAngleInOut:%1" ).arg( ptstr ), 4 );
1859 if ( !ptstr.isEmpty() )
1862 maxcharanglein = qBound( 20.0, (
double )maxcharanglePt.x(), 60.0 );
1863 maxcharangleout = qBound( 20.0, (
double )maxcharanglePt.y(), 95.0 );
1867 maxcharangleout = -( qAbs( maxcharangleout ) );
1878 QScopedPointer<QgsGeometry> clonedGeometry;
1882 clonedGeometry.reset( geom );
1891 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception" ).arg( f.
id() ), 4 );
1910 QString str = exprVal.toString().trimmed();
1913 if ( !str.isEmpty() )
1915 if ( str.compare(
"Visible", Qt::CaseInsensitive ) == 0 )
1917 wholeCentroid =
false;
1919 else if ( str.compare(
"Whole", Qt::CaseInsensitive ) == 0 )
1921 wholeCentroid =
true;
1938 clonedGeometry.reset( geom );
1943 bool do_clip =
false;
1944 if ( !centroidPoly || ( centroidPoly && !wholeCentroid ) )
1955 clonedGeometry.reset( geom );
1959 const GEOSGeometry* geos_geom = geom->
asGeos();
1961 if ( geos_geom == NULL )
1990 GEOSGeometry* geos_geom_clone;
1993 geos_geom_clone = GEOSBoundary( geos_geom );
1997 geos_geom_clone = GEOSGeom_clone( geos_geom );
2001 bool dataDefinedPosition =
false;
2002 bool labelIsPinned =
false;
2003 bool layerDefinedRotation =
false;
2004 bool dataDefinedRotation =
false;
2005 double xPos = 0.0, yPos = 0.0,
angle = 0.0;
2006 bool ddXPos =
false, ddYPos =
false;
2007 double quadOffsetX = 0.0, quadOffsetY = 0.0;
2008 double offsetX = 0.0, offsetY = 0.0;
2015 int quadInt = exprVal.toInt( &ok );
2017 if ( ok && 0 <= quadInt && quadInt <= 8 )
2068 QString ptstr = exprVal.toString().trimmed();
2071 if ( !ptstr.isEmpty() )
2083 QString units = exprVal.toString().trimmed();
2085 if ( !units.isEmpty() )
2097 if ( !offinmapunits )
2099 offsetX *= mapUntsPerMM;
2105 if ( !offinmapunits )
2107 offsetY *= mapUntsPerMM;
2115 layerDefinedRotation =
true;
2123 double rotD = exprVal.toDouble( &ok );
2127 dataDefinedRotation =
true;
2134 if ( !exprVal.isNull() )
2135 xPos = exprVal.toDouble( &ddXPos );
2141 if ( !exprVal.isNull() )
2142 yPos = exprVal.toDouble( &ddYPos );
2145 if ( ddXPos && ddYPos )
2147 dataDefinedPosition =
true;
2148 labelIsPinned =
true;
2150 if ( layerDefinedRotation && !dataDefinedRotation )
2162 QString haliString = exprVal.toString();
2164 if ( haliString.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2166 xdiff -= labelX / 2.0;
2168 else if ( haliString.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2177 QString valiString = exprVal.toString();
2180 if ( valiString.compare(
"Bottom", Qt::CaseInsensitive ) != 0 )
2182 if ( valiString.compare(
"Top", Qt::CaseInsensitive ) == 0 )
2188 double descentRatio = labelFontMetrics->descent() / labelFontMetrics->height();
2189 if ( valiString.compare(
"Base", Qt::CaseInsensitive ) == 0 )
2191 ydiff -= labelY * descentRatio;
2195 double capHeightRatio = ( labelFontMetrics->boundingRect(
'H' ).height() + 1 + labelFontMetrics->descent() ) / labelFontMetrics->height();
2196 ydiff -= labelY * capHeightRatio;
2197 if ( valiString.compare(
"Half", Qt::CaseInsensitive ) == 0 )
2199 ydiff += labelY * ( capHeightRatio - descentRatio ) / 2.0;
2206 if ( dataDefinedRotation )
2209 double xd = xdiff * cos(
angle ) - ydiff * sin(
angle );
2210 double yd = xdiff * sin(
angle ) + ydiff * cos(
angle );
2226 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due transformation exception on data-defined position" ).arg( f.
id() ), 4 );
2246 bool alwaysShow =
false;
2249 alwaysShow = exprVal.toBool();
2256 labelFont.letterSpacing(),
2257 labelFont.wordSpacing(),
2264 #if QT_VERSION >= 0x040800
2265 QgsDebugMsgLevel( QString(
"PAL font stored definedFont: %1, Style: %2" ).arg( labelFont.toString() ).arg( labelFont.styleName() ), 4 );
2272 if ( !
palLayer->registerFeature( lbl->
strId(), lbl, labelX, labelY, labelText.toUtf8().constData(),
2273 xPos, yPos, dataDefinedPosition,
angle, dataDefinedRotation,
2274 quadOffsetX, quadOffsetY, offsetX, offsetY, alwaysShow ) )
2277 catch ( std::exception &e )
2280 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( f.
id() ) + QString::fromLatin1( e.what() ), 4 );
2288 delete labelFontMetrics;
2293 double distance =
dist;
2297 double distD = exprVal.toDouble( &ok );
2308 QString units = exprVal.toString().trimmed();
2310 if ( !units.isEmpty() )
2316 if ( distance != 0 )
2318 if ( distinmapunit )
2326 feat->setDistLabel( qAbs(
ptOne.
x() - ptZero.
x() )* distance );
2331 QMap< DataDefinedProperties, QVariant >::const_iterator dIt =
dataDefinedValues.constBegin();
2347 QString dbgStr = QString(
"exprVal %1:" ).arg(
mDataDefinedNames.value( p ).first ) +
"%1";
2349 if ( valType == QString(
"bool" ) )
2351 bool bol = exprVal.toBool();
2356 if ( valType == QString(
"int" ) )
2359 int size = exprVal.toInt( &ok );
2368 if ( valType == QString(
"intpos" ) )
2371 int size = exprVal.toInt( &ok );
2374 if ( ok && size > 0 )
2380 if ( valType == QString(
"double" ) )
2383 double size = exprVal.toDouble( &ok );
2392 if ( valType == QString(
"doublepos" ) )
2395 double size = exprVal.toDouble( &ok );
2398 if ( ok && size > 0.0 )
2404 if ( valType == QString(
"rotation180" ) )
2407 double rot = exprVal.toDouble( &ok );
2411 if ( rot < -180.0 && rot >= -360 )
2415 if ( rot > 180.0 && rot <= 360 )
2419 if ( rot >= -180 && rot <= 180 )
2426 if ( valType == QString(
"transp" ) )
2429 int size = exprVal.toInt( &ok );
2431 if ( ok && size >= 0 && size <= 100 )
2437 if ( valType == QString(
"string" ) )
2439 QString str = exprVal.toString();
2445 if ( valType == QString(
"units" ) )
2447 QString unitstr = exprVal.toString().trimmed();
2450 if ( !unitstr.isEmpty() )
2456 if ( valType == QString(
"color" ) )
2458 QString colorstr = exprVal.toString().trimmed();
2462 if ( color.isValid() )
2468 if ( valType == QString(
"joinstyle" ) )
2470 QString joinstr = exprVal.toString().trimmed();
2473 if ( !joinstr.isEmpty() )
2479 if ( valType == QString(
"blendmode" ) )
2481 QString blendstr = exprVal.toString().trimmed();
2484 if ( !blendstr.isEmpty() )
2490 if ( valType == QString(
"pointf" ) )
2492 QString ptstr = exprVal.toString().trimmed();
2495 if ( !ptstr.isEmpty() )
2518 QString ddFontFamily(
"" );
2521 QString family = exprVal.toString().trimmed();
2524 if ( labelFont.family() != family )
2530 ddFontFamily = family;
2536 QString ddFontStyle(
"" );
2539 QString fontstyle = exprVal.toString().trimmed();
2540 QgsDebugMsgLevel( QString(
"exprVal Font style:%1" ).arg( fontstyle ), 4 );
2541 ddFontStyle = fontstyle;
2545 bool ddBold =
false;
2548 bool bold = exprVal.toBool();
2549 QgsDebugMsgLevel( QString(
"exprVal Font bold:%1" ).arg( bold ?
"true" :
"false" ), 4 );
2554 bool ddItalic =
false;
2557 bool italic = exprVal.toBool();
2558 QgsDebugMsgLevel( QString(
"exprVal Font italic:%1" ).arg( italic ?
"true" :
"false" ), 4 );
2565 QFont appFont = QApplication::font();
2566 bool newFontBuilt =
false;
2567 if ( ddBold || ddItalic )
2570 newFont = QFont( !ddFontFamily.isEmpty() ? ddFontFamily : labelFont.family() );
2571 newFontBuilt =
true;
2572 newFont.setBold( ddBold );
2573 newFont.setItalic( ddItalic );
2575 else if ( !ddFontStyle.isEmpty()
2576 && ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2578 if ( !ddFontFamily.isEmpty() )
2581 QFont styledfont =
mFontDB.font( ddFontFamily, ddFontStyle, appFont.pointSize() );
2582 if ( appFont != styledfont )
2584 newFont = styledfont;
2585 newFontBuilt =
true;
2592 else if ( !ddFontFamily.isEmpty() )
2594 if ( ddFontStyle.compare(
"Ignore", Qt::CaseInsensitive ) != 0 )
2598 if ( appFont != styledfont )
2600 newFont = styledfont;
2601 newFontBuilt =
true;
2606 newFont = QFont( ddFontFamily );
2607 newFontBuilt =
true;
2615 newFont.setPixelSize( labelFont.pixelSize() );
2616 newFont.setCapitalization( labelFont.capitalization() );
2617 newFont.setUnderline( labelFont.underline() );
2618 newFont.setStrikeOut( labelFont.strikeOut() );
2619 newFont.setWordSpacing( labelFont.wordSpacing() );
2620 newFont.setLetterSpacing( QFont::AbsoluteSpacing, labelFont.letterSpacing() );
2622 labelFont = newFont;
2626 double wordspace = labelFont.wordSpacing();
2630 double wspacing = exprVal.toDouble( &ok );
2631 QgsDebugMsgLevel( QString(
"exprVal FontWordSpacing:%1" ).arg( wspacing ), 4 );
2634 wordspace = wspacing;
2640 double letterspace = labelFont.letterSpacing();
2644 double lspacing = exprVal.toDouble( &ok );
2645 QgsDebugMsgLevel( QString(
"exprVal FontLetterSpacing:%1" ).arg( lspacing ), 4 );
2648 letterspace = lspacing;
2654 QFont::Capitalization fontcaps = labelFont.capitalization();
2657 QString fcase = exprVal.toString().trimmed();
2660 if ( !fcase.isEmpty() )
2662 if ( fcase.compare(
"NoChange", Qt::CaseInsensitive ) == 0 )
2664 fontcaps = QFont::MixedCase;
2666 else if ( fcase.compare(
"Upper", Qt::CaseInsensitive ) == 0 )
2668 fontcaps = QFont::AllUppercase;
2670 else if ( fcase.compare(
"Lower", Qt::CaseInsensitive ) == 0 )
2672 fontcaps = QFont::AllLowercase;
2674 else if ( fcase.compare(
"Capitalize", Qt::CaseInsensitive ) == 0 )
2676 fontcaps = QFont::Capitalize;
2679 if ( fontcaps != labelFont.capitalization() )
2681 labelFont.setCapitalization( fontcaps );
2689 bool strikeout = exprVal.toBool();
2690 QgsDebugMsgLevel( QString(
"exprVal Font strikeout:%1" ).arg( strikeout ?
"true" :
"false" ), 4 );
2691 labelFont.setStrikeOut( strikeout );
2697 bool underline = exprVal.toBool();
2698 QgsDebugMsgLevel( QString(
"exprVal Font underline:%1" ).arg( underline ?
"true" :
"false" ), 4 );
2699 labelFont.setUnderline( underline );
2723 drawBuffer = exprVal.toBool();
2735 bufrSize = exprVal.toDouble();
2742 bufTransp = exprVal.toInt();
2745 drawBuffer = ( drawBuffer && bufrSize > 0.0 && bufTransp < 100 );
2776 wrapchr = exprVal.toString();
2785 QString str = exprVal.toString().trimmed();
2786 QgsDebugMsgLevel( QString(
"exprVal MultiLineAlignment:%1" ).arg( str ), 4 );
2788 if ( !str.isEmpty() )
2793 if ( str.compare(
"Center", Qt::CaseInsensitive ) == 0 )
2797 else if ( str.compare(
"Right", Qt::CaseInsensitive ) == 0 )
2809 drawDirSymb = exprVal.toBool();
2823 QString str = exprVal.toString().trimmed();
2824 QgsDebugMsgLevel( QString(
"exprVal DirSymbPlacement:%1" ).arg( str ), 4 );
2826 if ( !str.isEmpty() )
2831 if ( str.compare(
"Above", Qt::CaseInsensitive ) == 0 )
2835 else if ( str.compare(
"Below", Qt::CaseInsensitive ) == 0 )
2858 drawShape = exprVal.toBool();
2870 shapeTransp = exprVal.toInt();
2873 drawShape = ( drawShape && shapeTransp < 100 );
2886 QString skind = exprVal.toString().trimmed();
2889 if ( !skind.isEmpty() )
2894 if ( skind.compare(
"Square", Qt::CaseInsensitive ) == 0 )
2898 else if ( skind.compare(
"Ellipse", Qt::CaseInsensitive ) == 0 )
2902 else if ( skind.compare(
"Circle", Qt::CaseInsensitive ) == 0 )
2906 else if ( skind.compare(
"SVG", Qt::CaseInsensitive ) == 0 )
2910 shapeKind = shpkind;
2919 QString svgfile = exprVal.toString().trimmed();
2920 QgsDebugMsgLevel( QString(
"exprVal ShapeSVGFile:%1" ).arg( svgfile ), 4 );
2931 QString stype = exprVal.toString().trimmed();
2934 if ( !stype.isEmpty() )
2939 if ( stype.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
2943 shpSizeType = sizType;
2952 ddShpSizeX = exprVal.toDouble();
2959 ddShpSizeY = exprVal.toDouble();
2965 && ( svgPath.isEmpty()
2966 || ( !svgPath.isEmpty()
2968 && ddShpSizeX == 0.0 ) ) )
2974 && ( ddShpSizeX == 0.0 || ddShpSizeY == 0.0 ) )
2996 QString rotstr = exprVal.toString().trimmed();
2997 QgsDebugMsgLevel( QString(
"exprVal ShapeRotationType:%1" ).arg( rotstr ), 4 );
2999 if ( !rotstr.isEmpty() )
3004 if ( rotstr.compare(
"Offset", Qt::CaseInsensitive ) == 0 )
3008 else if ( rotstr.compare(
"Fixed", Qt::CaseInsensitive ) == 0 )
3059 drawShadow = exprVal.toBool();
3071 shadowTransp = exprVal.toInt();
3078 shadowOffDist = exprVal.toDouble();
3085 shadowRad = exprVal.toDouble();
3088 drawShadow = ( drawShadow && shadowTransp < 100 && !( shadowOffDist == 0.0 && shadowRad == 0.0 ) );
3102 QString str = exprVal.toString().trimmed();
3105 if ( !str.isEmpty() )
3110 if ( str.compare(
"Text", Qt::CaseInsensitive ) == 0 )
3114 else if ( str.compare(
"Buffer", Qt::CaseInsensitive ) == 0 )
3118 else if ( str.compare(
"Background", Qt::CaseInsensitive ) == 0 )
3158 if ( unit ==
MapUnits && mapUnitsPerPixel > 0.0 )
3164 double ptsTomm = ( unit ==
Points ? 0.352778 : 1 );
3173 : mMapSettings( NULL ), mPal( NULL )
3183 switch ( p.getSearch() )
3227 bool enabled =
false;
3228 if ( layer->
customProperty(
"labeling" ).toString() == QString(
"pal" ) )
3229 enabled = layer->
customProperty(
"labeling/enabled", QVariant(
false ) ).toBool();
3237 QHash<QString, QgsPalLayerSettings>::iterator lit;
3250 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::iterator it = lyr.
dataDefinedProperties.begin();
3253 delete( it.value() );
3274 if ( lyrTmp.fieldName.isEmpty() )
3279 if ( lyrTmp.isExpression )
3317 attrNames.append( name );
3326 QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator dIt = lyr.
dataDefinedProperties.constBegin();
3338 QMap<QString, QVariant> exprParams;
3347 foreach ( QString name, cols )
3349 attrNames.append( name );
3354 Arrangement arrangement;
3363 default: Q_ASSERT(
"unsupported placement" && 0 );
return 0;
3367 double priority = 1 - lyr.
priority / 10.0;
3368 double min_scale = -1, max_scale = -1;
3377 Layer* l =
mPal->addLayer( layer->
id().toUtf8().data(),
3378 min_scale, max_scale, arrangement,
3379 METER, priority, lyr.
obstacle,
true,
true,
3386 l->setLabelMode( lyr.
labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature );
3402 double distD = exprVal.toDouble( &ok );
3413 QString units = exprVal.toString().trimmed();
3414 QgsDebugMsgLevel( QString(
"exprVal RepeatDistanceUnits:%1" ).arg( units ), 4 );
3415 if ( !units.isEmpty() )
3421 if ( repeatDist != 0 )
3423 if ( !repeatdistinmapunit )
3432 l->setRepeatDistance( repeatDist );
3435 Layer::UpsideDownLabels upsdnlabels;
3441 default: Q_ASSERT(
"unsupported upside-down label setting" && 0 );
return 0;
3443 l->setUpsidedownLabels( upsdnlabels );
3502 Layer* l =
mPal->addLayer( layer->
id().append(
"d" ).toUtf8().data(), -1, -1, pal::Arrangement( s->
placement ), METER, s->
priority, s->
obstacle,
true, true );
3532 QHash<QString, QgsDiagramLayerSettings>::iterator layerIt =
mActiveDiagramLayers.find( layerID );
3543 geom->
transform( *( layerIt.value().ct ) );
3546 const GEOSGeometry* geos_geom = geom->
asGeos();
3547 if ( geos_geom == 0 )
3557 layerIt.value().geometries.append( lbl );
3559 double diagramWidth = 0;
3560 double diagramHeight = 0;
3565 if ( diagSize.isValid() )
3567 diagramWidth = diagSize.width();
3568 diagramHeight = diagSize.height();
3576 int ddColX = layerIt.value().xPosColumn;
3577 int ddColY = layerIt.value().yPosColumn;
3578 double ddPosX = 0.0;
3579 double ddPosY = 0.0;
3580 bool ddPos = ( ddColX >= 0 && ddColY >= 0 );
3583 bool posXOk, posYOk;
3585 ddPosX = feat.
attribute( ddColX ).toDouble( &posXOk ) - diagramWidth / 2.0;
3586 ddPosY = feat.
attribute( ddColY ).toDouble( &posYOk ) - diagramHeight / 2.0;
3587 if ( !posXOk || !posYOk )
3604 if ( !layerIt.value().palLayer->registerFeature( lbl->
strId(), lbl, diagramWidth, diagramHeight,
"", ddPosX, ddPosY, ddPos ) )
3609 catch ( std::exception &e )
3612 QgsDebugMsgLevel( QString(
"Ignoring feature %1 due PAL exception:" ).arg( feat.
id() ) + QString::fromLatin1( e.what() ), 4 );
3616 pal::Feature* palFeat = layerIt.value().palLayer->getFeature( lbl->
strId() );
3617 QgsPoint ptZero = layerIt.value().xform->toMapCoordinates( 0, 0 );
3618 QgsPoint ptOne = layerIt.value().xform->toMapCoordinates( 1, 0 );
3619 palFeat->setDistLabel( qAbs( ptOne.
x() - ptZero.
x() ) * layerIt.value().dist );
3642 case Chain: s = CHAIN;
break;
3646 case Falp: s = FALP;
break;
3648 mPal->setSearch( s );
3670 QHash<QString, QgsPalLayerSettings>::iterator lit;
3673 if ( lit.key() == layerName )
3682 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3688 tmpLyr.
textColor = ddColor.value<QColor>();
3707 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3760 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3817 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
3928 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues )
4003 QPainter* painter = context.
painter();
4019 std::list<LabelPosition*>* labels;
4020 pal::Problem* problem;
4023 problem =
mPal->extractProblem( scale, bbox );
4025 catch ( std::exception& e )
4028 QgsDebugMsgLevel(
"PAL EXCEPTION :-( " + QString::fromLatin1( e.what() ), 4 );
4044 painter->setPen( QColor( 0, 0, 0, 64 ) );
4045 painter->setBrush( Qt::NoBrush );
4046 for (
int i = 0; i < problem->getNumFeatures(); i++ )
4048 for (
int j = 0; j < problem->getFeatureCandidateCount( i ); j++ )
4050 pal::LabelPosition* lp = problem->getFeatureCandidate( i, j );
4060 QgsDebugMsgLevel( QString(
"LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels->size() ), 4 );
4071 painter->setRenderHint( QPainter::Antialiasing );
4074 std::list<LabelPosition*>::iterator it = labels->begin();
4075 for ( ; it != labels->end(); ++it )
4087 QString layerName = QString::fromUtf8(( *it )->getLayerName() );
4095 if ( QString( dit.key() +
"d" ) == layerName )
4097 feature.
setFields( &dit.value().fields );
4098 palGeometry->
feature( feature );
4100 dit.value().renderer->renderDiagram( feature, context, QPointF( outPt.
x(), outPt.
y() ) );
4108 QString layerId = layerName;
4123 const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues = palGeometry->
dataDefinedValues();
4128 #if QT_VERSION >= 0x040800
4130 QgsDebugMsgLevel( QString(
"PAL font definedFont: %1, Style: %2" ).arg( dFont.toString() ).arg( dFont.styleName() ), 4 );
4185 QString labeltext = ((
QgsPalGeometry* )( *it )->getFeaturePart()->getUserGeometry() )->text();
4191 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
4193 QgsDebugMsgLevel( QString(
"LABELING draw: %1 ms" ).arg( t.elapsed() ), 4 );
4203 QHash<QString, QgsPalLayerSettings>::iterator lit;
4207 for ( QList<QgsPalGeometry*>::iterator git = lyr.
geometries.begin(); git != lyr.
geometries.end(); ++git )
4224 for ( QList<QgsPalGeometry*>::iterator git = dls.
geometries.begin(); git != dls.
geometries.end(); ++git )
4281 QgsPoint outPt2 = xform->
transform( lp->getX() + lp->getWidth(), lp->getY() + lp->getHeight() );
4284 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4285 painter->rotate( -lp->getAlpha() * 180 /
M_PI );
4286 QRectF rect( 0, 0, outPt2.
x() - outPt.
x(), outPt2.
y() - outPt.
y() );
4287 painter->drawRect( rect );
4291 rect.moveTo( outPt.
x(), outPt.
y() );
4295 if ( lp->getNextPart() )
4302 QPainter* painter = context.
painter();
4320 label->getY() + label->getHeight() / 2 );
4322 double xc = outPt2.
x() - outPt.
x();
4323 double yc = outPt2.
y() - outPt.
y();
4325 double angle = -label->getAlpha();
4326 double xd = xc * cos( angle ) - yc * sin( angle );
4327 double yd = xc * sin( angle ) + yc * cos( angle );
4329 centerPt.
setX( centerPt.
x() + xd );
4330 centerPt.
setY( centerPt.
y() + yd );
4333 component.
setSize(
QgsPoint( label->getWidth(), label->getHeight() ) );
4343 QString text = ((
QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();
4344 QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) );
4345 QFontMetricsF* labelfm = ((
QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->getLabelFontMetrics();
4347 QString wrapchr = !tmpLyr.
wrapChar.isEmpty() ? tmpLyr.
wrapChar : QString(
"\n" );
4353 bool prependSymb =
false;
4356 if ( label->getReversed() )
4371 prependSymb =
false;
4379 symb = symb + wrapchr;
4383 prependSymb =
false;
4384 symb = wrapchr + symb;
4389 txt.prepend( symb );
4399 QStringList multiLineList = txt.split( wrapchr );
4400 int lines = multiLineList.size();
4402 double labelWidest = 0.0;
4403 for (
int i = 0; i < lines; ++i )
4405 double labelWidth = labelfm->width( multiLineList.at( i ) );
4406 if ( labelWidth > labelWidest )
4408 labelWidest = labelWidth;
4412 double labelHeight = labelfm->ascent() + labelfm->descent();
4416 double ascentOffset = 0.25 * labelfm->ascent();
4418 for (
int i = 0; i < lines; ++i )
4421 painter->translate( QPointF( outPt.
x(), outPt.
y() ) );
4422 painter->rotate( -label->getAlpha() * 180 /
M_PI );
4429 double xMultiLineOffset = 0.0;
4430 double labelWidth = labelfm->width( multiLineList.at( i ) );
4433 double labelWidthDiff = labelWidest - labelWidth;
4436 labelWidthDiff /= 2;
4438 xMultiLineOffset = labelWidthDiff;
4442 double yMultiLineOffset = ( lines - 1 - i ) * labelHeight * tmpLyr.
multilineHeight;
4443 painter->translate( QPointF( xMultiLineOffset, - ascentOffset - yMultiLineOffset ) );
4445 component.
setText( multiLineList.at( i ) );
4460 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4465 textp.begin( &textPict );
4466 textp.setPen( Qt::NoPen );
4468 textp.drawPath( path );
4488 painter->setCompositionMode( tmpLyr.
blendMode );
4498 painter->drawPicture( 0, 0, textPict );
4503 painter->setFont( tmpLyr.
textFont );
4505 painter->setRenderHint( QPainter::TextAntialiasing );
4506 painter->drawText( 0, 0, component.
text() );
4514 if ( label->getNextPart() )
4515 drawLabel( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
4522 QPainter* p = context.
painter();
4528 path.addText( 0, 0, tmpLyr.
textFont, component.
text() );
4530 pen.setWidthF( penSize );
4536 tmpColor.setAlpha( 0 );
4542 buffp.begin( &buffPict );
4543 buffp.setPen( pen );
4544 buffp.setBrush( tmpColor );
4545 buffp.drawPath( path );
4569 p->drawPicture( 0, 0, buffPict );
4577 QPainter* p = context.
painter();
4578 double labelWidth = component.
size().
x(), labelHeight = component.
size().
y();
4608 double sizeOut = 0.0;
4617 if ( labelWidth >= labelHeight )
4618 sizeOut = labelWidth;
4619 else if ( labelHeight > labelWidth )
4620 sizeOut = labelHeight;
4625 sizeOut /= mmToMapUnits;
4639 map[
"size"] = QString::number( sizeOut );
4642 map[
"angle"] = QString::number( 0.0 );
4670 svgp.begin( &svgPict );
4689 svgShdwM->
renderPoint( QPointF( svgSize / 2, -svgSize / 2 ), svgShdwContext );
4706 p->translate( QPointF( xoff, yoff ) );
4708 p->translate( -svgSize / 2, svgSize / 2 );
4732 p->translate( QPointF( xoff, yoff ) );
4735 p->setCompositionMode( QPainter::CompositionMode_SourceOver );
4769 h = sqrt( pow( w, 2 ) + pow( h, 2 ) );
4775 h = h / sqrt( 2.0 ) * 2;
4776 w = w / sqrt( 2.0 ) * 2;
4788 QRectF rect( -w / 2.0, - h / 2.0, w, h );
4790 if ( rect.isNull() )
4794 p->translate( QPointF( component.
center().
x(), component.
center().
y() ) );
4798 p->translate( QPointF( xoff, yoff ) );
4807 pen.setWidthF( penSize );
4819 shapep.begin( &shapePict );
4820 shapep.setPen( pen );
4828 shapep.drawRoundedRect( rect, tmpLyr.
shapeRadii.x(), tmpLyr.
shapeRadii.y(), Qt::RelativeSize );
4834 shapep.drawRoundedRect( rect, xRadius, yRadius );
4840 shapep.drawEllipse( rect );
4865 p->drawPicture( 0, 0, shapePict );
4878 QPainter* p = context.
painter();
4879 double componentWidth = component.
size().
x(), componentHeight = component.
size().
y();
4880 double xOffset = component.
offset().
x(), yOffset = component.
offset().
y();
4887 radius = ( int )( radius + 0.5 );
4891 double blurBufferClippingScale = 3.75;
4892 int blurbuffer = ( radius > 17 ? 16 : radius ) * blurBufferClippingScale;
4894 QImage blurImg( componentWidth + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4895 componentHeight + ( pictbuffer * 2.0 ) + ( blurbuffer * 2.0 ),
4896 QImage::Format_ARGB32_Premultiplied );
4900 int minBlurImgSize = 1;
4904 int maxBlurImgSize = 40000;
4905 if ( blurImg.isNull()
4906 || ( blurImg.width() < minBlurImgSize || blurImg.height() < minBlurImgSize )
4907 || ( blurImg.width() > maxBlurImgSize || blurImg.height() > maxBlurImgSize ) )
4910 blurImg.fill( QColor( Qt::transparent ).rgba() );
4912 if ( !pictp.begin( &blurImg ) )
4914 pictp.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4915 QPointF imgOffset( blurbuffer + pictbuffer + xOffset,
4916 blurbuffer + pictbuffer + componentHeight + yOffset );
4918 pictp.drawPicture( imgOffset,
4922 pictp.setCompositionMode( QPainter::CompositionMode_SourceIn );
4923 pictp.fillRect( blurImg.rect(), tmpLyr.
shadowColor );
4936 picti.begin( &blurImg );
4937 picti.setBrush( Qt::Dense7Pattern );
4938 QPen imgPen( QColor( 0, 0, 255, 255 ) );
4939 imgPen.setWidth( 1 );
4940 picti.setPen( imgPen );
4941 picti.setOpacity( 0.1 );
4942 picti.drawRect( 0, 0, blurImg.width(), blurImg.height() );
4958 QPointF transPt( -offsetDist * cos( angleRad +
M_PI / 2 ),
4959 -offsetDist * sin( angleRad +
M_PI / 2 ) );
4962 p->setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
4969 double scale = ( double )tmpLyr.
shadowScale / 100.0;
4971 p->scale( scale, scale );
4976 p->translate( transPt );
4977 p->translate( -imgOffset.x(),
4979 p->drawImage( 0, 0, blurImg );
4987 p->setBrush( Qt::NoBrush );
4988 QPen imgPen( QColor( 255, 0, 0, 10 ) );
4989 imgPen.setWidth( 2 );
4990 imgPen.setStyle( Qt::DashLine );
4991 p->setPen( imgPen );
4992 p->scale( scale, scale );
4997 p->translate( transPt );
4998 p->translate( -imgOffset.x(),
5000 p->drawRect( 0, 0, blurImg.width(), blurImg.height() );
5005 p->setBrush( Qt::NoBrush );
5006 QPen componentRectPen( QColor( 0, 255, 0, 70 ) );
5007 componentRectPen.setWidth( 1 );
5012 p->setPen( componentRectPen );
5013 p->drawRect( QRect( -xOffset, -componentHeight - yOffset, componentWidth, componentHeight ) );
5024 "PAL",
"/SearchMethod", (
int )p.getSearch(), &saved ) );
5026 "PAL",
"/CandidatesPoint", p.getPointP(), &saved );
5028 "PAL",
"/CandidatesLine", p.getLineP(), &saved );
5030 "PAL",
"/CandidatesPolygon", p.getPolyP(), &saved );
5032 "PAL",
"/ShowingCandidates",
false, &saved );
5034 "PAL",
"/ShowingShadowRects",
false, &saved );
5036 "PAL",
"/ShowingAllLabels",
false, &saved );
5038 "PAL",
"/ShowingPartialsLabels", p.getShowPartial(), &saved );
5040 "PAL",
"/DrawOutlineLabels",
true, &saved );
5094 QList<QgsLabelPosition> positions;
5096 QList<QgsLabelPosition*> positionPointers;
5100 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
5101 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )
5112 QList<QgsLabelPosition> positions;
5114 QList<QgsLabelPosition*> positionPointers;
5118 QList<QgsLabelPosition*>::const_iterator pointerIt = positionPointers.constBegin();
5119 for ( ; pointerIt != positionPointers.constEnd(); ++pointerIt )
const QgsMapSettings & mapSettings()
bridge to QgsMapSettings
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)
static void _fixQPictureDPI(QPainter *p)
void calculateLabelSize(const QFontMetricsF *fm, QString text, double &labelX, double &labelY, QgsFeature *f=0)
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)
A rectangle specified with double values.
virtual Q_DECL_DEPRECATED QList< QgsLabelPosition > labelsWithinRect(const QgsRectangle &r)
return infos about labels within a given (map) rectangle
double maxCurvedCharAngleOut
QString leftDirectionSymbol
QgsExpression * expression
void label(const QgsPoint &p, QList< QgsLabelPosition * > &posList) const
Returns label position(s) at a given point.
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.
QgsMapUnitScale shapeSizeMapUnitScale
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)
QgsMapUnitScale shadowRadiusMapUnitScale
virtual void drawLabel(pal::LabelPosition *label, QgsRenderContext &context, QgsPalLayerSettings &tmpLyr, DrawLabelType drawType, double dpiRatio=1.0)
drawLabel
double scale() const
Return the calculated scale of the map.
double length()
get length of geometry using GEOS
SizeUnit repeatDistanceUnit
const QgsMapSettings * mMapSettings
void addDataDefinedValue(QgsPalLayerSettings::DataDefinedProperties p, QVariant v)
void setNumCandidatePositions(int candPoint, int candLine, int candPolygon)
QgsExpression * expression()
const QgsPoint & offset()
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
QgsLabelingResults * takeResults()
Return pointer to recently computed results (in drawLabeling()) and pass the ownership of results to ...
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)
virtual void clearActiveLayer(const QString &layerID)
clears data defined objects from PAL layer settings for a registered layer
void setSearchMethod(Search s)
virtual Q_DECL_DEPRECATED 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
QgsMapUnitScale shadowOffsetMapUnitScale
D