55#include <QApplication>
57#include <QFontMetrics>
62#include <QTextBoundaryFinder>
66using namespace Qt::StringLiterals;
100void QgsPalLayerSettings::initPropertyDefinitions()
102 if ( !sPropertyDefinitions()->isEmpty() )
105 const QString origin = u
"labeling"_s;
117 "e.g. Helvetica or Helvetica [Cronyx]" ), origin )
121 "e.g. Bold Condensed or Light Italic" ), origin )
163 "<b>Ellipse</b>|<b>Circle</b>|<b>SVG</b>]" ), origin )
187 "<b>Buffer</b>|<b>Background</b>]" ), origin )
203 "<b>3</b>=Left|<b>4</b>=Over|<b>5</b>=Right|<br>"
204 "<b>6</b>=Below Left|<b>7</b>=Below|<b>8</b>=Below Right]" ), origin )
225 + QStringLiteral(
"[<b>TL</b>=Top left|<b>TSL</b>=Top, slightly left|<b>T</b>=Top middle|<br>"
226 "<b>TSR</b>=Top, slightly right|<b>TR</b>=Top right|<br>"
227 "<b>L</b>=Left|<b>R</b>=Right|<br>"
228 "<b>BL</b>=Bottom left|<b>BSL</b>=Bottom, slightly left|<b>B</b>=Bottom middle|<br>"
229 "<b>BSR</b>=Bottom, slightly right|<b>BR</b>=Bottom right|<b>O</b>=Over point]" ), origin )
233 + QStringLiteral(
"[<b>OL</b>=On line|<b>AL</b>=Above line|<b>BL</b>=Below line|<br>"
234 "<b>LO</b>=Respect line orientation]" ), origin )
243 "<b>Half</b>|<b>Cap</b>|<b>Top</b>]" ), origin )
279 mPointSettings.setPredefinedPositionOrder( *DEFAULT_PLACEMENT_ORDER() );
281 initPropertyDefinitions();
289 : mDataDefinedProperties( s.mDataDefinedProperties )
324 mPolygonPlacementFlags = s.mPolygonPlacementFlags;
338 mRotationUnit = s.mRotationUnit;
358 mDataDefinedProperties = s.mDataDefinedProperties;
360 mCallout.reset( s.mCallout ? s.mCallout->clone() :
nullptr );
362 mPlacementSettings = s.mPlacementSettings;
363 mLineSettings = s.mLineSettings;
364 mPointSettings = s.mPointSettings;
365 mObstacleSettings = s.mObstacleSettings;
366 mThinningSettings = s.mThinningSettings;
373 mLegendString = s.mLegendString;
375 mUnplacedVisibility = s.mUnplacedVisibility;
410 if (
drawLabels || mObstacleSettings.isObstacle() )
425 for (
const QString &name : referencedColumns )
427 attributeNames.insert( name );
484 if ( mGeometryGeneratorExpression.hasParserError() )
490 const auto referencedColumns = mGeometryGeneratorExpression.referencedColumns();
491 for (
const QString &name : referencedColumns )
493 attributeNames.insert( name );
496 attributeNames.unite( mFormat.referencedFields( context ) );
500 const auto referencedColumns = mCallout->referencedFields( context );
501 for (
const QString &name : referencedColumns )
503 attributeNames.insert( name );
512 QSet<QString> referenced;
525 referenced.unite( mFormat.referencedFields( context ) );
530 referenced.unite( mDataDefinedProperties.referencedFields( context.
expressionContext(),
true ) );
540 referenced.unite( mCallout->referencedFields( context ) );
548 if ( mRenderStarted )
550 qWarning(
"Start render called for when a previous render was already underway!!" );
577 mCallout->startRender( context );
580 mRenderStarted =
true;
585 if ( !mRenderStarted )
587 qWarning(
"Stop render called for QgsPalLayerSettings without a startRender call!" );
593 mCallout->stopRender( context );
596 mRenderStarted =
false;
601 return mFormat.containsAdvancedEffects() || mCallout->containsAdvancedEffects();
606 if ( mRenderStarted )
608 qWarning(
"stopRender was not called on QgsPalLayerSettings object!" );
615 initPropertyDefinitions();
616 return *sPropertyDefinitions();
623 expression = std::make_unique<QgsExpression>(
fieldName );
625 return expression.get();
630 return mRotationUnit;
635 mRotationUnit = angleUnit;
641 QString newValue = value;
642 if ( !value.isEmpty() && !value.contains(
"~~"_L1 ) )
649 newValue = values.join(
"~~"_L1 );
657 QString newPropertyName =
"labeling/dataDefined/" + sPropertyDefinitions()->value(
static_cast< int >( p ) ).name();
658 QVariant newPropertyField = layer->
customProperty( newPropertyName, QVariant() );
660 if ( !newPropertyField.isValid() )
663 QString ddString = newPropertyField.toString();
665 if ( !ddString.isEmpty() && ddString !=
"0~~0~~~~"_L1 )
669 QStringList ddv = newStyleString.split( u
"~~"_s );
671 bool active = ddv.at( 0 ).toInt();
672 if ( ddv.at( 1 ).toInt() )
688void QgsPalLayerSettings::readOldDataDefinedPropertyMap(
QgsVectorLayer *layer, QDomElement *parentElem )
690 if ( !layer && !parentElem )
695 QgsPropertiesDefinition::const_iterator i = sPropertyDefinitions()->constBegin();
696 for ( ; i != sPropertyDefinitions()->constEnd(); ++i )
701 readOldDataDefinedProperty( layer,
static_cast< Property >( i.key() ) );
703 else if ( parentElem )
706 QDomElement e = parentElem->firstChildElement( i.value().name() );
709 bool active = e.attribute( u
"active"_s ).compare(
"true"_L1, Qt::CaseInsensitive ) == 0;
710 bool isExpression = e.attribute( u
"useExpr"_s ).compare(
"true"_L1, Qt::CaseInsensitive ) == 0;
717 mDataDefinedProperties.setProperty( i.key(),
QgsProperty::fromField( e.attribute( u
"field"_s ), active ) );
724void QgsPalLayerSettings::readFromLayerCustomProperties(
QgsVectorLayer *layer )
726 if ( layer->
customProperty( u
"labeling"_s ).toString() !=
"pal"_L1 )
743 mFormat.readFromLayer( layer );
751 QDomDocument doc( u
"substitutions"_s );
752 doc.setContent( layer->
customProperty( u
"labeling/substitutions"_s ).toString() );
753 QDomElement replacementElem = doc.firstChildElement( u
"substitutions"_s );
763 mLineSettings.setAddDirectionSymbol( layer->
customProperty( u
"labeling/addDirectionSymbol"_s ).toBool() );
764 mLineSettings.setLeftDirectionSymbol( layer->
customProperty( u
"labeling/leftDirectionSymbol"_s, QVariant(
"<" ) ).toString() );
765 mLineSettings.setRightDirectionSymbol( layer->
customProperty( u
"labeling/rightDirectionSymbol"_s, QVariant(
">" ) ).toString() );
766 mLineSettings.setReverseDirectionSymbol( layer->
customProperty( u
"labeling/reverseDirectionSymbol"_s ).toBool() );
779 if ( predefinedPositionOrder.isEmpty() )
780 predefinedPositionOrder = *DEFAULT_PLACEMENT_ORDER();
781 mPointSettings.setPredefinedPositionOrder( predefinedPositionOrder );
786 if ( layer->
customProperty( u
"labeling/distMapUnitScale"_s ).toString().isEmpty() )
789 double oldMin = layer->
customProperty( u
"labeling/distMapUnitMinScale"_s, 0.0 ).toDouble();
791 double oldMax = layer->
customProperty( u
"labeling/distMapUnitMaxScale"_s, 0.0 ).toDouble();
802 if ( layer->
customProperty( u
"labeling/labelOffsetInMapUnits"_s, QVariant(
true ) ).toBool() )
807 if ( layer->
customProperty( u
"labeling/labelOffsetMapUnitScale"_s ).toString().isEmpty() )
810 double oldMin = layer->
customProperty( u
"labeling/labelOffsetMapUnitMinScale"_s, 0.0 ).toDouble();
812 double oldMax = layer->
customProperty( u
"labeling/labelOffsetMapUnitMaxScale"_s, 0.0 ).toDouble();
820 QVariant tempAngle = layer->
customProperty( u
"labeling/angleOffset"_s, QVariant() );
821 if ( tempAngle.isValid() )
823 double oldAngle = layer->
customProperty( u
"labeling/angleOffset"_s, QVariant( 0.0 ) ).toDouble();
837 switch ( layer->
customProperty( u
"labeling/repeatDistanceUnit"_s, QVariant( 1 ) ).toUInt() )
852 if ( layer->
customProperty( u
"labeling/repeatDistanceMapUnitScale"_s ).toString().isEmpty() )
855 double oldMin = layer->
customProperty( u
"labeling/repeatDistanceMapUnitMinScale"_s, 0.0 ).toDouble();
857 double oldMax = layer->
customProperty( u
"labeling/repeatDistanceMapUnitMaxScale"_s, 0.0 ).toDouble();
866 double scalemn = layer->
customProperty( u
"labeling/scaleMin"_s, QVariant( 0 ) ).toDouble();
867 double scalemx = layer->
customProperty( u
"labeling/scaleMax"_s, QVariant( 0 ) ).toDouble();
870 QVariant scalevis = layer->
customProperty( u
"labeling/scaleVisibility"_s, QVariant() );
871 if ( scalevis.isValid() )
877 else if ( scalemn > 0 || scalemx > 0 )
893 if ( layer->
customProperty( u
"labeling/displayAll"_s, QVariant(
false ) ).toBool() )
896 mPlacementSettings.setAllowDegradedPlacement(
true );
901 mPlacementSettings.setAllowDegradedPlacement(
false );
905 mLineSettings.setMergeLines( layer->
customProperty( u
"labeling/mergeLines"_s ).toBool() );
906 mThinningSettings.setMinimumFeatureSize( layer->
customProperty( u
"labeling/minFeatureSize"_s ).toDouble() );
907 mThinningSettings.setLimitNumberLabelsEnabled( layer->
customProperty( u
"labeling/limitNumLabels"_s, QVariant(
false ) ).toBool() );
908 mThinningSettings.setMaximumNumberLabels( layer->
customProperty( u
"labeling/maxNumLabels"_s, QVariant( 2000 ) ).toInt() );
909 mObstacleSettings.setIsObstacle( layer->
customProperty( u
"labeling/obstacle"_s, QVariant(
true ) ).toBool() );
910 mObstacleSettings.setFactor( layer->
customProperty( u
"labeling/obstacleFactor"_s, QVariant( 1.0 ) ).toDouble() );
914 mDataDefinedProperties.clear();
915 if ( layer->
customProperty( u
"labeling/ddProperties"_s ).isValid() )
917 QDomDocument doc( u
"dd"_s );
918 doc.setContent( layer->
customProperty( u
"labeling/ddProperties"_s ).toString() );
919 QDomElement elem = doc.firstChildElement( u
"properties"_s );
920 mDataDefinedProperties.readXml( elem, *sPropertyDefinitions() );
925 readOldDataDefinedPropertyMap( layer,
nullptr );
969 QDomElement textStyleElem = elem.firstChildElement( u
"text-style"_s );
970 fieldName = textStyleElem.attribute( u
"fieldName"_s );
971 isExpression = textStyleElem.attribute( u
"isExpression"_s ).toInt();
973 mFormat.readXml( elem, context );
975 previewBkgrdColor = QColor( textStyleElem.attribute( u
"previewBkgrdColor"_s, u
"#ffffff"_s ) );
977 substitutions.readXml( textStyleElem.firstChildElement( u
"substitutions"_s ) );
978 useSubstitutions = textStyleElem.attribute( u
"useSubstitutions"_s ).toInt();
979 mLegendString = textStyleElem.attribute( u
"legendString"_s, QObject::tr(
"Aa" ) );
982 QDomElement textFormatElem = elem.firstChildElement( u
"text-format"_s );
983 wrapChar = textFormatElem.attribute( u
"wrapChar"_s );
984 autoWrapLength = textFormatElem.attribute( u
"autoWrapLength"_s, u
"0"_s ).toInt();
987 mLineSettings.setAddDirectionSymbol( textFormatElem.attribute( u
"addDirectionSymbol"_s ).toInt() );
988 mLineSettings.setLeftDirectionSymbol( textFormatElem.attribute( u
"leftDirectionSymbol"_s, u
"<"_s ) );
989 mLineSettings.setRightDirectionSymbol( textFormatElem.attribute( u
"rightDirectionSymbol"_s, u
">"_s ) );
990 mLineSettings.setReverseDirectionSymbol( textFormatElem.attribute( u
"reverseDirectionSymbol"_s ).toInt() );
992 formatNumbers = textFormatElem.attribute( u
"formatNumbers"_s ).toInt();
993 decimals = textFormatElem.attribute( u
"decimals"_s ).toInt();
994 plusSign = textFormatElem.attribute( u
"plussign"_s ).toInt();
997 QDomElement placementElem = elem.firstChildElement( u
"placement"_s );
1002 centroidWhole = placementElem.attribute( u
"centroidWhole"_s, u
"0"_s ).toInt();
1003 centroidInside = placementElem.attribute( u
"centroidInside"_s, u
"0"_s ).toInt();
1006 if ( predefinedPositionOrder.isEmpty() )
1007 predefinedPositionOrder = *DEFAULT_PLACEMENT_ORDER();
1008 mPointSettings.setPredefinedPositionOrder( predefinedPositionOrder );
1010 fitInPolygonOnly = placementElem.attribute( u
"fitInPolygonOnly"_s, u
"0"_s ).toInt();
1011 dist = placementElem.attribute( u
"dist"_s ).toDouble();
1012 if ( !placementElem.hasAttribute( u
"distUnits"_s ) )
1014 if ( placementElem.attribute( u
"distInMapUnits"_s ).toInt() )
1023 if ( !placementElem.hasAttribute( u
"distMapUnitScale"_s ) )
1026 double oldMin = placementElem.attribute( u
"distMapUnitMinScale"_s, u
"0"_s ).toDouble();
1028 double oldMax = placementElem.attribute( u
"distMapUnitMaxScale"_s, u
"0"_s ).toDouble();
1037 xOffset = placementElem.attribute( u
"xOffset"_s, u
"0"_s ).toDouble();
1038 yOffset = placementElem.attribute( u
"yOffset"_s, u
"0"_s ).toDouble();
1039 if ( !placementElem.hasAttribute( u
"offsetUnits"_s ) )
1047 if ( !placementElem.hasAttribute( u
"labelOffsetMapUnitScale"_s ) )
1050 double oldMin = placementElem.attribute( u
"labelOffsetMapUnitMinScale"_s, u
"0"_s ).toDouble();
1052 double oldMax = placementElem.attribute( u
"labelOffsetMapUnitMaxScale"_s, u
"0"_s ).toDouble();
1060 if ( placementElem.hasAttribute( u
"angleOffset"_s ) )
1062 double oldAngle = placementElem.attribute( u
"angleOffset"_s, u
"0"_s ).toDouble();
1067 angleOffset = placementElem.attribute( u
"rotationAngle"_s, u
"0"_s ).toDouble();
1070 preserveRotation = placementElem.attribute( u
"preserveRotation"_s, u
"1"_s ).toInt();
1073 if ( rotationUnitString.startsWith(
"Angle"_L1 ) )
1076 rotationUnitString = rotationUnitString.mid( 5 );
1081 maxCurvedCharAngleIn = placementElem.attribute( u
"maxCurvedCharAngleIn"_s, u
"25"_s ).toDouble();
1083 priority = placementElem.attribute( u
"priority"_s ).toInt();
1084 repeatDistance = placementElem.attribute( u
"repeatDistance"_s, u
"0"_s ).toDouble();
1085 if ( !placementElem.hasAttribute( u
"repeatDistanceUnits"_s ) )
1088 switch ( placementElem.attribute( u
"repeatDistanceUnit"_s, QString::number( 1 ) ).toUInt() )
1108 if ( !placementElem.hasAttribute( u
"repeatDistanceMapUnitScale"_s ) )
1111 double oldMin = placementElem.attribute( u
"repeatDistanceMapUnitMinScale"_s, u
"0"_s ).toDouble();
1113 double oldMax = placementElem.attribute( u
"repeatDistanceMapUnitMaxScale"_s, u
"0"_s ).toDouble();
1121 mLineSettings.setOverrunDistance( placementElem.attribute( u
"overrunDistance"_s, u
"0"_s ).toDouble() );
1124 mLineSettings.setLineAnchorPercent( placementElem.attribute( u
"lineAnchorPercent"_s, u
"0.5"_s ).toDouble() );
1131 mPointSettings.setMaximumDistance( placementElem.attribute( u
"maximumDistance"_s, u
"0"_s ).toDouble() );
1138 QString geometryTypeKey = placementElem.attribute( u
"geometryGeneratorType"_s );
1140 if ( geometryTypeKey.endsWith(
"Geometry"_L1 ) )
1141 geometryTypeKey.chop( 8 );
1146 QString layerTypeKey = placementElem.attribute( u
"layerType"_s );
1148 if ( layerTypeKey.endsWith(
"Geometry"_L1 ) )
1149 layerTypeKey.chop( 8 );
1154 mPlacementSettings.setAllowDegradedPlacement( placementElem.attribute( u
"allowDegraded"_s, u
"0"_s ).toInt() );
1157 QDomElement renderingElem = elem.firstChildElement( u
"rendering"_s );
1159 drawLabels = renderingElem.attribute( u
"drawLabels"_s, u
"1"_s ).toInt();
1161 maximumScale = renderingElem.attribute( u
"scaleMin"_s, u
"0"_s ).toDouble();
1162 minimumScale = renderingElem.attribute( u
"scaleMax"_s, u
"0"_s ).toDouble();
1163 scaleVisibility = renderingElem.attribute( u
"scaleVisibility"_s ).toInt();
1165 fontLimitPixelSize = renderingElem.attribute( u
"fontLimitPixelSize"_s, u
"0"_s ).toInt();
1166 fontMinPixelSize = renderingElem.attribute( u
"fontMinPixelSize"_s, u
"0"_s ).toInt();
1167 fontMaxPixelSize = renderingElem.attribute( u
"fontMaxPixelSize"_s, u
"10000"_s ).toInt();
1169 if ( placementElem.hasAttribute( u
"overlapHandling"_s ) )
1176 if ( renderingElem.attribute( u
"displayAll"_s, u
"0"_s ).toInt() )
1179 mPlacementSettings.setAllowDegradedPlacement(
true );
1184 mPlacementSettings.setAllowDegradedPlacement(
false );
1192 if ( placementElem.hasAttribute( u
"multipartBehavior"_s ) )
1199 if ( renderingElem.attribute( u
"labelPerPart"_s, u
"0"_s ).toInt() )
1211 mLineSettings.setMergeLines( renderingElem.attribute( u
"mergeLines"_s ).toInt() );
1212 mThinningSettings.setMinimumFeatureSize( renderingElem.attribute( u
"minFeatureSize"_s ).toDouble() );
1213 mThinningSettings.setLimitNumberLabelsEnabled( renderingElem.attribute( u
"limitNumLabels"_s, u
"0"_s ).toInt() );
1214 mThinningSettings.setMaximumNumberLabels( renderingElem.attribute( u
"maxNumLabels"_s, u
"2000"_s ).toInt() );
1216 mThinningSettings.setLabelMarginDistance( placementElem.attribute( u
"labelMarginDistance"_s, u
"0"_s ).toDouble() );
1221 mThinningSettings.setMinimumDistanceToDuplicateUnit(
QgsUnitTypes::decodeRenderUnit( placementElem.attribute( u
"minDistanceToDuplicatesUnit"_s ) ) );
1223 mThinningSettings.setAllowDuplicateRemoval( placementElem.attribute( u
"allowDuplicateRemoval"_s, u
"0"_s ).toInt() );
1225 mObstacleSettings.setIsObstacle( renderingElem.attribute( u
"obstacle"_s, u
"1"_s ).toInt() );
1226 mObstacleSettings.setFactor( renderingElem.attribute( u
"obstacleFactor"_s, u
"1"_s ).toDouble() );
1228 zIndex = renderingElem.attribute( u
"zIndex"_s, u
"0.0"_s ).toDouble();
1231 QDomElement ddElem = elem.firstChildElement( u
"dd_properties"_s );
1232 if ( !ddElem.isNull() )
1234 mDataDefinedProperties.readXml( ddElem, *sPropertyDefinitions() );
1239 mDataDefinedProperties.clear();
1240 QDomElement ddElem = elem.firstChildElement( u
"data-defined"_s );
1241 readOldDataDefinedPropertyMap(
nullptr, &ddElem );
1282 const QString calloutType = elem.attribute( u
"calloutType"_s );
1283 if ( calloutType.isEmpty() )
1295 QDomElement textStyleElem = mFormat.writeXml( doc, context );
1298 textStyleElem.setAttribute( u
"fieldName"_s,
fieldName );
1299 textStyleElem.setAttribute( u
"isExpression"_s,
isExpression );
1300 QDomElement replacementElem = doc.createElement( u
"substitutions"_s );
1302 textStyleElem.appendChild( replacementElem );
1304 textStyleElem.setAttribute( u
"legendString"_s, mLegendString );
1307 QDomElement textFormatElem = doc.createElement( u
"text-format"_s );
1308 textFormatElem.setAttribute( u
"wrapChar"_s,
wrapChar );
1309 textFormatElem.setAttribute( u
"autoWrapLength"_s,
autoWrapLength );
1311 textFormatElem.setAttribute( u
"multilineAlign"_s,
static_cast< unsigned int >(
multilineAlign ) );
1312 textFormatElem.setAttribute( u
"addDirectionSymbol"_s, mLineSettings.addDirectionSymbol() );
1313 textFormatElem.setAttribute( u
"leftDirectionSymbol"_s, mLineSettings.leftDirectionSymbol() );
1314 textFormatElem.setAttribute( u
"rightDirectionSymbol"_s, mLineSettings.rightDirectionSymbol() );
1315 textFormatElem.setAttribute( u
"reverseDirectionSymbol"_s, mLineSettings.reverseDirectionSymbol() );
1316 textFormatElem.setAttribute( u
"placeDirectionSymbol"_s,
static_cast< unsigned int >( mLineSettings.directionSymbolPlacement() ) );
1317 textFormatElem.setAttribute( u
"formatNumbers"_s,
formatNumbers );
1318 textFormatElem.setAttribute( u
"decimals"_s,
decimals );
1319 textFormatElem.setAttribute( u
"plussign"_s,
plusSign );
1322 QDomElement placementElem = doc.createElement( u
"placement"_s );
1323 placementElem.setAttribute( u
"placement"_s,
static_cast< int >(
placement ) );
1324 placementElem.setAttribute( u
"polygonPlacementFlags"_s,
static_cast< int >( mPolygonPlacementFlags ) );
1325 placementElem.setAttribute( u
"placementFlags"_s,
static_cast< unsigned int >( mLineSettings.placementFlags() ) );
1326 placementElem.setAttribute( u
"centroidWhole"_s,
centroidWhole );
1327 placementElem.setAttribute( u
"centroidInside"_s,
centroidInside );
1330 placementElem.setAttribute( u
"dist"_s,
dist );
1333 placementElem.setAttribute( u
"offsetType"_s,
static_cast< unsigned int >(
offsetType ) );
1334 placementElem.setAttribute( u
"quadOffset"_s,
static_cast< unsigned int >( mPointSettings.quadrant() ) );
1335 placementElem.setAttribute( u
"xOffset"_s,
xOffset );
1336 placementElem.setAttribute( u
"yOffset"_s,
yOffset );
1339 placementElem.setAttribute( u
"rotationAngle"_s,
angleOffset );
1343 const QString rotationUnitString = u
"Angle"_s +
qgsEnumValueToKey( mRotationUnit );
1344 placementElem.setAttribute( u
"rotationUnit"_s, rotationUnitString );
1348 placementElem.setAttribute( u
"priority"_s,
priority );
1349 placementElem.setAttribute( u
"repeatDistance"_s,
repeatDistance );
1352 placementElem.setAttribute( u
"overrunDistance"_s, mLineSettings.overrunDistance() );
1353 placementElem.setAttribute( u
"overrunDistanceUnit"_s,
QgsUnitTypes::encodeUnit( mLineSettings.overrunDistanceUnit() ) );
1355 placementElem.setAttribute( u
"lineAnchorPercent"_s, mLineSettings.lineAnchorPercent() );
1356 placementElem.setAttribute( u
"lineAnchorType"_s,
static_cast< int >( mLineSettings.anchorType() ) );
1357 placementElem.setAttribute( u
"lineAnchorClipping"_s,
static_cast< int >( mLineSettings.anchorClipping() ) );
1358 placementElem.setAttribute( u
"lineAnchorTextPoint"_s,
qgsEnumValueToKey( mLineSettings.anchorTextPoint() ) );
1361 placementElem.setAttribute( u
"curvedLabelMode"_s,
qgsEnumValueToKey( mLineSettings.curvedLabelMode() ) );
1364 placementElem.setAttribute( u
"maximumDistance"_s, mPointSettings.maximumDistance() );
1365 placementElem.setAttribute( u
"maximumDistanceUnit"_s,
QgsUnitTypes::encodeUnit( mPointSettings.maximumDistanceUnit() ) );
1374 placementElem.setAttribute( u
"overlapHandling"_s,
qgsEnumValueToKey( mPlacementSettings.overlapHandling() ) );
1375 placementElem.setAttribute( u
"prioritization"_s,
qgsEnumValueToKey( mPlacementSettings.prioritization() ) );
1376 placementElem.setAttribute( u
"allowDegraded"_s, mPlacementSettings.allowDegradedPlacement() ? u
"1"_s : u
"0"_s );
1379 QDomElement renderingElem = doc.createElement( u
"rendering"_s );
1380 renderingElem.setAttribute( u
"drawLabels"_s,
drawLabels );
1382 renderingElem.setAttribute( u
"scaleMin"_s,
maximumScale );
1383 renderingElem.setAttribute( u
"scaleMax"_s,
minimumScale );
1387 renderingElem.setAttribute( u
"upsidedownLabels"_s,
static_cast< unsigned int >(
upsidedownLabels ) );
1388 placementElem.setAttribute( u
"multipartBehavior"_s,
qgsEnumValueToKey( mPlacementSettings.multiPartBehavior() ) );
1390 placementElem.setAttribute( u
"whitespaceCollisions"_s,
qgsEnumValueToKey( mPlacementSettings.whitespaceCollisionHandling() ) );
1391 renderingElem.setAttribute( u
"mergeLines"_s, mLineSettings.mergeLines() );
1392 renderingElem.setAttribute( u
"minFeatureSize"_s, mThinningSettings.minimumFeatureSize() );
1393 renderingElem.setAttribute( u
"limitNumLabels"_s, mThinningSettings.limitNumberOfLabelsEnabled() );
1394 renderingElem.setAttribute( u
"maxNumLabels"_s, mThinningSettings.maximumNumberLabels() );
1396 if ( mThinningSettings.labelMarginDistance() > 0 )
1398 placementElem.setAttribute( u
"labelMarginDistance"_s, mThinningSettings.labelMarginDistance() );
1402 placementElem.setAttribute( u
"labelMarginDistanceUnit"_s,
QgsUnitTypes::encodeUnit( mThinningSettings.labelMarginDistanceUnit() ) );
1404 if ( !mThinningSettings.labelMarginDistanceMapUnitScale().isNull() )
1411 placementElem.setAttribute( u
"minDistanceToDuplicates"_s, mThinningSettings.minimumDistanceToDuplicate() );
1415 placementElem.setAttribute( u
"minDistanceToDuplicatesUnit"_s,
QgsUnitTypes::encodeUnit( mThinningSettings.minimumDistanceToDuplicateUnit() ) );
1417 if ( !mThinningSettings.minimumDistanceToDuplicateMapUnitScale().isNull() )
1421 if ( mThinningSettings.allowDuplicateRemoval() )
1423 placementElem.setAttribute( u
"allowDuplicateRemoval"_s, u
"1"_s );
1426 renderingElem.setAttribute( u
"obstacle"_s, mObstacleSettings.isObstacle() );
1427 renderingElem.setAttribute( u
"obstacleFactor"_s, mObstacleSettings.factor() );
1428 renderingElem.setAttribute( u
"obstacleType"_s,
static_cast< unsigned int >( mObstacleSettings.type() ) );
1429 renderingElem.setAttribute( u
"zIndex"_s,
zIndex );
1430 renderingElem.setAttribute( u
"unplacedVisibility"_s,
static_cast< int >( mUnplacedVisibility ) );
1432 QDomElement ddElem = doc.createElement( u
"dd_properties"_s );
1433 mDataDefinedProperties.writeXml( ddElem, *sPropertyDefinitions() );
1435 QDomElement elem = doc.createElement( u
"settings"_s );
1436 elem.appendChild( textStyleElem );
1437 elem.appendChild( textFormatElem );
1438 elem.appendChild( placementElem );
1439 elem.appendChild( renderingElem );
1440 elem.appendChild( ddElem );
1444 elem.setAttribute( u
"calloutType"_s, mCallout->type() );
1445 mCallout->saveProperties( doc, elem, context );
1462 QPixmap pixmap( size * devicePixelRatio );
1463 pixmap.fill( Qt::transparent );
1464 pixmap.setDevicePixelRatio( devicePixelRatio );
1466 painter.begin( &pixmap );
1468 painter.setRenderHint( QPainter::Antialiasing );
1470 const QRectF rect( 0, 0, size.width(), size.height() );
1473 painter.setPen( Qt::NoPen );
1475 if ( ( background1.lightnessF() < 0.7 ) )
1477 background1 = background1.darker( 125 );
1481 background1 = background1.lighter( 125 );
1484 QLinearGradient linearGrad( QPointF( 0, 0 ), QPointF( 0, rect.height() ) );
1485 linearGrad.setColorAt( 0, background1 );
1486 linearGrad.setColorAt( 1, background2 );
1487 painter.setBrush( QBrush( linearGrad ) );
1488 if ( size.width() > 30 )
1490 painter.drawRoundedRect( rect, 6, 6 );
1495 painter.drawRect( rect );
1497 painter.setBrush( Qt::NoBrush );
1498 painter.setPen( Qt::NoPen );
1513 QWidget *activeWindow = QApplication::activeWindow();
1514 if ( QScreen *screen = activeWindow ? activeWindow->screen() :
nullptr )
1534 ? fontSize * tempFormat.
buffer().
size() / 100
1539 double ytrans = 0.0;
1542 ? fontSize * tempFormat.
buffer().
size() / 100
1547 const QStringList text = QStringList() << ( previewText.isEmpty() ? settings.
legendString() : previewText );
1549 QRectF textRect = rect;
1550 textRect.setLeft( xtrans + padding );
1551 textRect.setWidth( rect.width() - xtrans - 2 * padding );
1553 if ( textRect.width() > 2000 )
1554 textRect.setWidth( 2000 - 2 * padding );
1556 const double bottom = textRect.height() / 2 + textHeight / 2;
1557 textRect.setTop( bottom - textHeight );
1558 textRect.setBottom( bottom );
1567 callout->startRender( context );
1569 QRectF labelRect( textRect.left() + ( textRect.width() - textWidth ) / 2.0, textRect.top(), textWidth, textRect.height() );
1571 callout->stopRender( context );
1576 if ( size.width() > 30 )
1581 rect.width() - iconWidth * 3, rect.height() - iconWidth * 3,
1582 iconWidth * 2, iconWidth * 2 ), Qt::AlignRight | Qt::AlignBottom );
1586 painter.setBrush( Qt::NoBrush );
1588 if ( size.width() > 30 )
1590 painter.drawRoundedRect( rect, 6, 6 );
1595 painter.drawRect( rect );
1604 return mUnplacedVisibility;
1609 mUnplacedVisibility = visibility;
1614 return QgsPalLabeling::checkMinimumSizeMM(
ct, geom, minSize );
1626 QString textCopy( text );
1629 std::unique_ptr< QgsRenderContext > scopedRc;
1632 scopedRc = std::make_unique<QgsRenderContext>( );
1634 scopedRc->expressionContext().setFeature( *f );
1640 double multilineH = mFormat.lineHeight();
1643 bool addDirSymb = mLineSettings.addDirectionSymbol();
1644 QString leftDirSymb = mLineSettings.leftDirectionSymbol();
1645 QString rightDirSymb = mLineSettings.rightDirectionSymbol();
1750 if ( wrapchr.isEmpty() )
1757 && ( !leftDirSymb.isEmpty() || !rightDirSymb.isEmpty() ) )
1759 QString dirSym = leftDirSymb;
1761 if ( fm->horizontalAdvance( rightDirSymb ) > fm->horizontalAdvance( dirSym ) )
1762 dirSym = rightDirSymb;
1764 switch ( placeDirSymb )
1767 textCopy.append( dirSym );
1772 textCopy.prepend( dirSym + u
"\n"_s );
1777 double w = 0.0, h = 0.0, rw = 0.0, rh = 0.0;
1778 double labelHeight = fm->ascent() + fm->descent();
1781 const int lines = multiLineSplit.size();
1783 const double lineHeightPainterUnits = rc->
convertToPainterUnits( mFormat.lineHeight(), mFormat.lineHeightUnit() );
1785 switch ( orientation )
1789 h += fm->height() +
static_cast< double >( ( lines - 1 ) * ( mFormat.lineHeightUnit() ==
Qgis::RenderUnit::Percentage ? ( labelHeight * multilineH ) : lineHeightPainterUnits ) );
1791 for (
const QString &line : std::as_const( multiLineSplit ) )
1793 w = std::max( w, fm->horizontalAdvance( line ) );
1800 double letterSpacing = mFormat.scaledFont( *rc ).letterSpacing();
1801 double labelWidth = fm->maxWidth();
1802 w = labelWidth + ( lines - 1 ) * ( mFormat.lineHeightUnit() ==
Qgis::RenderUnit::Percentage ? ( labelWidth * multilineH ) : lineHeightPainterUnits );
1804 int maxLineLength = 0;
1805 for (
const QString &line : std::as_const( multiLineSplit ) )
1807 maxLineLength = std::max( maxLineLength,
static_cast<int>( line.length() ) );
1809 h = fm->ascent() * maxLineLength + ( maxLineLength - 1 ) * letterSpacing;
1815 double widthHorizontal = 0.0;
1816 for (
const QString &line : std::as_const( multiLineSplit ) )
1818 widthHorizontal = std::max( widthHorizontal, fm->horizontalAdvance( line ) );
1821 double widthVertical = 0.0;
1822 double letterSpacing = mFormat.scaledFont( *rc ).letterSpacing();
1823 double labelWidth = fm->maxWidth();
1824 widthVertical = labelWidth + ( lines - 1 ) * ( mFormat.lineHeightUnit() ==
Qgis::RenderUnit::Percentage ? ( labelWidth * multilineH ) : lineHeightPainterUnits );
1826 double heightHorizontal = 0.0;
1827 heightHorizontal += fm->height() +
static_cast< double >( ( lines - 1 ) * ( mFormat.lineHeightUnit() ==
Qgis::RenderUnit::Percentage ? ( labelHeight * multilineH ) : lineHeightPainterUnits ) );
1829 double heightVertical = 0.0;
1830 int maxLineLength = 0;
1831 for (
const QString &line : std::as_const( multiLineSplit ) )
1833 maxLineLength = std::max( maxLineLength,
static_cast<int>( line.length() ) );
1835 heightVertical = fm->ascent() * maxLineLength + ( maxLineLength - 1 ) * letterSpacing;
1837 w = widthHorizontal;
1838 rw = heightVertical;
1839 h = heightHorizontal;
1845 double uPP =
xform->mapUnitsPerPixel();
1848 if ( rotatedLabelX && rotatedLabelY )
1850 *rotatedLabelX = rw * uPP;
1851 *rotatedLabelY = rh * uPP;
1864 bool addDirSymb = mLineSettings.addDirectionSymbol();
1865 QString leftDirSymb = mLineSettings.leftDirectionSymbol();
1866 QString rightDirSymb = mLineSettings.rightDirectionSymbol();
1868 double multilineH = mFormat.lineHeight();
1903 const double lineHeightPainterUnits = context.
convertToPainterUnits( mFormat.lineHeight(), mFormat.lineHeightUnit() );
1906 QSizeF maximumExtraSpaceAllowance( 0, 0 );
1907 QSizeF minimumSize( 0, 0 );
1909 && ( !leftDirSymb.isEmpty() || !rightDirSymb.isEmpty() ) )
1913 const QString dirSym = fm.horizontalAdvance( rightDirSymb ) > fm.horizontalAdvance( leftDirSymb )
1914 ? rightDirSymb : leftDirSymb;
1916 switch ( placeDirSymb )
1919 maximumExtraSpaceAllowance = QSizeF( fm.horizontalAdvance( dirSym ), 0 );
1924 maximumExtraSpaceAllowance = QSizeF( 0, ( mFormat.lineHeightUnit() ==
Qgis::RenderUnit::Percentage ? ( ( fm.ascent() + fm.descent() ) * multilineH ) : lineHeightPainterUnits ) );
1925 minimumSize = QSizeF( fm.horizontalAdvance( dirSym ), 0 );
1937 w = std::max( minimumSize.width(), documentSize.width() + maximumExtraSpaceAllowance.width() );
1938 h = std::max( minimumSize.height(), documentSize.height() + maximumExtraSpaceAllowance.height() );
1943 rh = std::max( minimumSize.width(), rotatedSize.width() + maximumExtraSpaceAllowance.width() );
1944 rw = std::max( minimumSize.height(), rotatedSize.height() + maximumExtraSpaceAllowance.height() );
1947 const double uPP =
xform->mapUnitsPerPixel();
1948 size = QSizeF( w * uPP, h * uPP );
1949 rotatedSize = QSizeF( rw * uPP, rh * uPP );
1955 outerBounds = QRectF( outerBoundsPixels.left() * uPP,
1956 outerBoundsPixels.top() * uPP,
1957 outerBoundsPixels.width() * uPP,
1958 outerBoundsPixels.height() * uPP );
1983 if ( useScaleVisibility )
1996 maxScale = 1 / std::fabs( maxScale );
2016 minScale = 1 / std::fabs( minScale );
2031 labelIsHidden =
false;
2032 QgsTextFormat evaluatedFormat = mFormat;
2034 QFont labelFont = evaluatedFormat.
font();
2042 QString units = exprVal.toString();
2043 if ( !units.isEmpty() )
2053 double fontSize = evaluatedFormat.
size();
2059 if ( fontSize <= 0.0 )
2061 labelIsHidden =
true;
2062 return evaluatedFormat;
2067 if ( fontPixelSize < 1 )
2069 labelIsHidden =
true;
2070 return evaluatedFormat;
2072 labelFont.setPixelSize( fontPixelSize );
2084 if ( fontMinPixel > labelFont.pixelSize() || labelFont.pixelSize() > fontMaxPixel )
2086 labelIsHidden =
true;
2087 return evaluatedFormat;
2103 labelFont.setCapitalization( QFont::MixedCase );
2113 QString fcase = exprVal.toString().trimmed();
2116 if ( !fcase.isEmpty() )
2118 if ( fcase.compare(
"NoChange"_L1, Qt::CaseInsensitive ) == 0 )
2122 else if ( fcase.compare(
"Upper"_L1, Qt::CaseInsensitive ) == 0 )
2126 else if ( fcase.compare(
"Lower"_L1, Qt::CaseInsensitive ) == 0 )
2130 else if ( fcase.compare(
"Capitalize"_L1, Qt::CaseInsensitive ) == 0 )
2134 else if ( fcase.compare(
"Title"_L1, Qt::CaseInsensitive ) == 0 )
2138#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
2139 else if ( fcase.compare(
"SmallCaps"_L1, Qt::CaseInsensitive ) == 0 )
2143 else if ( fcase.compare(
"AllSmallCaps"_L1, Qt::CaseInsensitive ) == 0 )
2152 parseTextStyle( labelFont, fontunits, context );
2153 if ( mDataDefinedProperties.hasActiveProperties() )
2155 parseTextFormatting( context );
2156 parseTextBuffer( context );
2157 parseTextMask( context );
2158 parseShapeBackground( context );
2159 parseDropShadow( context );
2164 QList<QgsTextFormat::Tab> tabPositions;
2168 for (
const QVariant &part : parts )
2170 tabPositions.append( QgsTextFormat::Tab( part.toDouble() ) );
2177 for (
const QString &part : parts )
2179 tabPositions.append( QgsTextFormat::Tab( part.toDouble() ) );
2190 evaluatedFormat.
setFont( labelFont );
2194 evaluatedFormat.
setSize( labelFont.pixelSize() / symbologyReferenceScaleFactor );
2197 return evaluatedFormat;
2247 if ( evalFormatNumbers )
2251 if ( decimalPlaces <= 0 )
2257 QVariant textV( labelText );
2259 double d = textV.toDouble( &ok );
2262 QString numberFormat;
2263 if ( d > 0 && signPlus )
2265 numberFormat.append(
'+' );
2267 numberFormat.append(
"%1" );
2268 labelText = numberFormat.arg( QLocale().toString( d,
'f', decimalPlaces ) );
2285 if ( wrapchr.isEmpty() )
2290 if ( allowMultipleLines )
2300 QgsGeometry geom = feature.
geometry();
2307 bool allowSimplify =
true;
2317 allowSimplify =
false;
2338 std::unique_ptr<QgsGeometry> scopedClonedGeom;
2343 QgsMapToPixelSimplifier simplifier( simplifyHints, simplifyMethod.
tolerance(), simplifyAlgorithm );
2344 geom = simplifier.
simplify( geom );
2356 bool isObstacle = mObstacleSettings.isObstacle();
2360 std::vector<std::unique_ptr<QgsLabelFeature> > res;
2367 std::unique_ptr< QgsLabelFeature > obstacle = registerObstacleFeature( f, context, obstacleGeometry );
2369 res.emplace_back( std::move( obstacle ) );
2378 if ( !isLabelVisible( context ) )
2385 if ( mGeometryGeneratorExpression.hasEvalError() )
2388 if ( obstacleGeometry.
isNull() )
2401 dataDefinedValues.clear();
2404 bool labelIsHidden =
false;
2405 QgsTextFormat evaluatedFormat = evaluateTextFormat( context, labelIsHidden );
2406 if ( labelIsHidden )
2414 bool allowMultipleLines =
true;
2425 allowMultipleLines =
false;
2430 allowMultipleLines =
true;
2447 if ( !evaluateLabelContent( feature, context, allowMultipleLines, labelText, doc, evaluatedFormat ) )
2469 QString str = exprVal.toString().trimmed();
2472 if ( !str.isEmpty() )
2474 if ( str.compare(
"Visible"_L1, Qt::CaseInsensitive ) == 0 )
2476 wholeCentroid =
false;
2478 else if ( str.compare(
"Whole"_L1, Qt::CaseInsensitive ) == 0 )
2480 wholeCentroid =
true;
2493 bool doClip =
false;
2494 if ( !centroidPoly || !wholeCentroid )
2512 std::unique_ptr< QgsTextLabelFeature > label = generateLabelFeature( context, feature, 0, geom, obstacleGeometry, doc, labelText, evaluatedFormat, symbol,
lineSettings,
pointSettings,
placementSettings, isObstacle, doClip );
2514 res.emplace_back( std::move( label ) );
2522 const std::size_t partCount = std::min( geometryParts.size(), documentParts.size() );
2523 res.reserve( partCount );
2524 for ( std::size_t i = 0; i < partCount; ++i )
2526 std::unique_ptr< QgsTextLabelFeature > label = generateLabelFeature( context, feature,
static_cast< int >( i ), geometryParts[i], obstacleGeometry, documentParts[i], labelText, evaluatedFormat, symbol,
lineSettings,
pointSettings,
placementSettings, isObstacle, doClip );
2528 res.emplace_back( std::move( label ) );
2538std::unique_ptr< QgsTextLabelFeature> QgsPalLayerSettings::generateLabelFeature(
QgsRenderContext &context,
const QgsFeature &feature,
int subPartId,
QgsGeometry geom,
const QgsGeometry &obstacleGeometry,
QgsTextDocument doc,
const QString &labelText,
const QgsTextFormat &evaluatedFormat,
const QgsSymbol *symbol,
const QgsLabelLineSettings &lineSettings,
const QgsLabelPointSettings &pointSettings,
const QgsLabelPlacementSettings &placementSettings,
bool isObstacle,
bool doClip )
const
2546 QFontMetricsF labelFontMetrics( evaluatedFormat.
font() );
2547 calculateLabelMetrics( labelFontMetrics, context, evaluatedFormat, doc, documentMetrics, labelSize, rotatedSize, outerBounds );
2551 double maxcharanglein = 20.0;
2552 double maxcharangleout = -20.0;
2570 maxcharanglein = std::clamp(
static_cast< double >( maxcharanglePt.x() ), 20.0, 60.0 );
2571 maxcharangleout = std::clamp(
static_cast< double >( maxcharanglePt.y() ), 20.0, 95.0 );
2575 maxcharangleout = -( std::fabs( maxcharangleout ) );
2602 if ( dataDefinedOutside.userType() == QMetaType::Type::QString )
2604 const QString value = dataDefinedOutside.toString().trimmed();
2605 if ( value.compare(
"force"_L1, Qt::CaseInsensitive ) == 0 )
2611 else if ( value.compare(
"yes"_L1, Qt::CaseInsensitive ) == 0 )
2616 else if ( value.compare(
"no"_L1, Qt::CaseInsensitive ) == 0 )
2624 if ( dataDefinedOutside.toBool() )
2670 QgsGeometry permissibleZone;
2673 permissibleZone = geom;
2698 QgsLabelThinningSettings featureThinningSettings = mThinningSettings;
2701 double minimumSize = 0.0;
2711 if ( !checkMinimumSizeMM( context, geom, featureThinningSettings.
minimumFeatureSize() ) )
2716 if ( !geos_geom_clone )
2745 bool layerDefinedRotation =
false;
2746 bool dataDefinedRotation =
false;
2747 double xPos = 0.0, yPos = 0.0;
2748 double angleInRadians = 0.0;
2749 double quadOffsetX = 0.0, quadOffsetY = 0.0;
2750 double offsetX = 0.0, offsetY = 0.0;
2751 QgsPointXY anchorPosition;
2762 bool ddFixedQuad =
false;
2771 int quadInt = exprVal.toInt( &ok );
2772 if ( ok && 0 <= quadInt && quadInt <= 8 )
2842 QString units = exprVal.toString().trimmed();
2843 if ( !units.isEmpty() )
2849 offUnit = decodedUnits;
2864 layerDefinedRotation =
true;
2865 angleInRadians = ( 360 -
angleOffset ) * M_PI / 180;
2868 const QgsMapToPixel &m2p = context.
mapToPixel();
2877 const double rotation = exprVal.toDouble( &ok );
2880 dataDefinedRotation =
true;
2888 angleInRadians = ( 360 - rotationDegrees ) * M_PI / 180.0;
2893 bool hasDataDefinedPosition =
false;
2895 bool ddPosition =
false;
2907 bool ddXPos =
false, ddYPos =
false;
2908 xPos = xPosProperty.toDouble( &ddXPos );
2909 yPos = yPosProperty.toDouble( &ddYPos );
2910 if ( ddXPos && ddYPos )
2911 hasDataDefinedPosition =
true;
2922 if ( pointPosProperty.userType() == qMetaTypeId<QgsReferencedGeometry>() )
2924 QgsReferencedGeometry referencedGeometryPoint = pointPosProperty.value<QgsReferencedGeometry>();
2925 point = QgsPoint( referencedGeometryPoint.
asPoint() );
2927 if ( !referencedGeometryPoint.
isNull()
2928 &&
ct.sourceCrs() != referencedGeometryPoint.
crs() )
2931 else if ( pointPosProperty.userType() == qMetaTypeId< QgsGeometry>() )
2933 point = QgsPoint( pointPosProperty.value<QgsGeometry>().asPoint() );
2938 hasDataDefinedPosition =
true;
2949 if ( hasDataDefinedPosition )
2952 if ( layerDefinedRotation && !dataDefinedRotation )
2954 angleInRadians = 0.0;
2963 QString haliString = exprVal.toString();
2964 if ( haliString.compare(
"Center"_L1, Qt::CaseInsensitive ) == 0 )
2966 xdiff -= labelSize.width() / 2.0;
2968 else if ( haliString.compare(
"Right"_L1, Qt::CaseInsensitive ) == 0 )
2970 xdiff -= labelSize.width();
2981 QString valiString = exprVal.toString();
2982 if ( valiString.compare(
"Bottom"_L1, Qt::CaseInsensitive ) != 0 )
2984 if ( valiString.compare(
"Top"_L1, Qt::CaseInsensitive ) == 0 )
2986 ydiff -= labelSize.height();
2990 double descentRatio = labelFontMetrics.descent() / labelFontMetrics.height();
2991 if ( valiString.compare(
"Base"_L1, Qt::CaseInsensitive ) == 0 )
2993 ydiff -= labelSize.height() * descentRatio;
2997 double capHeightRatio = ( labelFontMetrics.boundingRect(
'H' ).height() + 1 + labelFontMetrics.descent() ) / labelFontMetrics.height();
2998 ydiff -= labelSize.height() * capHeightRatio;
2999 if ( valiString.compare(
"Half"_L1, Qt::CaseInsensitive ) == 0 )
3001 ydiff += labelSize.height() * ( capHeightRatio - descentRatio ) / 2.0;
3009 if ( dataDefinedRotation )
3012 double xd = xdiff * std::cos( angleInRadians ) - ydiff * std::sin( angleInRadians );
3013 double yd = xdiff * std::sin( angleInRadians ) + ydiff * std::cos( angleInRadians );
3019 QgsGeometry ddPoint(
new QgsPoint( xPos, yPos ) );
3027 anchorPosition = QgsPointXY( xPos, yPos );
3031 QgsMessageLog::logMessage( QObject::tr(
"Invalid data defined label position (%1, %2)" ).arg( xPos ).arg( yPos ), QObject::tr(
"Labeling" ) );
3032 hasDataDefinedPosition =
false;
3037 anchorPosition = QgsPointXY( xPos, yPos );
3045 anchorPosition = QgsPointXY( xPos, yPos );
3051 bool alwaysShow =
false;
3073 QString units = exprVal.toString().trimmed();
3074 if ( !units.isEmpty() )
3080 repeatUnits = decodedUnits;
3095 double overrunDistanceEval =
lineSettings.overrunDistance();
3107 double maximumDistanceEval =
pointSettings.maximumDistance();
3114 auto labelFeature = std::make_unique< QgsTextLabelFeature>( feature.
id(), std::move( geos_geom_clone ), labelSize, subPartId );
3115 labelFeature->setAnchorPosition( anchorPosition );
3116 labelFeature->setFeature( feature );
3117 labelFeature->setSymbol( symbol );
3118 labelFeature->setDocument( doc, documentMetrics );
3120 labelFeature->setRotatedSize( rotatedSize );
3123 labelFeature->setHasFixedPosition( hasDataDefinedPosition );
3124 labelFeature->setFixedPosition( QgsPointXY( xPos, yPos ) );
3126 labelFeature->setHasFixedAngle( dataDefinedRotation || ( !hasDataDefinedPosition && !
qgsDoubleNear( angleInRadians, 0.0 ) ) );
3127 labelFeature->setFixedAngle( angleInRadians );
3128 labelFeature->setQuadOffset( QPointF( quadOffsetX, quadOffsetY ) );
3129 labelFeature->setPositionOffset( QgsPointXY( offsetX, offsetY ) );
3131 labelFeature->setAlwaysShow( alwaysShow );
3132 labelFeature->setRepeatDistance( repeatDist );
3133 labelFeature->setLabelText( labelText );
3134 labelFeature->setPermissibleZone( permissibleZone );
3135 labelFeature->setOverrunDistance( overrunDistanceEval );
3136 labelFeature->setOverrunSmoothDistance( overrunSmoothDist );
3137 labelFeature->setMaximumDistance( maximumDistanceEval );
3138 labelFeature->setLineAnchorPercent(
lineSettings.lineAnchorPercent() );
3139 labelFeature->setLineAnchorType(
lineSettings.anchorType() );
3140 labelFeature->setLineAnchorTextPoint(
lineSettings.anchorTextPoint() );
3141 labelFeature->setCurvedLabelMode(
lineSettings.curvedLabelMode() );
3144 labelFeature->setMinimumSize( minimumSize );
3145 labelFeature->setWhitespaceCollisionHandling(
placementSettings.whitespaceCollisionHandling() );
3149 labelFeature->setSymbolSize( QSizeF( obstacleGeometry.
boundingBox().
width(),
3153 if ( outerBounds.left() != 0 || outerBounds.top() != 0 || !
qgsDoubleNear( outerBounds.width(), labelSize.width() ) || !
qgsDoubleNear( outerBounds.height(), labelSize.height() ) )
3155 labelFeature->setOuterBounds( outerBounds );
3158 QgsLabelFeatureThinningSettings thinning;
3171 ( *labelFeature ).setThinningSettings( thinning );
3175 double topMargin = std::max( 0.25 * labelFontMetrics.ascent(), 0.0 );
3176 double bottomMargin = 1.0 + labelFontMetrics.descent();
3177 QgsMargins vm( 0.0, topMargin, 0.0, bottomMargin );
3178 vm *=
xform->mapUnitsPerPixel();
3179 labelFeature->setVisualMargin( vm );
3182 QgsDebugMsgLevel( u
"PAL font stored definedFont: %1, Style: %2"_s.arg( evaluatedFormat.
font().toString(), evaluatedFormat.
font().styleName() ), 4 );
3183 labelFeature->setDefinedFont( evaluatedFormat.
font() );
3185 labelFeature->setMaximumCharacterAngleInside( std::clamp( maxcharanglein, 20.0, 60.0 ) * M_PI / 180 );
3186 labelFeature->setMaximumCharacterAngleOutside( std::clamp( maxcharangleout, -95.0, -20.0 ) * M_PI / 180 );
3210 double distance =
dist;
3224 QString units = exprVal.toString().trimmed();
3226 if ( !units.isEmpty() )
3232 distUnit = decodedUnits;
3246 distance = ( distance < 0 ? -1 : 1 ) * std::max( std::fabs( distance ), 1.0 );
3258 distance = std::max( distance, 2.0 );
3263 distance = std::max( distance, 2.0 );
3270 labelFeature->setDistLabel( d );
3275 labelFeature->setHasFixedQuadrant(
true );
3278 labelFeature->setArrangementFlags(
lineSettings.placementFlags() );
3280 labelFeature->setPolygonPlacementFlags( polygonPlacement );
3289 labelFeature->setZIndex( z );
3299 double priorityD = exprVal.toDouble( &ok );
3302 priorityD = std::clamp( priorityD, 0.0, 10.0 );
3303 priorityD = 1 - priorityD / 10.0;
3304 labelFeature->setPriority( priorityD );
3309 labelFeature->setAllowDegradedPlacement(
placementSettings.allowDegradedPlacement() );
3313 QgsLabelObstacleSettings os = mObstacleSettings;
3317 labelFeature->setObstacleSettings( os );
3319 QVector< Qgis::LabelPredefinedPointPosition > positionOrder =
pointSettings.predefinedPositionOrder();
3320 if ( positionOrder.isEmpty() )
3321 positionOrder = *DEFAULT_PLACEMENT_ORDER();
3327 if ( !dataDefinedOrder.isEmpty() )
3332 labelFeature->setPredefinedPositionOrder( positionOrder );
3335 labelFeature->setDataDefinedValues( dataDefinedValues );
3337 return labelFeature;
3345 if ( !obstacleGeometry.
isNull() )
3347 geom = obstacleGeometry;
3362 if ( ls->numPoints() < 2 )
3368 std::unique_ptr<QgsGeometry> scopedClonedGeom;
3373 QgsMapToPixelSimplifier simplifier( simplifyHints, simplifyMethod.
tolerance(), simplifyAlgorithm );
3374 geom = simplifier.
simplify( geom );
3378 std::unique_ptr<QgsGeometry> scopedPreparedGeom;
3386 if ( !geos_geom_clone )
3390 auto obstacleFeature = std::make_unique< QgsLabelFeature >( f.
id(), std::move( geos_geom_clone ), QSizeF( 0, 0 ) );
3391 obstacleFeature->setFeature( f );
3393 QgsLabelObstacleSettings os = mObstacleSettings;
3396 obstacleFeature->setObstacleSettings( os );
3399 return obstacleFeature;
3402bool QgsPalLayerSettings::dataDefinedValEval( DataDefinedValueType valType,
3406 if ( !mDataDefinedProperties.isActive( p ) )
3410 exprVal = mDataDefinedProperties.value( p, context );
3417 bool bol = exprVal.toBool();
3418 dataDefinedValues.insert( p, QVariant( bol ) );
3424 int size = exprVal.toInt( &ok );
3428 dataDefinedValues.insert( p, QVariant( size ) );
3436 int size = exprVal.toInt( &ok );
3438 if ( ok && size > 0 )
3440 dataDefinedValues.insert( p, QVariant( size ) );
3448 double size = exprVal.toDouble( &ok );
3452 dataDefinedValues.insert( p, QVariant( size ) );
3460 double size = exprVal.toDouble( &ok );
3462 if ( ok && size > 0.0 )
3464 dataDefinedValues.insert( p, QVariant( size ) );
3472 double rot = exprVal.toDouble( &ok );
3475 if ( rot < -180.0 && rot >= -360 )
3479 if ( rot > 180.0 && rot <= 360 )
3483 if ( rot >= -180 && rot <= 180 )
3485 dataDefinedValues.insert( p, QVariant( rot ) );
3494 int size = exprVal.toInt( &ok );
3495 if ( ok && size >= 0 && size <= 100 )
3497 dataDefinedValues.insert( p, QVariant( size ) );
3504 QString str = exprVal.toString();
3506 dataDefinedValues.insert( p, QVariant( str ) );
3511 QString unitstr = exprVal.toString().trimmed();
3513 if ( !unitstr.isEmpty() )
3522 QString colorstr = exprVal.toString().trimmed();
3525 if ( color.isValid() )
3527 dataDefinedValues.insert( p, QVariant( color ) );
3534 QString joinstr = exprVal.toString().trimmed();
3536 if ( !joinstr.isEmpty() )
3545 QString blendstr = exprVal.toString().trimmed();
3547 if ( !blendstr.isEmpty() )
3560 dataDefinedValues.insert( p, res );
3571 dataDefinedValues.insert( p, res );
3581void QgsPalLayerSettings::parseTextStyle( QFont &labelFont,
3594 QString ddFontFamily;
3601 QString family = exprVal.toString().trimmed();
3605 if ( labelFont.family() != family )
3611 ddFontFamily = family;
3618 QString ddFontStyle;
3624 QString fontstyle = exprVal.toString().trimmed();
3626 ddFontStyle = fontstyle;
3631 bool ddBold =
false;
3639 bool ddItalic =
false;
3649 QFont appFont = QApplication::font();
3650 bool newFontBuilt =
false;
3651 if ( ddBold || ddItalic )
3655 newFontBuilt =
true;
3656 newFont.setBold( ddBold );
3657 newFont.setItalic( ddItalic );
3659 else if ( !ddFontStyle.isEmpty()
3660 && ddFontStyle.compare(
"Ignore"_L1, Qt::CaseInsensitive ) != 0 )
3662 if ( !ddFontFamily.isEmpty() )
3666 mFontDB = std::make_unique< QFontDatabase >();
3668 QFont styledfont = mFontDB->font( ddFontFamily, ddFontStyle, appFont.pointSize() );
3669 if ( appFont != styledfont )
3671 newFont = styledfont;
3672 newFontBuilt =
true;
3679 else if ( !ddFontFamily.isEmpty() )
3681 if ( ddFontStyle.compare(
"Ignore"_L1, Qt::CaseInsensitive ) != 0 )
3685 mFontDB = std::make_unique< QFontDatabase >();
3686 QFont styledfont = mFontDB->font( ddFontFamily, mFormat.namedStyle(), appFont.pointSize() );
3687 if ( appFont != styledfont )
3689 newFont = styledfont;
3690 newFontBuilt =
true;
3696 newFontBuilt =
true;
3704 newFont.setPixelSize( labelFont.pixelSize() );
3705 newFont.setUnderline( labelFont.underline() );
3706 newFont.setStrikeOut( labelFont.strikeOut() );
3707 newFont.setWordSpacing( labelFont.wordSpacing() );
3708 newFont.setLetterSpacing( QFont::AbsoluteSpacing, labelFont.letterSpacing() );
3710 labelFont = newFont;
3714 double wordspace = labelFont.wordSpacing();
3720 labelFont.setWordSpacing( context.
convertToPainterUnits( wordspace, fontunits, mFormat.sizeMapUnitScale() ) );
3723 double letterspace = labelFont.letterSpacing();
3729 labelFont.setLetterSpacing( QFont::AbsoluteSpacing, context.
convertToPainterUnits( letterspace, fontunits, mFormat.sizeMapUnitScale() ) );
3736 labelFont.setStrikeOut( strikeout );
3751 labelFont.setUnderline( underline );
3771 QgsTextBufferSettings buffer = mFormat.buffer();
3774 bool drawBuffer = mFormat.buffer().enabled();
3777 drawBuffer = exprVal.toBool();
3790 double bufrSize = buffer.
size();
3793 bufrSize = exprVal.toDouble();
3797 double bufferOpacity = buffer.
opacity() * 100;
3800 bufferOpacity = exprVal.toDouble();
3803 drawBuffer = ( drawBuffer && bufrSize > 0.0 && bufferOpacity > 0 );
3830 QgsTextMaskSettings mask = mFormat.mask();
3833 bool maskEnabled = mask.
enabled();
3836 maskEnabled = exprVal.toBool();
3845 double bufrSize = mask.
size();
3848 bufrSize = exprVal.toDouble();
3852 double opacity = mask.
opacity() * 100;
3855 opacity = exprVal.toDouble();
3858 maskEnabled = ( maskEnabled && bufrSize > 0.0 && opacity > 0 );
3883 wrapchr = exprVal.toString();
3889 evalAutoWrapLength = exprVal.toInt();
3910 QString str = exprVal.toString().trimmed();
3913 if ( !str.isEmpty() )
3918 if ( str.compare(
"Center"_L1, Qt::CaseInsensitive ) == 0 )
3922 else if ( str.compare(
"Right"_L1, Qt::CaseInsensitive ) == 0 )
3926 else if ( str.compare(
"Follow"_L1, Qt::CaseInsensitive ) == 0 )
3930 else if ( str.compare(
"Justify"_L1, Qt::CaseInsensitive ) == 0 )
3947 QString str = exprVal.toString().trimmed();
3948 if ( !str.isEmpty() )
3954 bool drawDirSymb = mLineSettings.addDirectionSymbol();
3957 drawDirSymb = exprVal.toBool();
3972 QString str = exprVal.toString().trimmed();
3975 if ( !str.isEmpty() )
3980 if ( str.compare(
"Above"_L1, Qt::CaseInsensitive ) == 0 )
3984 else if ( str.compare(
"Below"_L1, Qt::CaseInsensitive ) == 0 )
4003 QgsTextBackgroundSettings background = mFormat.background();
4006 bool drawShape = background.
enabled();
4009 drawShape = exprVal.toBool();
4018 double shapeOpacity = background.
opacity() * 100;
4021 shapeOpacity = 100.0 * exprVal.toDouble();
4024 drawShape = ( drawShape && shapeOpacity > 0 );
4040 QString skind = exprVal.toString().trimmed();
4043 if ( !skind.isEmpty() )
4052 QString svgPath = background.
svgFile();
4059 QString svgfile = exprVal.toString().trimmed();
4075 QString stype = exprVal.toString().trimmed();
4078 if ( !stype.isEmpty() )
4087 double ddShpSizeX = background.
size().width();
4090 ddShpSizeX = exprVal.toDouble();
4094 double ddShpSizeY = background.
size().height();
4097 ddShpSizeY = exprVal.toDouble();
4103 && ( svgPath.isEmpty()
4104 || ( !svgPath.isEmpty()
4106 && ddShpSizeX == 0.0 ) ) )
4114 && ddShpSizeX == 0.0 ) ) )
4121 && ( ddShpSizeX == 0.0 || ddShpSizeY == 0.0 ) )
4146 QString rotstr = exprVal.toString().trimmed();
4149 if ( !rotstr.isEmpty() )
4197 QgsTextShadowSettings shadow = mFormat.shadow();
4200 bool drawShadow = shadow.
enabled();
4203 drawShadow = exprVal.toBool();
4212 double shadowOpacity = shadow.
opacity() * 100;
4215 shadowOpacity = exprVal.toDouble();
4222 shadowOffDist = exprVal.toDouble();
4229 shadowRad = exprVal.toDouble();
4232 drawShadow = ( drawShadow && shadowOpacity > 0 && !( shadowOffDist == 0.0 && shadowRad == 0.0 ) );
4249 QString str = exprVal.toString().trimmed();
4252 if ( !str.isEmpty() )
4287 switch ( layer->
type() )
4291 const QgsVectorLayer *vl = qobject_cast< const QgsVectorLayer * >( layer );
4304 return !labeling->styles().empty();
4311 const QgsMeshLayer *ml = qobject_cast< const QgsMeshLayer * >( layer );
4317 const QgsRasterLayer *rl = qobject_cast< const QgsRasterLayer * >( layer );
4364QStringList
QgsPalLabeling::splitToLines(
const QString &text,
const QString &wrapCharacter,
const int autoWrapLength,
const bool useMaxLineLengthWhenAutoWrapping )
4366 QStringList multiLineSplit;
4367 if ( !wrapCharacter.isEmpty() && wrapCharacter !=
"\n"_L1 )
4370 const QStringList lines = text.split( wrapCharacter );
4371 for (
const QString &line : lines )
4373 multiLineSplit.append( line.split(
'\n' ) );
4378 multiLineSplit = text.split(
'\n' );
4382 if ( autoWrapLength != 0 )
4384 QStringList autoWrappedLines;
4385 autoWrappedLines.reserve( multiLineSplit.count() );
4386 for (
const QString &line : std::as_const( multiLineSplit ) )
4388 autoWrappedLines.append(
QgsStringUtils::wordWrap( line, autoWrapLength, useMaxLineLengthWhenAutoWrapping ).split(
'\n' ) );
4390 multiLineSplit = autoWrappedLines;
4392 return multiLineSplit;
4397 QStringList graphemes;
4398 QTextBoundaryFinder boundaryFinder( QTextBoundaryFinder::Grapheme, text );
4399 int currentBoundary = -1;
4400 int previousBoundary = 0;
4401 while ( ( currentBoundary = boundaryFinder.toNextBoundary() ) > 0 )
4403 graphemes << text.mid( previousBoundary, currentBoundary - previousBoundary );
4404 previousBoundary = currentBoundary;
4434 QgsDebugMsgLevel( u
"Ignoring feature due to transformation exception"_s, 4 );
4440 return std::isfinite( point.
x() ) && std::isfinite( point.
y() );
4444 cp->removeInvalidRings();
4448 for (
int i = 0; i < ms->numGeometries(); ++i )
4451 cp->removeInvalidRings();
4468 const bool mustClip = ( !clipGeometry.
isNull() &&
4472 bool mustClipExact =
false;
4496 QVector< QgsGeometry> parts;
4506 parts.append( partGeom );
4514 if ( bufferGeom.
isNull() )
4523 if ( mustClipExact )
4558 double length = geom.
length();
4559 if ( length >= 0.0 )
4561 return ( length >= ( minSize * mapUnitsPerMM ) );
4566 double area = geom.
area();
4569 return ( std::sqrt( area ) >= ( minSize * mapUnitsPerMM ) );
4577 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues )
4579 QgsTextFormat format = tmpLyr.
format();
4580 bool changed =
false;
4586 format.
setColor( ddColor.value<QColor>() );
4611 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues )
4625 QgsTextFormat format = tmpLyr.
format();
4632 QgsTextFormat format = tmpLyr.
format();
4633 QList<QgsTextFormat::Tab> tabPositions;
4637 for (
const QVariant &part : parts )
4639 tabPositions.append( QgsTextFormat::Tab( part.toDouble() ) );
4646 for (
const QString &part : parts )
4648 tabPositions.append( QgsTextFormat::Tab( part.toDouble() ) );
4667 QgsTextFormat format = tmpLyr.
format();
4702 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues )
4704 QgsTextBufferSettings buffer = tmpLyr.
format().
buffer();
4705 bool changed =
false;
4718 QgsTextFormat format = tmpLyr.
format();
4753 buffer.
setColor( ddColor.value<QColor>() );
4773 QgsTextFormat format = tmpLyr.
format();
4780 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues )
4782 if ( ddValues.isEmpty() )
4785 QgsTextMaskSettings mask = tmpLyr.
format().
mask();
4786 bool changed =
false;
4799 QgsTextFormat format = tmpLyr.
format();
4839 QgsTextFormat format = tmpLyr.
format();
4846 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues )
4849 bool changed =
false;
4862 QgsTextFormat format = tmpLyr.
format();
4889 QSizeF size = background.
size();
4896 QSizeF size = background.
size();
4990 QgsTextFormat format = tmpLyr.
format();
4997 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues )
4999 QgsTextShadowSettings shadow = tmpLyr.
format().
shadow();
5000 bool changed =
false;
5013 QgsTextFormat format = tmpLyr.
format();
5059 shadow.
setColor( ddColor.value<QColor>() );
5084 QgsTextFormat format = tmpLyr.
format();
5094 QMimeData *mimeData =
new QMimeData;
5095 mimeData->setColorData( QVariant(
format().color() ) );
5098 QDomDocument textDoc;
5099 QDomElement textElem =
writeXml( textDoc, rwContext );
5100 textDoc.appendChild( textElem );
5101 mimeData->setData(
"application/qgis.labelsettings"_L1, textDoc.toString().toUtf8() );
5111 if ( !data || !data->hasFormat(
"application/qgis.labelsettings"_L1 ) )
5114 QString text = QString::fromUtf8( data->data(
"application/qgis.labelsettings"_L1 ) );
5115 if ( !text.isEmpty() )
5121 if ( doc.setContent( text ) )
5123 elem = doc.documentElement();
5125 settings.
readXml( elem, rwContext );
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
@ StretchCharacterSpacingToFitLine
Increases (or decreases) the character spacing used for each label in order to fit the entire text ov...
@ Default
Default curved placement, characters are placed in an optimal position along the line....
@ StretchWordSpacingToFitLine
Increases (or decreases) the word spacing used for each label in order to fit the entire text over th...
@ PlaceCharactersAtVertices
Each individual character from the label text is placed such that their left-baseline position is loc...
@ LabelLargestPartOnly
Place a label only on the largest part from the geometry.
@ SplitLabelTextLinesOverParts
Splits the label text over the parts of the geometry, such that each consecutive part is labeled with...
@ LabelEveryPartWithEntireLabel
Place the (same) entire label over every part from the geometry.
QFlags< VectorRenderingSimplificationFlag > VectorRenderingSimplificationFlags
Simplification flags for vector feature rendering.
@ Success
Operation succeeded.
AngleUnit
Units of angles.
@ NoSimplification
No simplification can be applied.
LabelOffsetType
Behavior modifier for label offset and distance, only applies in some label placement modes.
@ FromPoint
Offset distance applies from point geometry.
@ FromSymbolBounds
Offset distance applies from rendered symbol bounds.
@ PreferCloser
Prefer closer labels, falling back to alternate positions before larger distances.
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
@ Curved
Arranges candidates following the curvature of a line feature. Applies to line layers only.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ Free
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...
@ OrderedPositionsAroundPoint
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
@ PerimeterCurved
Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
@ OutsidePolygons
Candidates are placed outside of polygon boundaries. Applies to polygon layers only.
@ AllowPlacementInsideOfPolygon
Labels can be placed inside a polygon feature.
@ AllowPlacementOutsideOfPolygon
Labels can be placed outside of a polygon feature.
VectorSimplificationAlgorithm
Simplification algorithms for vector features.
@ SkipEmptyInteriorRings
Skip any empty polygon interior ring.
@ Warning
Warning message.
QFlags< LabelLinePlacementFlag > LabelLinePlacementFlags
Line placement flags, which control how candidates are generated for a linear feature.
@ Labeling
Labeling-specific layout mode.
@ Rectangle
Text within rectangle layout mode.
Capitalization
String capitalization options.
@ AllSmallCaps
Force all characters to small caps.
@ MixedCase
Mixed case, ie no change.
@ AllLowercase
Convert all characters to lowercase.
@ TitleCase
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
@ SmallCaps
Mixed case small caps.
@ ForceFirstLetterToCapital
Convert just the first letter of each word to uppercase, leave the rest untouched.
@ AllUppercase
Convert all characters to uppercase.
QFlags< LabelPolygonPlacementFlag > LabelPolygonPlacementFlags
Polygon placement flags, which control how candidates are generated for a polygon feature.
LabelQuadrantPosition
Label quadrant positions.
TextOrientation
Text orientations.
@ Vertical
Vertically oriented text.
@ RotationBased
Horizontally or vertically oriented text based on rotation (only available for map labeling).
@ Horizontal
Horizontally oriented text.
UnplacedLabelVisibility
Unplaced label visibility.
@ FollowEngineSetting
Respect the label engine setting.
@ AffectsLabeling
If present, indicates that the renderer will participate in the map labeling problem.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
LabelMultiLineAlignment
Text alignment for multi-line labels.
@ FollowPlacement
Alignment follows placement of label, e.g., labels to the left of a feature will be drawn with right ...
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ TreatWhitespaceAsCollision
Treat overlapping whitespace text in labels and whitespace overlapping obstacles as collisions.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes).
@ Antialiasing
Use antialiasing while drawing.
@ AllowOverlapIfRequired
Avoids overlapping labels when possible, but permit overlaps if labels for features cannot otherwise ...
@ PreventOverlap
Do not allow labels to overlap other labels.
static const double UI_SCALE_FACTOR
UI scaling factor.
@ MiddleLeft
Label on left of point.
@ TopRight
Label on top-right of point.
@ MiddleRight
Label on right of point.
@ TopSlightlyRight
Label on top of point, slightly right of center.
@ BottomRight
Label on bottom right of point.
@ BottomLeft
Label on bottom-left of point.
@ BottomSlightlyRight
Label below point, slightly right of center.
@ TopLeft
Label on top-left of point.
UpsideDownLabelHandling
Handling techniques for upside down labels.
@ FlipUpsideDownLabels
Upside-down labels (90 <= angle < 270) are shown upright.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsFontManager * fontManager()
Returns the application font manager, which manages available fonts and font installation for the QGI...
static QgsCalloutRegistry * calloutRegistry()
Returns the application's callout registry, used for managing callout types.
Registry of available callout classes.
static QgsCallout * defaultCallout()
Create a new instance of a callout with default settings.
Contains additional contextual information about the context in which a callout is being rendered.
Abstract base class for callout renderers.
bool enabled() const
Returns true if the callout is enabled.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
Represents a coordinate reference system (CRS).
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
Custom exception class for Coordinate Reference System related exceptions.
Curve polygon geometry type.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
Handles parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
QString evalErrorString() const
Returns evaluation error.
QString parserErrorString() const
Returns parser error.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QVariant evaluate()
Evaluate the feature and return the result.
virtual Qgis::FeatureRendererFlags flags() const
Returns flags associated with the renderer.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Container of fields for a vector layer.
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QString processFontFamilyName(const QString &name) const
Processes a font family name, applying any matching fontFamilyReplacements() to the name.
static QFont createFont(const QString &family, int pointSize=-1, int weight=-1, bool italic=false)
Creates a font with the specified family.
static bool fontFamilyOnSystem(const QString &family)
Check whether font family is on system in a quick manner, which does not compare [foundry].
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
A geometry is the spatial representation of a feature.
QgsGeometry clipped(const QgsRectangle &rectangle)
Clips the geometry using the specified rectangle.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
double length() const
Returns the planar, 2-dimensional length of geometry.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
QgsGeometry mergeLines(const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
QgsGeometry makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false) const
Attempts to make an invalid geometry valid without losing vertices.
QString lastError() const
Returns an error string referring to the last error encountered either when this geometry was created...
bool isAxisParallelRectangle(double maximumDeviation, bool simpleRectanglesOnly=false) const
Returns true if the geometry is a polygon that is almost an axis-parallel rectangle.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
void filterVertices(const std::function< bool(const QgsPoint &) > &filter)
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
double area() const
Returns the planar, 2-dimensional area of the geometry.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
bool convertGeometryCollectionToSubclass(Qgis::GeometryType geomType)
Converts geometry collection to a the desired geometry type subclass (multi-point,...
QgsGeometry simplify(double tolerance) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
static geos::unique_ptr asGeos(const QgsGeometry &geometry, double precision=0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlags())
Returns a geos geometry - caller takes ownership of the object (should be deleted with GEOSGeom_destr...
void setNoRepeatDistance(double distance)
Sets the minimum distance (in label units) between labels for this feature and other labels with the ...
void setLabelMarginDistance(double distance)
Sets the minimum distance (in label units) between labels for this feature and other labels.
Contains settings related to how the label engine places and formats labels for line features (or pol...
AnchorType
Line anchor types.
AnchorClipping
Clipping behavior for line anchor calculation.
@ UseEntireLine
Entire original feature line geometry is used when calculating the line anchor for labels.
@ UseVisiblePartsOfLine
Only visible parts of lines are considered when calculating the line anchor for labels.
void setDirectionSymbolPlacement(DirectionSymbolPlacement placement)
Sets the placement for direction symbols.
void setLeftDirectionSymbol(const QString &symbol)
Sets the string to use for left direction arrows.
DirectionSymbolPlacement
Placement options for direction symbols.
@ SymbolLeftRight
Place direction symbols on left/right of label.
@ SymbolAbove
Place direction symbols on above label.
@ SymbolBelow
Place direction symbols on below label.
void setRightDirectionSymbol(const QString &symbol)
Sets the string to use for right direction arrows.
@ CenterOfText
Anchor using center of text.
bool addDirectionSymbol() const
Returns true if '<' or '>' (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) w...
void setReverseDirectionSymbol(bool reversed)
Sets whether the direction symbols should be reversed.
void setAddDirectionSymbol(bool enabled)
Sets whether '<' or '>' (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) will...
ObstacleType
Valid obstacle types, which affect how features within the layer will act as obstacles for labels.
@ PolygonInterior
Avoid placing labels over interior of polygon (prefer placing labels totally outside or just slightly...
void setIsObstacle(bool isObstacle)
Sets whether features are obstacles to labels of other layers.
void updateDataDefinedProperties(const QgsPropertyCollection &properties, QgsExpressionContext &context)
Updates the obstacle settings to respect any data defined properties set within the specified propert...
void setObstacleGeometry(const QgsGeometry &obstacleGeom)
Sets the label's obstacle geometry, if different to the feature geometry.
Contains general settings related to how labels are placed.
Contains settings related to how the label engine places and formats labels for point-like features.
double minimumFeatureSize() const
Returns the minimum feature size (in millimeters) for a feature to be labelled.
const QgsMapUnitScale & minimumDistanceToDuplicateMapUnitScale() const
Returns the map unit scale for the minimum distance to labels with duplicate text.
int maximumNumberLabels() const
Returns the maximum number of labels which should be drawn for this layer.
bool allowDuplicateRemoval() const
Returns whether duplicate label removal is permitted for this layer.
const QgsMapUnitScale & labelMarginDistanceMapUnitScale() const
Returns the map unit scale for the minimum distance to other labels.
double labelMarginDistance() const
Returns the minimum distance to other labels (i.e.
Qgis::RenderUnit labelMarginDistanceUnit() const
Returns the units for the minimum distance to other labels.
void updateDataDefinedProperties(const QgsPropertyCollection &properties, QgsExpressionContext &context)
Updates the thinning settings to respect any data defined properties set within the specified propert...
double minimumDistanceToDuplicate() const
Returns the minimum distance to labels with duplicate text.
Qgis::RenderUnit minimumDistanceToDuplicateUnit() const
Returns the units for the minimum distance to labels with duplicate text.
bool limitNumberOfLabelsEnabled() const
Returns true if the number of labels drawn for the layer should be limited.
static constexpr double DEFAULT_MINIMUM_DISTANCE_TO_DUPLICATE
Default minimum distance to duplicate labels.
static QString encodePredefinedPositionOrder(const QVector< Qgis::LabelPredefinedPointPosition > &positions)
Encodes an ordered list of predefined point label positions to a string.
static QVector< Qgis::LabelPredefinedPointPosition > decodePredefinedPositionOrder(const QString &positionString)
Decodes a string to an ordered list of predefined point label positions.
Base class for all map layer types.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
void removeCustomProperty(const QString &key)
Remove a custom property from layer.
T customEnumProperty(const QString &key, const T &defaultValue)
Returns the property value for a property based on an enum.
Contains configuration for rendering maps.
const QgsMapToPixel & mapToPixel() const
double extentBuffer() const
Returns the buffer in map units to use around the visible extent for rendering symbols whose correspo...
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
@ SimplifyEnvelope
The geometries can be fully simplified by its BoundingBox.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
double mapRotation() const
Returns the current map rotation in degrees (clockwise).
void setParameters(double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation)
Sets parameters for use in transforming coordinates.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
const QgsAbstractMeshLayerLabeling * labeling() const
Access to const labeling configuration.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Multi surface geometry collection.
static QStringList splitToLines(const QString &text, const QString &wrapCharacter, int autoWrapLength=0, bool useMaxLineLengthWhenAutoWrapping=true)
Splits a text string to a list of separate lines, using a specified wrap character (wrapCharacter).
static QgsGeometry prepareGeometry(const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry=QgsGeometry(), bool mergeLines=false)
Prepares a geometry for registration with PAL.
static bool geometryRequiresPreparation(const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry=QgsGeometry(), bool mergeLines=false)
Checks whether a geometry requires preparation before registration with PAL.
static bool staticWillUseLayer(const QgsMapLayer *layer)
Called to find out whether a specified layer is used for labeling.
static QStringList splitToGraphemes(const QString &text)
Splits a text string to a list of graphemes, which are the smallest allowable character divisions in ...
Contains settings for how a map layer will be labeled.
bool fitInPolygonOnly
true if only labels which completely fit within a polygon are allowed.
double yOffset
Vertical offset of label.
QgsMapUnitScale labelOffsetMapUnitScale
Map unit scale for label offset.
int fontMaxPixelSize
Maximum pixel size for showing rendered map unit labels (1 - 10000).
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
double maxCurvedCharAngleIn
Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
std::vector< std::unique_ptr< QgsLabelFeature > > registerFeatureWithDetails(const QgsFeature &feature, QgsRenderContext &context, QgsGeometry obstacleGeometry=QgsGeometry(), const QgsSymbol *symbol=nullptr)
Registers a feature for labeling.
const QgsMapToPixel * xform
void startRender(QgsRenderContext &context)
Prepares the label settings for rendering.
QString wrapChar
Wrapping character string.
QSet< QString > referencedFields(const QgsRenderContext &context) const
Returns all field names referenced by the configuration (e.g.
Qgis::LabelOffsetType offsetType
Offset type for layer (only applies in certain placement modes).
double xOffset
Horizontal offset of label.
Qgis::LabelPlacement placement
Label placement mode.
QgsCoordinateTransform ct
bool drawLabels
Whether to draw labels for this layer.
bool fontLimitPixelSize
true if label sizes should be limited by pixel size.
QString legendString() const
legendString
static QgsPalLayerSettings fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QgsPalLayerSettings.
double minimumScale
The minimum map scale (i.e.
Q_DECL_DEPRECATED void calculateLabelSize(const QFontMetricsF *fm, const QString &text, double &labelX, double &labelY, const QgsFeature *f=nullptr, QgsRenderContext *context=nullptr, double *rotatedLabelX=nullptr, double *rotatedLabelY=nullptr)
Calculates the space required to render the provided text in map units.
void registerFeature(const QgsFeature &f, QgsRenderContext &context)
Registers a feature for labeling.
QgsPalLayerSettings & operator=(const QgsPalLayerSettings &s)
copy operator - only copies the permanent members
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool scaleVisibility
Set to true to limit label visibility to a range of scales.
double repeatDistance
Distance for repeating labels for a single feature.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
QgsExpression * getLabelExpression() const
Returns the QgsExpression for this label settings.
bool geometryGeneratorEnabled
Defines if the geometry generator is enabled or not. If disabled, the standard geometry will be taken...
QMimeData * toMimeData() const
Returns new mime data representing the labeling settings.
Qgis::LabelMultiLineAlignment multilineAlign
Horizontal alignment of multi-line labels.
bool centroidInside
true if centroid positioned labels must be placed inside their corresponding feature polygon,...
int priority
Label priority.
Qgis::GeometryType geometryGeneratorType
The type of the result geometry of the geometry generator.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QgsCallout * callout() const
Returns the label callout renderer, responsible for drawing label callouts.
int fontMinPixelSize
Minimum pixel size for showing rendered map unit labels (1 - 1000).
double angleOffset
Label rotation, in degrees clockwise.
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0).
Qgis::AngleUnit rotationUnit() const
Unit for rotation of labels.
Qgis::GeometryType layerType
Geometry type of layers associated with these settings.
Qgis::RenderUnit offsetUnits
Units for offsets of label.
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
bool preserveRotation
True if label rotation should be preserved during label pin/unpin operations.
bool plusSign
Whether '+' signs should be prepended to positive numeric labels.
bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames, const QgsFields &fields, const QgsMapSettings &mapSettings, const QgsCoordinateReferenceSystem &crs)
Prepare for registration of features.
QString geometryGenerator
The geometry generator expression. Null if disabled.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
QgsMapUnitScale distMapUnitScale
Map unit scale for label feature distance.
QgsStringReplacementCollection substitutions
Substitution collection for automatic text substitution with labels.
Q_DECL_DEPRECATED QColor previewBkgrdColor
const QgsFeature * mCurFeat
int decimals
Number of decimal places to show for numeric labels.
double dist
Distance from feature to the label.
void setRotationUnit(Qgis::AngleUnit angleUnit)
Set unit for rotation of labels.
QgsMapUnitScale repeatDistanceMapUnitScale
Map unit scale for repeating labels for a single feature.
Qgis::RenderUnit distUnits
Units the distance from feature to the label.
bool centroidWhole
true if feature centroid should be calculated from the whole feature, or false if only the visible pa...
Property
Data definable properties.
@ PositionX
X-coordinate data defined label position.
@ LinePlacementOptions
Line placement flags.
@ MinScale
Min scale (deprecated, for old project compatibility only).
@ FontSizeUnit
Font size units.
@ WhitespaceCollisionHandling
Whitespace collision handling.
@ LabelRotation
Label rotation.
@ FontStyle
Font style name.
@ ShapeTransparency
Shape transparency (deprecated).
@ Italic
Use italic style.
@ ShapeOpacity
Shape opacity.
@ AllowDegradedPlacement
Allow degraded label placements.
@ MaskEnabled
Whether the mask is enabled.
@ PredefinedPositionOrder
@ OverlapHandling
Overlap handling technique.
@ PositionY
Y-coordinate data defined label position.
@ MaximumScale
Maximum map scale (ie most "zoomed in").
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top).
@ MinimumScale
Minimum map scale (ie most "zoomed out").
@ FontStretchFactor
Font stretch factor, since QGIS 3.24.
@ PolygonLabelOutside
Whether labels outside a polygon feature are permitted, or should be forced.
@ LineAnchorType
Line anchor type.
@ MaxScale
Max scale (deprecated, for old project compatibility only).
@ BufferOpacity
Buffer opacity.
@ BufferTransp
Buffer transparency (deprecated).
@ LineAnchorClipping
Clipping mode for line anchor calculation.
@ MaskJoinStyle
Mask join style.
@ Strikeout
Use strikeout.
@ LabelAllParts
Multipart geometry behavior.
@ LabelMarginDistance
Minimum distance from labels for this feature to other labels.
@ Underline
Use underline.
@ FontBlendMode
Text blend mode.
@ LineAnchorPercent
Portion along line at which labels should be anchored.
@ FontCase
Label text case.
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right).
@ MaskOpacity
Mask opacity.
@ RemoveDuplicateLabelDistance
Minimum distance from labels for this feature to other labels with duplicate text.
@ LineAnchorTextPoint
Line anchor text point.
@ ShadowTransparency
Shadow transparency (deprecated).
@ OverrunDistance
Distance which labels can extend past either end of linear features.
@ MaskBufferUnit
Mask buffer size unit.
@ FontOpacity
Text opacity.
@ FontWordSpacing
Word spacing.
@ FontTransp
Text transparency (deprecated).
@ CalloutDraw
Show callout.
@ CurvedLabelMode
Mode which determine how curved labels are generated and placed.
@ MaskBufferSize
Mask buffer size.
@ FontLetterSpacing
Letter spacing.
@ TabStopDistance
Tab stop distance, since QGIS 3.38.
@ ShadowOpacity
Shadow opacity.
@ RemoveDuplicateLabels
Whether this feature can cause removal of duplicate labels.
@ PositionPoint
Point-coordinate data defined label position.
@ MaximumDistance
Maximum distance of label from feature.
@ Rotation
Label rotation (deprecated, for old project compatibility only).
Qgis::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
Qgis::UpsideDownLabelHandling upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
QString fieldName
Name of field (or an expression) to use for label text.
static QPixmap labelSettingsPreviewPixmap(const QgsPalLayerSettings &settings, QSize size, const QString &previewText=QString(), int padding=0, const QgsScreenProperties &screen=QgsScreenProperties())
Returns a pixmap preview for label settings.
bool formatNumbers
Set to true to format numeric label text as numbers (e.g.
bool containsAdvancedEffects() const
Returns true if any component of the label settings requires advanced effects such as blend modes,...
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
void setCallout(QgsCallout *callout)
Sets the label callout renderer, responsible for drawing label callouts.
double maximumScale
The maximum map scale (i.e.
int autoWrapLength
If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified num...
Qgis::UnplacedLabelVisibility unplacedVisibility() const
Returns the layer's unplaced label visibility.
bool useMaxLineLengthForAutoWrap
If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum...
void setUnplacedVisibility(Qgis::UnplacedLabelVisibility visibility)
Sets the layer's unplaced label visibility.
const QgsLabelPointSettings & pointSettings() const
Returns the label point settings, which contain settings related to how the label engine places and f...
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the labeling property definitions.
void stopRender(QgsRenderContext &context)
Finalises the label settings after use.
bool useSubstitutions
True if substitutions should be applied.
Point geometry type, with support for z-dimension and m-values.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const final
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
@ Double
Double value (including negative values).
@ Double0To1
Double value between 0-1 (inclusive).
@ StrokeWidth
Line stroke width.
@ String
Any string value.
@ RenderUnits
Render units (eg mm/pixels/map units).
@ PenJoinStyle
Pen join style.
@ SvgPath
Path to an SVG file.
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
@ IntegerPositive
Positive integer values (including 0).
@ Opacity
Opacity (0-100).
@ ColorNoAlpha
Color with no alpha channel.
@ Rotation
Rotation (value between 0-360 degrees).
@ ColorWithAlpha
Color with alpha channel.
@ DoublePositive
Positive double value (including 0).
@ Size2D
2D size (width/height different)
@ DataTypeString
Property requires a string value.
@ DataTypeNumeric
Property requires a numeric value.
A store for object properties.
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
Represents a raster layer.
const QgsAbstractRasterLayerLabeling * labeling() const
Access to const labeling configuration.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
A container for the context for various read/write operations on objects.
A rectangle specified with double values.
Q_INVOKABLE QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void grow(double delta)
Grows the rectangle in place by the specified amount.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
double convertToMapUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QgsVectorSimplifyMethod & vectorSimplifyMethod()
Returns the simplification settings to use when rendering vector layers.
double symbologyReferenceScale() const
Returns the symbology reference scale.
void setDevicePixelRatio(float ratio)
Sets the device pixel ratio.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
double rendererScale() const
Returns the renderer map scale.
QgsExpressionContext & expressionContext()
Gets the expression context.
QgsGeometry featureClipGeometry() const
Returns the geometry to use to clip features at render time.
QgsRectangle mapExtent() const
Returns the original extent of the map being rendered.
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
static bool equalToOrGreaterThanMinimumScale(const double scale, const double minScale)
Returns whether the scale is equal to or greater than the minScale, taking non-round numbers into acc...
static bool lessThanMaximumScale(const double scale, const double maxScale)
Returns whether the scale is less than the maxScale, taking non-round numbers into account.
Stores properties relating to a screen.
double devicePixelRatio() const
Returns the ratio between physical pixels and device-independent pixels for the screen.
bool isValid() const
Returns true if the properties are valid.
void updateRenderContextForScreen(QgsRenderContext &context) const
Updates the settings in a render context to match the screen settings.
static QString capitalize(const QString &string, Qgis::Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
static QString wordWrap(const QString &string, int length, bool useMaxLineLength=true, const QString &customDelimiter=QString())
Automatically wraps a string by inserting new line characters at appropriate locations in the string.
QgsTextFormat defaultTextFormat(QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling) const
Returns the default text format to use for new text based objects in the specified context.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
@ Labeling
Text format used in labeling.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QSizeF toSize(const QVariant &value, bool *ok=nullptr)
Converts a value to a size.
static QPainter::CompositionMode decodeBlendMode(const QString &s)
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
Abstract base class for all rendered symbols.
void setRadiiUnit(Qgis::RenderUnit units)
Sets the units used for the shape's radii.
QString svgFile() const
Returns the absolute path to the background SVG file, if set.
QSizeF size() const
Returns the size of the background shape.
QSizeF radii() const
Returns the radii used for rounding the corners of shapes.
void setOpacity(double opacity)
Sets the background shape's opacity.
void setStrokeColor(const QColor &color)
Sets the color used for outlining the background shape.
Qt::PenJoinStyle joinStyle() const
Returns the join style used for drawing the background shape.
SizeType
Methods for determining the background shape size.
bool enabled() const
Returns whether the background is enabled.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the background shape.
double opacity() const
Returns the background shape's opacity.
double rotation() const
Returns the rotation for the background shape, in degrees clockwise.
QColor fillColor() const
Returns the color used for filing the background shape.
void setRadii(QSizeF radii)
Sets the radii used for rounding the corners of shapes.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
ShapeType type() const
Returns the type of background shape (e.g., square, ellipse, SVG).
double strokeWidth() const
Returns the width of the shape's stroke (stroke).
void setSizeType(SizeType type)
Sets the method used to determine the size of the background shape (e.g., fixed size or buffer around...
ShapeType
Background shape types.
@ ShapeMarkerSymbol
Marker symbol.
void setFillColor(const QColor &color)
Sets the color used for filing the background shape.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units used for the shape's size.
QColor strokeColor() const
Returns the color used for outlining the background shape.
void setRotationType(RotationType type)
Sets the method used for rotating the background shape.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the background shape.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the shape size.
void setType(ShapeType type)
Sets the type of background shape to draw (e.g., square, ellipse, SVG).
Qgis::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
RotationType
Methods for determining the rotation of the background shape.
void setEnabled(bool enabled)
Sets whether the text background will be drawn.
QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol to be rendered in the background.
void setRotation(double rotation)
Sets the rotation for the background shape, in degrees clockwise.
void setStrokeWidthUnit(Qgis::RenderUnit units)
Sets the units used for the shape's stroke width.
void setOffsetUnit(Qgis::RenderUnit units)
Sets the units used for the shape's offset.
void setOffset(QPointF offset)
Sets the offset used for drawing the background shape.
void setSize(QSizeF size)
Sets the size of the background shape.
void setSvgFile(const QString &file)
Sets the path to the background SVG file.
void setStrokeWidth(double width)
Sets the width of the shape's stroke (stroke).
QPointF offset() const
Returns the offset used for drawing the background shape.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the buffer.
Qgis::RenderUnit sizeUnit() const
Returns the units for the buffer size.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
double size() const
Returns the size of the buffer.
void setColor(const QColor &color)
Sets the color for the buffer.
void setOpacity(double opacity)
Sets the buffer opacity.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
bool enabled() const
Returns whether the buffer is enabled.
double opacity() const
Returns the buffer opacity.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units used for the buffer size.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
QColor color() const
Returns the color of the buffer.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the buffer.
void setSize(double size)
Sets the size of the buffer.
Contains pre-calculated metrics of a QgsTextDocument.
QSizeF documentSize(Qgis::TextLayoutMode mode, Qgis::TextOrientation orientation) const
Returns the overall size of the document.
static QgsTextDocumentMetrics calculateMetrics(const QgsTextDocument &document, const QgsTextFormat &format, const QgsRenderContext &context, double scaleFactor=1.0, const QgsTextDocumentRenderContext &documentContext=QgsTextDocumentRenderContext())
Returns precalculated text metrics for a text document, when rendered using the given base format and...
QRectF outerBounds(Qgis::TextLayoutMode mode, Qgis::TextOrientation orientation) const
Returns the outer bounds of the document, which is the documentSize() adjusted to account for any tex...
Represents a document consisting of one or more QgsTextBlock objects.
void splitLines(const QString &wrapCharacter, int autoWrapLength=0, bool useMaxLineLengthWhenAutoWrapping=true)
Splits lines of text in the document to separate lines, using a specified wrap character (wrapCharact...
QVector< QgsTextDocument > splitBlocksToDocuments() const
Splits the text document, such that each block in the document becomes a separate document of its own...
static QgsTextDocument fromTextAndFormat(const QStringList &lines, const QgsTextFormat &format)
Constructor for QgsTextDocument consisting of a set of lines, respecting settings from a text format.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the text.
void setSize(double size)
Sets the size for rendered text.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the size.
void setCapitalization(Qgis::Capitalization capitalization)
Sets the text capitalization style.
void setOrientation(Qgis::TextOrientation orientation)
Sets the orientation for the text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
void setShadow(const QgsTextShadowSettings &shadowSettings)
Sets the text's drop shadow settings.
void setMask(const QgsTextMaskSettings &maskSettings)
Sets the text's masking settings.
void setOpacity(double opacity)
Sets the text's opacity.
Qgis::Capitalization capitalization() const
Returns the text capitalization style.
QgsTextMaskSettings & mask()
Returns a reference to the masking settings.
void setBuffer(const QgsTextBufferSettings &bufferSettings)
Sets the text's buffer settings.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
Qgis::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
void setTabStopDistance(double distance)
Sets the distance for tab stops.
double size() const
Returns the size for rendered text.
QgsTextShadowSettings & shadow()
Returns a reference to the text drop shadow settings.
void setTabPositions(const QList< QgsTextFormat::Tab > &positions)
Sets the list of tab positions for tab stops.
void setBackground(const QgsTextBackgroundSettings &backgroundSettings)
Sets the text's background settings.q.
QFont font() const
Returns the font used for rendering text.
QColor previewBackgroundColor() const
Returns the background color for text previews.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
void setLineHeight(double height)
Sets the line height for text.
static QgsPrecalculatedTextMetrics calculateTextMetrics(const QgsMapToPixel *xform, const QgsRenderContext &context, const QgsTextFormat &format, const QFont &baseFont, const QFontMetricsF &fontMetrics, double letterSpacing, double wordSpacing, const QgsTextDocument &document, const QgsTextDocumentMetrics &metrics)
Calculate text metrics for later retrieval via textMetrics().
void setEnabled(bool)
Returns whether the mask is enabled.
void setSize(double size)
Sets the size of the buffer.
double size() const
Returns the size of the buffer.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the buffer.
double opacity() const
Returns the mask's opacity.
bool enabled() const
Returns whether the mask is enabled.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units used for the buffer size.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
void setOpacity(double opacity)
Sets the mask's opacity.
static QgsTextBackgroundSettings::ShapeType decodeShapeType(const QString &string)
Decodes a string representation of a background shape type to a type.
static Qgis::TextOrientation decodeTextOrientation(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a text orientation.
static QgsTextShadowSettings::ShadowPlacement decodeShadowPlacementType(const QString &string)
Decodes a string representation of a shadow placement type to a type.
static QgsTextBackgroundSettings::RotationType decodeBackgroundRotationType(const QString &string)
Decodes a string representation of a background rotation type to a type.
static QString encodeTextOrientation(Qgis::TextOrientation orientation)
Encodes a text orientation.
static QgsTextBackgroundSettings::SizeType decodeBackgroundSizeType(const QString &string)
Decodes a string representation of a background size type to a type.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static int sizeToPixel(double size, const QgsRenderContext &c, Qgis::RenderUnit unit, const QgsMapUnitScale &mapUnitScale=QgsMapUnitScale())
Calculates pixel size (considering output size should be in pixel or map units, scale factors and opt...
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
int offsetAngle() const
Returns the angle for offsetting the position of the shadow from the text.
void setBlurRadiusUnit(Qgis::RenderUnit units)
Sets the units used for the shadow's blur radius.
bool enabled() const
Returns whether the shadow is enabled.
void setOffsetUnit(Qgis::RenderUnit units)
Sets the units used for the shadow's offset.
int scale() const
Returns the scaling used for the drop shadow (in percentage of original size).
void setShadowPlacement(QgsTextShadowSettings::ShadowPlacement placement)
Sets the placement for the drop shadow.
double opacity() const
Returns the shadow's opacity.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the drop shadow.
void setColor(const QColor &color)
Sets the color for the drop shadow.
QColor color() const
Returns the color of the drop shadow.
ShadowPlacement
Placement positions for text shadow.
void setScale(int scale)
Sets the scaling used for the drop shadow (in percentage of original size).
double offsetDistance() const
Returns the distance for offsetting the position of the shadow from the text.
void setOffsetDistance(double distance)
Sets the distance for offsetting the position of the shadow from the text.
void setOpacity(double opacity)
Sets the shadow's opacity.
void setOffsetAngle(int angle)
Sets the angle for offsetting the position of the shadow from the text.
double blurRadius() const
Returns the blur radius for the shadow.
void setBlurRadius(double blurRadius)
Sets the blur radius for the shadow.
void setEnabled(bool enabled)
Sets whether the text shadow will be drawn.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based dataset.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
bool diagramsEnabled() const
Returns whether the layer contains diagrams which are enabled and should be drawn.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
const QgsDiagramRenderer * diagramRenderer() const
double tolerance() const
Gets the tolerance of simplification in map units. Represents the maximum distance in map units betwe...
bool forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported,...
Qgis::VectorRenderingSimplificationFlags simplifyHints() const
Gets the simplification hints of the vector layer managed.
Qgis::VectorSimplificationAlgorithm simplifyAlgorithm() const
Gets the local simplification algorithm of the vector layer managed.
Basic labeling configuration for vector tile layers.
Implements a map layer that is dedicated to rendering of vector tiles.
QgsVectorTileLabeling * labeling() const
Returns currently assigned labeling.
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
T qgsgeometry_cast(QgsAbstractGeometry *geom)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QString updateDataDefinedString(const QString &value)
QVector< Qgis::LabelPredefinedPointPosition > PredefinedPointPositionVector
Q_GLOBAL_STATIC_WITH_ARGS(PredefinedPointPositionVector, DEFAULT_PLACEMENT_ORDER,({ Qgis::LabelPredefinedPointPosition::TopRight, Qgis::LabelPredefinedPointPosition::TopLeft, Qgis::LabelPredefinedPointPosition::BottomRight, Qgis::LabelPredefinedPointPosition::BottomLeft, Qgis::LabelPredefinedPointPosition::MiddleRight, Qgis::LabelPredefinedPointPosition::MiddleLeft, Qgis::LabelPredefinedPointPosition::TopSlightlyRight, Qgis::LabelPredefinedPointPosition::BottomSlightlyRight })) void QgsPalLayerSettings
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.