Merge pull request #38730 from 3nids/conf-flag-check-cb

Use a checkable combobox for fields configuration flags
This commit is contained in:
Denis Rouzaud 2020-09-16 07:02:17 +02:00 committed by GitHub
commit f6c98ec5f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 1367 additions and 1212 deletions

View File

@ -292,6 +292,7 @@ Formats string for display
%End %End
bool convertCompatible( QVariant &v ) const; bool convertCompatible( QVariant &v ) const;
%Docstring %Docstring
Converts the provided variant to a compatible format Converts the provided variant to a compatible format

View File

@ -1968,24 +1968,36 @@ Convenience function that returns the attribute alias if defined or the field na
Returns a map of field name to attribute alias Returns a map of field name to attribute alias
%End %End
QSet<QString> excludeAttributesWms() const; QSet<QString> excludeAttributesWms() const /Deprecated/;
%Docstring %Docstring
A set of attributes that are not advertised in WMS requests with QGIS server. A set of attributes that are not advertised in WMS requests with QGIS server.
.. deprecated:: QGIS 3.16
use fields().configurationFlags() instead
%End %End
void setExcludeAttributesWms( const QSet<QString> &att ); void setExcludeAttributesWms( const QSet<QString> &att ) /Deprecated/;
%Docstring %Docstring
A set of attributes that are not advertised in WMS requests with QGIS server. A set of attributes that are not advertised in WMS requests with QGIS server.
.. deprecated:: QGIS 3.16
use setFieldConfigurationFlag instead
%End %End
QSet<QString> excludeAttributesWfs() const; QSet<QString> excludeAttributesWfs() const /Deprecated/;
%Docstring %Docstring
A set of attributes that are not advertised in WFS requests with QGIS server. A set of attributes that are not advertised in WFS requests with QGIS server.
.. deprecated:: QGIS 3.16
use fields().configurationFlags() instead
%End %End
void setExcludeAttributesWfs( const QSet<QString> &att ); void setExcludeAttributesWfs( const QSet<QString> &att ) /Deprecated/;
%Docstring %Docstring
A set of attributes that are not advertised in WFS requests with QGIS server. A set of attributes that are not advertised in WFS requests with QGIS server.
.. deprecated:: QGIS 3.16
use setFieldConfigurationFlag instead
%End %End
virtual bool deleteAttribute( int attr ); virtual bool deleteAttribute( int attr );
@ -2294,6 +2306,7 @@ can also be set. Setting an empty expression will clear any existing expression
void setEditorWidgetSetup( int index, const QgsEditorWidgetSetup &setup ); void setEditorWidgetSetup( int index, const QgsEditorWidgetSetup &setup );
%Docstring %Docstring
\copydoc editorWidgetSetup \copydoc editorWidgetSetup

View File

@ -62,6 +62,15 @@ no items selected.
:param text: default text :param text: default text
.. seealso:: :py:func:`defaultText` .. seealso:: :py:func:`defaultText`
%End
void addItemWithCheckState( const QString &text, Qt::CheckState state, const QVariant &userData = QVariant() );
%Docstring
Adds an item to the combobox with the given ``text``, check ``state`` (stored in the Qt.CheckStateRole)
and containing the specified ``userData`` (stored in the Qt.UserRole).
The item is appended to the list of existing items.
.. versionadded:: 3.16
%End %End
QStringList checkedItems() const; QStringList checkedItems() const;
@ -113,6 +122,7 @@ Toggles the item check state
.. seealso:: :py:func:`setItemCheckState` .. seealso:: :py:func:`setItemCheckState`
%End %End
virtual void hidePopup(); virtual void hidePopup();
%Docstring %Docstring

View File

