Skip to content
Permalink
Browse files

[feature][vectortiles] Add checkbox for showing only visible rules

in the vector tiles labeling and renderer widgets

Makes it much easier to locate troublesome rules or work with
complex vector tile styling
  • Loading branch information
nyalldawson committed Sep 9, 2020
1 parent c821288 commit 92c3a88da4254b6bbf59a7bd0f2b869d7cb1ecf0
@@ -96,6 +96,12 @@ QVariant QgsVectorTileBasicLabelingListModel::data( const QModelIndex &index, in
return style.isEnabled() ? Qt::Checked : Qt::Unchecked;
}

case MinZoom:
return style.minZoomLevel();

case MaxZoom:
return style.maxZoomLevel();

}
return QVariant();
}
@@ -308,11 +314,19 @@ QgsVectorTileBasicLabelingWidget::QgsVectorTileBasicLabelingWidget( QgsVectorTil
{
connect( mMapCanvas, &QgsMapCanvas::scaleChanged, this, [ = ]( double scale )
{
mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( QgsVectorTileUtils::scaleToZoomLevel( scale, 0, 99 ) ) );
const int zoom = QgsVectorTileUtils::scaleToZoomLevel( scale, 0, 99 );
mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( zoom ) );
if ( mProxyModel )
mProxyModel->setCurrentZoom( zoom );
} );
mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( QgsVectorTileUtils::scaleToZoomLevel( mMapCanvas->scale(), 0, 99 ) ) );
}

connect( mCheckVisibleOnly, &QCheckBox::toggled, this, [ = ]( bool filter )
{
mProxyModel->setFilterVisible( filter );
} );

setLayer( layer );
}

@@ -330,7 +344,14 @@ void QgsVectorTileBasicLabelingWidget::setLayer( QgsVectorTileLayer *layer )
}

mModel = new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
viewStyles->setModel( mModel );
mProxyModel = new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
viewStyles->setModel( mProxyModel );

if ( mMapCanvas )
{
const int zoom = QgsVectorTileUtils::scaleToZoomLevel( mMapCanvas->scale(), 0, 99 );
mProxyModel->setCurrentZoom( zoom );
}

connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsPanelWidget::widgetChanged );
connect( mModel, &QAbstractItemModel::rowsInserted, this, &QgsPanelWidget::widgetChanged );
@@ -351,16 +372,17 @@ void QgsVectorTileBasicLabelingWidget::addStyle( QgsWkbTypes::GeometryType geomT

int rows = mModel->rowCount();
mModel->insertStyle( rows, style );
viewStyles->selectionModel()->setCurrentIndex( mModel->index( rows, 0 ), QItemSelectionModel::ClearAndSelect );
viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
}

void QgsVectorTileBasicLabelingWidget::editStyle()
{
editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
}

