28 mStrokeWidth = strokeWidth;
38 mStrokeColoring = strokeColoring;
43 return mStrokeColoring;
48 mStrokeWidthUnit = strokeWidthUnit;
53 return mStrokeWidthUnit;
58 QPainter *painter = context.
painter();
62 QPointF dir = p2 - p1;
63 double length = sqrt( pow( dir.x(), 2 ) + pow( dir.y(), 2 ) );
64 QPointF diru = dir / length;
65 QPointF orthu = QPointF( -diru.y(), diru.x() );
67 QList<double> breakValues;
68 QList<QColor> breakColors;
69 QList<QLinearGradient> gradients;
71 mStrokeColoring.
graduatedColors( valueColor1, valueColor2, breakValues, breakColors, gradients );
74 if ( gradients.isEmpty() && !breakValues.empty() && !breakColors.isEmpty() )
76 Q_ASSERT( breakColors.count() == breakValues.count() );
77 for (
int i = 0; i < breakValues.count(); ++i )
79 const bool widthIsInverted { valueWidth1 > valueWidth2 };
80 const double value = breakValues.at( i );
82 QPen pen( mSelected ? selectedColor : breakColors.at( i ) );
83 pen.setWidthF( width );
84 pen.setCapStyle( Qt::PenCapStyle::RoundCap );
85 painter->setPen( pen );
86 const QPointF point = p1 + dir * ( value - valueColor1 ) / ( valueColor2 - valueColor1 );
87 painter->drawPoint( point );
92 double width1 = mStrokeWidth.
strokeWidth( valueWidth1 );
93 double width2 = mStrokeWidth.
strokeWidth( valueWidth2 );
95 if ( !std::isnan( width1 ) && !std::isnan( width2 ) )
98 QBrush brush( Qt::SolidPattern );
101 startAngle = ( acos( -orthu.x() ) / M_PI ) * 180;
103 startAngle = 360 - startAngle;
105 bool outOfRange1 = std::isnan( width1 );
106 bool outOfRange2 = std::isnan( width2 );
111 QRectF capBox1( p1.x() - width1 / 2, p1.y() - width1 / 2, width1, width1 );
112 brush.setColor( mSelected ? selectedColor : mStrokeColoring.
color( valueColor1 ) );
113 painter->setBrush( brush );
114 pen.setBrush( brush );
115 painter->setPen( pen );
116 painter->drawPie( capBox1, ( startAngle - 1 ) * 16, 182 * 16 );
122 QRectF capBox2( p2.x() - width2 / 2, p2.y() - width2 / 2, width2, width2 );
123 brush.setColor( mSelected ? selectedColor : mStrokeColoring.
color( valueColor2 ) );
124 pen.setBrush( brush );
125 painter->setBrush( brush );
126 painter->setPen( pen );
127 painter->drawPie( capBox2, ( startAngle + 179 ) * 16, 182 * 16 );
130 if ( ( gradients.isEmpty() && breakValues.empty() && breakColors.count() == 1 ) || mSelected )
132 double startAdjusting = 0;
134 adjustLine( valueColor1, valueColor1, valueColor2, width1, startAdjusting );
137 double endAdjusting = 0;
139 adjustLine( valueColor2, valueColor1, valueColor2, width2, endAdjusting );
141 QPointF pointStartAdjusted = p1 + dir * startAdjusting;
142 QPointF pointEndAdjusted = p2 - dir * endAdjusting;
145 double semiWidth1 = width1 / 2;
146 double semiWidth2 = width2 / 2;
148 varLine.append( pointStartAdjusted + orthu * semiWidth1 );
149 varLine.append( pointEndAdjusted + orthu * semiWidth2 );
150 varLine.append( pointEndAdjusted - orthu * semiWidth2 );
151 varLine.append( pointStartAdjusted - orthu * semiWidth1 );
153 QBrush brush( Qt::SolidPattern );
154 brush.setColor( mSelected ? selectedColor : breakColors.first() );
155 painter->setBrush( brush );
156 painter->setPen( pen );
159 pen.setBrush( brush );
161 painter->setPen( pen );
163 painter->drawPolygon( varLine );
166 else if ( !gradients.isEmpty() && !breakValues.isEmpty() && !breakColors.isEmpty() )
168 Q_ASSERT( breakColors.count() == breakValues.count() );
169 Q_ASSERT( breakColors.count() == gradients.count() + 1 );
170 double widthColorVariationValueRatio = ( valueWidth2 - valueWidth1 ) / ( valueColor2 - valueColor1 );
172 for (
int i = 0; i < gradients.count(); ++i )
174 double firstValue = breakValues.at( i );
175 double secondValue = breakValues.at( i + 1 );
176 double w1 = mStrokeWidth.
strokeWidth( widthColorVariationValueRatio * ( firstValue - valueColor1 ) + valueWidth1 );
177 double w2 = mStrokeWidth.
strokeWidth( widthColorVariationValueRatio * ( secondValue - valueColor1 ) + valueWidth1 );
179 if ( std::isnan( w1 ) && std::isnan( w2 ) )
182 double firstAdjusting = 0;
183 if ( std::isnan( w1 ) )
184 adjustLine( firstValue, valueColor1, valueColor2, w1, firstAdjusting );
187 double secondAdjusting = 0;
188 if ( std::isnan( w2 ) )
189 adjustLine( secondValue, valueColor1, valueColor2, w2, secondAdjusting );
194 QPointF pointStart = p1 + dir * ( firstValue - valueColor1 ) / ( valueColor2 - valueColor1 );
195 QPointF pointEnd = p1 + dir * ( secondValue - valueColor1 ) / ( valueColor2 - valueColor1 );
197 QPointF pointStartAdjusted = pointStart + dir * firstAdjusting;
198 QPointF pointEndAdjusted = pointEnd - dir * secondAdjusting;
204 varLine.append( pointStartAdjusted + orthu * sw1 );
205 varLine.append( pointEndAdjusted + orthu * sw2 );
206 varLine.append( pointEndAdjusted - orthu * sw2 );
207 varLine.append( pointStartAdjusted - orthu * sw1 );
209 QLinearGradient gradient = gradients.at( i );
210 gradient.setStart( pointStart );
211 gradient.setFinalStop( pointEnd );
212 QBrush brush( gradient );
213 painter->setBrush( brush );
216 pen.setBrush( brush );
218 painter->setPen( pen );
220 painter->drawPolygon( varLine );
235 if ( value1 > value2 )
237 std::swap( value1, value2 );
238 std::swap( point1, point2 );
254 if ( valueColor1 > valueColor2 )
256 std::swap( valueColor1, valueColor2 );
257 std::swap( valueWidth1, valueWidth2 );
258 std::swap( point1, point2 );
269 mSelected = selected;
272void QgsInterpolatedLineRenderer::adjustLine(
const double value,
const double value1,
const double value2,
double &width,
double &adjusting )
const
276 adjusting = fabs( ( value - mStrokeWidth.
maximumValue() ) / ( value2 - value1 ) );
281 adjusting = fabs( ( value - mStrokeWidth.
minimumValue() ) / ( value2 - value1 ) );
288 return mMinimumValue;
294 mNeedUpdateFormula =
true;
299 return mMaximumValue;
305 mNeedUpdateFormula =
true;
310 return mMinimumWidth;
316 mNeedUpdateFormula =
true;
321 return mMaximumWidth;
327 mNeedUpdateFormula =
true;
332 if ( mIsWidthVariable )
334 if ( mNeedUpdateFormula )
335 updateLinearFormula();
337 if ( mUseAbsoluteValue )
338 value = std::fabs( value );
340 if ( value > mMaximumValue )
342 if ( mIgnoreOutOfRange )
343 return std::numeric_limits<double>::quiet_NaN();
345 return mMaximumWidth;
348 if ( value < mMinimumValue )
350 if ( mIgnoreOutOfRange )
351 return std::numeric_limits<double>::quiet_NaN();
353 return mMinimumWidth;
356 return ( value - mMinimumValue ) * mLinearCoef + mMinimumWidth;
364 QDomElement elem = doc.createElement( QStringLiteral(
"mesh-stroke-width" ) );
366 elem.setAttribute( QStringLiteral(
"width-varying" ), mIsWidthVariable ? 1 : 0 );
367 elem.setAttribute( QStringLiteral(
"fixed-width" ), mFixedWidth );
368 elem.setAttribute( QStringLiteral(
"minimum-value" ), mMinimumValue );
369 elem.setAttribute( QStringLiteral(
"maximum-value" ), mMaximumValue );
370 elem.setAttribute( QStringLiteral(
"minimum-width" ), mMinimumWidth );
371 elem.setAttribute( QStringLiteral(
"maximum-width" ), mMaximumWidth );
372 elem.setAttribute( QStringLiteral(
"ignore-out-of-range" ), mIgnoreOutOfRange ? 1 : 0 );
373 elem.setAttribute( QStringLiteral(
"use-absolute-value" ), mUseAbsoluteValue ? 1 : 0 );
380 mIsWidthVariable = elem.attribute( QStringLiteral(
"width-varying" ) ).toInt();
381 mFixedWidth = elem.attribute( QStringLiteral(
"fixed-width" ) ).toDouble();
382 mMinimumValue = elem.attribute( QStringLiteral(
"minimum-value" ) ).toDouble();
383 mMaximumValue = elem.attribute( QStringLiteral(
"maximum-value" ) ).toDouble();
384 mMinimumWidth = elem.attribute( QStringLiteral(
"minimum-width" ) ).toDouble();
385 mMaximumWidth = elem.attribute( QStringLiteral(
"maximum-width" ) ).toDouble();
386 mIgnoreOutOfRange = elem.attribute( QStringLiteral(
"ignore-out-of-range" ) ).toInt();
387 mUseAbsoluteValue = elem.attribute( QStringLiteral(
"use-absolute-value" ) ).toInt();
392 return mUseAbsoluteValue;
407 return mIgnoreOutOfRange;
417 return mIsWidthVariable;
422 mIsWidthVariable = isWidthVarying;
427 mFixedWidth = fixedWidth;
430void QgsInterpolatedLineWidth::updateLinearFormula()
const
433 mLinearCoef = ( mMaximumWidth - mMinimumWidth ) / ( mMaximumValue - mMinimumValue ) ;
436 mNeedUpdateFormula =
false;
441 mColorRampShader.
setMinimumValue( std::numeric_limits<double>::quiet_NaN() );
442 mColorRampShader.
setMaximumValue( std::numeric_limits<double>::quiet_NaN() );
454 mColorRampShader.
setMinimumValue( std::numeric_limits<double>::quiet_NaN() );
455 mColorRampShader.
setMaximumValue( std::numeric_limits<double>::quiet_NaN() );
469 mSingleColor =
color;
475 if ( mColoringMethod ==
ColorRamp && lSourceColorRamp )
477 if ( mColorRampShader.
isEmpty() )
478 return lSourceColorRamp->
color( 0 );
481 if ( mColorRampShader.
shade( magnitude, &r, &g, &b, &a ) )
482 return QColor( r, g, b, a );
484 return QColor( 0, 0, 0, 0 );
494 return mColoringMethod;
499 return mColorRampShader;
509 QDomElement elem = doc.createElement( QStringLiteral(
"mesh-stroke-color" ) );
512 elem.setAttribute( QStringLiteral(
"coloring-method" ), mColoringMethod );
513 elem.appendChild( mColorRampShader.
writeXml( doc ) );
520 QDomElement shaderElem = elem.firstChildElement( QStringLiteral(
"colorrampshader" ) );
521 mColorRampShader.
readXml( shaderElem );
525 elem.attribute( QStringLiteral(
"coloring-method" ) ).toInt() );
535 breakColors.append( mSingleColor );
542 graduatedColorsInterpolated( value1, value2, breakValues, breakColors, gradients );
545 graduatedColorsDiscrete( value1, value2, breakValues, breakColors, gradients );
548 graduatedColorsExact( value1, value2, breakValues, breakColors, gradients );
559QLinearGradient QgsInterpolatedLineColor::makeSimpleLinearGradient(
const QColor &color1,
const QColor &color2 )
const
561 QLinearGradient gradient;
562 gradient.setColorAt( 0, color1 );
563 gradient.setColorAt( 1, color2 );
568int QgsInterpolatedLineColor::itemColorIndexInf(
double value )
const
570 QList<QgsColorRampShader::ColorRampItem> itemList = mColorRampShader.
colorRampItemList();
572 if ( itemList.isEmpty() || itemList.first().value > value )
576 itemList.removeLast();
578 if ( value > itemList.last().value )
579 return itemList.count() - 1;
581 int indSup = itemList.count() - 1;
586 if ( abs( indSup - indInf ) <= 1 )
589 int newInd = ( indInf + indSup ) / 2;
591 if ( std::isnan( itemList.at( newInd ).value ) )
594 if ( itemList.at( newInd ).value <= value )
601void QgsInterpolatedLineColor::graduatedColorsExact(
double value1,
double value2, QList<double> &breakValues, QList<QColor> &breakColors,
const QList<QLinearGradient> &gradients )
const
604 Q_ASSERT( breakValues.isEmpty() );
605 Q_ASSERT( breakColors.isEmpty() );
606 Q_ASSERT( gradients.isEmpty() );
608 const QList<QgsColorRampShader::ColorRampItem> &itemList = mColorRampShader.
colorRampItemList();
609 if ( itemList.isEmpty() )
612 int index = itemColorIndexInf( value1 );
613 if ( index < 0 || !
qgsDoubleNear( value1, itemList.at( index ).value ) )
619 breakColors.append( itemList.at( index ).color );
623 while ( index < itemList.count() && itemList.at( index ).value <= value2 )
625 breakValues.append( itemList.at( index ).value );
626 breakColors.append( itemList.at( index ).color );
631void QgsInterpolatedLineColor::graduatedColorsInterpolated(
double value1,
double value2, QList<double> &breakValues, QList<QColor> &breakColors, QList<QLinearGradient> &gradients )
const
634 Q_ASSERT( breakValues.isEmpty() );
635 Q_ASSERT( breakColors.isEmpty() );
636 Q_ASSERT( gradients.isEmpty() );
639 const QList<QgsColorRampShader::ColorRampItem> &itemList = mColorRampShader.
colorRampItemList();
640 if ( itemList.empty() )
643 if ( itemList.count() == 1 )
645 breakColors.append( itemList.first().color );
649 if ( value2 <= itemList.first().value )
651 if ( !mColorRampShader.
clip() )
652 breakColors.append( itemList.first().color );
656 if ( value1 > itemList.last().value )
658 if ( !mColorRampShader.
clip() )
659 breakColors.append( itemList.last().color );
669 if ( mColorRampShader.
shade( value1, &r, &g, &b, &a ) )
670 color = QColor( r, g, b, a );
671 breakColors.append(
color );
676 int index = itemColorIndexInf( value1 );
679 QColor
color = itemList.first().color;
680 breakColors.append(
color );
681 if ( mColorRampShader.
clip() )
682 breakValues.append( itemList.first().value );
684 breakValues.append( value1 );
691 if ( mColorRampShader.
shade( value1, &r, &g, &b, &a ) )
692 color = QColor( r, g, b, a );
693 breakValues.append( value1 );
694 breakColors.append(
color );
699 while ( index < itemList.count() && itemList.at( index ).value < value2 )
701 QColor color1 = breakColors.last();
702 QColor color2 = itemList.at( index ).color;
703 breakValues.append( itemList.at( index ).value );
704 breakColors.append( color2 );
705 gradients.append( makeSimpleLinearGradient( color1, color2 ) );
710 QColor color1 = breakColors.last();
712 if ( value2 < itemList.last().value )
715 if ( mColorRampShader.
shade( value2, &r, &g, &b, &a ) )
716 color2 = QColor( r, g, b, a );
717 breakValues.append( value2 );
721 color2 = itemList.last().color;
722 if ( mColorRampShader.
clip() )
723 breakValues.append( itemList.last().value );
725 breakValues.append( value2 );
727 breakColors.append( color2 );
728 gradients.append( makeSimpleLinearGradient( color1, color2 ) );
732void QgsInterpolatedLineColor::graduatedColorsDiscrete(
double value1,
double value2, QList<double> &breakValues, QList<QColor> &breakColors, QList<QLinearGradient> &gradients )
const
735 Q_ASSERT( breakValues.isEmpty() );
736 Q_ASSERT( breakColors.isEmpty() );
737 Q_ASSERT( gradients.isEmpty() );
739 const QList<QgsColorRampShader::ColorRampItem> &itemList = mColorRampShader.
colorRampItemList();
740 if ( itemList.empty() )
743 if ( itemList.count() == 1 )
745 breakColors.append( itemList.first().color );
749 double lastValue = itemList.at( itemList.count() - 2 ).value;
752 if ( value2 <= itemList.first().value )
754 breakColors.append( itemList.first().color );
758 if ( value1 > lastValue )
760 breakColors.append( itemList.last().color );
765 int index = itemColorIndexInf( value1 );
771 breakColors.append( itemList.at( index + 1 ).color );
777 breakValues.append( value1 );
778 breakColors.append( itemList.first().color );
782 QColor
color = itemList.at( index ).color;
783 breakValues.append( value1 );
784 breakColors.append(
color );
789 while ( index < ( itemList.count() - 1 ) && itemList.at( index ).value < value2 )
791 QColor
color = itemList.at( index ).color;
792 breakValues.append( itemList.at( index ).value );
793 breakColors.append(
color );
794 gradients.append( makeSimpleLinearGradient(
color,
color ) );
799 QColor lastColor = itemList.at( index ).color;
800 breakColors.append( lastColor );
801 breakValues.append( value2 );
802 gradients.append( makeSimpleLinearGradient( lastColor, lastColor ) );
826 std::unique_ptr<QgsInterpolatedLineSymbolLayer> symbolLayer;
829 if (
properties.contains( QStringLiteral(
"start_width_expression" ) ) )
831 if (
properties.contains( QStringLiteral(
"end_width_expression" ) ) )
834 if (
properties.contains( QStringLiteral(
"start_color_expression" ) ) )
836 if (
properties.contains( QStringLiteral(
"end_color_expression" ) ) )
839 if (
properties.contains( QStringLiteral(
"line_width" ) ) )
840 symbolLayer->mLineRender.mStrokeWidth.setFixedStrokeWidth(
properties.value( QStringLiteral(
"line_width" ) ).toDouble() ) ;
841 if (
properties.contains( QStringLiteral(
"line_width_unit" ) ) )
843 if (
properties.contains( QStringLiteral(
"width_varying_minimum_value" ) ) )
844 symbolLayer->mLineRender.mStrokeWidth.setMinimumValue(
properties.value( QStringLiteral(
"width_varying_minimum_value" ) ).toDouble() );
845 if (
properties.contains( QStringLiteral(
"width_varying_maximum_value" ) ) )
846 symbolLayer->mLineRender.mStrokeWidth.setMaximumValue(
properties.value( QStringLiteral(
"width_varying_maximum_value" ) ).toDouble() );
847 if (
properties.contains( QStringLiteral(
"width_varying_use_absolute_value" ) ) )
848 symbolLayer->mLineRender.mStrokeWidth.setUseAbsoluteValue(
properties.value( QStringLiteral(
"width_varying_use_absolute_value" ) ).toInt() );
849 if (
properties.contains( QStringLiteral(
"width_varying_minimum_width" ) ) )
850 symbolLayer->mLineRender.mStrokeWidth.setMinimumWidth(
properties.value( QStringLiteral(
"width_varying_minimum_width" ) ).toDouble() );
851 if (
properties.contains( QStringLiteral(
"width_varying_maximum_width" ) ) )
852 symbolLayer->mLineRender.mStrokeWidth.setMaximumWidth(
properties.value( QStringLiteral(
"width_varying_maximum_width" ) ).toDouble() );
853 if (
properties.contains( QStringLiteral(
"width_varying_ignore_out_of_range" ) ) )
854 symbolLayer->mLineRender.mStrokeWidth.setIgnoreOutOfRange(
properties.value( QStringLiteral(
"width_varying_ignore_out_of_range" ) ).toInt() );
855 if (
properties.contains( QStringLiteral(
"width_varying_is_variable_width" ) ) )
856 symbolLayer->mLineRender.mStrokeWidth.setIsVariableWidth(
properties.value( QStringLiteral(
"width_varying_is_variable_width" ) ).toInt() );
858 if (
properties.contains( QStringLiteral(
"single_color" ) ) )
860 if (
properties.contains( QStringLiteral(
"color_ramp_shader" ) ) )
861 symbolLayer->mLineRender.mStrokeColoring.setColor( createColorRampShaderFromProperties(
properties.value( QStringLiteral(
"color_ramp_shader" ) ) ) );
862 if (
properties.contains( QStringLiteral(
"coloring_method" ) ) )
863 symbolLayer->mLineRender.mStrokeColoring.setColoringMethod(
866 return symbolLayer.release();
879 props.insert( QStringLiteral(
"line_width" ), QString::number( mLineRender.mStrokeWidth.
fixedStrokeWidth() ) );
881 props.insert( QStringLiteral(
"width_varying_minimum_value" ), mLineRender.mStrokeWidth.
minimumValue() );
882 props.insert( QStringLiteral(
"width_varying_maximum_value" ), mLineRender.mStrokeWidth.
maximumValue() );
883 props.insert( QStringLiteral(
"width_varying_use_absolute_value" ), mLineRender.mStrokeWidth.
useAbsoluteValue() ? 1 : 0 );
884 props.insert( QStringLiteral(
"width_varying_minimum_width" ), mLineRender.mStrokeWidth.
minimumWidth() );
885 props.insert( QStringLiteral(
"width_varying_maximum_width" ), mLineRender.mStrokeWidth.
maximumWidth() );
886 props.insert( QStringLiteral(
"width_varying_ignore_out_of_range" ), mLineRender.mStrokeWidth.
ignoreOutOfRange() ? 1 : 0 );
887 props.insert( QStringLiteral(
"width_varying_is_variable_width" ), mLineRender.mStrokeWidth.
isVariableWidth() ? 1 : 0 );
890 props.insert( QStringLiteral(
"coloring_method" ), mLineRender.mStrokeColoring.
coloringMethod() );
892 props.insert( QStringLiteral(
"color_ramp_shader" ), colorRampShaderProperties() );
906 double totalLength = geometry.
length();
910 double variation = ( max - min ) / totalLength;
913 double lengthFromStart = 0;
914 for (
int i = 1; i < points.count(); ++i )
916 QPointF p1 = points.at( i - 1 );
917 QPointF p2 = points.at( i );
919 double v1 = min + variation * lengthFromStart;
920 QPointF vectDist = p2 - p1;
921 lengthFromStart += sqrt( pow( vectDist.x(), 2 ) + pow( vectDist.y(), 2 ) );
922 double v2 = min + variation * lengthFromStart;
945 if ( start.isEmpty() )
968 mLineRender.mStrokeWidthUnit = strokeWidthUnit;
975 mLineRender.mStrokeWidth = interpolatedLineWidth;
982 if ( start.isEmpty() )
1013QVariant QgsInterpolatedLineSymbolLayer::colorRampShaderProperties()
const
1020 props.insert( QStringLiteral(
"color_ramp_shader_type" ), colorRampShader.
colorRampType() );
1021 props.insert( QStringLiteral(
"color_ramp_shader_classification_mode" ), colorRampShader.
classificationMode() );
1022 QVariantList colorRampItemListVariant;
1024 const QList<QgsColorRampShader::ColorRampItem> colorRampItemList = colorRampShader.
colorRampItemList();
1027 QVariantMap itemVar;
1028 itemVar[QStringLiteral(
"label" )] = item.label;
1030 itemVar[QStringLiteral(
"value" )] = item.value;
1031 colorRampItemListVariant.append( itemVar );
1033 props.insert( QStringLiteral(
"color_ramp_shader_items_list" ), colorRampItemListVariant );
1035 props.insert( QStringLiteral(
"color_ramp_shader_minimum_value" ), colorRampShader.
minimumValue() );
1036 props.insert( QStringLiteral(
"color_ramp_shader_maximum_value" ), colorRampShader.
maximumValue() );
1037 props.insert( QStringLiteral(
"color_ramp_shader_value_out_of_range" ), colorRampShader.
clip() ? 1 : 0 );
1038 props.insert( QStringLiteral(
"color_ramp_shader_label_precision" ), colorRampShader.
labelPrecision() );
1043QgsColorRampShader QgsInterpolatedLineSymbolLayer::createColorRampShaderFromProperties(
const QVariant &properties )
1048 return colorRampShader;
1050 QVariantMap shaderVariantMap =
properties.toMap();
1052 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_source" ) ) )
1055 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_shader_type" ) ) )
1057 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_shader_classification_mode" ) ) )
1059 shaderVariantMap.value( QStringLiteral(
"color_ramp_shader_classification_mode" ) ).toInt() ) );
1061 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_shader_items_list" ) ) )
1063 QVariant colorRampItemsVar = shaderVariantMap.value( QStringLiteral(
"color_ramp_shader_items_list" ) );
1064 if ( colorRampItemsVar.type() == QVariant::List )
1066 QVariantList itemVariantList = colorRampItemsVar.toList();
1067 QList<QgsColorRampShader::ColorRampItem> colorRampItemList;
1068 for (
const QVariant &itemVar : std::as_const( itemVariantList ) )
1071 if ( itemVar.type() != QVariant::Map )
1073 QVariantMap itemVarMap = itemVar.toMap();
1074 if ( !itemVarMap.contains( QStringLiteral(
"label" ) ) || !itemVarMap.contains( QStringLiteral(
"color" ) ) || !itemVarMap.contains( QStringLiteral(
"value" ) ) )
1077 item.
label = itemVarMap.value( QStringLiteral(
"label" ) ).toString();
1079 item.
value = itemVarMap.value( QStringLiteral(
"value" ) ).toDouble();
1081 colorRampItemList.append( item );
1087 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_shader_minimum_value" ) ) )
1088 colorRampShader.
setMinimumValue( shaderVariantMap.value( QStringLiteral(
"color_ramp_shader_minimum_value" ) ).toDouble() );
1090 colorRampShader.
setMinimumValue( std::numeric_limits<double>::quiet_NaN() );
1092 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_shader_maximum_value" ) ) )
1093 colorRampShader.
setMaximumValue( shaderVariantMap.value( QStringLiteral(
"color_ramp_shader_maximum_value" ) ).toDouble() );
1095 colorRampShader.
setMaximumValue( std::numeric_limits<double>::quiet_NaN() );
1097 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_shader_value_out_of_range" ) ) )
1098 colorRampShader.
setClip( shaderVariantMap.value( QStringLiteral(
"color_ramp_shader_value_out_of_range" ) ).toInt() == 1 );
1099 if ( shaderVariantMap.contains( QStringLiteral(
"color_ramp_shader_label_precision" ) ) )
1100 colorRampShader.
setLabelPrecision( shaderVariantMap.value( QStringLiteral(
"color_ramp_shader_label_precision" ) ).toInt() );
1102 return colorRampShader;
1110 mRenderingFeature =
true;
1116 mRenderingFeature =
false;
1118 if ( mLineParts.empty() )
1121 render( mLineParts, context );
1125void QgsInterpolatedLineSymbolLayer::render(
const QVector< QPolygonF > &parts,
QgsRenderContext &context )
1127 const double totalLength = std::accumulate( parts.begin(), parts.end(), 0.0, [](
double total,
const QPolygonF & part )
1129 return total + QgsSymbolLayerUtils::polylineLength( part );
1135 double startValWidth = 0;
1136 double variationPerMapUnitWidth = 0;
1137 double startValColor = 0;
1138 double variationPerMapUnitColor = 0;
1151 double endValWidth = 0;
1159 variationPerMapUnitWidth = ( endValWidth - startValWidth ) / totalLength;
1171 double endValColor = 0;
1179 variationPerMapUnitColor = ( endValColor - startValColor ) / totalLength;
1182 for (
const QPolygonF &poly : parts )
1184 double lengthFromStart = 0;
1185 for (
int i = 1; i < poly.count(); ++i )
1187 const QPointF p1 = poly.at( i - 1 );
1188 const QPointF p2 = poly.at( i );
1190 const double v1c = startValColor + variationPerMapUnitColor * lengthFromStart;
1191 const double v1w = startValWidth + variationPerMapUnitWidth * lengthFromStart;
1193 const double v2c = startValColor + variationPerMapUnitColor * lengthFromStart;
1194 const double v2w = startValWidth + variationPerMapUnitWidth * lengthFromStart;
1204 if ( points.empty() )
1207 if ( mRenderingFeature )
1211 mLineParts.append( points );
@ DisableFeatureClipping
If present, indicates that features should never be clipped to the map extent during rendering.
RenderUnit
Rendering size units.
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.
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
ClassificationMode classificationMode() const
Returns the classification mode.
bool isEmpty() const
Whether the color ramp contains any items.
Type colorRampType() const
Returns the color ramp type.
void setSourceColorRamp(QgsColorRamp *colorramp)
Set the source color ramp.
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Returns the custom colormap.
ClassificationMode
Classification modes used to create the color ramp shader.
void setClip(bool clip)
Sets whether the shader should not render values out of range.
bool clip() const
Returns whether the shader will clip values which are out of range.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context=QgsReadWriteContext()) const
Writes configuration to a new DOM element.
bool shade(double value, int *returnRedValue, int *returnGreenValue, int *returnBlueValue, int *returnAlphaValue) const override
Generates and new RGB value based on one input value.
QgsColorRamp * sourceColorRamp() const
Returns the source color ramp.
Type
Supported methods for color interpolation.
@ Interpolated
Interpolates the color between two class breaks linearly.
@ Discrete
Assigns the color of the higher class for every pixel between two class breaks.
@ Exact
Assigns the color of the exact matching value in the color ramp item list.
void setClassificationMode(ClassificationMode classificationMode)
Sets classification mode.
void setColorRampItemList(const QList< QgsColorRampShader::ColorRampItem > &list)
Sets a custom colormap.
void setColorRampType(QgsColorRampShader::Type colorRampType)
Sets the color ramp type.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context=QgsReadWriteContext())
Reads configuration from the given DOM element.
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
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.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
static double distance2D(double x1, double y1, double x2, double y2)
Returns the 2D distance between (x1, y1) and (x2, y2).
A geometry is the spatial representation of a feature.
QPolygonF asQPolygonF() const
Returns contents of the geometry as a QPolygonF.
double length() const
Returns the planar, 2-dimensional length of geometry.
Class defining color to render mesh datasets.
QgsInterpolatedLineColor::ColoringMethod coloringMethod() const
Returns the coloring method used.
QgsColorRampShader colorRampShader() const
Returns the color ramp shader.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads configuration from the given DOM element.
QColor color(double magnitude) const
Returns the color corresponding to the magnitude.
void graduatedColors(double value1, double value2, QList< double > &breakValues, QList< QColor > &breakColors, QList< QLinearGradient > &gradients) const
Returns the break values, graduated colors and the associated gradients between two values.
QgsInterpolatedLineColor()
Default constructor.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Writes configuration to a new DOM element.
void setColor(const QgsColorRampShader &colorRampShader)
Sets the color ramp to define the coloring.
QColor singleColor() const
Returns the single color that is used if SingleColor coloring mode is set.
void setColoringMethod(ColoringMethod coloringMethod)
Sets the coloring method used.
ColoringMethod
Defines how the color is defined.
@ ColorRamp
Render with a color ramp.
@ SingleColor
Render with a single color.
void setInterpolatedColor(const QgsInterpolatedLineColor &strokeColoring)
Sets the stroke color used to render.
void renderInDeviceCoordinates(double valueColor1, double valueColor2, double valueWidth1, double valueWidth2, QPointF point1, QPointF point2, QgsRenderContext &context) const
Renders a line in the context between point1 and point2 in device (painter) coordinates with color th...
Qgis::RenderUnit widthUnit() const
Returns the unit of the stroke width.
void setInterpolatedWidth(const QgsInterpolatedLineWidth &strokeWidth)
Sets the stroke width used to render.
void setSelected(bool selected)
Sets if the rendering must be done as the element is selected.
void render(double value1, double value2, const QgsPointXY &point1, const QgsPointXY &point2, QgsRenderContext &context) const
Renders a line in the context between point1 and point2 with color and width that vary depending on v...
QgsInterpolatedLineWidth interpolatedLineWidth() const
Returns the stroke width used to render.
QgsInterpolatedLineColor interpolatedColor() const
Returns the stroke color used to render.
void setWidthUnit(Qgis::RenderUnit strokeWidthUnit)
Sets the unit of the stroke width.
A symbol layer that represents vector layer line feature as interpolated line The interpolation is do...
Q_DECL_DEPRECATED QString endValueExpressionForWidth() const
Returns the expression related to the end extremity value for width.
QColor color() const override
Returns the "representative" color of the symbol layer.
Q_DECL_DEPRECATED QString endValueExpressionForColor() const
Returns the expression related to the end extremity value for width for color.
Q_DECL_DEPRECATED void setExpressionsStringForColor(const QString &start, const QString &end)
Sets the expressions (as string) that define the extremety values af the line feature for color.
Qgis::RenderUnit widthUnit() const
Returns the width unit.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
QgsInterpolatedLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
void renderPolyline(const QPolygonF &points, QgsSymbolRenderContext &context) override
Renders the line symbol layer along the line joining points, using the given render context.
QgsInterpolatedLineColor interpolatedColor() const
Returns the interpolated color used to render the colors of lines, see QgsInterpolatedLineColor.
Q_DECL_DEPRECATED QString startValueExpressionForColor() const
Returns the epression related to the start extremity value for width for color.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsInterpolatedLineSymbolLayer()
Constructor.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QString layerType() const override
Returns a string that represents this layer type.
Q_DECL_DEPRECATED void setExpressionsStringForWidth(const QString &start, const QString &end)
Sets the expressions (as string) that define the extremety values af the line feature for width.
void setInterpolatedWidth(const QgsInterpolatedLineWidth &interpolatedLineWidth)
Sets the interpolated width used to render the width of lines, see QgsInterpolatedLineWidth.
void setInterpolatedColor(const QgsInterpolatedLineColor &interpolatedLineColor)
Sets the interpolated color used to render the colors of lines, see QgsInterpolatedLineColor.
Q_DECL_DEPRECATED QString startValueExpressionForWidth() const
Returns the epression related to the start extremity value for width.
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsInterpolatedLineWidth interpolatedWidth() const
Returns the interpolated width used to render the width of lines, see QgsInterpolatedLineWidth.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void setWidthUnit(Qgis::RenderUnit strokeWidthUnit)
Sets the width unit.
static QgsSymbolLayer * create(const QVariantMap &properties)
Creates the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Represents a width than can vary depending on values.
void setFixedStrokeWidth(double fixedWidth)
Sets the fixed width.
double strokeWidth(double value) const
Returns the variable width depending on value, if not varying returns the fixed width.
void setUseAbsoluteValue(bool useAbsoluteValue)
Sets whether absolute value are used as input.
double minimumValue() const
Returns the minimum value used to defined the variable width.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads configuration from the given DOM element.
void setIgnoreOutOfRange(bool ignoreOutOfRange)
Sets whether the variable width ignores out of range value.
void setMaximumValue(double maximumValue)
Sets the maximum value used to defined the variable width.
bool useAbsoluteValue() const
Returns whether absolute value are used as input.
void setIsVariableWidth(bool isVariableWidth)
Returns whether the width is variable.
void setMinimumValue(double minimumValue)
Sets the minimum value used to defined the variable width.
double maximumWidth() const
Returns the maximum width used to defined the variable width.
void setMaximumWidth(double maximumWidth)
Sets the maximum width used to defined the variable width.
double maximumValue() const
Returns the maximum value used to defined the variable width.
void setMinimumWidth(double minimumWidth)
Sets the minimum width used to defined the variable width.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Writes configuration to a new DOM element.
bool ignoreOutOfRange() const
Returns whether the variable width ignores out of range value.
double minimumWidth() const
Returns the minimum width used to defined the variable width.
double fixedStrokeWidth() const
Returns the fixed width.
bool isVariableWidth() const
Returns whether the width is variable.
QgsGeometry geometry() const
Returns the geometry for the patch shape.
Perform transforms between map coordinates and device coordinates.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
A class to represent a 2D point.
QPointF toQPointF() const
Converts a point to a QPointF.
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.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
A store for object properties.
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
double maximumValue() const
Returns the minimum value for the raster shader.
void setLabelPrecision(int labelPrecision)
Sets label precision to labelPrecision.
int labelPrecision() const
Returns label precision.
virtual void setMaximumValue(double value)
Sets the maximum value for the raster shader.
virtual void setMinimumValue(double value)
Sets the minimum value for the raster shader.
double minimumValue() const
Returns the maximum value for the raster shader.
The class is used as a container of context for various read/write operations on other 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.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QColor selectionColor() const
Returns the color to use when rendering selected features.
Scoped object for saving and restoring a QPainter object's state.
QgsLegendPatchShape defaultPatch(Qgis::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
static QVariant colorRampToVariant(const QString &name, QgsColorRamp *ramp)
Saves a color ramp to a QVariantMap, wrapped in a QVariant.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
@ LineEndColorValue
End line color for interpolated line renderer (since QGIS 3.22)
@ LineStartColorValue
Start line color for interpolated line renderer (since QGIS 3.22)
@ LineEndWidthValue
End line width for interpolated line renderer (since QGIS 3.22)
@ LineStartWidthValue
Start line width for interpolated line renderer (since QGIS 3.22)
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsPropertyCollection mDataDefinedProperties
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
const QgsLegendPatchShape * patchShape() const
Returns the symbol patch shape, to use if rendering symbol preview icons.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
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.
#define BUILTIN_UNREACHABLE
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)