@@ -544,7 +544,28 @@ void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureRenderer *renderer, Q
544
544
{
545
545
const bool isMainRenderer = renderer == mRenderer ;
546
546
547
- QHash< QgsSymbol *, QList<QgsFeature> > features; // key = symbol, value = array of features
547
+ // We need to figure out in which order all the features should be rendered.
548
+ // Ordering is based on (a) a "level" which is determined by the configured
549
+ // feature rendering order" and (b) the symbol level. The "level" is
550
+ // determined by the values of the attributes defined in the feature
551
+ // rendering order settings. Each time the attribute(s) have a new distinct
552
+ // value, a new empty QHash is added to the "features" list. This QHash is
553
+ // then filled by mappings from the symbol to a list of all the features
554
+ // that should be rendered by that symbol.
555
+ //
556
+ // If orderBy is not enabled, this list will only ever contain a single
557
+ // element.
558
+ QList<QHash< QgsSymbol *, QList<QgsFeature> >> features;
559
+
560
+ // We have at least one "level" for the features.
561
+ features.push_back ( {} );
562
+
563
+ QSet<int > orderByAttributeIdx;
564
+ if ( renderer->orderByEnabled () )
565
+ {
566
+ orderByAttributeIdx = renderer->orderBy ().usedAttributeIndices ( mSource ->fields () );
567
+ }
568
+
548
569
QgsRenderContext &context = *renderContext ();
549
570
550
571
QgsSingleSymbolRenderer *selRenderer = nullptr ;
@@ -572,6 +593,7 @@ void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureRenderer *renderer, Q
572
593
573
594
// 1. fetch features
574
595
QgsFeature fet;
596
+ std::vector<QVariant> prevValues; // previous values of ORDER BY attributes
575
597
while ( fit.nextFeature ( fet ) )
576
598
{
577
599
if ( context.renderingStopped () )
@@ -595,13 +617,33 @@ void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureRenderer *renderer, Q
595
617
continue ;
596
618
}
597
619
620
+ if ( renderer->orderByEnabled () )
621
+ {
622
+ std::vector<QVariant> currentValues;
623
+ for ( auto const idx : orderByAttributeIdx )
624
+ {
625
+ currentValues.push_back ( fet.attribute ( idx ) );
626
+ }
627
+ if ( prevValues.empty () )
628
+ {
629
+ prevValues = std::move ( currentValues );
630
+ }
631
+ else if ( currentValues != prevValues )
632
+ {
633
+ // Current values of ORDER BY attributes are different than previous
634
+ // values of these attributes. Start a new level.
635
+ prevValues = std::move ( currentValues );
636
+ features.push_back ( {} );
637
+ }
638
+ }
639
+
598
640
if ( !context.testFlag ( Qgis::RenderContextFlag::SkipSymbolRendering ) )
599
641
{
600
- if ( !features.contains ( sym ) )
642
+ if ( !features.back (). contains ( sym ) )
601
643
{
602
- features.insert ( sym, QList<QgsFeature>() );
644
+ features.back (). insert ( sym, QList<QgsFeature>() );
603
645
}
604
- features[sym].append ( fet );
646
+ features. back () [sym].append ( fet );
605
647
}
606
648
607
649
// new labeling engine
@@ -637,7 +679,7 @@ void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureRenderer *renderer, Q
637
679
638
680
scopePopper.reset ();
639
681
640
- if ( features.empty () )
682
+ if ( features.back (). empty () )
641
683
{
642
684
// nothing to draw
643
685
stopRenderer ( renderer, selRenderer );
@@ -666,52 +708,54 @@ void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureRenderer *renderer, Q
666
708
context.setFeatureClipGeometry ( mClipFeatureGeom );
667
709
668
710
// 2. draw features in correct order
669
- for ( int l = 0 ; l < levels. count (); l++ )
711
+ for ( auto &featureLists : features )
670
712
{
671
- QgsSymbolLevel &level = levels[l];
672
- for ( int i = 0 ; i < level.count (); i++ )
713
+ for ( int l = 0 ; l < levels.count (); l++ )
673
714
{
674
- QgsSymbolLevelItem &item = level[i ];
675
- if ( !features. contains ( item. symbol () ) )
715
+ const QgsSymbolLevel &level = levels[l ];
716
+ for ( int i = 0 ; i < level. count (); i++ )
676
717
{
677
- QgsDebugMsg ( QStringLiteral ( " level item's symbol not found!" ) );
678
- continue ;
679
- }
680
- int layer = item.layer ();
681
- QList<QgsFeature> &lst = features[item.symbol ()];
682
- QList<QgsFeature>::iterator fit;
683
- for ( fit = lst.begin (); fit != lst.end (); ++fit )
684
- {
685
- if ( context.renderingStopped () )
718
+ const QgsSymbolLevelItem &item = level[i];
719
+ if ( !featureLists.contains ( item.symbol () ) )
686
720
{
687
- stopRenderer ( renderer, selRenderer );
688
- return ;
721
+ QgsDebugMsg ( QStringLiteral ( " level item's symbol not found! " ) );
722
+ continue ;
689
723
}
724
+ const int layer = item.layer ();
725
+ const QList<QgsFeature> &lst = featureLists[item.symbol ()];
726
+ for ( auto fit = lst.begin (); fit != lst.end (); ++fit )
727
+ {
728
+ if ( context.renderingStopped () )
729
+ {
730
+ stopRenderer ( renderer, selRenderer );
731
+ return ;
732
+ }
690
733
691
- bool sel = isMainRenderer && context.showSelection () && mSelectedFeatureIds .contains ( fit->id () );
692
- // maybe vertex markers should be drawn only during the last pass...
693
- bool drawMarker = isMainRenderer && ( mDrawVertexMarkers && context.drawEditingInformation () && ( !mVertexMarkerOnlyForSelection || sel ) );
694
-
695
- if ( ! mNoSetLayerExpressionContext )
696
- context.expressionContext ().setFeature ( *fit );
734
+ const bool sel = isMainRenderer && context.showSelection () && mSelectedFeatureIds .contains ( fit->id () );
735
+ // maybe vertex markers should be drawn only during the last pass...
736
+ const bool drawMarker = isMainRenderer && ( mDrawVertexMarkers && context.drawEditingInformation () && ( !mVertexMarkerOnlyForSelection || sel ) );
697
737
698
- try
699
- {
700
- renderer->renderFeature ( *fit, context, layer, sel, drawMarker );
738
+ if ( ! mNoSetLayerExpressionContext )
739
+ context.expressionContext ().setFeature ( *fit );
701
740
702
- // as soon as first feature is rendered, we can start showing layer updates.
703
- // but if we are blocking render updates (so that a previously cached image is being shown), we wait
704
- // at most e.g. 3 seconds before we start forcing progressive updates.
705
- if ( !mBlockRenderUpdates || mElapsedTimer .elapsed () > MAX_TIME_TO_USE_CACHED_PREVIEW_IMAGE )
741
+ try
706
742
{
707
- mReadyToCompose = true ;
743
+ renderer->renderFeature ( *fit, context, layer, sel, drawMarker );
744
+
745
+ // as soon as first feature is rendered, we can start showing layer updates.
746
+ // but if we are blocking render updates (so that a previously cached image is being shown), we wait
747
+ // at most e.g. 3 seconds before we start forcing progressive updates.
748
+ if ( !mBlockRenderUpdates || mElapsedTimer .elapsed () > MAX_TIME_TO_USE_CACHED_PREVIEW_IMAGE )
749
+ {
750
+ mReadyToCompose = true ;
751
+ }
752
+ }
753
+ catch ( const QgsCsException &cse )
754
+ {
755
+ Q_UNUSED ( cse )
756
+ QgsDebugMsg ( QStringLiteral ( " Failed to transform a point while drawing a feature with ID '%1'. Ignoring this feature. %2" )
757
+ .arg ( fet.id () ).arg ( cse.what () ) );
708
758
}
709
- }
710
- catch ( const QgsCsException &cse )
711
- {
712
- Q_UNUSED ( cse )
713
- QgsDebugMsg ( QStringLiteral ( " Failed to transform a point while drawing a feature with ID '%1'. Ignoring this feature. %2" )
714
- .arg ( fet.id () ).arg ( cse.what () ) );
715
759
}
716
760
}
717
761
}
0 commit comments