@@ -804,10 +804,10 @@ QString QgsInterpolatedLineSymbolLayer::layerType() const {return QStringLiteral
804
804
void QgsInterpolatedLineSymbolLayer::startRender ( QgsSymbolRenderContext &context )
805
805
{
806
806
// find out attribute index from name
807
- mStartWidthAttributeIndex = mFields .lookupField ( mStartWidthExpressionString );
808
- mEndWidthAttributeIndex = mFields .lookupField ( mEndWidthExpressionString );
809
- mStartColorAttributeIndex = mFields .lookupField ( mStartColorExpressionString );
810
- mEndColorAttributeIndex = mFields .lookupField ( mEndColorExpressionString );
807
+ mStartWidthAttributeIndex = - 1 ; // mFields.lookupField( mStartWidthExpressionString );
808
+ mEndWidthAttributeIndex = - 1 ; // mFields.lookupField( mEndWidthExpressionString );
809
+ mStartColorAttributeIndex = - 1 ; // mFields.lookupField( mStartColorExpressionString );
810
+ mEndColorAttributeIndex = - 1 ; // mFields.lookupField( mEndColorExpressionString );
811
811
812
812
if ( mStartWidthAttributeIndex == -1 )
813
813
{
@@ -932,8 +932,6 @@ void QgsInterpolatedLineSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &co
932
932
{
933
933
QgsGeometry geometry = context.patchShape () ? context.patchShape ()->geometry ()
934
934
: QgsStyle::defaultStyle ()->defaultPatch ( Qgis::SymbolType::Line, size ).geometry ();
935
- QgsFeature feature;
936
- feature.setGeometry ( geometry );
937
935
938
936
startRender ( context );
939
937
mStartWidthAttributeIndex = -1 ;
@@ -1118,74 +1116,38 @@ QgsColorRampShader QgsInterpolatedLineSymbolLayer::createColorRampShaderFromProp
1118
1116
QgsInterpolatedLineSymbolLayer::QgsInterpolatedLineSymbolLayer (): QgsLineSymbolLayer( true ) {}
1119
1117
1120
1118
1121
- void QgsInterpolatedLineSymbolLayer::startFeatureRender ( const QgsFeature &feature , QgsRenderContext & )
1119
+ void QgsInterpolatedLineSymbolLayer::startFeatureRender ( const QgsFeature &, QgsRenderContext & )
1122
1120
{
1123
- mFeature = feature;
1121
+ mRenderingFeature = true ;
1122
+ mLineParts .clear ();
1124
1123
}
1125
1124
1126
- void QgsInterpolatedLineSymbolLayer::stopFeatureRender ( const QgsFeature &, QgsRenderContext & )
1125
+ void QgsInterpolatedLineSymbolLayer::stopFeatureRender ( const QgsFeature &, QgsRenderContext &context )
1127
1126
{
1128
- mFeature = QgsFeature ();
1127
+ mRenderingFeature = false ;
1128
+
1129
+ if ( mLineParts .empty () )
1130
+ return ;
1131
+
1132
+ render ( mLineParts , context );
1133
+ mLineParts .clear ();
1129
1134
}
1130
1135
1131
- void QgsInterpolatedLineSymbolLayer::renderPolyline ( const QPolygonF &points, QgsSymbolRenderContext &context )
1136
+ void QgsInterpolatedLineSymbolLayer::render ( const QVector< QPolygonF > &parts, QgsRenderContext &context )
1132
1137
{
1133
- Q_UNUSED ( points ); // this symbol layer need to used all the feature geometry, not clipped/simplified geometry
1138
+ const double totalLength = std::accumulate ( parts.begin (), parts.end (), 0.0 , []( double total, const QPolygonF & part )
1139
+ {
1140
+ return total + QgsSymbolLayerUtils::polylineLength ( part );
1141
+ } );
1134
1142
1135
- QVector<QgsPolylineXY> lineStrings;
1143
+ if ( qgsDoubleNear ( totalLength, 0 ) )
1144
+ return ;
1136
1145
1137
1146
double startValWidth = 0 ;
1138
- double endValWidth = 0 ;
1139
1147
double variationPerMapUnitWidth = 0 ;
1140
1148
double startValColor = 0 ;
1141
- double endValColor = 0 ;
1142
1149
double variationPerMapUnitColor = 0 ;
1143
1150
1144
- QgsRenderContext renderContext = context.renderContext ();
1145
-
1146
- QgsGeometry geom = mFeature .geometry ();
1147
-
1148
- mLineRender .setSelected ( context.selected () );
1149
-
1150
- if ( geom.isEmpty () )
1151
- return ;
1152
-
1153
- switch ( QgsWkbTypes::flatType ( geom.wkbType () ) )
1154
- {
1155
- case QgsWkbTypes::Unknown:
1156
- case QgsWkbTypes::Point:
1157
- case QgsWkbTypes::Polygon:
1158
- case QgsWkbTypes::Triangle:
1159
- case QgsWkbTypes::MultiPoint:
1160
- case QgsWkbTypes::MultiPolygon:
1161
- case QgsWkbTypes::GeometryCollection:
1162
- case QgsWkbTypes::CurvePolygon:
1163
- case QgsWkbTypes::MultiSurface:
1164
- case QgsWkbTypes::NoGeometry:
1165
- return ;
1166
- break ;
1167
- case QgsWkbTypes::LineString:
1168
- case QgsWkbTypes::CircularString:
1169
- case QgsWkbTypes::CompoundCurve:
1170
- lineStrings.append ( geom.asPolyline () );
1171
- break ;
1172
- case QgsWkbTypes::MultiCurve:
1173
- case QgsWkbTypes::MultiLineString:
1174
- lineStrings = geom.asMultiPolyline ();
1175
- break ;
1176
- default :
1177
- return ;
1178
- break ;
1179
- }
1180
-
1181
- QgsExpressionContext expressionContext = renderContext.expressionContext ();
1182
- expressionContext.setFeature ( mFeature );
1183
-
1184
- double totalLength = geom.length ();
1185
-
1186
- if ( totalLength == 0 )
1187
- return ;
1188
-
1189
1151
QVariant val1WidthVariant;
1190
1152
QVariant val2WidthVariant;
1191
1153
QVariant val1ColorVariant;
@@ -1196,19 +1158,19 @@ void QgsInterpolatedLineSymbolLayer::renderPolyline( const QPolygonF &points, Qg
1196
1158
{
1197
1159
if ( mStartWidthExpression )
1198
1160
{
1199
- val1WidthVariant = mStartWidthExpression ->evaluate ( &expressionContext );
1161
+ val1WidthVariant = mStartWidthExpression ->evaluate ( &context. expressionContext () );
1200
1162
ok |= mStartWidthExpression ->hasEvalError ();
1201
1163
}
1202
- else
1203
- val1WidthVariant = mFeature .attribute ( mStartWidthAttributeIndex );
1164
+ // else
1165
+ // val1WidthVariant = mFeature.attribute( mStartWidthAttributeIndex );
1204
1166
1205
1167
if ( mEndWithExpression )
1206
1168
{
1207
- val2WidthVariant = mEndWithExpression ->evaluate ( &expressionContext );
1169
+ val2WidthVariant = mEndWithExpression ->evaluate ( &context. expressionContext () );
1208
1170
ok |= mEndWithExpression ->hasEvalError ();
1209
1171
}
1210
- else
1211
- val2WidthVariant = mFeature .attribute ( mEndWidthAttributeIndex );
1172
+ // else
1173
+ // val2WidthVariant = mFeature.attribute( mEndWidthAttributeIndex );
1212
1174
1213
1175
if ( !ok )
1214
1176
return ;
@@ -1217,7 +1179,7 @@ void QgsInterpolatedLineSymbolLayer::renderPolyline( const QPolygonF &points, Qg
1217
1179
if ( !ok )
1218
1180
return ;
1219
1181
1220
- endValWidth = val2WidthVariant.toDouble ( &ok );
1182
+ const double endValWidth = val2WidthVariant.toDouble ( &ok );
1221
1183
if ( !ok )
1222
1184
return ;
1223
1185
@@ -1228,48 +1190,67 @@ void QgsInterpolatedLineSymbolLayer::renderPolyline( const QPolygonF &points, Qg
1228
1190
{
1229
1191
if ( mStartColorExpression )
1230
1192
{
1231
- val1ColorVariant = mStartColorExpression ->evaluate ( &expressionContext );
1193
+ val1ColorVariant = mStartColorExpression ->evaluate ( &context. expressionContext () );
1232
1194
ok |= mStartColorExpression ->hasEvalError ();
1233
1195
}
1234
- else
1235
- val1ColorVariant = mFeature .attribute ( mStartColorAttributeIndex );
1196
+ // else
1197
+ // val1ColorVariant = mFeature.attribute( mStartColorAttributeIndex );
1236
1198
1237
1199
if ( mEndColorExpression )
1238
1200
{
1239
- val2ColorVariant = mEndColorExpression ->evaluate ( &expressionContext );
1201
+ val2ColorVariant = mEndColorExpression ->evaluate ( &context. expressionContext () );
1240
1202
ok |= mEndColorExpression ->hasEvalError ();
1241
1203
}
1242
- else
1243
- val2ColorVariant = mFeature .attribute ( mEndColorAttributeIndex );
1204
+ // else
1205
+ // val2ColorVariant = mFeature.attribute( mEndColorAttributeIndex );
1244
1206
1245
1207
startValColor = val1ColorVariant.toDouble ( &ok );
1246
1208
if ( !ok )
1247
1209
return ;
1248
1210
1249
- endValColor = val2ColorVariant.toDouble ( &ok );
1211
+ const double endValColor = val2ColorVariant.toDouble ( &ok );
1250
1212
if ( !ok )
1251
1213
return ;
1252
1214
1253
1215
variationPerMapUnitColor = ( endValColor - startValColor ) / totalLength;
1254
1216
}
1255
1217
1256
- for ( const QgsPolylineXY &poly : std::as_const ( lineStrings ) )
1218
+ for ( const QPolygonF &poly : parts )
1257
1219
{
1258
1220
double lengthFromStart = 0 ;
1259
1221
for ( int i = 1 ; i < poly.count (); ++i )
1260
1222
{
1261
- QgsPointXY p1 = poly.at ( i - 1 );
1262
- QgsPointXY p2 = poly.at ( i );
1263
-
1264
- double v1c = startValColor + variationPerMapUnitColor * lengthFromStart;
1265
- double v1w = startValWidth + variationPerMapUnitWidth * lengthFromStart;
1266
- lengthFromStart += p1.distance ( p2 );
1267
- double v2c = startValColor + variationPerMapUnitColor * lengthFromStart;
1268
- double v2w = startValWidth + variationPerMapUnitWidth * lengthFromStart;
1269
- mLineRender .render ( v1c, v2c, v1w, v2w, p1, p2, renderContext );
1223
+ const QPointF p1 = poly.at ( i - 1 );
1224
+ const QPointF p2 = poly.at ( i );
1225
+
1226
+ const double v1c = startValColor + variationPerMapUnitColor * lengthFromStart;
1227
+ const double v1w = startValWidth + variationPerMapUnitWidth * lengthFromStart;
1228
+ lengthFromStart += std::sqrt ( ( p1.x () - p2. x () ) * ( p1. x () - p2. x () ) + ( p1. y () - p2. y () ) * ( p1. y () - p2. y () ) );
1229
+ const double v2c = startValColor + variationPerMapUnitColor * lengthFromStart;
1230
+ const double v2w = startValWidth + variationPerMapUnitWidth * lengthFromStart;
1231
+ mLineRender .renderInDeviceCoordinates ( v1c, v2c, v1w, v2w, p1, p2, context );
1270
1232
}
1271
1233
}
1234
+ }
1272
1235
1236
+ void QgsInterpolatedLineSymbolLayer::renderPolyline ( const QPolygonF &points, QgsSymbolRenderContext &context )
1237
+ {
1238
+ mLineRender .setSelected ( context.selected () );
1239
+
1240
+ if ( points.empty () )
1241
+ return ;
1242
+
1243
+ if ( mRenderingFeature )
1244
+ {
1245
+ // in the middle of rendering a possibly multi-part feature, so we collect all the parts and defer the actual rendering
1246
+ // until after we've received the final part
1247
+ mLineParts .append ( points );
1248
+ }
1249
+ else
1250
+ {
1251
+ // not rendering a feature, so we can just render the polyline immediately
1252
+ render ( { points }, context.renderContext () );
1253
+ }
1273
1254
}
1274
1255
1275
1256
bool QgsInterpolatedLineSymbolLayer::isCompatibleWithSymbol ( QgsSymbol *symbol ) const
0 commit comments