45#include <QAbstractTextDocumentLayout>
46#include <QDomDocument>
48#include <QFontMetricsF>
51#include <QTextDocument>
53#include "moc_qgslayoutitemscalebar.cpp"
55using namespace Qt::StringLiterals;
98 if (
mLayout->renderContext().isPreviewRender() )
104 const QRectF thisPaintRect = QRectF( 0, 0, rect().width() * scale, rect().
height() * scale );
106 painter->setBrush( QBrush( QColor( 255, 125, 125, 125 ) ) );
107 painter->setPen( Qt::NoPen );
108 painter->drawRect( thisPaintRect );
109 painter->setBrush( Qt::NoBrush );
111 painter->setPen( QColor( 200, 0, 0, 255 ) );
113 td.setTextWidth( thisPaintRect.width() );
115 u
"<span style=\"color: rgb(200,0,0);\"><b>%1</b><br>%2</span>"_s.arg( tr(
"Invalid scale!" ), tr(
"The scale bar cannot be rendered due to invalid settings or an incompatible linked map extent." ) )
117 painter->setClipRect( thisPaintRect );
118 QAbstractTextDocumentLayout::PaintContext ctx;
119 td.documentLayout()->draw( painter, ctx );
128 std::unique_ptr< QgsLineSymbol > sym( mSettings.lineSymbol()->clone() );
135 mSettings.setLineSymbol( sym.release() );
141 std::unique_ptr< QgsFillSymbol > sym( mSettings.fillSymbol()->clone() );
145 mSettings.setFillSymbol( sym.release() );
151 std::unique_ptr< QgsFillSymbol > sym( mSettings.alternateFillSymbol()->clone() );
155 mSettings.setAlternateFillSymbol( sym.release() );
158 mStyle->draw( context.
renderContext(), mSettings, scaleContext );
165 mSettings.setNumberOfSegments( nSegments );
168 mSettings.setNumberOfSegments( nSegments );
176 mSettings.setUnitsPerSegment(
units );
179 mSettings.setUnitsPerSegment(
units );
180 refreshSegmentMillimeters();
189 mSettings.setSegmentSizeMode( mode );
192 mSettings.setSegmentSizeMode( mode );
193 refreshSegmentMillimeters();
201 mSettings.setMinimumBarWidth( minWidth );
204 mSettings.setMinimumBarWidth( minWidth );
205 refreshSegmentMillimeters();
213 mSettings.setMaximumBarWidth( maxWidth );
216 mSettings.setMaximumBarWidth( maxWidth );
217 refreshSegmentMillimeters();
223 return mSettings.textFormat();
228 mSettings.setTextFormat( format );
235 return mSettings.lineSymbol();
240 mSettings.setLineSymbol( symbol );
245 return mSettings.divisionLineSymbol();
250 mSettings.setDivisionLineSymbol( symbol );
255 return mSettings.subdivisionLineSymbol();
260 mSettings.setSubdivisionLineSymbol( symbol );
265 return mSettings.fillSymbol();
270 mSettings.setFillSymbol( symbol );
275 return mSettings.alternateFillSymbol();
280 mSettings.setAlternateFillSymbol( symbol );
287 mSettings.setNumberOfSegmentsLeft( nSegmentsLeft );
290 mSettings.setNumberOfSegmentsLeft( nSegmentsLeft );
298 mSettings.setBoxContentSpace( space );
301 mSettings.setBoxContentSpace( space );
307 disconnectCurrentMap();
317 connect( mMap, &QObject::destroyed,
this, &QgsLayoutItemScaleBar::disconnectCurrentMap );
319 refreshSegmentMillimeters();
323void QgsLayoutItemScaleBar::disconnectCurrentMap()
331 disconnect( mMap, &QObject::destroyed,
this, &QgsLayoutItemScaleBar::disconnectCurrentMap );
346 refreshSegmentMillimeters();
413 int leftSegments = mSettings.numberOfSegmentsLeft();
433 int rightSegments = mSettings.numberOfSegments();
453 bool forceUpdate =
false;
458 double height = mSettings.height();
478 double height = mSettings.subdivisionsHeight();
497 refreshNumberOfSegmentsLeft( &context );
503 refreshNumberOfSegmentsRight( &context );
510 int segments = mSettings.numberOfSubdivisions();
530 refreshUnitsPerSegment( &context );
536 refreshMinimumBarWidth( &context );
542 refreshMaximumBarWidth( &context );
574void QgsLayoutItemScaleBar::refreshSegmentMillimeters()
579 const QRectF composerItemRect = mMap->rect();
581 const double currentMapWidth = mapWidth();
582 if (
qgsDoubleNear( currentMapWidth, 0 ) || std::isnan( currentMapWidth ) )
584 mSegmentMillimeters = std::numeric_limits< double >::quiet_NaN();
588 switch ( mSettings.segmentSizeMode() )
593 mSegmentMillimeters = composerItemRect.width() / currentMapWidth * mSettings.unitsPerSegment();
599 if ( mSettings.maximumBarWidth() < mSettings.minimumBarWidth() )
601 mSegmentMillimeters = 0;
605 const double nSegments = ( mSettings.numberOfSegmentsLeft() != 0 ) + mSettings.numberOfSegments();
607 const double minUnitsPerSeg = ( mSettings.minimumBarWidth() * currentMapWidth ) / ( nSegments * composerItemRect.width() );
608 const double maxUnitsPerSeg = ( mSettings.maximumBarWidth() * currentMapWidth ) / ( nSegments * composerItemRect.width() );
610 mSegmentMillimeters = composerItemRect.width() / currentMapWidth * mSettings.unitsPerSegment();
618double QgsLayoutItemScaleBar::mapWidth()
const
625 const QgsRectangle mapExtent = mMap->extent();
628 return mapExtent.
width();
638 QList< double > yValues;
673 double sumValidMeasures = 0;
674 int validMeasureCount = 0;
676 for (
const double y : std::as_const( yValues ) )
681 if ( std::isnan( measure ) )
684 QgsDebugError( u
"An error occurred while calculating length"_s );
689 sumValidMeasures += measure;
692 catch ( QgsCsException & )
695 QgsDebugError( u
"An error occurred while calculating length"_s );
700 if ( validMeasureCount == 0 )
701 return std::numeric_limits< double >::quiet_NaN();
703 return sumValidMeasures / validMeasureCount;
709 QgsScaleBarRenderer::ScaleBarContext scaleContext;
710 scaleContext.
size = rect().size();
712 scaleContext.
scale = mMap ? mMap->scale() : 1.0;
713 scaleContext.
flags = mStyle->flags();
719 mSettings.setLabelVerticalPlacement( placement );
726 mSettings.setLabelHorizontalPlacement( placement );
733 mSettings.setUnitLabelPlacements( placements );
740 mSettings.setAlignment( a );
747 mSettings.setUnits( u );
748 refreshSegmentMillimeters();
756 return mSettings.lineJoinStyle();
763 if ( mSettings.lineJoinStyle() ==
style )
768 mSettings.setLineJoinStyle(
style );
777 return mSettings.lineCapStyle();
784 if ( mSettings.lineCapStyle() ==
style )
789 mSettings.setLineCapStyle(
style );
798 mStyle = std::make_unique< QgsSingleBoxScaleBarRenderer >();
807 if ( !defaultFontString.isEmpty() )
815 mSettings.setTextFormat( format );
843 const double widthInSelectedUnits = mapWidth();
844 if ( std::isnan( widthInSelectedUnits ) )
847 const double initialUnitsPerSegment = widthInSelectedUnits / 10.0;
852 if ( initialUnitsPerSegment > 1000.0 )
860 if ( initialUnitsPerSegment > 5419.95 )
875 mSettings.setUnits(
units );
878 double upperMagnitudeMultiplier = 1.0;
879 const double widthInSelectedUnits = mapWidth();
880 if ( !std::isnan( widthInSelectedUnits ) )
882 const double initialUnitsPerSegment = widthInSelectedUnits / 10.0;
883 mSettings.setUnitsPerSegment( initialUnitsPerSegment );
886 upperMagnitudeMultiplier = 1;
888 const double segmentWidth = initialUnitsPerSegment / upperMagnitudeMultiplier;
889 const int segmentMagnitude = std::floor( std::log10( segmentWidth ) );
890 double unitsPerSegment = upperMagnitudeMultiplier * ( std::pow( 10.0, segmentMagnitude ) );
891 const double multiplier = std::floor( ( widthInSelectedUnits / (
unitsPerSegment * 10.0 ) ) / 2.5 ) * 2.5;
893 if ( multiplier > 0 )
898 mSettings.setMapUnitsPerScaleBarUnit( upperMagnitudeMultiplier );
900 mSettings.setNumberOfSegments( 2 );
901 mSettings.setNumberOfSegmentsLeft( 0 );
905 refreshSegmentMillimeters();
921 const double widthMM = mStyle->calculateBoxSize( context, mSettings, scaleContext ).width();
932 if ( mStyle && mStyle->id() !=
"Numeric"_L1 )
936 QgsLayoutItem::update();
939void QgsLayoutItemScaleBar::updateScale()
941 refreshSegmentMillimeters();
943 if ( mStyle && mStyle->id() !=
"Numeric"_L1 )
956 mStyle = std::move( renderer );
976 return mSettings.numericFormat();
981 mSettings.setNumericFormat( format );
986 return mSettings.textFormat().font();
992 mSettings.setFont(
font );
1000 QColor color = mSettings.textFormat().color();
1001 color.setAlphaF( mSettings.textFormat().opacity() );
1007 mSettings.textFormat().setColor( color );
1008 mSettings.textFormat().setOpacity( color.alphaF() );
1014 return mSettings.fillColor();
1021 mSettings.setFillColor( color );
1028 return mSettings.fillColor2();
1035 mSettings.setFillColor2( color );
1042 return mSettings.lineColor();
1049 mSettings.setLineColor( color );
1056 return mSettings.lineWidth();
1063 mSettings.setLineWidth( width );
1070 return mSettings.pen();
1077 return mSettings.brush();
1084 return mSettings.brush2();
1090 composerScaleBarElem.setAttribute( u
"height"_s, QString::number( mSettings.height() ) );
1091 composerScaleBarElem.setAttribute( u
"labelBarSpace"_s, QString::number( mSettings.labelBarSpace() ) );
1092 composerScaleBarElem.setAttribute( u
"boxContentSpace"_s, QString::number( mSettings.boxContentSpace() ) );
1093 composerScaleBarElem.setAttribute( u
"numSegments"_s, mSettings.numberOfSegments() );
1094 composerScaleBarElem.setAttribute( u
"numSegmentsLeft"_s, mSettings.numberOfSegmentsLeft() );
1095 composerScaleBarElem.setAttribute( u
"numSubdivisions"_s, mSettings.numberOfSubdivisions() );
1096 composerScaleBarElem.setAttribute( u
"subdivisionsHeight"_s, mSettings.subdivisionsHeight() );
1097 composerScaleBarElem.setAttribute( u
"numUnitsPerSegment"_s, QString::number( mSettings.unitsPerSegment() ) );
1098 composerScaleBarElem.setAttribute( u
"segmentSizeMode"_s,
static_cast< int >( mSettings.segmentSizeMode() ) );
1099 composerScaleBarElem.setAttribute( u
"minBarWidth"_s, mSettings.minimumBarWidth() );
1100 composerScaleBarElem.setAttribute( u
"maxBarWidth"_s, mSettings.maximumBarWidth() );
1101 composerScaleBarElem.setAttribute( u
"segmentMillimeters"_s, QString::number( mSegmentMillimeters ) );
1102 composerScaleBarElem.setAttribute( u
"numMapUnitsPerScaleBarUnit"_s, QString::number( mSettings.mapUnitsPerScaleBarUnit() ) );
1105 const QDomElement textElem = mSettings.textFormat().writeXml( doc, rwContext );
1106 composerScaleBarElem.appendChild( textElem );
1110 composerScaleBarElem.setAttribute( u
"outlineWidth"_s, QString::number( mSettings.lineWidth() ) );
1114 QDomElement strokeColorElem = doc.createElement( u
"strokeColor"_s );
1115 strokeColorElem.setAttribute( u
"red"_s, QString::number( mSettings.lineColor().red() ) );
1116 strokeColorElem.setAttribute( u
"green"_s, QString::number( mSettings.lineColor().green() ) );
1117 strokeColorElem.setAttribute( u
"blue"_s, QString::number( mSettings.lineColor().blue() ) );
1118 strokeColorElem.setAttribute( u
"alpha"_s, QString::number( mSettings.lineColor().alpha() ) );
1119 composerScaleBarElem.appendChild( strokeColorElem );
1122 composerScaleBarElem.setAttribute( u
"unitLabelString"_s, mSettings.unitLabel() );
1125 QDomElement numericFormatElem = doc.createElement( u
"numericFormat"_s );
1126 mSettings.numericFormat()->writeXml( numericFormatElem, doc, rwContext );
1127 composerScaleBarElem.appendChild( numericFormatElem );
1132 composerScaleBarElem.setAttribute( u
"style"_s, mStyle->id() );
1138 composerScaleBarElem.setAttribute( u
"mapUuid"_s, mMap->uuid() );
1147 QDomElement fillColorElem = doc.createElement( u
"fillColor"_s );
1148 fillColorElem.setAttribute( u
"red"_s, QString::number( mSettings.fillColor().red() ) );
1149 fillColorElem.setAttribute( u
"green"_s, QString::number( mSettings.fillColor().green() ) );
1150 fillColorElem.setAttribute( u
"blue"_s, QString::number( mSettings.fillColor().blue() ) );
1151 fillColorElem.setAttribute( u
"alpha"_s, QString::number( mSettings.fillColor().alpha() ) );
1152 composerScaleBarElem.appendChild( fillColorElem );
1155 QDomElement fillColor2Elem = doc.createElement( u
"fillColor2"_s );
1156 fillColor2Elem.setAttribute( u
"red"_s, QString::number( mSettings.fillColor2().red() ) );
1157 fillColor2Elem.setAttribute( u
"green"_s, QString::number( mSettings.fillColor2().green() ) );
1158 fillColor2Elem.setAttribute( u
"blue"_s, QString::number( mSettings.fillColor2().blue() ) );
1159 fillColor2Elem.setAttribute( u
"alpha"_s, QString::number( mSettings.fillColor2().alpha() ) );
1160 composerScaleBarElem.appendChild( fillColor2Elem );
1165 composerScaleBarElem.setAttribute( u
"labelVerticalPlacement"_s, QString::number(
static_cast< int >( mSettings.labelVerticalPlacement() ) ) );
1166 composerScaleBarElem.setAttribute( u
"labelHorizontalPlacement"_s, QString::number(
static_cast< int >( mSettings.labelHorizontalPlacement() ) ) );
1169 composerScaleBarElem.setAttribute( u
"unitLabelPlacement"_s,
qgsFlagValueToKeys( mSettings.unitLabelPlacements() ) );
1173 composerScaleBarElem.setAttribute( u
"alignment"_s, QString::number(
static_cast< int >( mSettings.alignment() ) ) );
1175 QDomElement
lineSymbol = doc.createElement( u
"lineSymbol"_s );
1178 composerScaleBarElem.appendChild(
lineSymbol );
1180 QDomElement divisionSymbol = doc.createElement( u
"divisionLineSymbol"_s );
1182 divisionSymbol.appendChild( divisionSymbolElem );
1183 composerScaleBarElem.appendChild( divisionSymbol );
1185 QDomElement subdivisionSymbol = doc.createElement( u
"subdivisionLineSymbol"_s );
1187 subdivisionSymbol.appendChild( subdivisionSymbolElem );
1188 composerScaleBarElem.appendChild( subdivisionSymbol );
1190 QDomElement fillSymbol1Elem = doc.createElement( u
"fillSymbol1"_s );
1192 fillSymbol1Elem.appendChild( symbol1Elem );
1193 composerScaleBarElem.appendChild( fillSymbol1Elem );
1195 QDomElement fillSymbol2Elem = doc.createElement( u
"fillSymbol2"_s );
1197 fillSymbol2Elem.appendChild( symbol2Elem );
1198 composerScaleBarElem.appendChild( fillSymbol2Elem );
1206 mSettings.setHeight( itemElem.attribute( u
"height"_s, u
"5.0"_s ).toDouble() );
1207 mSettings.setLabelBarSpace( itemElem.attribute( u
"labelBarSpace"_s, u
"3.0"_s ).toDouble() );
1208 mSettings.setBoxContentSpace( itemElem.attribute( u
"boxContentSpace"_s, u
"1.0"_s ).toDouble() );
1209 mSettings.setNumberOfSegments( itemElem.attribute( u
"numSegments"_s, u
"2"_s ).toInt() );
1210 mSettings.setNumberOfSegmentsLeft( itemElem.attribute( u
"numSegmentsLeft"_s, u
"0"_s ).toInt() );
1211 mSettings.setNumberOfSubdivisions( itemElem.attribute( u
"numSubdivisions"_s, u
"1"_s ).toInt() );
1212 mSettings.setSubdivisionsHeight( itemElem.attribute( u
"subdivisionsHeight"_s, u
"1.5"_s ).toDouble() );
1213 mSettings.setUnitsPerSegment( itemElem.attribute( u
"numUnitsPerSegment"_s, u
"1.0"_s ).toDouble() );
1215 mSettings.setMinimumBarWidth( itemElem.attribute( u
"minBarWidth"_s, u
"50"_s ).toDouble() );
1216 mSettings.setMaximumBarWidth( itemElem.attribute( u
"maxBarWidth"_s, u
"150"_s ).toDouble() );
1217 mSegmentMillimeters = itemElem.attribute( u
"segmentMillimeters"_s, u
"0.0"_s ).toDouble();
1218 mSettings.setMapUnitsPerScaleBarUnit( itemElem.attribute( u
"numMapUnitsPerScaleBarUnit"_s, u
"1.0"_s ).toDouble() );
1223 const QDomElement lineSymbolElem = itemElem.firstChildElement( u
"lineSymbol"_s );
1224 bool foundLineSymbol =
false;
1225 if ( !lineSymbolElem.isNull() )
1227 const QDomElement symbolElem = lineSymbolElem.firstChildElement( u
"symbol"_s );
1231 mSettings.setLineSymbol(
lineSymbol.release() );
1232 foundLineSymbol =
true;
1235 const QDomElement divisionSymbolElem = itemElem.firstChildElement( u
"divisionLineSymbol"_s );
1236 if ( !divisionSymbolElem.isNull() )
1238 const QDomElement symbolElem = divisionSymbolElem.firstChildElement( u
"symbol"_s );
1242 mSettings.setDivisionLineSymbol(
lineSymbol.release() );
1245 else if ( foundLineSymbol )
1247 mSettings.setDivisionLineSymbol( mSettings.lineSymbol()->clone() );
1249 const QDomElement subdivisionSymbolElem = itemElem.firstChildElement( u
"subdivisionLineSymbol"_s );
1250 if ( !subdivisionSymbolElem.isNull() )
1252 const QDomElement symbolElem = subdivisionSymbolElem.firstChildElement( u
"symbol"_s );
1256 mSettings.setSubdivisionLineSymbol(
lineSymbol.release() );
1259 else if ( foundLineSymbol )
1261 mSettings.setSubdivisionLineSymbol( mSettings.lineSymbol()->clone() );
1264 if ( !foundLineSymbol )
1267 auto lineSymbol = std::make_unique< QgsLineSymbol >();
1268 auto lineSymbolLayer = std::make_unique< QgsSimpleLineSymbolLayer >();
1269 lineSymbolLayer->setWidth( itemElem.attribute( u
"outlineWidth"_s, u
"0.3"_s ).toDouble() );
1275 const QDomNodeList strokeColorList = itemElem.elementsByTagName( u
"strokeColor"_s );
1276 if ( !strokeColorList.isEmpty() )
1278 const QDomElement strokeColorElem = strokeColorList.at( 0 ).toElement();
1279 bool redOk, greenOk, blueOk, alphaOk;
1280 int strokeRed, strokeGreen, strokeBlue, strokeAlpha;
1282 strokeRed = strokeColorElem.attribute( u
"red"_s ).toDouble( &redOk );
1283 strokeGreen = strokeColorElem.attribute( u
"green"_s ).toDouble( &greenOk );
1284 strokeBlue = strokeColorElem.attribute( u
"blue"_s ).toDouble( &blueOk );
1285 strokeAlpha = strokeColorElem.attribute( u
"alpha"_s ).toDouble( &alphaOk );
1287 if ( redOk && greenOk && blueOk && alphaOk )
1289 lineSymbolLayer->setColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) );
1294 lineSymbolLayer->setColor( QColor( itemElem.attribute( u
"penColor"_s, u
"#000000"_s ) ) );
1304 lineSymbol->changeSymbolLayer( 0, lineSymbolLayer.release() );
1305 mSettings.setLineSymbol(
lineSymbol->clone() );
1306 mSettings.setDivisionLineSymbol(
lineSymbol->clone() );
1307 mSettings.setSubdivisionLineSymbol(
lineSymbol.release() );
1310 if ( itemElem.hasAttribute( u
"unitLabelString"_s ) )
1312 mSettings.setUnitLabel( itemElem.attribute( u
"unitLabelString"_s ) );
1318 mSettings.setUnitLabel(
' ' + itemElem.attribute( u
"unitLabel"_s ) );
1321 const QDomNodeList textFormatNodeList = itemElem.elementsByTagName( u
"text-style"_s );
1322 if ( !textFormatNodeList.isEmpty() )
1324 const QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
1325 mSettings.textFormat().readXml( textFormatElem, context );
1332 f.fromString( itemElem.attribute( u
"font"_s, QString() ) );
1334 mSettings.textFormat().setFont( f );
1335 if ( f.pointSizeF() > 0 )
1337 mSettings.textFormat().setSize( f.pointSizeF() );
1340 else if ( f.pixelSize() > 0 )
1342 mSettings.textFormat().setSize( f.pixelSize() );
1347 const QDomNodeList numericFormatNodeList = itemElem.elementsByTagName( u
"numericFormat"_s );
1348 if ( !numericFormatNodeList.isEmpty() )
1350 const QDomElement numericFormatElem = numericFormatNodeList.at( 0 ).toElement();
1354 const QDomElement fillSymbol1Elem = itemElem.firstChildElement( u
"fillSymbol1"_s );
1355 bool foundFillSymbol1 =
false;
1356 if ( !fillSymbol1Elem.isNull() )
1358 const QDomElement symbolElem = fillSymbol1Elem.firstChildElement( u
"symbol"_s );
1362 mSettings.setFillSymbol(
fillSymbol.release() );
1363 foundFillSymbol1 =
true;
1366 if ( !foundFillSymbol1 )
1369 auto fillSymbol = std::make_unique< QgsFillSymbol >();
1370 auto fillSymbolLayer = std::make_unique< QgsSimpleFillSymbolLayer >();
1371 fillSymbolLayer->setStrokeStyle( Qt::NoPen );
1374 const QDomNodeList fillColorList = itemElem.elementsByTagName( u
"fillColor"_s );
1375 if ( !fillColorList.isEmpty() )
1377 const QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
1378 bool redOk, greenOk, blueOk, alphaOk;
1379 int fillRed, fillGreen, fillBlue, fillAlpha;
1381 fillRed = fillColorElem.attribute( u
"red"_s ).toDouble( &redOk );
1382 fillGreen = fillColorElem.attribute( u
"green"_s ).toDouble( &greenOk );
1383 fillBlue = fillColorElem.attribute( u
"blue"_s ).toDouble( &blueOk );
1384 fillAlpha = fillColorElem.attribute( u
"alpha"_s ).toDouble( &alphaOk );
1386 if ( redOk && greenOk && blueOk && alphaOk )
1388 fillSymbolLayer->setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
1393 fillSymbolLayer->setColor( QColor( itemElem.attribute( u
"brushColor"_s, u
"#000000"_s ) ) );
1401 fillSymbol->changeSymbolLayer( 0, fillSymbolLayer.release() );
1402 mSettings.setFillSymbol(
fillSymbol.release() );
1405 const QDomElement fillSymbol2Elem = itemElem.firstChildElement( u
"fillSymbol2"_s );
1406 bool foundFillSymbol2 =
false;
1407 if ( !fillSymbol2Elem.isNull() )
1409 const QDomElement symbolElem = fillSymbol2Elem.firstChildElement( u
"symbol"_s );
1413 mSettings.setAlternateFillSymbol(
fillSymbol.release() );
1414 foundFillSymbol2 =
true;
1417 if ( !foundFillSymbol2 )
1420 auto fillSymbol = std::make_unique< QgsFillSymbol >();
1421 auto fillSymbolLayer = std::make_unique< QgsSimpleFillSymbolLayer >();
1422 fillSymbolLayer->setStrokeStyle( Qt::NoPen );
1426 const QDomNodeList fillColor2List = itemElem.elementsByTagName( u
"fillColor2"_s );
1427 if ( !fillColor2List.isEmpty() )
1429 const QDomElement fillColor2Elem = fillColor2List.at( 0 ).toElement();
1430 bool redOk, greenOk, blueOk, alphaOk;
1431 int fillRed, fillGreen, fillBlue, fillAlpha;
1433 fillRed = fillColor2Elem.attribute( u
"red"_s ).toDouble( &redOk );
1434 fillGreen = fillColor2Elem.attribute( u
"green"_s ).toDouble( &greenOk );
1435 fillBlue = fillColor2Elem.attribute( u
"blue"_s ).toDouble( &blueOk );
1436 fillAlpha = fillColor2Elem.attribute( u
"alpha"_s ).toDouble( &alphaOk );
1438 if ( redOk && greenOk && blueOk && alphaOk )
1440 fillSymbolLayer->setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
1445 fillSymbolLayer->setColor( QColor( itemElem.attribute( u
"brush2Color"_s, u
"#ffffff"_s ) ) );
1453 fillSymbol->changeSymbolLayer( 0, fillSymbolLayer.release() );
1454 mSettings.setAlternateFillSymbol(
fillSymbol.release() );
1458 const QDomNodeList textColorList = itemElem.elementsByTagName( u
"textColor"_s );
1459 if ( !textColorList.isEmpty() )
1461 const QDomElement textColorElem = textColorList.at( 0 ).toElement();
1462 bool redOk, greenOk, blueOk, alphaOk;
1463 int textRed, textGreen, textBlue, textAlpha;
1465 textRed = textColorElem.attribute( u
"red"_s ).toDouble( &redOk );
1466 textGreen = textColorElem.attribute( u
"green"_s ).toDouble( &greenOk );
1467 textBlue = textColorElem.attribute( u
"blue"_s ).toDouble( &blueOk );
1468 textAlpha = textColorElem.attribute( u
"alpha"_s ).toDouble( &alphaOk );
1470 if ( redOk && greenOk && blueOk && alphaOk )
1472 mSettings.textFormat().setColor( QColor( textRed, textGreen, textBlue, textAlpha ) );
1475 else if ( itemElem.hasAttribute( u
"fontColor"_s ) )
1478 c.setNamedColor( itemElem.attribute( u
"fontColor"_s, u
"#000000"_s ) );
1479 mSettings.textFormat().setColor(
c );
1483 setStyle( itemElem.attribute( u
"style"_s, QString() ) );
1488 if ( itemElem.attribute( u
"unitType"_s ).isEmpty() )
1491 switch ( itemElem.attribute( u
"units"_s ).toInt() )
1506 mSettings.setUnits( u );
1517 mSettings.setAlignment(
static_cast< Qgis::ScaleBarAlignment >( itemElem.attribute( u
"alignment"_s, u
"0"_s ).toInt() ) );
1520 disconnectCurrentMap();
1522 mMapUuid = itemElem.attribute( u
"mapUuid"_s );
1529 if (
mLayout && !mMapUuid.isEmpty() )
1531 disconnectCurrentMap();
1532 mMap = qobject_cast< QgsLayoutItemMap * >(
mLayout->itemByUuid( mMapUuid,
true ) );
1536 connect( mMap, &QObject::destroyed,
this, &QgsLayoutItemScaleBar::disconnectCurrentMap );
ScaleBarDistanceLabelHorizontalPlacement
Scale bar distance label horizontal placement.
ScaleBarDistanceLabelVerticalPlacement
Scale bar distance label vertical placement.
@ Millimeters
Millimeters.
ScaleBarAlignment
Scalebar alignment.
DistanceUnit
Units of distance.
@ Miles
Terrestrial miles.
@ Unknown
Unknown distance unit.
@ Degrees
Degrees, for planar geographic CRS distance measurements.
@ NauticalMiles
Nautical miles.
@ AfterLastDistanceLabel
Placed after the last distance label.
QFlags< ScaleBarUnitLabelPlacement > ScaleBarUnitLabelPlacements
Available placement options for a scale bar's unit label.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes).
ScaleCalculationMethod
Scale calculation logic.
@ HorizontalTop
Calculate horizontally, across top of map.
@ HorizontalMiddle
Calculate horizontally, across midle of map.
@ AtEquator
Always calculate the scale at the equator, regardless of the actual visible map extent....
@ HorizontalAverage
Calculate horizontally, using the average of the top, middle and bottom scales.
@ HorizontalBottom
Calculate horizontally, across bottom of map.
ScaleBarSegmentSizeMode
Modes for setting size for scale bar segments.
@ FitWidth
Scale bar segment size is calculated to fit a size range.
@ Fixed
Scale bar segment size is fixed to a map unit.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
static QgsScaleBarRendererRegistry * scaleBarRendererRegistry()
Gets the registry of available scalebar renderers.
static QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Represents a coordinate reference system (CRS).
Qgis::DistanceUnit mapUnits
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Qgis::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
void extentChanged()
Emitted when the map's extent changes.
@ LayoutScaleBar
Scale bar item.
Contains settings and helpers relating to a render of a QgsLayoutItem.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void setNumberOfSegments(int segments)
Sets the number of segments included in the scalebar.
Q_DECL_DEPRECATED QBrush brush() const
Returns the primary brush for the scalebar.
Q_DECL_DEPRECATED QColor fillColor2() const
Returns the secondary color used for fills in the scalebar.
Q_DECL_DEPRECATED double lineWidth() const
Returns the line width in millimeters for lines in the scalebar.
QIcon icon() const override
Returns the item's icon.
Q_DECL_DEPRECATED void setFillColor(const QColor &color)
Sets the color used for fills in the scalebar.
QgsLineSymbol * divisionLineSymbol() const
Returns the line symbol used to render the scalebar divisions (only used for some scalebar types).
QgsFillSymbol * alternateFillSymbol() const
Returns the secondary fill symbol used to render the scalebar (only used for some scalebar types).
Q_DECL_DEPRECATED QBrush brush2() const
Returns the secondary brush for the scalebar.
double height() const
Returns the scalebar height (in millimeters).
void setMinimumBarWidth(double minWidth)
Sets the minimum width (in millimeters) for scale bar segments.
QgsFillSymbol * fillSymbol() const
Returns the primary fill symbol used to render the scalebar (only used for some scalebar types).
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
Q_DECL_DEPRECATED QColor fontColor() const
Returns the color used for drawing text in the scalebar.
void setMaximumBarWidth(double maxWidth)
Sets the maximum width (in millimeters) for scale bar segments.
Q_DECL_DEPRECATED QColor fillColor() const
Returns the color used for fills in the scalebar.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for numbers in the scalebar.
Q_DECL_DEPRECATED void setLineColor(const QColor &color)
Sets the color used for lines in the scalebar.
void setDivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar divisions (only used for some scalebar types).
Q_DECL_DEPRECATED QColor lineColor() const
Returns the color used for lines in the scalebar.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void update()
Adjusts the scale bar box size and updates the item.
void setFillSymbol(QgsFillSymbol *symbol)
Sets the primary fill symbol used to render the scalebar (only used for some scalebar types).
double unitsPerSegment() const
Returns the number of scalebar units per segment.
void setAlignment(Qgis::ScaleBarAlignment alignment)
Sets the scalebar alignment.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
bool applyDefaultRendererSettings(QgsScaleBarRenderer *renderer)
Applies any default settings relating to the specified renderer to the item.
double minimumBarWidth() const
Returns the minimum width (in millimeters) for scale bar segments.
QgsLineSymbol * subdivisionLineSymbol() const
Returns the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
Q_DECL_DEPRECATED QFont font() const
Returns the font used for drawing text in the scalebar.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setAlternateFillSymbol(QgsFillSymbol *symbol)
Sets the secondary fill symbol used to render the scalebar (only used for some scalebar types).
int type() const override
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar (only used for some scalebar types).
void setStyle(const QString &name)
Sets the scale bar style by name.
Q_DECL_DEPRECATED void setFillColor2(const QColor &color)
Sets the secondary color used for fills in the scalebar.
void applyDefaultSettings()
Applies the default scalebar settings to the scale bar.
void setLabelVerticalPlacement(Qgis::ScaleBarDistanceLabelVerticalPlacement placement)
Sets the vertical placement of text labels.
void setLabelHorizontalPlacement(Qgis::ScaleBarDistanceLabelHorizontalPlacement placement)
Sets the horizontal placement of text labels.
void setUnitLabelPlacements(Qgis::ScaleBarUnitLabelPlacements placements)
Sets the placements for unit labels.
void setHeight(double height)
Sets the scalebar height (in millimeters).
Q_DECL_DEPRECATED Qt::PenCapStyle lineCapStyle() const
Returns the cap style used for drawing lines in the scalebar.
void setSubdivisionsHeight(double height)
Sets the scalebar subdivisions height (in millimeters) for segments included in the right part of the...
void setNumberOfSegmentsLeft(int segments)
Sets the number of segments included in the left part of the scalebar.
Qgis::DistanceUnit units() const
Returns the distance units used by the scalebar.
void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties) override
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
Q_DECL_DEPRECATED Qt::PenJoinStyle lineJoinStyle() const
Returns the join style used for drawing lines in the scalebar.
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for drawing text in the scalebar.
void setUnits(Qgis::DistanceUnit units)
Sets the distance units used by the scalebar.
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map item linked to the scalebar.
QgsLayoutSize minimumSize() const override
Returns the minimum allowed size of the item, if applicable, or an empty size if item can be freely r...
Q_DECL_DEPRECATED void setLineJoinStyle(Qt::PenJoinStyle style)
Sets the join style used when drawing the lines in the scalebar.
void setSegmentSizeMode(Qgis::ScaleBarSegmentSizeMode mode)
Sets the size mode for scale bar segments.
QgsLineSymbol * lineSymbol() const
Returns the line symbol used to render the scalebar (only used for some scalebar types).
double maximumBarWidth() const
Returns the maximum width (in millimeters) for scale bar segments.
Q_DECL_DEPRECATED void setFontColor(const QColor &color)
Sets the color used for drawing text in the scalebar.
Q_DECL_DEPRECATED void setLineWidth(double width)
Sets the line width in millimeters for lines in the scalebar.
Q_DECL_DEPRECATED QPen pen() const
Returns the pen used for drawing outlines in the scalebar.
void setBoxContentSpace(double space)
Sets the space (margin) between the scalebar box and content in millimeters.
const QgsNumericFormat * numericFormat() const
Returns the numeric format used for numbers in the scalebar.
void setUnitLabel(const QString &label)
Sets the label for units.
QString style() const
Returns the scale bar style name.
ExportLayerBehavior exportLayerBehavior() const override
Returns the behavior of this item during exporting to layered exports (e.g.
QgsTextFormat textFormat() const
Returns the text format used for drawing text in the scalebar.
Q_DECL_DEPRECATED void setLineCapStyle(Qt::PenCapStyle style)
Sets the cap style used when drawing the lines in the scalebar.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
void resizeToMinimumWidth()
Resizes the scale bar to its minimum width, without changing the height.
void setUnitsPerSegment(double units)
Sets the number of scalebar units per segment.
static QgsLayoutItemScaleBar * create(QgsLayout *layout)
Returns a new scale bar item for the specified layout.
void setMethod(Qgis::ScaleCalculationMethod method)
Sets the scale calculation method, which determines how the bar's scale will be calculated.
Q_DECL_DEPRECATED void setFont(const QFont &font)
Sets the font used for drawing text in the scalebar.
Qgis::DistanceUnit guessUnits() const
Attempts to guess the most reasonable unit choice for the scalebar, given the current linked map's sc...
void setSubdivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
void applyDefaultSize(Qgis::DistanceUnit units=Qgis::DistanceUnit::Meters)
Applies the default size to the scale bar (scale bar 1/5 of map item width).
Qgis::ScaleCalculationMethod method() const
Returns the scale calculation method, which determines how the bar's scale will be calculated.
void setNumberOfSubdivisions(int subdivisions)
Sets the number of subdivisions for segments included in the right part of the scalebar (only used fo...
QgsLayoutItemScaleBar(QgsLayout *layout)
Constructor for QgsLayoutItemScaleBar, with the specified parent layout.
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::DataDefinedProperty::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
QgsLayoutItem(QgsLayout *layout, bool manageZValue=true)
Constructor for QgsLayoutItem, with the specified parent layout.
friend class QgsLayoutItemMap
void refreshItemSize()
Refreshes an item's size by rechecking it against any possible item fixed or minimum sizes.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual QString displayName() const
Gets item display name.
virtual void attemptResize(const QgsLayoutSize &size, bool includesFrame=false)
Attempts to resize the item to a specified target size.
virtual QString uuid() const
Returns the item identification string.
ExportLayerBehavior
Behavior of item when exporting to layered outputs.
@ CanGroupWithItemsOfSameType
Item can only be placed on layers with other items of the same type, but multiple items of this type ...
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the object's property collection, used for data defined overrides.
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
QPointer< QgsLayout > mLayout
DataDefinedProperty
Data defined properties for different item types.
@ ScalebarMinimumWidth
Scalebar segment minimum width.
@ ScalebarRightSegments
Number of segments on the right of 0.
@ ScalebarLineColor
Scalebar line color (deprecated, use data defined properties on scalebar line symbol instead).
@ ScalebarRightSegmentSubdivisions
Number of subdivisions per segment on right of 0.
@ ScalebarMaximumWidth
Scalebar segment maximum width.
@ ScalebarHeight
Scalebar height.
@ ScalebarFillColor2
Scalebar secondary fill color (deprecated, use data defined properties on scalebar fill symbol 2 inst...
@ ScalebarSubdivisionHeight
Scalebar subdivision height.
@ ScalebarFillColor
Scalebar fill color (deprecated, use data defined properties on scalebar fill symbol 1 instead).
@ ScalebarLineWidth
Scalebar line width (deprecated, use data defined properties on scalebar line symbol instead).
@ ScalebarLeftSegments
Number of segments on the left of 0.
@ ScalebarSegmentWidth
Scalebar width in map units of a single segment.
@ AllProperties
All properties for item.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
static QgsLayoutSize decodeSize(const QString &string)
Decodes a size from a string.
void setWidth(const double width)
Sets the width for the size.
Qgis::LayoutUnit units() const
Returns the units for the size.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
static double calculatePrettySize(double minimumSize, double maximumSize)
Calculates a "pretty" size which falls between the range [minimumSize, maximumSize].
static const QgsSettingsEntryString * settingsLayoutDefaultFont
Settings entry for the default font family used for new layout items.
A line symbol type, for rendering LineString and MultiLineString geometries.
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(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
A store for object properties.
A container for the context for various read/write operations on objects.
Contains information about the context of a rendering operation.
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).
QPainter * painter()
Returns the destination QPainter for the render operation.
Abstract base class for scale bar renderers.
virtual bool applyDefaultSettings(QgsScaleBarSettings &settings) const
Applies any default settings relating to the scalebar to the passed settings object.
double unitsPerSegment() const
Returns the number of scalebar units per segment.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A text format entity for QgsStyle databases.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QString encodePenCapStyle(Qt::PenCapStyle style)
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
@ StrokeColor
Stroke color.
@ StrokeWidth
Stroke width.
Container for all settings relating to text rendering.
void setSize(double size)
Sets the size for rendered 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.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
static Q_INVOKABLE QString toAbbreviatedString(Qgis::DistanceUnit unit)
Returns a translated abbreviation representing a distance unit.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE Qgis::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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.
QString qgsFlagValueToKeys(const T &value, bool *returnOk=nullptr)
Returns the value for the given keys of a flag.
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given keys of a flag.
#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).
#define QgsDebugError(str)
Contains parameters regarding scalebar calculations.
QSizeF size
Destination size for scalebar.
double scale
Scale denominator.
bool isValid() const
Returns true if the context has valid settings.
QgsScaleBarRenderer::Flags flags
Scalebar renderer flags.
double segmentWidth
The width, in millimeters, of each individual segment drawn.
Contains information relating to the style entity currently being visited.