Skip to content

Commit

Permalink
[feature][vectortiles] Add checkbox for showing only visible rules
Browse files Browse the repository at this point in the history
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 92c3a88
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 20 deletions.
79 changes: 69 additions & 10 deletions src/gui/vectortile/qgsvectortilebasiclabelingwidget.cpp
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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 );
}

Expand All @@ -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 );
Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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();
Expand Down Expand Up @@ -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
28 changes: 28 additions & 0 deletions src/gui/vectortile/qgsvectortilebasiclabelingwidget.h
Expand Up @@ -23,6 +23,7 @@
#include "qgswkbtypes.h"

#include <memory>
#include <QSortFilterProxyModel>

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

/**
* \ingroup gui
Expand Down Expand Up @@ -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;
};
Expand Down Expand Up @@ -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;
Expand All @@ -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
80 changes: 70 additions & 10 deletions src/gui/vectortile/qgsvectortilebasicrendererwidget.cpp
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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 );
}

Expand All @@ -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 );
Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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.