17#include "moc_qgsvectortilebasicrendererwidget.cpp"
29#include <QAbstractListModel>
30#include <QInputDialog>
39QgsVectorTileBasicRendererListModel::QgsVectorTileBasicRendererListModel(
QgsVectorTileBasicRenderer *r, QObject *parent, QScreen *screen )
40 : QAbstractListModel( parent )
46int QgsVectorTileBasicRendererListModel::rowCount(
const QModelIndex &parent )
const
48 if ( parent.isValid() )
51 return mRenderer->styles().count();
54int QgsVectorTileBasicRendererListModel::columnCount(
const QModelIndex & )
const
59QVariant QgsVectorTileBasicRendererListModel::data(
const QModelIndex &index,
int role )
const
61 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
64 const QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
72 if ( index.column() == 0 )
74 else if ( index.column() == 1 )
75 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
76 else if ( index.column() == 2 )
78 else if ( index.column() == 3 )
80 else if ( index.column() == 4 )
81 return style.
filterExpression().isEmpty() ? tr(
"(no filter)" ) : style.filterExpression();
88 if ( index.column() == 0 )
90 else if ( index.column() == 1 )
92 else if ( index.column() == 2 )
94 else if ( index.column() == 3 )
96 else if ( index.column() == 4 )
102 case Qt::DecorationRole:
104 if ( index.column() == 0 && style.
symbol() )
112 case Qt::CheckStateRole:
114 if ( index.column() != 0 )
116 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
138QVariant QgsVectorTileBasicRendererListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
140 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
143 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
150Qt::ItemFlags QgsVectorTileBasicRendererListModel::flags(
const QModelIndex &index )
const
152 if ( !index.isValid() )
153 return Qt::ItemIsDropEnabled;
155 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
157 return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
158 Qt::ItemIsEditable | checkable |
159 Qt::ItemIsDragEnabled;
162bool QgsVectorTileBasicRendererListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
164 if ( !index.isValid() )
169 if ( role == Qt::CheckStateRole )
171 style.
setEnabled( value.toInt() == Qt::Checked );
172 mRenderer->setStyle( index.row(), style );
173 emit dataChanged( index, index );
177 if ( role == Qt::EditRole )
179 if ( index.column() == 0 )
181 else if ( index.column() == 1 )
183 else if ( index.column() == 2 )
185 else if ( index.column() == 3 )
187 else if ( index.column() == 4 )
190 mRenderer->setStyle( index.row(), style );
191 emit dataChanged( index, index );
198bool QgsVectorTileBasicRendererListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
200 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
202 if ( row < 0 || row >= styles.count() )
205 beginRemoveRows( parent, row, row + count - 1 );
207 for (
int i = 0; i < count; i++ )
209 if ( row < styles.count() )
211 styles.removeAt( row );
215 mRenderer->setStyles( styles );
223 beginInsertRows( QModelIndex(), row, row );
225 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
226 styles.insert( row, style );
227 mRenderer->setStyles( styles );
232Qt::DropActions QgsVectorTileBasicRendererListModel::supportedDropActions()
const
234 return Qt::MoveAction;
237QStringList QgsVectorTileBasicRendererListModel::mimeTypes()
const
240 types << QStringLiteral(
"application/vnd.text.list" );
244QMimeData *QgsVectorTileBasicRendererListModel::mimeData(
const QModelIndexList &indexes )
const
246 QMimeData *mimeData =
new QMimeData();
247 QByteArray encodedData;
249 QDataStream stream( &encodedData, QIODevice::WriteOnly );
251 const auto constIndexes = indexes;
252 for (
const QModelIndex &index : constIndexes )
255 if ( !index.isValid() || index.column() != 0 )
261 QDomElement rootElem = doc.createElement( QStringLiteral(
"vector_tile_basic_renderer_style_mime" ) );
263 doc.appendChild( rootElem );
265 stream << doc.toString( -1 );
268 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
272bool QgsVectorTileBasicRendererListModel::dropMimeData(
const QMimeData *data,
273 Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
277 if ( action == Qt::IgnoreAction )
280 if ( !data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
283 if ( parent.column() > 0 )
286 QByteArray encodedData = data->data( QStringLiteral(
"application/vnd.text.list" ) );
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() != QLatin1String(
"vector_tile_basic_renderer_style_mime" ) )
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 );
349 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
355 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
357 mProxyModel->setCurrentZoom( zoom );
361 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
362 mapSettings.destinationCrs(),
363 mapSettings.visibleExtent(),
364 mapSettings.outputSize(),
365 mapSettings.outputDpi() ) : mMapCanvas->scale();
366 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
369 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [ = ](
bool filter )
371 mProxyModel->setFilterVisible( filter );
374 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [ = ](
const QString & text )
376 mProxyModel->setFilterString( text );
379 syncToLayer( layer );
382 connect( mBlendModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &
QgsPanelWidget::widgetChanged );
385void QgsVectorTileBasicRendererWidget::syncToLayer(
QgsMapLayer *layer )
402 mModel =
new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles, screen() );
403 mProxyModel =
new QgsVectorTileBasicRendererProxyModel( mModel, viewStyles );
404 viewStyles->setModel( mProxyModel );
409 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
415 mProxyModel->setCurrentZoom( zoom );
422 mOpacityWidget->setOpacity( mVTLayer->opacity() );
426 mBlendModeComboBox->setBlendMode( mVTLayer->blendMode() );
429QgsVectorTileBasicRendererWidget::~QgsVectorTileBasicRendererWidget() =
default;
431void QgsVectorTileBasicRendererWidget::apply()
433 mVTLayer->setRenderer( mRenderer->clone() );
434 mVTLayer->setBlendMode( mBlendModeComboBox->blendMode() );
435 mVTLayer->setOpacity( mOpacityWidget->opacity() );
459 const int rows = mModel->rowCount();
460 mModel->insertStyle( rows, style );
461 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
464void QgsVectorTileBasicRendererWidget::editStyle()
466 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
469void QgsVectorTileBasicRendererWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
471 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
472 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
480 std::unique_ptr< QgsSymbol > symbol( style.
symbol()->
clone() );
489 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
498 tileScope.
setVariable(
"vector_tile_zoom", mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoom( mMapCanvas->scale() ) :
QgsVectorTileUtils::scaleToZoom( mMapCanvas->scale() ), true );
517 dlg.setContext( context );
518 if ( !dlg.exec() || !symbol )
524 mRenderer->setStyle( index.row(), style );
525 emit widgetChanged();
531 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
539 mRenderer->setStyle( index, style );
540 emit widgetChanged();
543void QgsVectorTileBasicRendererWidget::removeStyle()
545 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
548 for (
const QModelIndex &proxyIndex : sel )
550 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
551 if ( !res.contains( sourceIndex.row() ) )
552 res << sourceIndex.row();
554 std::sort( res.begin(), res.end() );
556 for (
int i = res.size() - 1; i >= 0; --i )
558 mModel->removeRow( res[ i ] );
561 viewStyles->selectionModel()->clear();
564QgsVectorTileBasicRendererProxyModel::QgsVectorTileBasicRendererProxyModel( QgsVectorTileBasicRendererListModel *source, QObject *parent )
565 : QSortFilterProxyModel( parent )
567 setSourceModel( source );
568 setDynamicSortFilter(
true );
571void QgsVectorTileBasicRendererProxyModel::setCurrentZoom(
int zoom )
577void QgsVectorTileBasicRendererProxyModel::setFilterVisible(
bool enabled )
579 mFilterVisible = enabled;
583void QgsVectorTileBasicRendererProxyModel::setFilterString(
const QString &
string )
585 mFilterString = string;
589bool QgsVectorTileBasicRendererProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
591 if ( mCurrentZoom >= 0 && mFilterVisible )
593 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MinZoom ).toInt();
594 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MaxZoom ).toInt();
596 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
599 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
603 if ( !mFilterString.isEmpty() )
605 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Label ).toString();
606 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Layer ).toString();
607 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Filter ).toString();
608 if ( !name.contains( mFilterString, Qt::CaseInsensitive )
609 && !layer.contains( mFilterString, Qt::CaseInsensitive )
610 && !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.
The QgsMapSettings class contains configuration for rendering of the map.
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.
The class is used as a container of context for various read/write operations on other 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 data sets.
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.
Random utility functions for working with vector tiles.
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,...