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
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
double computeMapUnitsPerPixel(const QgsRenderContext &c) const
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)
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
virtual Q_DECL_DEPRECATED 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 bool _palIsCancelled(void *ctx)
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
static QPointF decodePoint(QString str)
Container of fields for a vector layer.
static QgsPalLayerSettings fromLayer(QgsVectorLayer *layer)
void setAttributes(const QgsAttributes &attrs)
void saveEngineSettings()
void readFromLayer(QgsVectorLayer *layer)
static QColor decodeColor(QString str)
QString expressionString() const
const QgsRectangle & extent() const
const QgsMapToPixel & mapToPixel() 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 setIsDiagram(bool d)
QgsMapUnitScale repeatDistanceMapUnitScale
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...
virtual int addDiagramLayer(QgsVectorLayer *layer, const QgsDiagramLayerSettings *s)
adds a diagram layer to the labeling engine
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)
QMap< QString, QString > QgsStringMap
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=0) const
double maxCurvedCharAngleIn
bool reverseDirectionSymbol
double maxScale
The maximum scale, or 0.0 if unset.
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.
QgsMapUnitScale fontSizeMapUnitScale
bool dataDefinedEvaluate(QgsPalLayerSettings::DataDefinedProperties p, QVariant &exprVal) const
Get data defined property value from expression string or attribute field name.
The QgsMapSettings class contains configuration for rendering of the map.
QgsMapUnitScale shapeBorderWidthMapUnitScale
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
bool dataDefinedUseExpression(QgsPalLayerSettings::DataDefinedProperties p) const
Whether data definition is set to use an expression.
static bool staticWillUseLayer(QgsVectorLayer *layer)
called to find out whether the layer is used for labeling
bool isGeosValid()
check validity using GEOS
Perform transforms between map coordinates and device coordinates.
QList< QgsLabelPosition > labelsWithinRect(const QgsRectangle &r) const
return infos about labels within a given (map) rectangle
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()
QgsGeometry * buffer(double distance, int segments)
Returns a buffer region around this geometry having the given width and with a specified number of se...
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
QgsMapUnitScale shapeRadiiMapUnitScale
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
bool renderingStopped() const
QMap< QgsPalLayerSettings::DataDefinedProperties, QPair< QString, int > > mDataDefinedNames
QPainter::CompositionMode blendMode
const QgsPoint & center()
static bool fontFamilyOnSystem(const QString &family)
Check whether font family is on system in a quick manner, which does not compare [foundry].
QHash< QString, QgsDiagramLayerSettings > mActiveDiagramLayers
QList< QgsLabelPosition > labelsAtPosition(const QgsPoint &p) const
return infos about labels at a given (map) position
void setField(const QString &field)
QString updateDataDefinedString(const QString &value)
Convert old property value to new one as delimited values.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
virtual QgsAttrPalIndexNameHash palAttributeIndexNames() const
Return list of indexes to names for QgsPalLabeling fix.
static void drawLabelShadow(QgsRenderContext &context, QgsLabelComponent component, const QgsPalLayerSettings &tmpLyr)
void registerFeature(QgsFeature &f, const QgsRenderContext &context)
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)
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 deleteTemporaryData()
void setDpiRatio(double ratio)
QgsMapUnitScale bufferSizeMapUnitScale
double mapUnitsPerPixel() const
Return current map units per pixel.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
const QgsPoint & origin()
QgsDiagramRendererV2 * renderer
void removeCustomProperty(const QString &key)
Remove a custom property from layer.
QPainter::CompositionMode shapeBlendMode
void setPictureBuffer(double buffer)
double scaleToPixelContext(double size, const QgsRenderContext &c, SizeUnit unit, bool rasterfactor=false, const QgsMapUnitScale &mapUnitScale=QgsMapUnitScale()) const
Calculates size (considering output size should be in pixel or map units, scale factors and optionall...
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.
const QgsDiagramRendererV2 * diagramRenderer() const
A class to represent a point geometry.
QHash< QString, QgsPalLayerSettings > mActiveLayers
void setFields(const QgsFields *fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
void setDiagramAttributes(const QgsAttributes &attrs)
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)
virtual void registerDiagramFeature(const QString &layerID, QgsFeature &feat, const QgsRenderContext &context=QgsRenderContext())
called for every diagram feature
Q_GUI_EXPORT int qt_defaultDpiX()
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
virtual void registerFeature(const QString &layerID, QgsFeature &feat, const QgsRenderContext &context=QgsRenderContext())
hook called when drawing for every feature in a layer
QgsLabelSearchTree * mLabelSearchTree
void setValid(bool validity)
Set the validity of the feature.
void setSize(QgsPoint point)
QString rightDirectionSymbol
Q_GUI_EXPORT int qt_defaultDpiY()
virtual int prepareLayer(QgsVectorLayer *layer, QStringList &attrNames, QgsRenderContext &ctx)
hook called when drawing layer before issuing select()
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.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
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)
QgsMapUnitScale distMapUnitScale
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
bool shadowRadiusAlphaOnly
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
int sizeToPixel(double size, const QgsRenderContext &c, SizeUnit unit, bool rasterfactor=false, const QgsMapUnitScale &mapUnitScale=QgsMapUnitScale()) const
Calculates pixel size (considering output size should be in pixel or map units, scale factors and opt...
static QgsProject * instance()
access to canonical QgsProject instance
virtual void clearActiveLayers()
clears all PAL layer settings for registered layers
void setMapToPixel(const QgsMapToPixel &mtp)
int size() const
Return number of items.
SizeUnit shadowRadiusUnits
virtual QgsDiagramRendererV2 * clone() const =0
Returns new instance that is equivalent to this one.
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)
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
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
Class that stores computed placement from labeling engine.
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
QgsMapUnitScale shapeOffsetMapUnitScale
QList< QgsLabelCandidate > mCandidates
Labeling engine interface.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
void setCenter(QgsPoint point)
SizeUnit shapeOffsetUnits
void labelsInRect(const QgsRectangle &r, QList< QgsLabelPosition * > &posList) const
Returns label position(s) in given rectangle.
void setScale(double scale)
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.
double minScale
The minimum scale, or 0.0 if unset.
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
QgsMapUnitScale labelOffsetMapUnitScale
QMap< DataDefinedProperties, QVariant > dataDefinedValues
static QColor _readColor(QgsVectorLayer *layer, QString property, QColor defaultColor=Qt::black, bool withAlpha=true)
QgsLabelingResults * mResults
LinePlacementFlags placementFlags
const QgsFields * mCurFields
void setOrigin(QgsPoint point)
DirectionSymbols placeDirectionSymbol
void parseShapeBackground()
void dataDefinedTextFormatting(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)