30#include <QAbstractListModel>
31#include <QInputDialog>
37#include "moc_qgsvectortilebasicrendererwidget.cpp"
39using namespace Qt::StringLiterals;
44QgsVectorTileBasicRendererListModel::QgsVectorTileBasicRendererListModel(
QgsVectorTileBasicRenderer *r, QObject *parent, QScreen *screen )
45 : QAbstractListModel( parent )
50int QgsVectorTileBasicRendererListModel::rowCount(
const QModelIndex &parent )
const
52 if ( parent.isValid() )
55 return mRenderer->styles().count();
58int QgsVectorTileBasicRendererListModel::columnCount(
const QModelIndex & )
const
63QVariant QgsVectorTileBasicRendererListModel::data(
const QModelIndex &index,
int role )
const
65 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
68 const QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
76 if ( index.column() == 0 )
78 else if ( index.column() == 1 )
79 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
80 else if ( index.column() == 2 )
82 else if ( index.column() == 3 )
84 else if ( index.column() == 4 )
92 if ( index.column() == 0 )
94 else if ( index.column() == 1 )
96 else if ( index.column() == 2 )
98 else if ( index.column() == 3 )
100 else if ( index.column() == 4 )
106 case Qt::DecorationRole:
108 if ( index.column() == 0 && style.
symbol() )
116 case Qt::CheckStateRole:
118 if ( index.column() != 0 )
120 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
141QVariant QgsVectorTileBasicRendererListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
143 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
146 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
153Qt::ItemFlags QgsVectorTileBasicRendererListModel::flags(
const QModelIndex &index )
const
155 if ( !index.isValid() )
156 return Qt::ItemIsDropEnabled;
158 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
160 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | checkable | Qt::ItemIsDragEnabled;
163bool QgsVectorTileBasicRendererListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
165 if ( !index.isValid() )
170 if ( role == Qt::CheckStateRole )
172 style.
setEnabled( value.toInt() == Qt::Checked );
173 mRenderer->setStyle( index.row(), style );
174 emit dataChanged( index, index );
178 if ( role == Qt::EditRole )
180 if ( index.column() == 0 )
182 else if ( index.column() == 1 )
184 else if ( index.column() == 2 )
186 else if ( index.column() == 3 )
188 else if ( index.column() == 4 )
191 mRenderer->setStyle( index.row(), style );
192 emit dataChanged( index, index );
199bool QgsVectorTileBasicRendererListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
201 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
203 if ( row < 0 || row >= styles.count() )
206 beginRemoveRows( parent, row, row + count - 1 );
208 for (
int i = 0; i < count; i++ )
210 if ( row < styles.count() )
212 styles.removeAt( row );
216 mRenderer->setStyles( styles );
224 beginInsertRows( QModelIndex(), row, row );
226 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
227 styles.insert( row, style );
228 mRenderer->setStyles( styles );
233Qt::DropActions QgsVectorTileBasicRendererListModel::supportedDropActions()
const
235 return Qt::MoveAction;
238QStringList QgsVectorTileBasicRendererListModel::mimeTypes()
const
241 types << u
"application/vnd.text.list"_s;
245QMimeData *QgsVectorTileBasicRendererListModel::mimeData(
const QModelIndexList &indexes )
const
247 QMimeData *mimeData =
new QMimeData();
248 QByteArray encodedData;
250 QDataStream stream( &encodedData, QIODevice::WriteOnly );
252 const auto constIndexes = indexes;
253 for (
const QModelIndex &index : constIndexes )
256 if ( !index.isValid() || index.column() != 0 )
262 QDomElement rootElem = doc.createElement( u
"vector_tile_basic_renderer_style_mime"_s );
264 doc.appendChild( rootElem );
266 stream << doc.toString( -1 );
269 mimeData->setData( u
"application/vnd.text.list"_s, encodedData );
273bool QgsVectorTileBasicRendererListModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
277 if ( action == Qt::IgnoreAction )
280 if ( !data->hasFormat( u
"application/vnd.text.list"_s ) )
283 if ( parent.column() > 0 )
286 QByteArray encodedData = data->data( u
"application/vnd.text.list"_s );
287 QDataStream stream( &encodedData, QIODevice::ReadOnly );
293 row = rowCount( parent );
296 while ( !stream.atEnd() )
302 if ( !doc.setContent( text ) )
304 const QDomElement rootElem = doc.documentElement();
305 if ( rootElem.tagName() !=
"vector_tile_basic_renderer_style_mime"_L1 )
311 insertStyle( row + rows, style );
323 , mMapCanvas( canvas )
324 , mMessageBar( messageBar )
327 layout()->setContentsMargins( 0, 0, 0, 0 );
329 mFilterLineEdit->setShowClearButton(
true );
330 mFilterLineEdit->setShowSearchIcon(
true );
331 mFilterLineEdit->setPlaceholderText( tr(
"Filter rules" ) );
333 QMenu *menuAddRule =
new QMenu( btnAddRule );
337 btnAddRule->setMenu( menuAddRule );
339 connect( btnEditRule, &QPushButton::clicked,
this, &QgsVectorTileBasicRendererWidget::editStyle );
340 connect( btnRemoveRule, &QAbstractButton::clicked,
this, &QgsVectorTileBasicRendererWidget::removeStyle );
342 connect( viewStyles, &QAbstractItemView::doubleClicked,
this, &QgsVectorTileBasicRendererWidget::editStyleAtIndex );
348 const double tileScale
353 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
355 mProxyModel->setCurrentZoom( zoom );
359 const double tileScale
360 = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(), mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() )
361 : mMapCanvas->
scale();
362 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
365 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [
this](
bool filter ) { mProxyModel->setFilterVisible( filter ); } );
367 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [
this](
const QString &text ) { mProxyModel->setFilterString( text ); } );
369 syncToLayer( layer );
372 connect( mBlendModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &
QgsPanelWidget::widgetChanged );
375void QgsVectorTileBasicRendererWidget::syncToLayer(
QgsMapLayer *layer )
389 mRenderer = std::make_unique<QgsVectorTileBasicRenderer>();
392 mModel =
new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles, screen() );
393 mProxyModel =
new QgsVectorTileBasicRendererProxyModel( mModel, viewStyles );
394 viewStyles->setModel( mProxyModel );
399 const double tileScale
401 : mMapCanvas->
scale();
403 mProxyModel->setCurrentZoom( zoom );
410 mOpacityWidget->setOpacity( mVTLayer->opacity() );
414 mBlendModeComboBox->setBlendMode( mVTLayer->blendMode() );
417QgsVectorTileBasicRendererWidget::~QgsVectorTileBasicRendererWidget() =
default;
419void QgsVectorTileBasicRendererWidget::apply()
421 mVTLayer->setRenderer( mRenderer->clone() );
422 mVTLayer->setBlendMode( mBlendModeComboBox->blendMode() );
423 mVTLayer->setOpacity( mOpacityWidget->opacity() );
447 const int rows = mModel->rowCount();
448 mModel->insertStyle( rows, style );
449 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
452void QgsVectorTileBasicRendererWidget::editStyle()
454 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
457void QgsVectorTileBasicRendererWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
459 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
460 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
468 std::unique_ptr<QgsSymbol> symbol( style.
symbol()->
clone() );
477 const double tileScale
479 : mMapCanvas->
scale();
503 dlg.setContext( context );
504 if ( !dlg.exec() || !symbol )
510 mRenderer->setStyle( index.row(), style );
511 emit widgetChanged();
517 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
525 mRenderer->setStyle( index, style );
526 emit widgetChanged();
529void QgsVectorTileBasicRendererWidget::removeStyle()
531 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
534 for (
const QModelIndex &proxyIndex : sel )
536 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
537 if ( !res.contains( sourceIndex.row() ) )
538 res << sourceIndex.row();
540 std::sort( res.begin(), res.end() );
542 for (
int i = res.size() - 1; i >= 0; --i )
544 mModel->removeRow( res[i] );
547 viewStyles->selectionModel()->clear();
550QgsVectorTileBasicRendererProxyModel::QgsVectorTileBasicRendererProxyModel( QgsVectorTileBasicRendererListModel *source, QObject *parent )
551 : QSortFilterProxyModel( parent )
553 setSourceModel( source );
554 setDynamicSortFilter(
true );
557void QgsVectorTileBasicRendererProxyModel::setCurrentZoom(
int zoom )
563void QgsVectorTileBasicRendererProxyModel::setFilterVisible(
bool enabled )
565 mFilterVisible = enabled;
569void QgsVectorTileBasicRendererProxyModel::setFilterString(
const QString &
string )
571 mFilterString = string;
575bool QgsVectorTileBasicRendererProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
577 if ( mCurrentZoom >= 0 && mFilterVisible )
579 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MinZoom ).toInt();
580 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MaxZoom ).toInt();
582 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
585 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
589 if ( !mFilterString.isEmpty() )
591 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Label ).toString();
592 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Layer ).toString();
593 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Filter ).toString();
594 if ( !name.contains( mFilterString, Qt::CaseInsensitive ) && !layer.contains( mFilterString, Qt::CaseInsensitive ) && !filter.contains( mFilterString, Qt::CaseInsensitive ) )
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
Map canvas is a class for displaying all GIS data types on a canvas.
void scaleChanged(double scale)
Emitted when the scale of the map changes.
Base class for all map layer types.
Contains configuration for rendering maps.
double scale() const
Returns the calculated map scale.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
A bar for displaying non-blocking messages to the user.
static bool layerIsContainedInGroupLayer(QgsProject *project, QgsMapLayer *layer)
Returns true if the specified layer is a child layer from any QgsGroupLayer in the given project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
A container for the context for various read/write operations on objects.
Stores properties relating to a screen.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
A dialog that can be used to select and build a symbol.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setAdditionalExpressionContextScopes(const QList< QgsExpressionContextScope > &scopes)
Sets a list of additional expression context scopes to show as available within the layer.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Represents a vector layer which manages a vector based dataset.
Definition of map rendering of a subset of vector tile data.
void setEnabled(bool enabled)
Sets whether this style is enabled (used for rendering).
void setMinZoomLevel(int minZoom)
Sets minimum zoom level index (negative number means no limit).
void setLayerName(const QString &name)
Sets name of the sub-layer to render (empty layer means that all layers match).
QgsSymbol * symbol() const
Returns symbol for rendering.
QString filterExpression() const
Returns filter expression (empty filter means that all features match).
QString styleName() const
Returns human readable name of this style.
void setFilterExpression(const QString &expr)
Sets filter expression (empty filter means that all features match).
void setSymbol(QgsSymbol *sym)
Sets symbol for rendering. Takes ownership of the symbol.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes object content to given DOM element.
void setStyleName(const QString &name)
Sets human readable name of this style.
bool isEnabled() const
Returns whether this style is enabled (used for rendering).
void setMaxZoomLevel(int maxZoom)
Sets maximum zoom level index (negative number means no limit).
int minZoomLevel() const
Returns the minimum zoom level index (negative number means no limit).
int maxZoomLevel() const
Returns the maximum zoom level index (negative number means no limit).
QString layerName() const
Returns name of the sub-layer to render (empty layer means that all layers match).
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads object content from given DOM element.
The default vector tile renderer implementation.
Implements a map layer that is dedicated to rendering of vector tiles.
QgsVectorTileRenderer * renderer() const
Returns currently assigned renderer.
virtual QString type() const =0
Returns unique type name of the renderer implementation.
virtual QgsVectorTileRenderer * clone() const =0
Returns a clone of the renderer.
static double scaleToZoom(double mapScale, double z0Scale=559082264.0287178)
Finds zoom level given map scale denominator.
static int scaleToZoomLevel(double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale=559082264.0287178)
Finds the best fitting zoom level given a map scale denominator and allowed zoom level range.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...