QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
qgspointcloudattributemodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudattributemodel.cpp
3 ---------------------
4 begin : November 2020
5 copyright : (C) 2020 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include "qgsapplication.h"
21#include "qgspointcloudindex.h"
22#include "qgspointcloudlayer.h"
23#include "qgsvariantutils.h"
24
25#include <QString>
26
27#include "moc_qgspointcloudattributemodel.cpp"
28
29using namespace Qt::StringLiterals;
30
34
36{
37 if ( layer )
38 {
39 mLayer = layer;
40 setAttributes( layer->attributes() );
41 }
42 else
43 {
44 mLayer = nullptr;
46 }
47}
48
53
55{
56 beginResetModel();
57 mAttributes = attributes;
58 endResetModel();
59}
60
62{
63 if ( allowEmpty == mAllowEmpty )
64 return;
65
66 if ( allowEmpty )
67 {
68 beginInsertRows( QModelIndex(), 0, 0 );
69 mAllowEmpty = true;
70 endInsertRows();
71 }
72 else
73 {
74 beginRemoveRows( QModelIndex(), 0, 0 );
75 mAllowEmpty = false;
76 endRemoveRows();
77 }
78}
79
80QModelIndex QgsPointCloudAttributeModel::indexFromName( const QString &name )
81{
82 if ( !name.isEmpty() )
83 {
84 const int idx = mAttributes.indexOf( name );
85 if ( idx >= 0 )
86 {
87 if ( mAllowEmpty )
88 return index( 1 + idx, 0 );
89 else
90 return index( idx, 0 );
91 }
92 }
93
94 if ( mAllowEmpty && name.isEmpty() )
95 return index( 0, 0 );
96
97 return QModelIndex();
98}
99
100QModelIndex QgsPointCloudAttributeModel::index( int row, int column, const QModelIndex &parent ) const
101{
102 if ( hasIndex( row, column, parent ) )
103 {
104 return createIndex( row, column, row );
105 }
106
107 return QModelIndex();
108}
109
110QModelIndex QgsPointCloudAttributeModel::parent( const QModelIndex &child ) const
111{
112 Q_UNUSED( child )
113 return QModelIndex();
114}
115
116int QgsPointCloudAttributeModel::rowCount( const QModelIndex &parent ) const
117{
118 if ( parent.isValid() )
119 {
120 return 0;
121 }
122
123 return ( mAllowEmpty ? 1 : 0 ) + mAttributes.count();
124}
125
127{
128 Q_UNUSED( parent )
129 return 1;
130}
131
132QVariant QgsPointCloudAttributeModel::data( const QModelIndex &index, int role ) const
133{
134 if ( !index.isValid() )
135 return QVariant();
136
137 const bool isEmpty = mAllowEmpty && index.row() == 0;
138 const int fieldOffset = mAllowEmpty ? 1 : 0;
139
140 if ( !isEmpty && ( index.row() - fieldOffset >= mAttributes.count() ) )
141 return QVariant();
142
143 switch ( role )
144 {
145 case static_cast< int >( CustomRole::AttributeName ):
146 {
147 if ( isEmpty )
148 {
149 return QVariant();
150 }
151 return mAttributes.at( index.row() - fieldOffset ).name();
152 }
153
154 case static_cast< int >( CustomRole::AttributeIndex ):
155 {
156 if ( isEmpty )
157 {
158 return QVariant();
159 }
160 return index.row() - fieldOffset;
161 }
162
163 case static_cast< int >( CustomRole::AttributeSize ):
164 {
165 if ( isEmpty )
166 {
167 return QVariant();
168 }
169 return static_cast< int >( mAttributes.at( index.row() - fieldOffset ).size() );
170 }
171
172 case static_cast< int >( CustomRole::AttributeType ):
173 {
174 if ( isEmpty )
175 {
176 return QVariant();
177 }
178 return static_cast< int >( mAttributes.at( index.row() - fieldOffset ).type() );
179 }
180
181 case static_cast< int >( CustomRole::IsEmpty ):
182 {
183 return isEmpty;
184 }
185
186 case static_cast< int >( CustomRole::IsNumeric ):
187 {
188 if ( isEmpty )
189 {
190 return QVariant();
191 }
192 return QgsPointCloudAttribute::isNumeric( mAttributes.at( index.row() - fieldOffset ).type() );
193 }
194
195 case Qt::DisplayRole:
196 case Qt::EditRole:
197 case Qt::ToolTipRole:
198 {
199 if ( isEmpty )
200 {
201 return QVariant();
202 }
203 else if ( role == Qt::ToolTipRole )
204 {
205 return attributeToolTip( mAttributes.at( index.row() - fieldOffset ) );
206 }
207 else
208 return mAttributes.at( index.row() - fieldOffset ).name();
209 }
210
211 case Qt::DecorationRole:
212 {
213 if ( !isEmpty )
214 {
215 return iconForAttributeType( mAttributes.at( index.row() - fieldOffset ).type() );
216 }
217 return QIcon();
218 }
219
220 default:
221 return QVariant();
222 }
223}
224
226{
227 QString toolTip = u"<b>%1</b>"_s.arg( attribute.name() );
228
229 toolTip += u"<br><font style='font-family:monospace; white-space: nowrap;'>%3</font>"_s.arg( attribute.displayType() );
230
231 return toolTip;
232}
233
235{
236 switch ( type )
237 {
246 {
247 return QgsApplication::getThemeIcon( "/mIconFieldInteger.svg" );
248 }
251 {
252 return QgsApplication::getThemeIcon( "/mIconFieldFloat.svg" );
253 }
254 }
255 return QIcon();
256}
257
258//
259// QgsPointCloudAttributeProxyModel
260//
261
263 : QSortFilterProxyModel( parent )
264 , mModel( source )
265{
266 setSourceModel( mModel );
267}
268
275
276bool QgsPointCloudAttributeProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
277{
278 const QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
279
280 if ( mFilters.testFlag( AllTypes ) )
281 return true;
282
283 const QVariant typeVar = mModel->data( index, static_cast< int >( QgsPointCloudAttributeModel::CustomRole::AttributeType ) );
284 if ( QgsVariantUtils::isNull( typeVar ) )
285 return true;
286
287 bool ok;
288 const QgsPointCloudAttribute::DataType type = static_cast< QgsPointCloudAttribute::DataType >( typeVar.toInt( &ok ) );
289 if ( !ok )
290 return true;
291
292 if ( ( mFilters.testFlag( Char ) && type == QgsPointCloudAttribute::Char )
293 || ( mFilters.testFlag( Char ) && type == QgsPointCloudAttribute::UChar )
294 || ( mFilters.testFlag( Short ) && type == QgsPointCloudAttribute::Short )
295 || ( mFilters.testFlag( Short ) && type == QgsPointCloudAttribute::UShort )
296 || ( mFilters.testFlag( Int32 ) && type == QgsPointCloudAttribute::Int32 )
297 || ( mFilters.testFlag( Int32 ) && type == QgsPointCloudAttribute::UInt32 )
298 || ( mFilters.testFlag( Int32 ) && type == QgsPointCloudAttribute::Int64 )
299 || ( mFilters.testFlag( Int32 ) && type == QgsPointCloudAttribute::UInt64 )
300 || ( mFilters.testFlag( Float ) && type == QgsPointCloudAttribute::Float )
301 || ( mFilters.testFlag( Double ) && type == QgsPointCloudAttribute::Double ) )
302 return true;
303
304 return false;
305}
306
307bool QgsPointCloudAttributeProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
308{
309 // empty field is always first
310 if ( sourceModel()->data( left, static_cast< int >( QgsPointCloudAttributeModel::CustomRole::IsEmpty ) ).toBool() )
311 return true;
312 else if ( sourceModel()->data( right, static_cast< int >( QgsPointCloudAttributeModel::CustomRole::IsEmpty ) ).toBool() )
313 return false;
314
315 // order is attribute order
316 bool lok, rok;
317 const int leftId = sourceModel()->data( left, static_cast< int >( QgsPointCloudAttributeModel::CustomRole::AttributeIndex ) ).toInt( &lok );
318 const int rightId = sourceModel()->data( right, static_cast< int >( QgsPointCloudAttributeModel::CustomRole::AttributeIndex ) ).toInt( &rok );
319
320 if ( !lok )
321 return false;
322 if ( !rok )
323 return true;
324
325 return leftId < rightId;
326}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A collection of point cloud attributes.
A model for display of available attributes from a point cloud.
QgsPointCloudAttributeCollection attributes() const
Returns the attributes associated with the model.
QModelIndex parent(const QModelIndex &child) const override
void setAllowEmptyAttributeName(bool allowEmpty)
Sets whether an optional empty attribute ("not set") option is present in the model.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
int columnCount(const QModelIndex &parent) const override
@ IsNumeric
true if the index corresponds to a numeric attributre
@ AttributeIndex
Attribute index if index corresponds to an attribute.
@ AttributeType
Attribute type, see QgsPointCloudAttribute::DataType.
@ IsEmpty
true if the index corresponds to the empty value
void setLayer(QgsPointCloudLayer *layer)
Sets the layer associated with the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
QgsPointCloudAttributeModel(QObject *parent=nullptr)
Constructor for QgsPointCloudAttributeModel, with the specified parent object.
void setAttributes(const QgsPointCloudAttributeCollection &attributes)
Sets the attributes to include in the model.
static QString attributeToolTip(const QgsPointCloudAttribute &attribute)
Returns a HTML formatted tooltip string for a attribute, containing details like the attribute name a...
QModelIndex indexFromName(const QString &name)
Returns the index corresponding to a given attribute name.
QgsPointCloudLayer * layer()
Returns the layer associated with the model.
static QIcon iconForAttributeType(QgsPointCloudAttribute::DataType type)
Returns an icon corresponding to an attribute type.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
Filters filters() const
Returns the filters controlling displayed attributes.
QgsPointCloudAttributeProxyModel * setFilters(QgsPointCloudAttributeProxyModel::Filters filters)
Set flags that affect how fields are filtered in the model.
QgsPointCloudAttributeProxyModel(QgsPointCloudAttributeModel *source, QObject *parent=nullptr)
Constructor for QgsPointCloudAttributeProxyModel, with the specified source model and parent object.
Attribute for point cloud data pair of name and size in bytes.
DataType
Systems of unit measurement.
@ UShort
Unsigned short int 2 bytes.
@ UChar
Unsigned char 1 byte.
@ UInt32
Unsigned int32 4 bytes.
@ UInt64
Unsigned int64 8 bytes.
static bool isNumeric(DataType type)
Returns true if the specified data type is numeric.
QString displayType() const
Returns the type to use when displaying this field.
QString name() const
Returns name of the attribute.
Represents a map layer supporting display of point clouds.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.