28#include <QAbstractListModel>
29#include <QInputDialog>
38QgsVectorTileBasicRendererListModel::QgsVectorTileBasicRendererListModel(
QgsVectorTileBasicRenderer *r, QObject *parent, QScreen *screen )
39 : QAbstractListModel( parent )
45int QgsVectorTileBasicRendererListModel::rowCount(
const QModelIndex &parent )
const
47 if ( parent.isValid() )
50 return mRenderer->styles().count();
53int QgsVectorTileBasicRendererListModel::columnCount(
const QModelIndex & )
const
58QVariant QgsVectorTileBasicRendererListModel::data(
const QModelIndex &index,
int role )
const
60 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
63 const QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
71 if ( index.column() == 0 )
73 else if ( index.column() == 1 )
74 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
75 else if ( index.column() == 2 )
77 else if ( index.column() == 3 )
79 else if ( index.column() == 4 )
80 return style.
filterExpression().isEmpty() ? tr(
"(no filter)" ) : style.filterExpression();
87 if ( index.column() == 0 )
89 else if ( index.column() == 1 )
91 else if ( index.column() == 2 )
93 else if ( index.column() == 3 )
95 else if ( index.column() == 4 )
101 case Qt::DecorationRole:
103 if ( index.column() == 0 && style.
symbol() )
111 case Qt::CheckStateRole:
113 if ( index.column() != 0 )
115 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
137QVariant QgsVectorTileBasicRendererListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
139 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
142 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
149Qt::ItemFlags QgsVectorTileBasicRendererListModel::flags(
const QModelIndex &index )
const
151 if ( !index.isValid() )
152 return Qt::ItemIsDropEnabled;
154 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
156 return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
157 Qt::ItemIsEditable | checkable |
158 Qt::ItemIsDragEnabled;
161bool QgsVectorTileBasicRendererListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
163 if ( !index.isValid() )
168 if ( role == Qt::CheckStateRole )
170 style.
setEnabled( value.toInt() == Qt::Checked );
171 mRenderer->setStyle( index.row(), style );
172 emit dataChanged( index, index );
176 if ( role == Qt::EditRole )
178 if ( index.column() == 0 )
180 else if ( index.column() == 1 )
182 else if ( index.column() == 2 )
184 else if ( index.column() == 3 )
186 else if ( index.column() == 4 )
189 mRenderer->setStyle( index.row(), style );
190 emit dataChanged( index, index );
197bool QgsVectorTileBasicRendererListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
199 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
201 if ( row < 0 || row >= styles.count() )
204 beginRemoveRows( parent, row, row + count - 1 );
206 for (
int i = 0; i < count; i++ )
208 if ( row < styles.count() )
210 styles.removeAt( row );
214 mRenderer->setStyles( styles );
222 beginInsertRows( QModelIndex(), row, row );
224 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
225 styles.insert( row, style );
226 mRenderer->setStyles( styles );
231Qt::DropActions QgsVectorTileBasicRendererListModel::supportedDropActions()
const
233 return Qt::MoveAction;
236QStringList QgsVectorTileBasicRendererListModel::mimeTypes()
const
239 types << QStringLiteral(
"application/vnd.text.list" );
243QMimeData *QgsVectorTileBasicRendererListModel::mimeData(
const QModelIndexList &indexes )
const
245 QMimeData *mimeData =
new QMimeData();
246 QByteArray encodedData;
248 QDataStream stream( &encodedData, QIODevice::WriteOnly );
250 const auto constIndexes = indexes;
251 for (
const QModelIndex &index : constIndexes )
254 if ( !index.isValid() || index.column() != 0 )
260 QDomElement rootElem = doc.createElement( QStringLiteral(
"vector_tile_basic_renderer_style_mime" ) );
262 doc.appendChild( rootElem );
264 stream << doc.toString( -1 );
267 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
271bool QgsVectorTileBasicRendererListModel::dropMimeData(
const QMimeData *data,
272 Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
276 if ( action == Qt::IgnoreAction )
279 if ( !data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
282 if ( parent.column() > 0 )
285 QByteArray encodedData = data->data( QStringLiteral(
"application/vnd.text.list" ) );
286 QDataStream stream( &encodedData, QIODevice::ReadOnly );
292 row = rowCount( parent );
295 while ( !stream.atEnd() )
301 if ( !doc.setContent( text ) )
303 const QDomElement rootElem = doc.documentElement();
304 if ( rootElem.tagName() != QLatin1String(
"vector_tile_basic_renderer_style_mime" ) )
310 insertStyle( row + rows, style );
322 , mMapCanvas( canvas )
323 , mMessageBar( messageBar )
326 layout()->setContentsMargins( 0, 0, 0, 0 );
328 mFilterLineEdit->setShowClearButton(
true );
329 mFilterLineEdit->setShowSearchIcon(
true );
330 mFilterLineEdit->setPlaceholderText( tr(
"Filter rules" ) );
332 QMenu *menuAddRule =
new QMenu( btnAddRule );
336 btnAddRule->setMenu( menuAddRule );
338 connect( btnEditRule, &QPushButton::clicked,
this, &QgsVectorTileBasicRendererWidget::editStyle );
339 connect( btnRemoveRule, &QAbstractButton::clicked,
this, &QgsVectorTileBasicRendererWidget::removeStyle );
341 connect( viewStyles, &QAbstractItemView::doubleClicked,
this, &QgsVectorTileBasicRendererWidget::editStyleAtIndex );
348 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
354 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
356 mProxyModel->setCurrentZoom( zoom );
360 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
361 mapSettings.destinationCrs(),
362 mapSettings.visibleExtent(),
363 mapSettings.outputSize(),
364 mapSettings.outputDpi() ) : mMapCanvas->scale();
365 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
368 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [ = ](
bool filter )
370 mProxyModel->setFilterVisible( filter );
373 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [ = ](
const QString & text )
375 mProxyModel->setFilterString( text );
378 syncToLayer( layer );
381 connect( mBlendModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &
QgsPanelWidget::widgetChanged );
384void QgsVectorTileBasicRendererWidget::syncToLayer(
QgsMapLayer *layer )
401 mModel =
new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles, screen() );
402 mProxyModel =
new QgsVectorTileBasicRendererProxyModel( mModel, viewStyles );
403 viewStyles->setModel( mProxyModel );
408 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
414 mProxyModel->setCurrentZoom( zoom );
421 mOpacityWidget->setOpacity( mVTLayer->opacity() );
425 mBlendModeComboBox->setBlendMode( mVTLayer->blendMode() );
428QgsVectorTileBasicRendererWidget::~QgsVectorTileBasicRendererWidget() =
default;
430void QgsVectorTileBasicRendererWidget::apply()
432 mVTLayer->setRenderer( mRenderer->clone() );
433 mVTLayer->setBlendMode( mBlendModeComboBox->blendMode() );
434 mVTLayer->setOpacity( mOpacityWidget->opacity() );
458 const int rows = mModel->rowCount();
459 mModel->insertStyle( rows, style );
460 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
463void QgsVectorTileBasicRendererWidget::editStyle()
465 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
468void QgsVectorTileBasicRendererWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
470 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
471 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
479 std::unique_ptr< QgsSymbol > symbol( style.
symbol()->
clone() );
488 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
497 tileScope.
setVariable(
"vector_tile_zoom", mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoom( mMapCanvas->scale() ) :
QgsVectorTileUtils::scaleToZoom( mMapCanvas->scale() ), true );
516 dlg.setContext( context );
517 if ( !dlg.exec() || !symbol )
523 mRenderer->setStyle( index.row(), style );
524 emit widgetChanged();
530 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
538 mRenderer->setStyle( index, style );
539 emit widgetChanged();
542void QgsVectorTileBasicRendererWidget::removeStyle()
544 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
547 for (
const QModelIndex &proxyIndex : sel )
549 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
550 if ( !res.contains( sourceIndex.row() ) )
551 res << sourceIndex.row();
553 std::sort( res.begin(), res.end() );
555 for (
int i = res.size() - 1; i >= 0; --i )
557 mModel->removeRow( res[ i ] );
560 viewStyles->selectionModel()->clear();
563QgsVectorTileBasicRendererProxyModel::QgsVectorTileBasicRendererProxyModel( QgsVectorTileBasicRendererListModel *source, QObject *parent )
564 : QSortFilterProxyModel( parent )
566 setSourceModel( source );
567 setDynamicSortFilter(
true );
570void QgsVectorTileBasicRendererProxyModel::setCurrentZoom(
int zoom )
576void QgsVectorTileBasicRendererProxyModel::setFilterVisible(
bool enabled )
578 mFilterVisible = enabled;
582void QgsVectorTileBasicRendererProxyModel::setFilterString(
const QString &
string )
584 mFilterString = string;
588bool QgsVectorTileBasicRendererProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
590 if ( mCurrentZoom >= 0 && mFilterVisible )
592 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MinZoom ).toInt();
593 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MaxZoom ).toInt();
595 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
598 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
602 if ( !mFilterString.isEmpty() )
604 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Label ).toString();
605 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Layer ).toString();
606 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Filter ).toString();
607 if ( !name.contains( mFilterString, Qt::CaseInsensitive )
608 && !layer.contains( mFilterString, Qt::CaseInsensitive )
609 && !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)
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()
Returns 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.
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,...