27#include <QAbstractListModel>
28#include <QInputDialog>
36 : QAbstractListModel( parent )
41int QgsVectorTileBasicRendererListModel::rowCount(
const QModelIndex &parent )
const
43 if ( parent.isValid() )
46 return mRenderer->styles().count();
49int QgsVectorTileBasicRendererListModel::columnCount(
const QModelIndex & )
const
54QVariant QgsVectorTileBasicRendererListModel::data(
const QModelIndex &index,
int role )
const
56 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
59 const QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
67 if ( index.column() == 0 )
69 else if ( index.column() == 1 )
70 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
71 else if ( index.column() == 2 )
73 else if ( index.column() == 3 )
75 else if ( index.column() == 4 )
76 return style.
filterExpression().isEmpty() ? tr(
"(no filter)" ) : style.filterExpression();
83 if ( index.column() == 0 )
85 else if ( index.column() == 1 )
87 else if ( index.column() == 2 )
89 else if ( index.column() == 3 )
91 else if ( index.column() == 4 )
97 case Qt::DecorationRole:
99 if ( index.column() == 0 && style.
symbol() )
107 case Qt::CheckStateRole:
109 if ( index.column() != 0 )
111 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
133QVariant QgsVectorTileBasicRendererListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
135 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
138 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
145Qt::ItemFlags QgsVectorTileBasicRendererListModel::flags(
const QModelIndex &index )
const
147 if ( !index.isValid() )
148 return Qt::ItemIsDropEnabled;
150 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
152 return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
153 Qt::ItemIsEditable | checkable |
154 Qt::ItemIsDragEnabled;
157bool QgsVectorTileBasicRendererListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
159 if ( !index.isValid() )
164 if ( role == Qt::CheckStateRole )
166 style.
setEnabled( value.toInt() == Qt::Checked );
167 mRenderer->setStyle( index.row(), style );
168 emit dataChanged( index, index );
172 if ( role == Qt::EditRole )
174 if ( index.column() == 0 )
176 else if ( index.column() == 1 )
178 else if ( index.column() == 2 )
180 else if ( index.column() == 3 )
182 else if ( index.column() == 4 )
185 mRenderer->setStyle( index.row(), style );
186 emit dataChanged( index, index );
193bool QgsVectorTileBasicRendererListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
195 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
197 if ( row < 0 || row >= styles.count() )
200 beginRemoveRows( parent, row, row + count - 1 );
202 for (
int i = 0; i < count; i++ )
204 if ( row < styles.count() )
206 styles.removeAt( row );
210 mRenderer->setStyles( styles );
218 beginInsertRows( QModelIndex(), row, row );
220 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
221 styles.insert( row, style );
222 mRenderer->setStyles( styles );
227Qt::DropActions QgsVectorTileBasicRendererListModel::supportedDropActions()
const
229 return Qt::MoveAction;
232QStringList QgsVectorTileBasicRendererListModel::mimeTypes()
const
235 types << QStringLiteral(
"application/vnd.text.list" );
239QMimeData *QgsVectorTileBasicRendererListModel::mimeData(
const QModelIndexList &indexes )
const
241 QMimeData *mimeData =
new QMimeData();
242 QByteArray encodedData;
244 QDataStream stream( &encodedData, QIODevice::WriteOnly );
246 const auto constIndexes = indexes;
247 for (
const QModelIndex &index : constIndexes )
250 if ( !index.isValid() || index.column() != 0 )
256 QDomElement rootElem = doc.createElement( QStringLiteral(
"vector_tile_basic_renderer_style_mime" ) );
258 doc.appendChild( rootElem );
260 stream << doc.toString( -1 );
263 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
267bool QgsVectorTileBasicRendererListModel::dropMimeData(
const QMimeData *data,
268 Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
272 if ( action == Qt::IgnoreAction )
275 if ( !data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
278 if ( parent.column() > 0 )
281 QByteArray encodedData = data->data( QStringLiteral(
"application/vnd.text.list" ) );
282 QDataStream stream( &encodedData, QIODevice::ReadOnly );
288 row = rowCount( parent );
291 while ( !stream.atEnd() )
297 if ( !doc.setContent( text ) )
299 const QDomElement rootElem = doc.documentElement();
300 if ( rootElem.tagName() != QLatin1String(
"vector_tile_basic_renderer_style_mime" ) )
306 insertStyle( row + rows, style );
318 , mMapCanvas( canvas )
319 , mMessageBar( messageBar )
322 layout()->setContentsMargins( 0, 0, 0, 0 );
324 mFilterLineEdit->setShowClearButton(
true );
325 mFilterLineEdit->setShowSearchIcon(
true );
326 mFilterLineEdit->setPlaceholderText( tr(
"Filter rules" ) );
328 QMenu *menuAddRule =
new QMenu( btnAddRule );
332 btnAddRule->setMenu( menuAddRule );
334 connect( btnEditRule, &QPushButton::clicked,
this, &QgsVectorTileBasicRendererWidget::editStyle );
335 connect( btnRemoveRule, &QAbstractButton::clicked,
this, &QgsVectorTileBasicRendererWidget::removeStyle );
337 connect( viewStyles, &QAbstractItemView::doubleClicked,
this, &QgsVectorTileBasicRendererWidget::editStyleAtIndex );
344 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
350 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
352 mProxyModel->setCurrentZoom( zoom );
356 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
357 mapSettings.destinationCrs(),
358 mapSettings.visibleExtent(),
359 mapSettings.outputSize(),
360 mapSettings.outputDpi() ) : mMapCanvas->
scale();
361 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
364 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [ = ](
bool filter )
366 mProxyModel->setFilterVisible( filter );
369 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [ = ](
const QString & text )
371 mProxyModel->setFilterString( text );
390 mModel =
new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles );
391 mProxyModel =
new QgsVectorTileBasicRendererProxyModel( mModel, viewStyles );
392 viewStyles->setModel( mProxyModel );
397 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
403 mProxyModel->setCurrentZoom( zoom );
411QgsVectorTileBasicRendererWidget::~QgsVectorTileBasicRendererWidget() =
default;
413void QgsVectorTileBasicRendererWidget::apply()
415 mVTLayer->setRenderer( mRenderer->clone() );
439 const int rows = mModel->rowCount();
440 mModel->insertStyle( rows, style );
441 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
444void QgsVectorTileBasicRendererWidget::editStyle()
446 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
449void QgsVectorTileBasicRendererWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
451 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
452 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
460 std::unique_ptr< QgsSymbol > symbol( style.
symbol()->
clone() );
469 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
499 if ( !dlg.exec() || !symbol )
505 mRenderer->setStyle( index.row(), style );
506 emit widgetChanged();
510void QgsVectorTileBasicRendererWidget::updateSymbolsFromWidget()
512 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
521 mRenderer->setStyle( index, style );
522 emit widgetChanged();
525void QgsVectorTileBasicRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
534void QgsVectorTileBasicRendererWidget::removeStyle()
536 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
539 for (
const QModelIndex &proxyIndex : sel )
541 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
542 if ( !res.contains( sourceIndex.row() ) )
543 res << sourceIndex.row();
545 std::sort( res.begin(), res.end() );
547 for (
int i = res.size() - 1; i >= 0; --i )
549 mModel->removeRow( res[ i ] );
552 viewStyles->selectionModel()->clear();
555QgsVectorTileBasicRendererProxyModel::QgsVectorTileBasicRendererProxyModel( QgsVectorTileBasicRendererListModel *source, QObject *parent )
556 : QSortFilterProxyModel( parent )
558 setSourceModel( source );
559 setDynamicSortFilter(
true );
562void QgsVectorTileBasicRendererProxyModel::setCurrentZoom(
int zoom )
568void QgsVectorTileBasicRendererProxyModel::setFilterVisible(
bool enabled )
570 mFilterVisible = enabled;
574void QgsVectorTileBasicRendererProxyModel::setFilterString(
const QString &
string )
576 mFilterString = string;
580bool QgsVectorTileBasicRendererProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
582 if ( mCurrentZoom >= 0 && mFilterVisible )
584 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MinZoom ).toInt();
585 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MaxZoom ).toInt();
587 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
590 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
594 if ( !mFilterString.isEmpty() )
596 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Label ).toString();
597 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Layer ).toString();
598 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::Filter ).toString();
599 if ( !name.contains( mFilterString, Qt::CaseInsensitive )
600 && !layer.contains( mFilterString, Qt::CaseInsensitive )
601 && !filter.contains( mFilterString, Qt::CaseInsensitive ) )
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.
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.
The class is used as a container of context for various read/write operations on other objects.
static QgsStyle * defaultStyle()
Returns default application-wide style.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
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.
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
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 minimum zoom level index (negative number means no limit)
int maxZoomLevel() const
Returns maxnimum 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.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
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,...