@ -346,6 +346,23 @@ QString QgsField::displayString( const QVariant &v ) const
return v.toString(); return v.toString();
} }
QString QgsField::readableConfigurationFlag( QgsField::ConfigurationFlag flag )
{
switch ( flag )
{
case ConfigurationFlag::None:
return QObject::tr( "None" );
case ConfigurationFlag::Searchable:
return QObject::tr( "Searchable" );
case ConfigurationFlag::ExposeViaWms:
return QStringLiteral( "Expose via WMS" );
case ConfigurationFlag::ExposeViaWfs:
return QStringLiteral( "Expose via WFS" );
case ConfigurationFlag::DefaultFlags:
return QObject::tr( "Default flags" );
}
}
/*************************************************************************** /***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with * This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfield.cpp. * full unit tests in testqgsfield.cpp.

View File

@ -80,8 +80,10 @@ class CORE_EXPORT QgsField
#endif #endif
{ {
None = 0, //!< No flag is defined None = 0, //!< No flag is defined
Searchable = 0x1, //!< Defines if the field is searchable (used in the locator search for instance) Searchable = 1 << 1, //!< Defines if the field is searchable (used in the locator search for instance)
DefaultFlags = Searchable, //!< Default set of flags for a field ExposeViaWms = 1 << 2, //!< Fields is available if layer is served as WMS from QGIS server
ExposeViaWfs = 1 << 3, //!< Fields is available if layer is served as WFS from QGIS server
DefaultFlags = Searchable | ExposeViaWms | ExposeViaWfs, //!< Default set of flags for a field
}; };
Q_ENUM( ConfigurationFlag ) Q_ENUM( ConfigurationFlag )
Q_DECLARE_FLAGS( ConfigurationFlags, ConfigurationFlag ) Q_DECLARE_FLAGS( ConfigurationFlags, ConfigurationFlag )
@ -327,6 +329,12 @@ class CORE_EXPORT QgsField
//! Formats string for display //! Formats string for display
QString displayString( const QVariant &v ) const; QString displayString( const QVariant &v ) const;
/**
* Returns the reabable and translated value of the configuration flag
* \since QGIS 3.16
*/
static QString readableConfigurationFlag( QgsField::ConfigurationFlag flag ) SIP_SKIP;
#ifndef SIP_RUN #ifndef SIP_RUN
/** /**

View File

@ -274,8 +274,6 @@ QgsVectorLayer *QgsVectorLayer::clone() const
layer->setMapTipTemplate( mapTipTemplate() ); layer->setMapTipTemplate( mapTipTemplate() );
layer->setReadOnly( isReadOnly() ); layer->setReadOnly( isReadOnly() );
layer->selectByIds( selectedFeatureIds() ); layer->selectByIds( selectedFeatureIds() );
layer->setExcludeAttributesWms( excludeAttributesWms() );
layer->setExcludeAttributesWfs( excludeAttributesWfs() );
layer->setAttributeTableConfig( attributeTableConfig() ); layer->setAttributeTableConfig( attributeTableConfig() );
layer->setFeatureBlendMode( featureBlendMode() ); layer->setFeatureBlendMode( featureBlendMode() );
layer->setOpacity( opacity() ); layer->setOpacity( opacity() );
@ -2306,29 +2304,6 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes
updateFields(); updateFields();
//Attributes excluded from WMS and WFS
mExcludeAttributesWMS.clear();
QDomNode excludeWMSNode = layerNode.namedItem( QStringLiteral( "excludeAttributesWMS" ) );
if ( !excludeWMSNode.isNull() )
{
QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( QStringLiteral( "attribute" ) );
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
}
}
mExcludeAttributesWFS.clear();
QDomNode excludeWFSNode = layerNode.namedItem( QStringLiteral( "excludeAttributesWFS" ) );
if ( !excludeWFSNode.isNull() )
{
QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( QStringLiteral( "attribute" ) );
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
}
}
// Load editor widget configuration // Load editor widget configuration
QDomElement widgetsElem = layerNode.namedItem( QStringLiteral( "fieldConfiguration" ) ).toElement(); QDomElement widgetsElem = layerNode.namedItem( QStringLiteral( "fieldConfiguration" ) ).toElement();
QDomNodeList fieldConfigurationElementList = widgetsElem.elementsByTagName( QStringLiteral( "field" ) ); QDomNodeList fieldConfigurationElementList = widgetsElem.elementsByTagName( QStringLiteral( "field" ) );
@ -2351,6 +2326,28 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes
QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( widgetType, optionsMap ); QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( widgetType, optionsMap );
mFieldWidgetSetups[fieldName] = setup; mFieldWidgetSetups[fieldName] = setup;
} }
// Legacy reading for QGIS 3.14 and older projects
// Attributes excluded from WMS and WFS
const QList<QPair<QString, QgsField::ConfigurationFlag>> legacyConfig
{
qMakePair( QStringLiteral( "excludeAttributesWMS" ), QgsField::ConfigurationFlag::ExposeViaWms ),
qMakePair( QStringLiteral( "excludeAttributesWFS" ), QgsField::ConfigurationFlag::ExposeViaWfs )
};
for ( const auto &config : legacyConfig )
{
QDomNode excludeNode = layerNode.namedItem( config.first );
if ( !excludeNode.isNull() )
{
QDomNodeList attributeNodeList = excludeNode.toElement().elementsByTagName( QStringLiteral( "attribute" ) );
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
QString fieldName = attributeNodeList.at( i ).toElement().text();
int index = mFields.indexFromName( fieldName );
setFieldConfigurationFlag( index, config.second, false );
}
}
}
} }
if ( categories.testFlag( GeometryOptions ) ) if ( categories.testFlag( GeometryOptions ) )
@ -2660,30 +2657,6 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString
} }
node.appendChild( aliasElem ); node.appendChild( aliasElem );
//exclude attributes WMS
QDomElement excludeWMSElem = doc.createElement( QStringLiteral( "excludeAttributesWMS" ) );
QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
{
QDomElement attrElem = doc.createElement( QStringLiteral( "attribute" ) );
QDomText attrText = doc.createTextNode( *attWMSIt );
attrElem.appendChild( attrText );
excludeWMSElem.appendChild( attrElem );
}
node.appendChild( excludeWMSElem );
//exclude attributes WFS
QDomElement excludeWFSElem = doc.createElement( QStringLiteral( "excludeAttributesWFS" ) );
QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
{
QDomElement attrElem = doc.createElement( QStringLiteral( "attribute" ) );
QDomText attrText = doc.createTextNode( *attWFSIt );
attrElem.appendChild( attrText );
excludeWFSElem.appendChild( attrElem );
}
node.appendChild( excludeWFSElem );
//default expressions //default expressions
QDomElement defaultsElem = doc.createElement( QStringLiteral( "defaults" ) ); QDomElement defaultsElem = doc.createElement( QStringLiteral( "defaults" ) );
for ( const QgsField &field : qgis::as_const( mFields ) ) for ( const QgsField &field : qgis::as_const( mFields ) )
@ -5487,12 +5460,19 @@ void QgsVectorLayer::setFieldConfigurationFlags( int index, QgsField::Configurat
if ( index < 0 || index >= mFields.count() ) if ( index < 0 || index >= mFields.count() )
return; return;
mFields.at( index ).setConfigurationFlags( flags );
mFieldConfigurationFlags.insert( mFields.at( index ).name(), flags ); mFieldConfigurationFlags.insert( mFields.at( index ).name(), flags );
updateFields(); updateFields();
} }
void QgsVectorLayer::setFieldConfigurationFlag( int index, QgsField::ConfigurationFlag flag, bool active )
{
if ( index < 0 || index >= mFields.count() )
return;
QgsField::ConfigurationFlags flags = mFields.at( index ).configurationFlags();
flags.setFlag( flag, active );
setFieldConfigurationFlags( index, flags );
}
QgsField::ConfigurationFlags QgsVectorLayer::fieldConfigurationFlags( int index ) const QgsField::ConfigurationFlags QgsVectorLayer::fieldConfigurationFlags( int index ) const
{ {

View File

@ -1839,23 +1839,27 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
/** /**
* A set of attributes that are not advertised in WMS requests with QGIS server. * A set of attributes that are not advertised in WMS requests with QGIS server.
* \deprecated since QGIS 3.16, use fields().configurationFlags() instead
*/ */
QSet<QString> excludeAttributesWms() const { return mExcludeAttributesWMS; } Q_DECL_DEPRECATED QSet<QString> excludeAttributesWms() const SIP_DEPRECATED { return mExcludeAttributesWMS; }
/** /**
* A set of attributes that are not advertised in WMS requests with QGIS server. * A set of attributes that are not advertised in WMS requests with QGIS server.
* \deprecated since QGIS 3.16, use setFieldConfigurationFlag instead
*/ */
void setExcludeAttributesWms( const QSet<QString> &att ) { mExcludeAttributesWMS = att; } Q_DECL_DEPRECATED void setExcludeAttributesWms( const QSet<QString> &att ) SIP_DEPRECATED { mExcludeAttributesWMS = att; }
/** /**
* A set of attributes that are not advertised in WFS requests with QGIS server. * A set of attributes that are not advertised in WFS requests with QGIS server.
* \deprecated since QGIS 3.16, use fields().configurationFlags() instead
*/ */
QSet<QString> excludeAttributesWfs() const { return mExcludeAttributesWFS; } Q_DECL_DEPRECATED QSet<QString> excludeAttributesWfs() const SIP_DEPRECATED { return mExcludeAttributesWFS; }
/** /**
* A set of attributes that are not advertised in WFS requests with QGIS server. * A set of attributes that are not advertised in WFS requests with QGIS server.
* \deprecated since QGIS 3.16, use setFieldConfigurationFlag instead
*/ */
void setExcludeAttributesWfs( const QSet<QString> &att ) { mExcludeAttributesWFS = att; } Q_DECL_DEPRECATED void setExcludeAttributesWfs( const QSet<QString> &att ) SIP_DEPRECATED { mExcludeAttributesWFS = att; }
/** /**
* Deletes an attribute field (but does not commit it). * Deletes an attribute field (but does not commit it).
@ -2122,6 +2126,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/ */
void setFieldConfigurationFlags( int index, QgsField::ConfigurationFlags flags ) SIP_SKIP; void setFieldConfigurationFlags( int index, QgsField::ConfigurationFlags flags ) SIP_SKIP;
/**
* Sets the given configuration \a flag for the field at given \a index to be \a active or not.
* \since QGIS 3.16
*/
void setFieldConfigurationFlag( int index, QgsField::ConfigurationFlag flag, bool active ) SIP_SKIP;
/** /**
* Returns the configuration flags of the field at given index * Returns the configuration flags of the field at given index
* \see QgsField::ConfigurationFlag * \see QgsField::ConfigurationFlag

View File

@ -77,8 +77,9 @@ void QgsCheckBoxDelegate::paint( QPainter *painter, const QStyleOptionViewItem &
QgsCheckableComboBox::QgsCheckableComboBox( QWidget *parent ) QgsCheckableComboBox::QgsCheckableComboBox( QWidget *parent )
: QComboBox( parent ) : QComboBox( parent )
, mSeparator( QStringLiteral( ", " ) ) , mSeparator( QStringLiteral( ", " ) )
, mModel( new QgsCheckableItemModel( this ) )
{ {
setModel( new QgsCheckableItemModel( this ) ); setModel( mModel );
setItemDelegate( new QgsCheckBoxDelegate( this ) ); setItemDelegate( new QgsCheckBoxDelegate( this ) );
QLineEdit *lineEdit = new QLineEdit( this ); QLineEdit *lineEdit = new QLineEdit( this );
@ -134,6 +135,12 @@ void QgsCheckableComboBox::setDefaultText( const QString &text )
} }
} }
void QgsCheckableComboBox::addItemWithCheckState( const QString &text, Qt::CheckState state, const QVariant &userData )
{
QComboBox::addItem( text, userData );
setItemCheckState( count() - 1, state );
}
QStringList QgsCheckableComboBox::checkedItems() const QStringList QgsCheckableComboBox::checkedItems() const
{ {
QStringList items; QStringList items;

View File

@ -163,6 +163,14 @@ class GUI_EXPORT QgsCheckableComboBox : public QComboBox
*/ */
void setDefaultText( const QString &text ); void setDefaultText( const QString &text );
/**
* Adds an item to the combobox with the given \a text, check \a state (stored in the Qt::CheckStateRole)
* and containing the specified \a userData (stored in the Qt::UserRole).
* The item is appended to the list of existing items.
* \since QGIS 3.16
*/
void addItemWithCheckState( const QString &text, Qt::CheckState state, const QVariant &userData = QVariant() );
/** /**
* Returns currently checked items. * Returns currently checked items.
* \see setCheckedItems() * \see setCheckedItems()
@ -201,6 +209,13 @@ class GUI_EXPORT QgsCheckableComboBox : public QComboBox
*/ */
void toggleItemCheckState( int index ); void toggleItemCheckState( int index );
/**
* Returns the custom item model which handles checking the items
* \see QgsCheckableItemModel
* \since QGIS 3.16
*/
QgsCheckableItemModel *model() const SIP_SKIP {return mModel;}
/** /**
* Hides the list of items in the combobox if it is currently * Hides the list of items in the combobox if it is currently
* visible and resets the internal state. * visible and resets the internal state.
@ -260,6 +275,8 @@ class GUI_EXPORT QgsCheckableComboBox : public QComboBox
QString mSeparator; QString mSeparator;
QString mDefaultText; QString mDefaultText;
QgsCheckableItemModel *mModel = nullptr;
bool mSkipHide = false; bool mSkipHide = false;
QMenu *mContextMenu = nullptr; QMenu *mContextMenu = nullptr;

View File

@ -15,6 +15,7 @@
***************************************************************************/ ***************************************************************************/
#include "qgsaddattrdialog.h" #include "qgsaddattrdialog.h"
#include "qgscheckablecombobox.h"
#include "qgssourcefieldsproperties.h" #include "qgssourcefieldsproperties.h"
#include "qgsvectorlayer.h" #include "qgsvectorlayer.h"
#include "qgsproject.h" #include "qgsproject.h"
@ -64,15 +65,9 @@ QgsSourceFieldsProperties::QgsSourceFieldsProperties( QgsVectorLayer *layer, QWi
mFieldsList->setHorizontalHeaderItem( AttrLengthCol, new QTableWidgetItem( tr( "Length" ) ) ); mFieldsList->setHorizontalHeaderItem( AttrLengthCol, new QTableWidgetItem( tr( "Length" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrPrecCol, new QTableWidgetItem( tr( "Precision" ) ) ); mFieldsList->setHorizontalHeaderItem( AttrPrecCol, new QTableWidgetItem( tr( "Precision" ) ) );
mFieldsList->setHorizontalHeaderItem( AttrCommentCol, new QTableWidgetItem( tr( "Comment" ) ) ); mFieldsList->setHorizontalHeaderItem( AttrCommentCol, new QTableWidgetItem( tr( "Comment" ) ) );
const auto wmsWi = new QTableWidgetItem( QStringLiteral( "WMS" ) ); const auto configurationFlagsWi = new QTableWidgetItem( QStringLiteral( "Configuration" ) );
wmsWi->setToolTip( tr( "Defines if this field is available in QGIS Server WMS service" ) ); configurationFlagsWi->setToolTip( tr( "Configures the field" ) );
mFieldsList->setHorizontalHeaderItem( AttrWMSCol, wmsWi ); mFieldsList->setHorizontalHeaderItem( AttrConfigurationFlagsCol, configurationFlagsWi );
const auto wfsWi = new QTableWidgetItem( QStringLiteral( "WFS" ) );
wfsWi->setToolTip( tr( "Defines if this field is available in QGIS Server WFS (and OAPIF) service" ) );
mFieldsList->setHorizontalHeaderItem( AttrWFSCol, wfsWi );
const auto searchableWi = new QTableWidgetItem( QStringLiteral( "Searchable" ) );
searchableWi->setToolTip( tr( "Defines if this field is searchable (active layer locator filter)" ) );
mFieldsList->setHorizontalHeaderItem( AttrSearchableCol, searchableWi );
mFieldsList->setHorizontalHeaderItem( AttrAliasCol, new QTableWidgetItem( tr( "Alias" ) ) ); mFieldsList->setHorizontalHeaderItem( AttrAliasCol, new QTableWidgetItem( tr( "Alias" ) ) );
mFieldsList->setSortingEnabled( true ); mFieldsList->setSortingEnabled( true );
@ -163,6 +158,9 @@ void QgsSourceFieldsProperties::attributeAdded( int idx )
for ( int i = 0; i < mFieldsList->columnCount(); i++ ) for ( int i = 0; i < mFieldsList->columnCount(); i++ )
{ {
if ( i == AttrConfigurationFlagsCol )
continue;
switch ( mLayer->fields().fieldOrigin( idx ) ) switch ( mLayer->fields().fieldOrigin( idx ) )
{ {
case QgsFields::OriginExpression: case QgsFields::OriginExpression:
@ -272,20 +270,19 @@ void QgsSourceFieldsProperties::setRow( int row, int idx, const QgsField &field
else else
mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() & ~Qt::ItemIsEditable ); mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() & ~Qt::ItemIsEditable );
//published WMS/WFS attributes // Flags
QTableWidgetItem *wmsAttrItem = new QTableWidgetItem(); QgsCheckableComboBox *cb = new QgsCheckableComboBox( mFieldsList );
wmsAttrItem->setCheckState( mLayer->excludeAttributesWms().contains( field.name() ) ? Qt::Unchecked : Qt::Checked ); const QList<QgsField::ConfigurationFlag> flagList = qgsEnumMap<QgsField::ConfigurationFlag>().keys();
wmsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ); for ( const QgsField::ConfigurationFlag flag : flagList )
mFieldsList->setItem( row, AttrWMSCol, wmsAttrItem ); {
QTableWidgetItem *wfsAttrItem = new QTableWidgetItem(); if ( flag == QgsField::ConfigurationFlag::None || flag == QgsField::ConfigurationFlag::DefaultFlags )
wfsAttrItem->setCheckState( mLayer->excludeAttributesWfs().contains( field.name() ) ? Qt::Unchecked : Qt::Checked ); continue;
wfsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
mFieldsList->setItem( row, AttrWFSCol, wfsAttrItem );
QTableWidgetItem *searchableAttrItem = new QTableWidgetItem();
searchableAttrItem->setCheckState( mLayer->fieldConfigurationFlags( idx ).testFlag( QgsField::ConfigurationFlag::Searchable ) ? Qt::Checked : Qt::Unchecked );
searchableAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
mFieldsList->setItem( row, AttrSearchableCol, searchableAttrItem );
cb->addItemWithCheckState( QgsField::readableConfigurationFlag( flag ),
mLayer->fieldConfigurationFlags( idx ).testFlag( flag ) ? Qt::Checked : Qt::Unchecked,
QVariant::fromValue( flag ) );
}
mFieldsList->setCellWidget( row, AttrConfigurationFlagsCol, cb );
} }
bool QgsSourceFieldsProperties::addAttribute( const QgsField &field ) bool QgsSourceFieldsProperties::addAttribute( const QgsField &field )
@ -307,34 +304,25 @@ bool QgsSourceFieldsProperties::addAttribute( const QgsField &field )
void QgsSourceFieldsProperties::apply() void QgsSourceFieldsProperties::apply()
{ {
QSet<QString> excludeAttributesWMS, excludeAttributesWFS;
for ( int i = 0; i < mFieldsList->rowCount(); i++ ) for ( int i = 0; i < mFieldsList->rowCount(); i++ )
{ {
if ( mFieldsList->item( i, AttrWMSCol )->checkState() == Qt::Unchecked )
{
excludeAttributesWMS.insert( mFieldsList->item( i, AttrNameCol )->text() );
}
if ( mFieldsList->item( i, AttrWFSCol )->checkState() == Qt::Unchecked )
{
excludeAttributesWFS.insert( mFieldsList->item( i, AttrNameCol )->text() );
}
int idx = mFieldsList->item( i, AttrIdCol )->data( Qt::DisplayRole ).toInt(); int idx = mFieldsList->item( i, AttrIdCol )->data( Qt::DisplayRole ).toInt();
QgsField::ConfigurationFlags flags = mLayer->fieldConfigurationFlags( idx ); QgsField::ConfigurationFlags flags = mLayer->fieldConfigurationFlags( idx );
if ( mFieldsList->item( i, AttrSearchableCol )->checkState() == Qt::Checked )
{
flags.setFlag( QgsField::ConfigurationFlag::Searchable, true );
}
else
{
flags.setFlag( QgsField::ConfigurationFlag::Searchable, false );
}
mLayer->setFieldConfigurationFlags( idx, flags );
}
mLayer->setExcludeAttributesWms( excludeAttributesWMS ); QgsCheckableComboBox *cb = qobject_cast<QgsCheckableComboBox *>( mFieldsList->cellWidget( i, AttrConfigurationFlagsCol ) );
mLayer->setExcludeAttributesWfs( excludeAttributesWFS ); if ( cb )
{
QgsCheckableItemModel *model = cb->model();
for ( int r = 0; r < model->rowCount(); ++r )
{
QModelIndex index = model->index( r, 0 );
QgsField::ConfigurationFlag flag = model->data( index, Qt::UserRole ).value<QgsField::ConfigurationFlag>();
bool active = model->data( index, Qt::CheckStateRole ).value<Qt::CheckState>() == Qt::Checked ? true : false;
flags.setFlag( flag, active );
}
mLayer->setFieldConfigurationFlags( idx, flags );
}
}
} }
//SLOTS //SLOTS

View File

@ -80,9 +80,7 @@ class GUI_EXPORT QgsSourceFieldsProperties : public QWidget, private Ui_QgsSourc
AttrLengthCol, AttrLengthCol,
AttrPrecCol, AttrPrecCol,
AttrCommentCol, AttrCommentCol,
AttrWMSCol, AttrConfigurationFlagsCol,
AttrWFSCol,
AttrSearchableCol,
AttrColCount, AttrColCount,
}; };

View File

@ -453,34 +453,38 @@ json QgsLandingPageUtils::projectInfo( const QString &projectUri )
wmsLayer[ "pk" ] = vl->primaryKeyAttributes(); wmsLayer[ "pk" ] = vl->primaryKeyAttributes();
int fieldIdx { 0 }; int fieldIdx { 0 };
json fieldsData; json fieldsData;
const auto &cFields { vl->fields() }; const QgsFields &cFields { vl->fields() };
for ( const auto &f : cFields ) for ( const QgsField &field : cFields )
{ {
// TODO: replace with non deprecated method and fix the tests
// if ( !field.configurationFlags().testFlag( QgsField::ConfigurationFlag::ExposeViaWfs ) )
Q_NOWARN_DEPRECATED_PUSH
if ( vl->excludeAttributesWfs().contains( vl->name() ) ) if ( vl->excludeAttributesWfs().contains( vl->name() ) )
{ {
++fieldIdx; ++fieldIdx;
continue; continue;
} }
const auto &constraints { f.constraints().constraints() }; Q_NOWARN_DEPRECATED_POP
const QgsFieldConstraints::Constraints constraints { field.constraints().constraints() };
const bool notNull { constraints &QgsFieldConstraints::Constraint::ConstraintNotNull && const bool notNull { constraints &QgsFieldConstraints::Constraint::ConstraintNotNull &&
f.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintNotNull ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintNotNull ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard };
const bool unique { constraints &QgsFieldConstraints::Constraint::ConstraintUnique && const bool unique { constraints &QgsFieldConstraints::Constraint::ConstraintUnique &&
f.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintUnique ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintUnique ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard };
const bool hasExpression { constraints &QgsFieldConstraints::Constraint::ConstraintExpression && const bool hasExpression { constraints &QgsFieldConstraints::Constraint::ConstraintExpression &&
f.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintExpression ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintExpression ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard };
const QString &defaultValue { vl->dataProvider()->defaultValueClause( fieldIdx ) }; const QString &defaultValue { vl->dataProvider()->defaultValueClause( fieldIdx ) };
const bool isReadOnly( notNull && unique && ! defaultValue.isEmpty() ); const bool isReadOnly( notNull && unique && ! defaultValue.isEmpty() );
fieldsData[ f.name().toStdString() ] = fieldsData[ field.name().toStdString() ] =
{ {
{ "type", f.typeName().toStdString() }, { "type", field.typeName().toStdString() },
{ "label", f.alias().isEmpty() ? f.name().toStdString() : f.alias().toStdString() }, { "label", field.alias().isEmpty() ? field.name().toStdString() : field.alias().toStdString() },
{ "precision", f.precision() }, { "precision", field.precision() },
{ "length", f.length() }, { "length", field.length() },
{ "unique", unique }, { "unique", unique },
{ "not_null", notNull }, { "not_null", notNull },
{ "has_expression", hasExpression }, { "has_expression", hasExpression },
{ "default", defaultValue.toStdString() }, { "default", defaultValue.toStdString() },
{ "expression", f.constraints().constraintExpression().toStdString() }, { "expression", field.constraints().constraintExpression().toStdString() },
{ "editable", !isReadOnly } { "editable", !isReadOnly }
}; };

View File

@ -262,13 +262,12 @@ namespace QgsWfs
//Attributes //Attributes
QgsFields fields = layer->fields(); QgsFields fields = layer->fields();
//hidden attributes for this layer //hidden attributes for this layer
const QSet<QString> &layerExcludedAttributes = layer->excludeAttributesWfs();
for ( int idx = 0; idx < fields.count(); ++idx ) for ( int idx = 0; idx < fields.count(); ++idx )
{ {
const QgsField field = fields.at( idx ); const QgsField field = fields.at( idx );
QString attributeName = field.name(); QString attributeName = field.name();
//skip attribute if excluded from WFS publication //skip attribute if excluded from WFS publication
if ( layerExcludedAttributes.contains( attributeName ) ) if ( !field.configurationFlags().testFlag( QgsField::ConfigurationFlag::ExposeViaWfs ) )
{ {
continue; continue;
} }

View File

@ -249,7 +249,7 @@ namespace QgsWfs
//Using pending attributes and pending fields //Using pending attributes and pending fields
QgsAttributeList attrIndexes = vlayer->attributeList(); QgsAttributeList attrIndexes = vlayer->attributeList();
QgsFields fields = vlayer->fields(); const QgsFields fields = vlayer->fields();
bool withGeom = true; bool withGeom = true;
if ( !propertyList.isEmpty() && propertyList.first() != QStringLiteral( "*" ) ) if ( !propertyList.isEmpty() && propertyList.first() != QStringLiteral( "*" ) )
{ {
@ -259,10 +259,10 @@ namespace QgsWfs
// build corresponding propertyname // build corresponding propertyname
QList<QString> propertynames; QList<QString> propertynames;
QList<QString> fieldnames; QList<QString> fieldnames;
for ( int idx = 0; idx < fields.count(); ++idx ) for ( const QgsField &field : fields )
{ {
fieldnames.append( fields[idx].name() ); fieldnames.append( field.name() );
propertynames.append( fields.field( idx ).name().replace( ' ', '_' ).replace( cleanTagNameRegExp, QString() ) ); propertynames.append( field.name().replace( ' ', '_' ).replace( cleanTagNameRegExp, QString() ) );
} }
QString fieldName; QString fieldName;
for ( plstIt = propertyList.constBegin(); plstIt != propertyList.constEnd(); ++plstIt ) for ( plstIt = propertyList.constBegin(); plstIt != propertyList.constEnd(); ++plstIt )
@ -289,20 +289,21 @@ namespace QgsWfs
} }
//excluded attributes for this layer //excluded attributes for this layer
const QSet<QString> &layerExcludedAttributes = vlayer->excludeAttributesWfs(); if ( !attrIndexes.isEmpty() )
if ( !attrIndexes.isEmpty() && !layerExcludedAttributes.isEmpty() )
{ {
foreach ( const QString &excludedAttribute, layerExcludedAttributes ) for ( const QgsField &field : fields )
{ {
int fieldNameIdx = fields.indexOf( excludedAttribute ); if ( !field.configurationFlags().testFlag( QgsField::ConfigurationFlag::ExposeViaWfs ) )
if ( fieldNameIdx > -1 && attrIndexes.contains( fieldNameIdx ) )
{ {
attrIndexes.removeOne( fieldNameIdx ); int fieldNameIdx = fields.indexOf( field.name() );
if ( fieldNameIdx > -1 && attrIndexes.contains( fieldNameIdx ) )
{
attrIndexes.removeOne( fieldNameIdx );
}
} }
} }
} }
// update request // update request
QgsFeatureRequest featureRequest = query.featureRequest; QgsFeatureRequest featureRequest = query.featureRequest;

View File

@ -242,13 +242,12 @@ QgsFields QgsWfs3AbstractItemsHandler::publishedFields( const QgsVectorLayer *vL
QStringList publishedAttributes = QStringList(); QStringList publishedAttributes = QStringList();
// Removed attributes // Removed attributes
// WFS excluded attributes for this layer // WFS excluded attributes for this layer
const QSet<QString> &layerExcludedAttributes = vLayer->excludeAttributesWfs();
const QgsFields &fields = vLayer->fields(); const QgsFields &fields = vLayer->fields();
for ( int i = 0; i < fields.count(); ++i ) for ( const QgsField &field : fields )
{ {
if ( ! layerExcludedAttributes.contains( fields.at( i ).name() ) ) if ( field.configurationFlags().testFlag( QgsField::ConfigurationFlag::ExposeViaWfs ) )
{ {
publishedAttributes.push_back( fields.at( i ).name() ); publishedAttributes.push_back( field.name() );
} }
} }

View File

@ -1862,7 +1862,6 @@ namespace QgsWms
case QgsMapLayerType::VectorLayer: case QgsMapLayerType::VectorLayer:
{ {
QgsVectorLayer *vLayer = static_cast<QgsVectorLayer *>( currentLayer ); QgsVectorLayer *vLayer = static_cast<QgsVectorLayer *>( currentLayer );
const QSet<QString> &excludedAttributes = vLayer->excludeAttributesWms();
int displayFieldIdx = -1; int displayFieldIdx = -1;
QString displayField = QStringLiteral( "maptip" ); QString displayField = QStringLiteral( "maptip" );
@ -1879,7 +1878,7 @@ namespace QgsWms
for ( int idx = 0; idx < layerFields.count(); ++idx ) for ( int idx = 0; idx < layerFields.count(); ++idx )
{ {
QgsField field = layerFields.at( idx ); QgsField field = layerFields.at( idx );
if ( excludedAttributes.contains( field.name() ) ) if ( !field.configurationFlags().testFlag( QgsField::ConfigurationFlag::ExposeViaWms ) )
{ {
continue; continue;
} }

View File

@ -1447,7 +1447,6 @@ namespace QgsWms
const QgsFields fields = layer->fields(); const QgsFields fields = layer->fields();
bool addWktGeometry = ( QgsServerProjectUtils::wmsFeatureInfoAddWktGeometry( *mProject ) && mWmsParameters.withGeometry() ); bool addWktGeometry = ( QgsServerProjectUtils::wmsFeatureInfoAddWktGeometry( *mProject ) && mWmsParameters.withGeometry() );
bool segmentizeWktGeometry = QgsServerProjectUtils::wmsFeatureInfoSegmentizeWktGeometry( *mProject ); bool segmentizeWktGeometry = QgsServerProjectUtils::wmsFeatureInfoSegmentizeWktGeometry( *mProject );
const QSet<QString> &excludedAttributes = layer->excludeAttributesWms();
bool hasGeometry = QgsServerProjectUtils::wmsFeatureInfoAddWktGeometry( *mProject ) || addWktGeometry || featureBBox || layerFilterGeom; bool hasGeometry = QgsServerProjectUtils::wmsFeatureInfoAddWktGeometry( *mProject ) || addWktGeometry || featureBBox || layerFilterGeom;
fReq.setFlags( ( ( hasGeometry ) ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) | QgsFeatureRequest::ExactIntersect ); fReq.setFlags( ( ( hasGeometry ) ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) | QgsFeatureRequest::ExactIntersect );
@ -1568,7 +1567,7 @@ namespace QgsWms
for ( int i = 0; i < featureAttributes.count(); ++i ) for ( int i = 0; i < featureAttributes.count(); ++i )
{ {
//skip attribute if it is explicitly excluded from WMS publication //skip attribute if it is explicitly excluded from WMS publication
if ( excludedAttributes.contains( fields.at( i ).name() ) ) if ( !fields.at( i ).configurationFlags().testFlag( QgsField::ConfigurationFlag::ExposeViaWms ) )
{ {
continue; continue;
} }
@ -2417,7 +2416,7 @@ namespace QgsWms
{ {
QString attributeName = fields.at( i ).name(); QString attributeName = fields.at( i ).name();
//skip attribute if it is explicitly excluded from WMS publication //skip attribute if it is explicitly excluded from WMS publication
if ( layer && layer->excludeAttributesWms().contains( attributeName ) ) if ( !fields.at( i ).configurationFlags().testFlag( QgsField::ConfigurationFlag::ExposeViaWms ) )
{ {
continue; continue;
} }

View File

@ -1,5 +1,5 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> <!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis saveUser="ale" version="3.13.0-Master" projectname="Project1 Title" saveUserFull="Alessandro Pasotti"> <qgis saveUserFull="Denis Rouzaud" version="3.15.0-Master" projectname="Project1 Title" saveUser="denis" saveDateTime="2020-09-15T16:25:28">
<homePath path=""/> <homePath path=""/>
<title>Project1 Title</title> <title>Project1 Title</title>
<autotransaction active="0"/> <autotransaction active="0"/>
@ -20,20 +20,20 @@
</projectCrs> </projectCrs>
<layer-tree-group> <layer-tree-group>
<customproperties/> <customproperties/>
<layer-tree-layer legend_exp="" name="points" providerKey="ogr" source="./project_data.gpkg|layername=points" expanded="1" id="points_842425df_7f45_4091_a6c9_086e1dc1edd1" checked="Qt::Checked"> <layer-tree-layer id="points_842425df_7f45_4091_a6c9_086e1dc1edd1" source="./project_data.gpkg|layername=points" legend_split_behavior="0" patch_size="0,0" name="points" checked="Qt::Checked" expanded="1" legend_exp="" providerKey="ogr">
<customproperties/> <customproperties/>
</layer-tree-layer> </layer-tree-layer>
<custom-order enabled="0"> <custom-order enabled="0">
<item>points_842425df_7f45_4091_a6c9_086e1dc1edd1</item> <item>points_842425df_7f45_4091_a6c9_086e1dc1edd1</item>
</custom-order> </custom-order>
</layer-tree-group> </layer-tree-group>
<snapping-settings type="1" tolerance="12" mode="2" unit="1" intersection-snapping="0" minScale="0" scaleDependencyMode="0" enabled="0" maxScale="0"> <snapping-settings unit="1" scaleDependencyMode="0" mode="2" tolerance="12" intersection-snapping="0" maxScale="0" type="1" enabled="0" minScale="0" self-snapping="0">
<individual-layer-settings> <individual-layer-settings>
<layer-setting type="1" tolerance="12" units="1" id="points_842425df_7f45_4091_a6c9_086e1dc1edd1" minScale="0" enabled="0" maxScale="0"/> <layer-setting id="points_842425df_7f45_4091_a6c9_086e1dc1edd1" tolerance="12" units="1" maxScale="0" type="1" enabled="0" minScale="0"/>
</individual-layer-settings> </individual-layer-settings>
</snapping-settings> </snapping-settings>
<relations/> <relations/>
<mapcanvas name="theMapCanvas" annotationsVisible="1"> <mapcanvas annotationsVisible="1" name="theMapCanvas">
<units>degrees</units> <units>degrees</units>
<extent> <extent>
<xmin>-23.31087998257129357</xmin> <xmin>-23.31087998257129357</xmin>
@ -58,17 +58,65 @@
<rendermaptile>0</rendermaptile> <rendermaptile>0</rendermaptile>
<expressionContextScope/> <expressionContextScope/>
</mapcanvas> </mapcanvas>
<projectModels/>
<legend updateDrawingOrder="true"> <legend updateDrawingOrder="true">
<legendlayer name="points" open="true" checked="Qt::Checked" drawingOrder="-1" showFeatureCount="0"> <legendlayer open="true" drawingOrder="-1" showFeatureCount="0" checked="Qt::Checked" name="points">
<filegroup hidden="false" open="true"> <filegroup open="true" hidden="false">
<legendlayerfile visible="1" isInOverview="0" layerid="points_842425df_7f45_4091_a6c9_086e1dc1edd1"/> <legendlayerfile layerid="points_842425df_7f45_4091_a6c9_086e1dc1edd1" isInOverview="0" visible="1"/>
</filegroup> </filegroup>
</legendlayer> </legendlayer>
</legend> </legend>
<mapViewDocks/> <mapViewDocks/>
<mapViewDocks3D/>
<main-annotation-layer refreshOnNotifyMessage="" refreshOnNotifyEnabled="0" autoRefreshEnabled="0" autoRefreshTime="0" type="annotation">
<id>Annotations_e424930a_3838_4a42_94ca_e28ac525201f</id>
<datasource></datasource>
<keywordList>
<value></value>
</keywordList>
<layername></layername>
<srs>
<spatialrefsys>
<wkt></wkt>
<proj4></proj4>
<srsid>0</srsid>
<srid>0</srid>
<authid></authid>
<description></description>
<projectionacronym></projectionacronym>
<ellipsoidacronym></ellipsoidacronym>
<geographicflag>false</geographicflag>
</spatialrefsys>
</srs>
<resourceMetadata>
<identifier></identifier>
<parentidentifier></parentidentifier>
<language></language>
<type></type>
<title></title>
<abstract></abstract>
<links/>
<fees></fees>
<encoding></encoding>
<crs>
<spatialrefsys>
<wkt></wkt>
<proj4></proj4>
<srsid>0</srsid>
<srid>0</srid>
<authid></authid>
<description></description>
<projectionacronym></projectionacronym>
<ellipsoidacronym></ellipsoidacronym>
<geographicflag>false</geographicflag>
</spatialrefsys>
</crs>
<extent/>
</resourceMetadata>
<items/>
<layerOpacity>1</layerOpacity>
</main-annotation-layer>
<projectlayers> <projectlayers>
<maplayer labelsEnabled="0" wkbType="Point" autoRefreshTime="0" styleCategories="AllStyleCategories" simplifyDrawingTol="1.2" simplifyDrawingHints="0" simplifyAlgorithm="0" type="vector" autoRefreshEnabled="0" simplifyMaxScale="1" refreshOnNotifyMessage="" minScale="100000000" refreshOnNotifyEnabled="0" geometry="Point" simplifyLocal="1" hasScaleBasedVisibilityFlag="0" readOnly="0" maxScale="0"> <maplayer wkbType="Point" simplifyDrawingHints="0" readOnly="0" simplifyLocal="1" autoRefreshTime="0" simplifyAlgorithm="0" labelsEnabled="0" maxScale="0" refreshOnNotifyMessage="" autoRefreshEnabled="0" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" geometry="Point" refreshOnNotifyEnabled="0" simplifyMaxScale="1" minScale="100000000" simplifyDrawingTol="1.2" type="vector">
<extent> <extent>
<xmin>-1.12365841865539995</xmin> <xmin>-1.12365841865539995</xmin>
<ymin>43.23918533325200286</ymin> <ymin>43.23918533325200286</ymin>
@ -85,7 +133,7 @@
</keywordList> </keywordList>
<dataUrl format="">http://data.url</dataUrl> <dataUrl format="">http://data.url</dataUrl>
<attribution href="http://attribution.url">Qgis Server Layer Properties Attribution</attribution> <attribution href="http://attribution.url">Qgis Server Layer Properties Attribution</attribution>
<metadataUrl format="text/plain" type="FGDC">http://metadata.url</metadataUrl> <metadataUrl type="FGDC" format="text/plain">http://metadata.url</metadataUrl>
<layername>points</layername> <layername>points</layername>
<srs> <srs>
<spatialrefsys> <spatialrefsys>
@ -129,7 +177,7 @@
<role>distributor</role> <role>distributor</role>
</contact> </contact>
<links> <links>
<link format="HTML" size="unknown" type="https" name="A link" url="https://www.itopen.it" mimeType="text/html" description="An interesting link"/> <link size="unknown" url="https://www.itopen.it" description="An interesting link" name="A link" type="https" mimeType="text/html" format="HTML"/>
</links> </links>
<history>Once upon a time ...</history> <history>Once upon a time ...</history>
<fees>None</fees> <fees>None</fees>
@ -151,7 +199,7 @@
</spatialrefsys> </spatialrefsys>
</crs> </crs>
<extent> <extent>
<spatial crs="EPSG:4326" minz="0" minx="-154.68031310999998595" miny="31.41943359400000091" maxx="-142.43476867699999389" maxy="40.44245529199999822" dimensions="2" maxz="0"/> <spatial maxy="40.44245529199999822" maxx="-142.43476867699999389" miny="31.41943359400000091" maxz="0" minx="-154.68031310999998595" minz="0" crs="EPSG:4326" dimensions="2"/>
<temporal> <temporal>
<period> <period>
<start></start> <start></start>
@ -175,10 +223,16 @@
<Removable>1</Removable> <Removable>1</Removable>
<Searchable>1</Searchable> <Searchable>1</Searchable>
</flags> </flags>
<renderer-v2 type="singleSymbol" symbollevels="0" forceraster="0" enableorderby="0"> <temporal durationField="" endField="" fixedDuration="0" startField="" mode="0" accumulate="0" endExpression="" durationUnit="min" enabled="0" startExpression="">
<fixedRange>
<start></start>
<end></end>
</fixedRange>
</temporal>
<renderer-v2 symbollevels="0" enableorderby="0" type="singleSymbol" forceraster="0">
<symbols> <symbols>
<symbol clip_to_extent="1" type="marker" name="0" force_rhr="0" alpha="1"> <symbol alpha="1" name="0" force_rhr="0" type="marker" clip_to_extent="1">
<layer locked="0" pass="0" enabled="1" class="SimpleMarker"> <layer class="SimpleMarker" pass="0" enabled="1" locked="0">
<prop v="0" k="angle"/> <prop v="0" k="angle"/>
<prop v="183,72,75,255" k="color"/> <prop v="183,72,75,255" k="color"/>
<prop v="1" k="horizontal_anchor_point"/> <prop v="1" k="horizontal_anchor_point"/>
@ -199,9 +253,9 @@
<prop v="1" k="vertical_anchor_point"/> <prop v="1" k="vertical_anchor_point"/>
<data_defined_properties> <data_defined_properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" value="" type="QString"/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" value="collection" type="QString"/>
</Option> </Option>
</data_defined_properties> </data_defined_properties>
</layer> </layer>
@ -219,16 +273,20 @@
<featureBlendMode>0</featureBlendMode> <featureBlendMode>0</featureBlendMode>
<layerOpacity>1</layerOpacity> <layerOpacity>1</layerOpacity>
<SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Histogram"> <SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Histogram">
<DiagramCategory sizeScale="3x:0,0,0,0,0,0" diagramOrientation="Up" backgroundColor="#ffffff" spacing="5" sizeType="MM" minScaleDenominator="0" scaleBasedVisibility="0" backgroundAlpha="255" penAlpha="255" spacingUnit="MM" spacingUnitScale="3x:0,0,0,0,0,0" labelPlacementMethod="XHeight" height="15" maxScaleDenominator="1e+08" enabled="0" minimumSize="0" showAxis="1" lineSizeType="MM" opacity="1" penWidth="0" penColor="#000000" barWidth="5" direction="0" lineSizeScale="3x:0,0,0,0,0,0" scaleDependency="Area" rotationOffset="270" width="15"> <DiagramCategory rotationOffset="270" penWidth="0" penColor="#000000" labelPlacementMethod="XHeight" spacing="5" direction="0" minimumSize="0" scaleBasedVisibility="0" minScaleDenominator="0" showAxis="1" spacingUnitScale="3x:0,0,0,0,0,0" maxScaleDenominator="1e+08" enabled="0" height="15" sizeType="MM" barWidth="5" diagramOrientation="Up" opacity="1" spacingUnit="MM" lineSizeScale="3x:0,0,0,0,0,0" backgroundAlpha="255" scaleDependency="Area" backgroundColor="#ffffff" width="15" penAlpha="255" lineSizeType="MM" sizeScale="3x:0,0,0,0,0,0">
<fontProperties style="Regular" description="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular"/> <fontProperties style="Regular" description="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular"/>
<attribute label="" field="" color="#000000"/> <attribute label="" color="#000000" field=""/>
<axisSymbol> <axisSymbol>
<symbol clip_to_extent="1" type="line" name="" force_rhr="0" alpha="1"> <symbol alpha="1" name="" force_rhr="0" type="line" clip_to_extent="1">
<layer locked="0" pass="0" enabled="1" class="SimpleLine"> <layer class="SimpleLine" pass="0" enabled="1" locked="0">
<prop v="0" k="align_dash_pattern"/>
<prop v="square" k="capstyle"/> <prop v="square" k="capstyle"/>
<prop v="5;2" k="customdash"/> <prop v="5;2" k="customdash"/>
<prop v="3x:0,0,0,0,0,0" k="customdash_map_unit_scale"/> <prop v="3x:0,0,0,0,0,0" k="customdash_map_unit_scale"/>
<prop v="MM" k="customdash_unit"/> <prop v="MM" k="customdash_unit"/>
<prop v="0" k="dash_pattern_offset"/>
<prop v="3x:0,0,0,0,0,0" k="dash_pattern_offset_map_unit_scale"/>
<prop v="MM" k="dash_pattern_offset_unit"/>
<prop v="0" k="draw_inside_polygon"/> <prop v="0" k="draw_inside_polygon"/>
<prop v="bevel" k="joinstyle"/> <prop v="bevel" k="joinstyle"/>
<prop v="35,35,35,255" k="line_color"/> <prop v="35,35,35,255" k="line_color"/>
@ -239,13 +297,14 @@
<prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/> <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
<prop v="MM" k="offset_unit"/> <prop v="MM" k="offset_unit"/>
<prop v="0" k="ring_filter"/> <prop v="0" k="ring_filter"/>
<prop v="0" k="tweak_dash_pattern_on_corners"/>
<prop v="0" k="use_custom_dash"/> <prop v="0" k="use_custom_dash"/>
<prop v="3x:0,0,0,0,0,0" k="width_map_unit_scale"/> <prop v="3x:0,0,0,0,0,0" k="width_map_unit_scale"/>
<data_defined_properties> <data_defined_properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" value="" type="QString"/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" value="collection" type="QString"/>
</Option> </Option>
</data_defined_properties> </data_defined_properties>
</layer> </layer>
@ -253,12 +312,12 @@
</axisSymbol> </axisSymbol>
</DiagramCategory> </DiagramCategory>
</SingleCategoryDiagramRenderer> </SingleCategoryDiagramRenderer>
<DiagramLayerSettings linePlacementFlags="18" dist="0" zIndex="0" priority="0" showAll="1" obstacle="0" placement="0"> <DiagramLayerSettings priority="0" showAll="1" obstacle="0" linePlacementFlags="18" zIndex="0" dist="0" placement="0">
<properties> <properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" value="" type="QString"/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" value="collection" type="QString"/>
</Option> </Option>
</properties> </properties>
</DiagramLayerSettings> </DiagramLayerSettings>
@ -267,16 +326,15 @@
<checkConfiguration/> <checkConfiguration/>
</geometryOptions> </geometryOptions>
<referencedLayers/> <referencedLayers/>
<referencingLayers/>
<fieldConfiguration> <fieldConfiguration>
<field name="fid"> <field name="fid" configurationFlags="DefaultFlags">
<editWidget type="TextEdit"> <editWidget type="TextEdit">
<config> <config>
<Option/> <Option/>
</config> </config>
</editWidget> </editWidget>
</field> </field>
<field name="name"> <field name="name" configurationFlags="DefaultFlags">
<editWidget type="TextEdit"> <editWidget type="TextEdit">
<config> <config>
<Option/> <Option/>
@ -285,32 +343,30 @@
</field> </field>
</fieldConfiguration> </fieldConfiguration>
<aliases> <aliases>
<alias name="" field="fid" index="0"/> <alias field="fid" index="0" name=""/>
<alias name="" field="name" index="1"/> <alias field="name" index="1" name=""/>
</aliases> </aliases>
<excludeAttributesWMS/>
<excludeAttributesWFS/>
<defaults> <defaults>
<default expression="" field="fid" applyOnUpdate="0"/> <default expression="" field="fid" applyOnUpdate="0"/>
<default expression="" field="name" applyOnUpdate="0"/> <default expression="" field="name" applyOnUpdate="0"/>
</defaults> </defaults>
<constraints> <constraints>
<constraint unique_strength="1" constraints="3" exp_strength="0" field="fid" notnull_strength="1"/> <constraint field="fid" exp_strength="0" constraints="3" notnull_strength="1" unique_strength="1"/>
<constraint unique_strength="0" constraints="0" exp_strength="0" field="name" notnull_strength="0"/> <constraint field="name" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
</constraints> </constraints>
<constraintExpressions> <constraintExpressions>
<constraint exp="" field="fid" desc=""/> <constraint desc="" exp="" field="fid"/>
<constraint exp="" field="name" desc=""/> <constraint desc="" exp="" field="name"/>
</constraintExpressions> </constraintExpressions>
<expressionfields/> <expressionfields/>
<attributeactions> <attributeactions>
<defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/> <defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
</attributeactions> </attributeactions>
<attributetableconfig sortExpression="" sortOrder="0" actionWidgetStyle="dropDown"> <attributetableconfig sortExpression="" actionWidgetStyle="dropDown" sortOrder="0">
<columns> <columns>
<column hidden="0" type="field" name="fid" width="-1"/> <column hidden="0" name="fid" width="-1" type="field"/>
<column hidden="0" type="field" name="name" width="-1"/> <column hidden="0" name="name" width="-1" type="field"/>
<column hidden="1" type="actions" width="-1"/> <column hidden="1" width="-1" type="actions"/>
</columns> </columns>
</attributetableconfig> </attributetableconfig>
<conditionalstyles> <conditionalstyles>
@ -342,8 +398,8 @@ def my_form_open(dialog, layer, feature):
<featformsuppress>0</featformsuppress> <featformsuppress>0</featformsuppress>
<editorlayout>generatedlayout</editorlayout> <editorlayout>generatedlayout</editorlayout>
<editable> <editable>
<field name="fid" editable="1"/> <field editable="1" name="fid"/>
<field name="name" editable="1"/> <field editable="1" name="name"/>
</editable> </editable>
<labelOnTop> <labelOnTop>
<field name="fid" labelOnTop="0"/> <field name="fid" labelOnTop="0"/>
@ -485,9 +541,16 @@ def my_form_open(dialog, layer, feature):
</WMTSPngLayers> </WMTSPngLayers>
<WMTSUrl type="QString"></WMTSUrl> <WMTSUrl type="QString"></WMTSUrl>
</properties> </properties>
<dataDefinedServerProperties>
<Option type="Map">
<Option name="name" value="" type="QString"/>
<Option name="properties"/>
<Option name="type" value="collection" type="QString"/>
</Option>
</dataDefinedServerProperties>
<visibility-presets/> <visibility-presets/>
<transformContext> <transformContext>
<srcDest allowFallback="1" coordinateOp="+proj=pipeline +step +inv +proj=sterea +lat_0=52.1561605555556 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +step +proj=push +v_3 +step +proj=cart +ellps=bessel +step +proj=helmert +x=565.2369 +y=50.0087 +z=465.658 +rx=0.406857330322398 +ry=-0.350732676542563 +rz=1.8703473836068 +s=4.0812 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg"> <srcDest coordinateOp="+proj=pipeline +step +inv +proj=sterea +lat_0=52.1561605555556 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +step +proj=push +v_3 +step +proj=cart +ellps=bessel +step +proj=helmert +x=565.2369 +y=50.0087 +z=465.658 +rx=0.406857330322398 +ry=-0.350732676542563 +rz=1.8703473836068 +s=4.0812 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg" allowFallback="1">
<src> <src>
<spatialrefsys> <spatialrefsys>
<wkt>PROJCRS["Amersfoort / RD New",BASEGEOGCRS["Amersfoort",DATUM["Amersfoort",ELLIPSOID["Bessel 1841",6377397.155,299.1528128,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4289]],CONVERSION["RD New",METHOD["Oblique Stereographic",ID["EPSG",9809]],PARAMETER["Latitude of natural origin",52.1561605555556,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",5.38763888888889,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9999079,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",155000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",463000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["Netherlands - onshore"],BBOX[50.75,3.2,53.7,7.22]],ID["EPSG",28992]]</wkt> <wkt>PROJCRS["Amersfoort / RD New",BASEGEOGCRS["Amersfoort",DATUM["Amersfoort",ELLIPSOID["Bessel 1841",6377397.155,299.1528128,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4289]],CONVERSION["RD New",METHOD["Oblique Stereographic",ID["EPSG",9809]],PARAMETER["Latitude of natural origin",52.1561605555556,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",5.38763888888889,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9999079,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",155000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",463000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["Netherlands - onshore"],BBOX[50.75,3.2,53.7,7.22]],ID["EPSG",28992]]</wkt>
@ -515,7 +578,7 @@ def my_form_open(dialog, layer, feature):
</spatialrefsys> </spatialrefsys>
</dest> </dest>
</srcDest> </srcDest>
<srcDest allowFallback="1" coordinateOp="+proj=pipeline +step +inv +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg"> <srcDest coordinateOp="+proj=pipeline +step +inv +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg" allowFallback="1">
<src> <src>
<spatialrefsys> <spatialrefsys>
<wkt>PROJCRS["ETRS89-extended / LAEA Europe",BASEGEOGCRS["ETRS89",DATUM["European Terrestrial Reference System 1989",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4258]],CONVERSION["Europe Equal Area 2001",METHOD["Lambert Azimuthal Equal Area",ID["EPSG",9820]],PARAMETER["Latitude of natural origin",52,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",10,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",4321000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",3210000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["northing (Y)",north,ORDER[1],LENGTHUNIT["metre",1]],AXIS["easting (X)",east,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["Europe - LCC &amp; LAEA"],BBOX[24.6,-35.58,84.17,44.83]],ID["EPSG",3035]]</wkt> <wkt>PROJCRS["ETRS89-extended / LAEA Europe",BASEGEOGCRS["ETRS89",DATUM["European Terrestrial Reference System 1989",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4258]],CONVERSION["Europe Equal Area 2001",METHOD["Lambert Azimuthal Equal Area",ID["EPSG",9820]],PARAMETER["Latitude of natural origin",52,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",10,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",4321000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",3210000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["northing (Y)",north,ORDER[1],LENGTHUNIT["metre",1]],AXIS["easting (X)",east,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["Europe - LCC &amp; LAEA"],BBOX[24.6,-35.58,84.17,44.83]],ID["EPSG",3035]]</wkt>
@ -573,7 +636,7 @@ def my_form_open(dialog, layer, feature):
<role>custodian</role> <role>custodian</role>
</contact> </contact>
<links> <links>
<link format="WTF" size="big" type="OpenSearch1.1:Description" name="link1" url="http://url.com" mimeType="application/octet-stream" description="A link"/> <link size="big" url="http://url.com" description="A link" name="link1" type="OpenSearch1.1:Description" mimeType="application/octet-stream" format="WTF"/>
</links> </links>
<history>History1</history> <history>History1</history>
<author>Alessandro Pasotti</author> <author>Alessandro Pasotti</author>
@ -585,18 +648,18 @@ def my_form_open(dialog, layer, feature):
<ProjectViewSettings UseProjectScales="0"> <ProjectViewSettings UseProjectScales="0">
<Scales/> <Scales/>
</ProjectViewSettings> </ProjectViewSettings>
<ProjectTimeSettings timeStepUnit="h" frameRate="1" timeStep="1"/> <ProjectTimeSettings frameRate="1" timeStep="1" cumulativeTemporalRange="0" timeStepUnit="h"/>
<ProjectDisplaySettings> <ProjectDisplaySettings>
<BearingFormat id="bearing"> <BearingFormat id="bearing">
<Option type="Map"> <Option type="Map">
<Option type="QChar" name="decimal_separator" value=""/> <Option name="decimal_separator" value="" type="QChar"/>
<Option type="int" name="decimals" value="6"/> <Option name="decimals" value="6" type="int"/>
<Option type="int" name="direction_format" value="0"/> <Option name="direction_format" value="0" type="int"/>
<Option type="int" name="rounding_type" value="0"/> <Option name="rounding_type" value="0" type="int"/>
<Option type="bool" name="show_plus" value="false"/> <Option name="show_plus" value="false" type="bool"/>
<Option type="bool" name="show_thousand_separator" value="true"/> <Option name="show_thousand_separator" value="true" type="bool"/>
<Option type="bool" name="show_trailing_zeros" value="false"/> <Option name="show_trailing_zeros" value="false" type="bool"/>
<Option type="QChar" name="thousand_separator" value=""/> <Option name="thousand_separator" value="" type="QChar"/>
</Option> </Option>
</BearingFormat> </BearingFormat>
</ProjectDisplaySettings> </ProjectDisplaySettings>