void QgsVectorTileBasicLabelingWidget::editStyleAtIndex( const QModelIndex &index )
void QgsVectorTileBasicLabelingWidget::editStyleAtIndex( const QModelIndex &proxyIndex )
{
const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
return;

@@ -400,7 +422,7 @@ void QgsVectorTileBasicLabelingWidget::editStyleAtIndex( const QModelIndex &inde

void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
{
int index = viewStyles->selectionModel()->currentIndex().row();
int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
if ( index < 0 )
return;

@@ -415,12 +437,12 @@ void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()

void QgsVectorTileBasicLabelingWidget::removeStyle()
{
QItemSelection sel = viewStyles->selectionModel()->selection();
const auto constSel = sel;
for ( const QItemSelectionRange &range : constSel )
const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
for ( const QModelIndex &proxyIndex : sel )
{
if ( range.isValid() )
mModel->removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
if ( sourceIndex.isValid() )
mModel->removeRow( sourceIndex.row() );
}
// make sure that the selection is gone
viewStyles->selectionModel()->clear();
@@ -460,4 +482,41 @@ QgsPalLayerSettings QgsLabelingPanelWidget::labelSettings()
return mLabelingGui->layerSettings();
}


QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
: QSortFilterProxyModel( parent )
{
setSourceModel( source );
setDynamicSortFilter( true );
}

void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom( int zoom )
{
mCurrentZoom = zoom;
invalidateFilter();
}

void QgsVectorTileBasicLabelingProxyModel::setFilterVisible( bool enabled )
{
mFilterVisible = enabled;
invalidateFilter();
}

bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
{
if ( mCurrentZoom < 0 || !mFilterVisible )
return true;

const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();

if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
return false;

if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
return false;

return true;
}

///@endcond
@@ -23,6 +23,7 @@
#include "qgswkbtypes.h"

#include <memory>
#include <QSortFilterProxyModel>

///@cond PRIVATE
#define SIP_NO_FILE
@@ -32,6 +33,7 @@ class QgsVectorTileBasicLabelingListModel;
class QgsVectorTileLayer;
class QgsMapCanvas;
class QgsMessageBar;
class QgsVectorTileBasicLabelingProxyModel;

/**
* \ingroup gui
@@ -65,6 +67,7 @@ class GUI_EXPORT QgsVectorTileBasicLabelingWidget : public QgsMapLayerConfigWidg
QgsVectorTileLayer *mVTLayer = nullptr;
std::unique_ptr<QgsVectorTileBasicLabeling> mLabeling;
QgsVectorTileBasicLabelingListModel *mModel = nullptr;
QgsVectorTileBasicLabelingProxyModel *mProxyModel = nullptr;
QgsMapCanvas *mMapCanvas = nullptr;
QgsMessageBar *mMessageBar = nullptr;
};
@@ -103,6 +106,13 @@ class QgsVectorTileBasicLabelingListModel : public QAbstractListModel
{
Q_OBJECT
public:

enum Role
{
MinZoom = Qt::UserRole + 1,
MaxZoom,
};

QgsVectorTileBasicLabelingListModel( QgsVectorTileBasicLabeling *r, QObject *parent = nullptr );

int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
@@ -126,6 +136,24 @@ class QgsVectorTileBasicLabelingListModel : public QAbstractListModel
QgsVectorTileBasicLabeling *mLabeling = nullptr;
};

class QgsVectorTileBasicLabelingProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent = nullptr );

void setCurrentZoom( int zoom );
void setFilterVisible( bool enabled );

bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const override;

private:

bool mFilterVisible = false;
int mCurrentZoom = -1;
};


///@endcond

#endif // QGSVECTORTILEBASICLABELINGWIDGET_H
@@ -111,6 +111,12 @@ QVariant QgsVectorTileBasicRendererListModel::data( const QModelIndex &index, in
return style.isEnabled() ? Qt::Checked : Qt::Unchecked;
}

case MinZoom:
return style.minZoomLevel();

case MaxZoom:
return style.maxZoomLevel();

}
return QVariant();
}
@@ -321,11 +327,19 @@ QgsVectorTileBasicRendererWidget::QgsVectorTileBasicRendererWidget( QgsVectorTil
{
connect( mMapCanvas, &QgsMapCanvas::scaleChanged, this, [ = ]( double scale )
{
mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( QgsVectorTileUtils::scaleToZoomLevel( scale, 0, 99 ) ) );
const int zoom = QgsVectorTileUtils::scaleToZoomLevel( scale, 0, 99 );
mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( zoom ) );
if ( mProxyModel )
mProxyModel->setCurrentZoom( zoom );
} );
mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( QgsVectorTileUtils::scaleToZoomLevel( mMapCanvas->scale(), 0, 99 ) ) );
}

connect( mCheckVisibleOnly, &QCheckBox::toggled, this, [ = ]( bool filter )
{
mProxyModel->setFilterVisible( filter );
} );

setLayer( layer );
}

@@ -343,7 +357,14 @@ void QgsVectorTileBasicRendererWidget::setLayer( QgsVectorTileLayer *layer )
}

mModel = new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles );
viewStyles->setModel( mModel );
mProxyModel = new QgsVectorTileBasicRendererProxyModel( mModel, viewStyles );
viewStyles->setModel( mProxyModel );

if ( mMapCanvas )
{
const int zoom = QgsVectorTileUtils::scaleToZoomLevel( mMapCanvas->scale(), 0, 99 );
mProxyModel->setCurrentZoom( zoom );
}

connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsPanelWidget::widgetChanged );
connect( mModel, &QAbstractItemModel::rowsInserted, this, &QgsPanelWidget::widgetChanged );
@@ -364,16 +385,17 @@ void QgsVectorTileBasicRendererWidget::addStyle( QgsWkbTypes::GeometryType geomT

int rows = mModel->rowCount();
mModel->insertStyle( rows, style );
viewStyles->selectionModel()->setCurrentIndex( mModel->index( rows, 0 ), QItemSelectionModel::ClearAndSelect );
viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
}

void QgsVectorTileBasicRendererWidget::editStyle()
{
editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
}

void QgsVectorTileBasicRendererWidget::editStyleAtIndex( const QModelIndex &index )
void QgsVectorTileBasicRendererWidget::editStyleAtIndex( const QModelIndex &proxyIndex )
{
const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
return;

@@ -417,7 +439,7 @@ void QgsVectorTileBasicRendererWidget::editStyleAtIndex( const QModelIndex &inde

void QgsVectorTileBasicRendererWidget::updateSymbolsFromWidget()
{
int index = viewStyles->selectionModel()->currentIndex().row();
int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
if ( index < 0 )
return;

@@ -441,15 +463,53 @@ void QgsVectorTileBasicRendererWidget::cleanUpSymbolSelector( QgsPanelWidget *co

void QgsVectorTileBasicRendererWidget::removeStyle()
{
QItemSelection sel = viewStyles->selectionModel()->selection();
const auto constSel = sel;
for ( const QItemSelectionRange &range : constSel )
const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
for ( const QModelIndex &proxyIndex : sel )
{
if ( range.isValid() )
mModel->removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
if ( sourceIndex.isValid() )
mModel->removeRow( sourceIndex.row() );
}
// make sure that the selection is gone
viewStyles->selectionModel()->clear();
}

QgsVectorTileBasicRendererProxyModel::QgsVectorTileBasicRendererProxyModel( QgsVectorTileBasicRendererListModel *source, QObject *parent )
: QSortFilterProxyModel( parent )
{
setSourceModel( source );
setDynamicSortFilter( true );
}

void QgsVectorTileBasicRendererProxyModel::setCurrentZoom( int zoom )
{
mCurrentZoom = zoom;
invalidateFilter();
}

void QgsVectorTileBasicRendererProxyModel::setFilterVisible( bool enabled )
{
mFilterVisible = enabled;
invalidateFilter();
}

bool QgsVectorTileBasicRendererProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
{
if ( mCurrentZoom < 0 || !mFilterVisible )
return true;

const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MinZoom ).toInt();
const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MaxZoom ).toInt();

if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
return false;

if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
return false;

return true;
}



///@endcond

0 comments on commit 92c3a88

Please sign in to comment.
You can’t perform that action at this time.