void TestQgsFields::clear() { QgsFields original; QgsField field( "testfield" ); original.append( field ); QCOMPARE( original.count(), 1 ); QgsFields copy( original ); copy.clear(); QCOMPARE( copy.count(), 0 ); QCOMPARE( original.count(), 1 ); }
QString QgsZonalStatistics::getUniqueFieldName( const QString& fieldName ) { QgsVectorDataProvider* dp = mPolygonLayer->dataProvider(); if ( !dp->storageType().contains( QLatin1String( "ESRI Shapefile" ) ) ) { return fieldName; } QgsFields providerFields = dp->fields(); QString shortName = fieldName.mid( 0, 10 ); bool found = false; for ( int idx = 0; idx < providerFields.count(); ++idx ) { if ( shortName == providerFields.at( idx ).name() ) { found = true; break; } } if ( !found ) { return shortName; } int n = 1; shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n ); found = true; while ( found ) { found = false; for ( int idx = 0; idx < providerFields.count(); ++idx ) { if ( shortName == providerFields.at( idx ).name() ) { n += 1; if ( n < 9 ) { shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n ); } else { shortName = QStringLiteral( "%1_%2" ).arg( fieldName.mid( 0, 7 ) ).arg( n ); } found = true; } } } return shortName; }
void QgsFeatureAction::onFeatureSaved( const QgsFeature& feature ) { QgsAttributeForm* form = qobject_cast<QgsAttributeForm*>( sender() ); Q_UNUSED( form ) // only used for Q_ASSERT Q_ASSERT( form ); // Assign provider generated values if ( mFeature ) *mFeature = feature; mFeatureSaved = true; QSettings settings; bool reuseLastValues = settings.value( "/qgis/digitizing/reuseLastValues", false ).toBool(); QgsDebugMsg( QString( "reuseLastValues: %1" ).arg( reuseLastValues ) ); if ( reuseLastValues ) { QgsFields fields = mLayer->fields(); for ( int idx = 0; idx < fields.count(); ++idx ) { QgsAttributes newValues = feature.attributes(); QgsAttributeMap origValues = sLastUsedValues[ mLayer ]; if ( origValues[idx] != newValues.at( idx ) ) { QgsDebugMsg( QString( "saving %1 for %2" ).arg( sLastUsedValues[ mLayer ][idx].toString() ).arg( idx ) ); sLastUsedValues[ mLayer ][idx] = newValues.at( idx ); } } } }
void TestQgsFields::count() { QgsFields fields; QCOMPARE( fields.count(), 0 ); QCOMPARE( fields.size(), 0 ); QgsField field( "testfield" ); fields.append( field ); QCOMPARE( fields.count(), 1 ); QCOMPARE( fields.size(), 1 ); QgsField field2( "testfield2" ); fields.append( field2 ); QCOMPARE( fields.count(), 2 ); QCOMPARE( fields.size(), 2 ); }
void QgsFields::extend( const QgsFields &other ) { for ( int i = 0; i < other.count(); ++i ) { append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) ); } }
void TestQgsFields::assignment() { QgsFields original; //add field QgsField field( QStringLiteral( "testfield" ) ); original.append( field ); QgsFields copy; copy = original; QVERIFY( copy == original ); QgsField copyfield( QStringLiteral( "copyfield" ) ); copy.append( copyfield ); QCOMPARE( original.count(), 1 ); QCOMPARE( copy.count(), 2 ); QVERIFY( copy != original ); }
QgsFieldConstraints::Constraints QgsVectorDataProvider::fieldConstraints( int fieldIndex ) const { QgsFields f = fields(); if ( fieldIndex < 0 || fieldIndex >= f.count() ) return nullptr; return f.at( fieldIndex ).constraints().constraints(); }
void TestQgsFields::copy() { QgsFields original; //add field QgsField field( "testfield" ); original.append( field ); QCOMPARE( original.count(), 1 ); QgsFields copy( original ); QCOMPARE( copy.count(), 1 ); QVERIFY( copy == original ); QgsField copyfield( "copyfield" ); copy.append( copyfield ); QCOMPARE( copy.count(), 2 ); QCOMPARE( original.count(), 1 ); QVERIFY( copy != original ); }
QgsDataDefinedSymbolDialog::QgsDataDefinedSymbolDialog( const QMap< QString, QPair< QString, QString > >& properties, const QgsVectorLayer* vl, QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f ), mVectorLayer( vl ) { setupUi( this ); QgsFields attributeFields; if ( mVectorLayer ) { attributeFields = mVectorLayer->pendingFields(); } mTableWidget->setRowCount( properties.size() ); int i = 0; QMap< QString, QPair< QString, QString > >::const_iterator it = properties.constBegin(); for ( ; it != properties.constEnd(); ++it ) { //check box QCheckBox* cb = new QCheckBox( this ); cb->setChecked( !it.value().second.isEmpty() ); mTableWidget->setCellWidget( i, 0, cb ); mTableWidget->setColumnWidth( 0, cb->width() ); //property name QTableWidgetItem* propertyItem = new QTableWidgetItem( it.value().first ); propertyItem->setData( Qt::UserRole, it.key() ); mTableWidget->setItem( i, 1, propertyItem ); //attribute list QString expressionString = it.value().second; QComboBox* attributeComboBox = new QComboBox( this ); attributeComboBox->addItem( QString() ); for ( int j = 0; j < attributeFields.count(); ++j ) { attributeComboBox->addItem( attributeFields.at( j ).name() ); } int attrComboIndex = comboIndexForExpressionString( expressionString, attributeComboBox ); if ( attrComboIndex >= 0 ) { attributeComboBox->setCurrentIndex( attrComboIndex ); } else { attributeComboBox->setItemText( 0, expressionString ); } mTableWidget->setCellWidget( i, 2, attributeComboBox ); //expression button QPushButton* expressionButton = new QPushButton( "...", this ); QObject::connect( expressionButton, SIGNAL( clicked() ), this, SLOT( expressionButtonClicked() ) ); mTableWidget->setCellWidget( i, 3, expressionButton ); ++i; } }
QgsFeature::QgsFeature( const QgsFields &fields, QgsFeatureId id ) : mFid( id ) , mGeometry( 0 ) , mOwnsGeometry( 0 ) , mValid( false ) , mFields( &fields ) { initAttributes( fields.count() ); }
QSet<QString> QgsDiagramLayerSettings::referencedFields( const QgsExpressionContext &context, const QgsFields& fieldsParameter ) const { QSet< QString > referenced; if ( renderer ) referenced = renderer->referencedFields( context, fieldsParameter ); //and the ones needed for data defined diagram positions if ( xPosColumn >= 0 && xPosColumn < fieldsParameter.count() ) referenced << fieldsParameter.at( xPosColumn ).name(); if ( yPosColumn >= 0 && yPosColumn < fieldsParameter.count() ) referenced << fieldsParameter.at( yPosColumn ).name(); // and the ones needed for data defined diagram visibility if ( showColumn >= 0 && showColumn < fieldsParameter.count() ) referenced << fieldsParameter.at( showColumn ).name(); return referenced; }
void QgsAtlasComposition::readXml( const QDomElement& atlasElem, const QDomDocument& ) { mEnabled = atlasElem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) ? true : false; emit toggled( mEnabled ); if ( !mEnabled ) { emit parameterChanged(); return; } // look for stored layer name mCoverageLayer = nullptr; QMap<QString, QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers(); for ( QMap<QString, QgsMapLayer*>::const_iterator it = layers.begin(); it != layers.end(); ++it ) { if ( it.key() == atlasElem.attribute( QStringLiteral( "coverageLayer" ) ) ) { mCoverageLayer = dynamic_cast<QgsVectorLayer*>( it.value() ); break; } } mPageNameExpression = atlasElem.attribute( QStringLiteral( "pageNameExpression" ), QString() ); mSingleFile = atlasElem.attribute( QStringLiteral( "singleFile" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) ? true : false; mFilenamePattern = atlasElem.attribute( QStringLiteral( "filenamePattern" ), QLatin1String( "" ) ); mSortFeatures = atlasElem.attribute( QStringLiteral( "sortFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) ? true : false; if ( mSortFeatures ) { mSortKeyAttributeName = atlasElem.attribute( QStringLiteral( "sortKey" ), QLatin1String( "" ) ); // since 2.3, the field name is saved instead of the field index // following code keeps compatibility with version 2.2 projects // to be removed in QGIS 3.0 bool isIndex; int idx = mSortKeyAttributeName.toInt( &isIndex ); if ( isIndex && mCoverageLayer ) { QgsFields fields = mCoverageLayer->fields(); if ( idx >= 0 && idx < fields.count() ) { mSortKeyAttributeName = fields.at( idx ).name(); } } mSortAscending = atlasElem.attribute( QStringLiteral( "sortAscending" ), QStringLiteral( "true" ) ) == QLatin1String( "true" ) ? true : false; } mFilterFeatures = atlasElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) ? true : false; if ( mFilterFeatures ) { mFeatureFilter = atlasElem.attribute( QStringLiteral( "featureFilter" ), QLatin1String( "" ) ); } mHideCoverage = atlasElem.attribute( QStringLiteral( "hideCoverage" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) ? true : false; emit parameterChanged(); }
void QgsOverlayAnalyzer::combineFieldLists( QgsFields& fieldListA, const QgsFields& fieldListB ) { QList<QString> names; for ( int idx = 0; idx < fieldListA.count(); ++idx ) names.append( fieldListA.at( idx ).name() ); for ( int idx = 0; idx < fieldListB.count(); ++idx ) { QgsField field = fieldListB[idx]; int count = 0; while ( names.contains( field.name() ) ) { QString name = QString( "%1_%2" ).arg( field.name() ).arg( count ); field = QgsField( name, field.type() ); ++count; } fieldListA.append( field ); names.append( field.name() ); } }
void TestQgsFields::extend() { QgsFields destination; QgsField field( "testfield" ); destination.append( field ); QgsField field2( "testfield2" ); destination.append( field2 ); QgsFields source; QgsField field3( "testfield3" ); source.append( field3, QgsFields::OriginJoin, 5 ); QgsField field4( "testfield4" ); source.append( field4 ); QCOMPARE( destination.count(), 2 ); destination.extend( source ); QCOMPARE( destination.count(), 4 ); QCOMPARE( destination.at( 2 ), field3 ); QCOMPARE( destination.at( 3 ), field4 ); }
bool QgsOgrUtils::readOgrFeatureAttributes( OGRFeatureH ogrFet, const QgsFields& fields, QgsFeature& feature, QTextCodec* encoding ) { // read all attributes feature.initAttributes( fields.count() ); feature.setFields( fields ); if ( !ogrFet ) return false; bool ok = false; for ( int idx = 0; idx < fields.count(); ++idx ) { QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok ); if ( ok ) { feature.setAttribute( idx, value ); } } return true; }
QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const { QMap<QString, int> resultMap; QgsFields theFields = fields(); for ( int i = 0; i < theFields.count(); ++i ) { resultMap.insert( theFields.at( i ).name(), i ); } return resultMap; }
void QgsAtlasComposition::readXml( const QDomElement &atlasElem, const QDomDocument & ) { mEnabled = atlasElem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ); emit toggled( mEnabled ); if ( !mEnabled ) { emit parameterChanged(); return; } // look for stored layer name QString layerId = atlasElem.attribute( QStringLiteral( "coverageLayer" ) ); QString layerName = atlasElem.attribute( QStringLiteral( "coverageLayerName" ) ); QString layerSource = atlasElem.attribute( QStringLiteral( "coverageLayerSource" ) ); QString layerProvider = atlasElem.attribute( QStringLiteral( "coverageLayerProvider" ) ); mCoverageLayer = QgsVectorLayerRef( layerId, layerName, layerSource, layerProvider ); mCoverageLayer.resolveWeakly( mComposition->project() ); mPageNameExpression = atlasElem.attribute( QStringLiteral( "pageNameExpression" ), QString() ); mSingleFile = atlasElem.attribute( QStringLiteral( "singleFile" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ); mFilenamePattern = atlasElem.attribute( QStringLiteral( "filenamePattern" ), QLatin1String( "" ) ); mSortFeatures = atlasElem.attribute( QStringLiteral( "sortFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ); if ( mSortFeatures ) { mSortKeyAttributeName = atlasElem.attribute( QStringLiteral( "sortKey" ), QLatin1String( "" ) ); // since 2.3, the field name is saved instead of the field index // following code keeps compatibility with version 2.2 projects // to be removed in QGIS 3.0 bool isIndex; int idx = mSortKeyAttributeName.toInt( &isIndex ); if ( isIndex && mCoverageLayer ) { QgsFields fields = mCoverageLayer->fields(); if ( idx >= 0 && idx < fields.count() ) { mSortKeyAttributeName = fields.at( idx ).name(); } } mSortAscending = atlasElem.attribute( QStringLiteral( "sortAscending" ), QStringLiteral( "true" ) ) == QLatin1String( "true" ); } mFilterFeatures = atlasElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ); if ( mFilterFeatures ) { mFeatureFilter = atlasElem.attribute( QStringLiteral( "featureFilter" ), QLatin1String( "" ) ); } mHideCoverage = atlasElem.attribute( QStringLiteral( "hideCoverage" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ); emit parameterChanged(); }
void QgsAtlasComposition::setSortKeyAttributeIndex( int idx ) { if ( mCoverageLayer ) { QgsFields fields = mCoverageLayer->fields(); if ( idx >= 0 && idx < fields.count() ) { mSortKeyAttributeName = fields.at( idx ).name(); return; } } mSortKeyAttributeName = ""; }
void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement& layerElem, QDomDocument& doc ) const { if ( mapLayer->type() != QgsMapLayer::VectorLayer ) { return; } QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer*>( mapLayer ); if ( !vectorLayer ) { return; } QDomNode editTypesNode = doc.createElement( "edittypes" ); QgsFields fields = vectorLayer->fields(); for ( int idx = 0; idx < fields.count(); ++idx ) { QgsField field = fields.at( idx ); const QString& widgetType = vectorLayer->editFormConfig()->widgetType( idx ); if ( !mWidgetFactories.contains( widgetType ) ) { QgsMessageLog::logMessage( tr( "Could not save unknown editor widget type '%1'." ).arg( widgetType ) ); continue; } QDomElement editTypeElement = doc.createElement( "edittype" ); editTypeElement.setAttribute( "name", field.name() ); editTypeElement.setAttribute( "widgetv2type", widgetType ); if ( mWidgetFactories.contains( widgetType ) ) { QDomElement ewv2CfgElem = doc.createElement( "widgetv2config" ); ewv2CfgElem.setAttribute( "fieldEditable", !vectorLayer->editFormConfig()->readOnly( idx ) ); ewv2CfgElem.setAttribute( "labelOnTop", vectorLayer->editFormConfig()->labelOnTop( idx ) ); ewv2CfgElem.setAttribute( "notNull", vectorLayer->editFormConfig()->notNull( idx ) ); ewv2CfgElem.setAttribute( "constraint", vectorLayer->editFormConfig()->expression( idx ) ); ewv2CfgElem.setAttribute( "constraintDescription", vectorLayer->editFormConfig()->expressionDescription( idx ) ); mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig()->widgetConfig( idx ), ewv2CfgElem, doc, vectorLayer, idx ); editTypeElement.appendChild( ewv2CfgElem ); } editTypesNode.appendChild( editTypeElement ); } layerElem.appendChild( editTypesNode ); }
void QgsFeatureAction::updateLastUsedValues( const QgsFeature& feature ) { QgsAttributeForm* form = qobject_cast<QgsAttributeForm*>( sender() ); Q_ASSERT( form ); QgsFields fields = mLayer->pendingFields(); for ( int idx = 0; idx < fields.count(); ++idx ) { const QgsAttributes &newValues = feature.attributes(); QgsAttributeMap origValues = sLastUsedValues[ mLayer ]; if ( origValues[idx] != newValues[idx] ) { QgsDebugMsg( QString( "saving %1 for %2" ).arg( sLastUsedValues[ mLayer ][idx].toString() ).arg( idx ) ); sLastUsedValues[ mLayer ][idx] = newValues[idx]; } } }
void TestQgsFields::appendExpressionField() { QgsFields fields; QgsField field( QString( "testfield" ) ); fields.append( field ); QgsField field2( QString( "testfield2" ) ); fields.append( field2 ); QgsField dupeName( QString( "testfield" ) ); QVERIFY( !fields.appendExpressionField( dupeName, 1 ) ); //good name QgsField exprField( QString( "expression" ) ); QVERIFY( fields.appendExpressionField( exprField, 5 ) ); QCOMPARE( fields.count(), 3 ); QCOMPARE( fields.fieldOrigin( 2 ), QgsFields::OriginExpression ); QCOMPARE( fields.fieldOriginIndex( 2 ), 5 ); }
void TestQgsFields::remove() { QgsFields fields; //test for no crash fields.remove( 1 ); QgsField field( "testfield" ); fields.append( field ); QgsField field2( "testfield2" ); fields.append( field2 ); //test for no crash fields.remove( -1 ); fields.remove( 5 ); //remove valid field fields.remove( 0 ); QCOMPARE( fields.count(), 1 ); QCOMPARE( fields.at( 0 ).name(), QString( "testfield2" ) ); QCOMPARE( fields.indexFromName( "testfield2" ), 0 ); }
QWidget *QgsFormAnnotation::createDesignerWidget( const QString &filePath ) { QFile file( filePath ); if ( !file.open( QFile::ReadOnly ) ) { return nullptr; } QUiLoader loader; QFileInfo fi( file ); loader.setWorkingDirectory( fi.dir() ); QWidget *widget = loader.load( &file, nullptr ); file.close(); //get feature and set attribute information QgsAttributeEditorContext context; QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mapLayer() ); if ( vectorLayer && associatedFeature().isValid() ) { QgsFields fields = vectorLayer->fields(); QgsAttributes attrs = associatedFeature().attributes(); for ( int i = 0; i < attrs.count(); ++i ) { if ( i < fields.count() ) { QWidget *attWidget = widget->findChild<QWidget *>( fields.at( i ).name() ); if ( attWidget ) { QgsEditorWidgetWrapper *eww = QgsGui::editorWidgetRegistry()->create( vectorLayer, i, attWidget, widget, context ); if ( eww ) { eww->setValue( attrs.at( i ) ); } } } } } return widget; }
QgsAttributeActionDialog::QgsAttributeActionDialog( QgsAttributeAction* actions, const QgsFields& fields, QWidget* parent ): QWidget( parent ), mActions( actions ) { setupUi( this ); QHeaderView *header = attributeActionTable->horizontalHeader(); header->setHighlightSections( false ); header->setStretchLastSection( true ); attributeActionTable->setColumnWidth( 0, 100 ); attributeActionTable->setColumnWidth( 1, 230 ); attributeActionTable->setCornerButtonEnabled( false ); connect( attributeActionTable, SIGNAL( itemSelectionChanged() ), this, SLOT( itemSelectionChanged() ) ); connect( actionName, SIGNAL( textChanged( QString ) ), this, SLOT( updateButtons() ) ); connect( actionAction, SIGNAL( textChanged() ), this, SLOT( updateButtons() ) ); connect( moveUpButton, SIGNAL( clicked() ), this, SLOT( moveUp() ) ); connect( moveDownButton, SIGNAL( clicked() ), this, SLOT( moveDown() ) ); connect( removeButton, SIGNAL( clicked() ), this, SLOT( remove() ) ); connect( addDefaultActionsButton, SIGNAL( clicked() ), this, SLOT( addDefaultActions() ) ); connect( browseButton, SIGNAL( clicked() ), this, SLOT( browse() ) ); connect( insertButton, SIGNAL( clicked() ), this, SLOT( insert() ) ); connect( updateButton, SIGNAL( clicked() ), this, SLOT( update() ) ); connect( insertFieldButton, SIGNAL( clicked() ), this, SLOT( insertField() ) ); connect( insertExpressionButton, SIGNAL( clicked() ), this, SLOT( insertExpression() ) ); connect( chooseIconButton, SIGNAL( clicked() ), this, SLOT( chooseIcon() ) ); init(); // Populate the combo box with the field names. Will the field names // change? If so, they need to be passed into the init() call, or // some access to them retained in this class. for ( int idx = 0; idx < fields.count(); ++idx ) fieldComboBox->addItem( fields[idx].name() ); }
void QgsVectorDataProvider::fillMinMaxCache() const { if ( !mCacheMinMaxDirty ) return; QgsFields flds = fields(); for ( int i = 0; i < flds.count(); ++i ) { if ( flds.at( i ).type() == QVariant::Int ) { mCacheMinValues[i] = QVariant( INT_MAX ); mCacheMaxValues[i] = QVariant( INT_MIN ); } else if ( flds.at( i ).type() == QVariant::LongLong ) { mCacheMinValues[i] = QVariant( std::numeric_limits<qlonglong>::max() ); mCacheMaxValues[i] = QVariant( std::numeric_limits<qlonglong>::min() ); } else if ( flds.at( i ).type() == QVariant::Double ) { mCacheMinValues[i] = QVariant( DBL_MAX ); mCacheMaxValues[i] = QVariant( -DBL_MAX ); } else { mCacheMinValues[i] = QVariant(); mCacheMaxValues[i] = QVariant(); } } QgsFeature f; QgsAttributeList keys = mCacheMinValues.keys(); QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys ) ); while ( fi.nextFeature( f ) ) { QgsAttributes attrs = f.attributes(); for ( QgsAttributeList::const_iterator it = keys.begin(); it != keys.end(); ++it ) { const QVariant& varValue = attrs.at( *it ); if ( varValue.isNull() ) continue; if ( flds.at( *it ).type() == QVariant::Int ) { int value = varValue.toInt(); if ( value < mCacheMinValues[*it].toInt() ) mCacheMinValues[*it] = value; if ( value > mCacheMaxValues[*it].toInt() ) mCacheMaxValues[*it] = value; } else if ( flds.at( *it ).type() == QVariant::LongLong ) { qlonglong value = varValue.toLongLong(); if ( value < mCacheMinValues[*it].toLongLong() ) mCacheMinValues[*it] = value; if ( value > mCacheMaxValues[*it].toLongLong() ) mCacheMaxValues[*it] = value; } else if ( flds.at( *it ).type() == QVariant::Double ) { double value = varValue.toDouble(); if ( value < mCacheMinValues[*it].toDouble() ) mCacheMinValues[*it] = value; if ( value > mCacheMaxValues[*it].toDouble() ) mCacheMaxValues[*it] = value; } else { QString value = varValue.toString(); if ( mCacheMinValues[*it].isNull() || value < mCacheMinValues[*it].toString() ) { mCacheMinValues[*it] = value; } if ( mCacheMaxValues[*it].isNull() || value > mCacheMaxValues[*it].toString() ) { mCacheMaxValues[*it] = value; } } } } mCacheMinMaxDirty = false; }
void TestQgsFields::create() { QgsFields fields; QCOMPARE( fields.count(), 0 ); }
QVariantMap QgsJoinWithLinesAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) { if ( parameters.value( QStringLiteral( "SPOKES" ) ) == parameters.value( QStringLiteral( "HUBS" ) ) ) throw QgsProcessingException( QObject::tr( "Same layer given for both hubs and spokes" ) ); std::unique_ptr< QgsProcessingFeatureSource > hubSource( parameterAsSource( parameters, QStringLiteral( "HUBS" ), context ) ); if ( !hubSource ) throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "HUBS" ) ) ); std::unique_ptr< QgsProcessingFeatureSource > spokeSource( parameterAsSource( parameters, QStringLiteral( "SPOKES" ), context ) ); if ( !hubSource || !spokeSource ) throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "SPOKES" ) ) ); QString fieldHubName = parameterAsString( parameters, QStringLiteral( "HUB_FIELD" ), context ); int fieldHubIndex = hubSource->fields().lookupField( fieldHubName ); const QStringList hubFieldsToCopy = parameterAsFields( parameters, QStringLiteral( "HUB_FIELDS" ), context ); QString fieldSpokeName = parameterAsString( parameters, QStringLiteral( "SPOKE_FIELD" ), context ); int fieldSpokeIndex = spokeSource->fields().lookupField( fieldSpokeName ); const QStringList spokeFieldsToCopy = parameterAsFields( parameters, QStringLiteral( "SPOKE_FIELDS" ), context ); if ( fieldHubIndex < 0 || fieldSpokeIndex < 0 ) throw QgsProcessingException( QObject::tr( "Invalid ID field" ) ); const bool geodesic = parameterAsBool( parameters, QStringLiteral( "GEODESIC" ), context ); const double geodesicDistance = parameterAsDouble( parameters, QStringLiteral( "GEODESIC_DISTANCE" ), context ) * 1000; bool dynamicGeodesicDistance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "GEODESIC_DISTANCE" ) ); QgsExpressionContext expressionContext = createExpressionContext( parameters, context, hubSource.get() ); QgsProperty geodesicDistanceProperty; if ( dynamicGeodesicDistance ) { geodesicDistanceProperty = parameters.value( QStringLiteral( "GEODESIC_DISTANCE" ) ).value< QgsProperty >(); } const bool splitAntimeridian = parameterAsBool( parameters, QStringLiteral( "ANTIMERIDIAN_SPLIT" ), context ); QgsDistanceArea da; da.setSourceCrs( hubSource->sourceCrs(), context.transformContext() ); da.setEllipsoid( context.project()->ellipsoid() ); QgsFields hubOutFields; QgsAttributeList hubFieldIndices; if ( hubFieldsToCopy.empty() ) { hubOutFields = hubSource->fields(); hubFieldIndices.reserve( hubOutFields.count() ); for ( int i = 0; i < hubOutFields.count(); ++i ) { hubFieldIndices << i; } } else { hubFieldIndices.reserve( hubOutFields.count() ); for ( const QString &field : hubFieldsToCopy ) { int index = hubSource->fields().lookupField( field ); if ( index >= 0 ) { hubFieldIndices << index; hubOutFields.append( hubSource->fields().at( index ) ); } } } QgsAttributeList hubFields2Fetch = hubFieldIndices; hubFields2Fetch << fieldHubIndex; QgsFields spokeOutFields; QgsAttributeList spokeFieldIndices; if ( spokeFieldsToCopy.empty() ) { spokeOutFields = spokeSource->fields(); spokeFieldIndices.reserve( spokeOutFields.count() ); for ( int i = 0; i < spokeOutFields.count(); ++i ) { spokeFieldIndices << i; } } else { for ( const QString &field : spokeFieldsToCopy ) { int index = spokeSource->fields().lookupField( field ); if ( index >= 0 ) { spokeFieldIndices << index; spokeOutFields.append( spokeSource->fields().at( index ) ); } } } QgsAttributeList spokeFields2Fetch = spokeFieldIndices; spokeFields2Fetch << fieldSpokeIndex; QgsFields fields = QgsProcessingUtils::combineFields( hubOutFields, spokeOutFields ); QgsWkbTypes::Type outType = geodesic ? QgsWkbTypes::MultiLineString : QgsWkbTypes::LineString; bool hasZ = false; if ( QgsWkbTypes::hasZ( hubSource->wkbType() ) || QgsWkbTypes::hasZ( spokeSource->wkbType() ) ) { outType = QgsWkbTypes::addZ( outType ); hasZ = true; } bool hasM = false; if ( QgsWkbTypes::hasM( hubSource->wkbType() ) || QgsWkbTypes::hasM( spokeSource->wkbType() ) ) { outType = QgsWkbTypes::addM( outType ); hasM = true; } QString dest; std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outType, hubSource->sourceCrs(), QgsFeatureSink::RegeneratePrimaryKey ) ); if ( !sink ) throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) ); auto getPointFromFeature = [hasZ, hasM]( const QgsFeature & feature )->QgsPoint { QgsPoint p; if ( feature.geometry().type() == QgsWkbTypes::PointGeometry && !feature.geometry().isMultipart() ) p = *static_cast< const QgsPoint *>( feature.geometry().constGet() ); else p = *static_cast< const QgsPoint *>( feature.geometry().pointOnSurface().constGet() ); if ( hasZ && !p.is3D() ) p.addZValue( 0 ); if ( hasM && !p.isMeasure() ) p.addMValue( 0 ); return p; }; QgsFeatureIterator hubFeatures = hubSource->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( hubFields2Fetch ), QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks ); double step = hubSource->featureCount() > 0 ? 100.0 / hubSource->featureCount() : 1; int i = 0; QgsFeature hubFeature; while ( hubFeatures.nextFeature( hubFeature ) ) { i++; if ( feedback->isCanceled() ) { break; } feedback->setProgress( i * step ); if ( !hubFeature.hasGeometry() ) continue; QgsPoint hubPoint = getPointFromFeature( hubFeature ); // only keep selected attributes QgsAttributes hubAttributes; for ( int j = 0; j < hubFeature.attributes().count(); ++j ) { if ( !hubFieldIndices.contains( j ) ) continue; hubAttributes << hubFeature.attribute( j ); } QgsFeatureRequest spokeRequest = QgsFeatureRequest().setDestinationCrs( hubSource->sourceCrs(), context.transformContext() ); spokeRequest.setSubsetOfAttributes( spokeFields2Fetch ); spokeRequest.setFilterExpression( QgsExpression::createFieldEqualityExpression( fieldSpokeName, hubFeature.attribute( fieldHubIndex ) ) ); QgsFeatureIterator spokeFeatures = spokeSource->getFeatures( spokeRequest, QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks ); QgsFeature spokeFeature; while ( spokeFeatures.nextFeature( spokeFeature ) ) { if ( feedback->isCanceled() ) { break; } if ( !spokeFeature.hasGeometry() ) continue; QgsPoint spokePoint = getPointFromFeature( spokeFeature ); QgsGeometry line; if ( !geodesic ) { line = QgsGeometry( new QgsLineString( QVector< QgsPoint >() << hubPoint << spokePoint ) ); if ( splitAntimeridian ) line = da.splitGeometryAtAntimeridian( line ); } else { double distance = geodesicDistance; if ( dynamicGeodesicDistance ) { expressionContext.setFeature( hubFeature ); distance = geodesicDistanceProperty.valueAsDouble( expressionContext, distance ); } std::unique_ptr< QgsMultiLineString > ml = qgis::make_unique< QgsMultiLineString >(); std::unique_ptr< QgsLineString > l = qgis::make_unique< QgsLineString >( QVector< QgsPoint >() << hubPoint ); QVector< QVector< QgsPointXY > > points = da.geodesicLine( QgsPointXY( hubPoint ), QgsPointXY( spokePoint ), distance, splitAntimeridian ); QVector< QgsPointXY > points1 = points.at( 0 ); points1.pop_front(); if ( points.count() == 1 ) points1.pop_back(); QgsLineString geodesicPoints( points1 ); l->append( &geodesicPoints ); if ( points.count() == 1 ) l->addVertex( spokePoint ); ml->addGeometry( l.release() ); if ( points.count() > 1 ) { QVector< QgsPointXY > points2 = points.at( 1 ); points2.pop_back(); l = qgis::make_unique< QgsLineString >( points2 ); if ( hasZ ) l->addZValue( std::numeric_limits<double>::quiet_NaN() ); if ( hasM ) l->addMValue( std::numeric_limits<double>::quiet_NaN() ); l->addVertex( spokePoint ); ml->addGeometry( l.release() ); } line = QgsGeometry( std::move( ml ) ); } QgsFeature outFeature; QgsAttributes outAttributes = hubAttributes; // only keep selected attributes QgsAttributes spokeAttributes; for ( int j = 0; j < spokeFeature.attributes().count(); ++j ) { if ( !spokeFieldIndices.contains( j ) ) continue; spokeAttributes << spokeFeature.attribute( j ); } outAttributes.append( spokeAttributes ); outFeature.setAttributes( outAttributes ); outFeature.setGeometry( line ); sink->addFeature( outFeature, QgsFeatureSink::FastInsert ); } } QVariantMap outputs; outputs.insert( QStringLiteral( "OUTPUT" ), dest ); return outputs; }
/** * This method is an extension of the constructor. It was implemented to reduce the amount of code duplicated between the constuctors. */ bool eVisGenericEventBrowserGui::initBrowser() { //setup gui setWindowTitle( tr( "Generic Event Browser" ) ); connect( treeEventData, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ), this, SLOT( launchExternalApplication( QTreeWidgetItem *, int ) ) ); mHighlightSymbol.load( ":/evis/eVisHighlightSymbol.png" ); mPointerSymbol.load( ":/evis/eVisPointerSymbol.png" ); mCompassOffset = 0.0; //Flag to let us know if the browser fully loaded mBrowserInitialized = false; //Initialize some class variables mDefaultEventImagePathField = 0; mDefaultCompassBearingField = 0; mDefaultCompassOffsetField = 0; //initialize Display tab GUI elements pbtnNext->setEnabled( false ); pbtnPrevious->setEnabled( false ); //Set up Attribute display treeEventData->setColumnCount( 2 ); QStringList treeHeaders; treeHeaders << tr( "Field" ) << tr( "Value" ); treeEventData->setHeaderLabels( treeHeaders ); //Initialize Options tab GUI elements cboxEventImagePathField->setEnabled( true ); chkboxEventImagePathRelative->setChecked( false ); chkboxDisplayCompassBearing->setChecked( false ); cboxCompassBearingField->setEnabled( true ); rbtnManualCompassOffset->setChecked( false ); dsboxCompassOffset->setEnabled( true ); dsboxCompassOffset->setValue( 0.0 ); rbtnAttributeCompassOffset->setChecked( false ); cboxCompassOffsetField->setEnabled( true ); chkboxUseOnlyFilename->setChecked( false ); QString myThemePath = QgsApplication::activeThemePath(); pbtnResetEventImagePathData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) ); pbtnResetCompassBearingData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) ); pbtnResetCompassOffsetData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) ); pbtnResetBasePathData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) ); pbtnResetUseOnlyFilenameData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) ); pbtnResetApplyPathRulesToDocs->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) ); chkboxSaveEventImagePathData->setChecked( false ); chkboxSaveCompassBearingData->setChecked( false ); chkboxSaveCompassOffsetData->setChecked( false ); chkboxSaveBasePathData->setChecked( false ); chkboxSaveUseOnlyFilenameData->setChecked( false ); //Set up Configure External Application buttons pbtnAddFileType->setIcon( QIcon( QPixmap( myThemePath + "/mActionNewAttribute.png" ) ) ); pbtnDeleteFileType->setIcon( QIcon( QPixmap( myThemePath + "/mActionDeleteAttribute.png" ) ) ); //Check to for interface, not null when launched from plugin toolbar, otherwise expect map canvas if ( mInterface ) { //check for active layer if ( mInterface->activeLayer() ) { //verify that the active layer is a vector layer if ( QgsMapLayer::VectorLayer == mInterface->activeLayer()->type() ) { mVectorLayer = ( QgsVectorLayer* )mInterface->activeLayer(); mCanvas = mInterface->mapCanvas(); } else { QMessageBox::warning( this, tr( "Warning" ), tr( "This tool only supports vector data" ) ); return false; } } else { QMessageBox::warning( this, tr( "Warning" ), tr( "No active layers found" ) ); return false; } } //check for map canvas, if map canvas is null, throw error else if ( mCanvas ) { //check for active layer if ( mCanvas->currentLayer() ) { //verify that the active layer is a vector layer if ( QgsMapLayer::VectorLayer == mCanvas->currentLayer()->type() ) { mVectorLayer = ( QgsVectorLayer* )mCanvas->currentLayer(); } else { QMessageBox::warning( this, tr( "Warning" ), tr( "This tool only supports vector data" ) ); return false; } } else { QMessageBox::warning( this, tr( "Warning" ), tr( "No active layers found" ) ); return false; } } else { QMessageBox::warning( this, tr( "Error" ), tr( "Unable to connect to either the map canvas or application interface" ) ); return false; } //Connect rendering routine for highlighting symbols and load symbols connect( mCanvas, SIGNAL( renderComplete( QPainter * ) ), this, SLOT( renderSymbol( QPainter * ) ) ); mDataProvider = mVectorLayer->dataProvider(); /* * A list of the selected feature ids is made so that we can move forward and backward through * the list. The data providers only have the ability to get one feature at a time or * sequentially move forward through the selected features */ if ( 0 == mVectorLayer->selectedFeatureCount() ) //if nothing is selected select everything { mVectorLayer->invertSelection(); mFeatureIds = mVectorLayer->selectedFeaturesIds().toList(); } else //use selected features { mFeatureIds = mVectorLayer->selectedFeaturesIds().toList(); } if ( 0 == mFeatureIds.size() ) return false; //get the first feature in the list so we can set the field in the pulldown menues QgsFeature* myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) ); if ( !myFeature ) { QMessageBox::warning( this, tr( "Error" ), tr( "An invalid feature was received during initialization" ) ); return false; } QgsFields myFields = mDataProvider->fields(); mIgnoreEvent = true; //Ignore indexChanged event when adding items to combo boxes for ( int x = 0; x < myFields.count(); x++ ) { QString name = myFields.at( x ).name(); cboxEventImagePathField->addItem( name ); cboxCompassBearingField->addItem( name ); cboxCompassOffsetField->addItem( name ); if ( myFeature->attribute( x ).toString().contains( QRegExp( "(jpg|jpeg|tif|tiff|gif)", Qt::CaseInsensitive ) ) ) { mDefaultEventImagePathField = x; } if ( name.contains( QRegExp( "(comp|bear)", Qt::CaseInsensitive ) ) ) { mDefaultCompassBearingField = x; } if ( name.contains( QRegExp( "(offset|declination)", Qt::CaseInsensitive ) ) ) { mDefaultCompassOffsetField = x; } } mIgnoreEvent = false; //Set Display tab gui items if ( mFeatureIds.size() > 1 ) { pbtnNext->setEnabled( true ); } setWindowTitle( tr( "Event Browser - Displaying records 01 of %1" ).arg( mFeatureIds.size(), 2, 10, QChar( '0' ) ) ); //Set Options tab gui items initOptionsTab(); //Load file associations into Configure External Applications tab gui items QSettings myQSettings; myQSettings.beginWriteArray( "/eVis/filetypeassociations" ); int myTotalAssociations = myQSettings.childGroups().count(); int myIterator = 0; while ( myIterator < myTotalAssociations ) { myQSettings.setArrayIndex( myIterator ); tableFileTypeAssociations->insertRow( tableFileTypeAssociations->rowCount() ); tableFileTypeAssociations->setItem( myIterator, 0, new QTableWidgetItem( myQSettings.value( "extension", "" ).toString() ) ); tableFileTypeAssociations->setItem( myIterator, 1, new QTableWidgetItem( myQSettings.value( "application", "" ).toString() ) ); myIterator++; } myQSettings.endArray(); mBrowserInitialized = true; return true; }
void QgsFieldModel::updateModel() { if ( mLayer ) { QgsFields newFields = mLayer->fields(); if ( mFields.toList() != newFields.toList() ) { // Try to handle two special cases: addition of a new field and removal of a field. // It would be better to listen directly to attributeAdded/attributeDeleted // so we would not have to check for addition/removal here. if ( mFields.count() == newFields.count() - 1 ) { QgsFields tmpNewFields = newFields; tmpNewFields.remove( tmpNewFields.count() - 1 ); if ( mFields.toList() == tmpNewFields.toList() ) { // the only change is a new field at the end beginInsertRows( QModelIndex(), mFields.count(), mFields.count() ); mFields = newFields; endInsertRows(); return; } } if ( mFields.count() == newFields.count() + 1 ) { QgsFields tmpOldFields = mFields; tmpOldFields.remove( tmpOldFields.count() - 1 ); if ( tmpOldFields.toList() == newFields.toList() ) { // the only change is a field removed at the end beginRemoveRows( QModelIndex(), mFields.count() - 1, mFields.count() - 1 ); mFields = newFields; endRemoveRows(); return; } for ( int i = 0; i < newFields.count(); ++i ) { if ( mFields.at( i ) != newFields.at( i ) ) { QgsFields tmpOldFields = mFields; tmpOldFields.remove( i ); if ( tmpOldFields.toList() != newFields.toList() ) break; // the change is more complex - go with general case // the only change is a field removed at index i beginRemoveRows( QModelIndex(), i, i ); mFields = newFields; endRemoveRows(); return; } } } // general case with reset - not good - resets selections beginResetModel(); mFields = mLayer->fields(); endResetModel(); } else emit dataChanged( index( 0, 0 ), index( rowCount(), 0 ) ); } else { beginResetModel(); mFields = QgsFields(); endResetModel(); } }
QVariant QgsOgrUtils::getOgrFeatureAttribute( OGRFeatureH ogrFet, const QgsFields& fields, int attIndex, QTextCodec* encoding , bool* ok ) { if ( !ogrFet || attIndex < 0 || attIndex >= fields.count() ) { if ( ok ) *ok = false; return QVariant(); } OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex ); if ( ! fldDef ) { if ( ok ) *ok = false; QgsDebugMsg( "ogrFet->GetFieldDefnRef(attindex) returns NULL" ); return QVariant(); } QVariant value; if ( ok ) *ok = true; if ( OGR_F_IsFieldSet( ogrFet, attIndex ) ) { switch ( fields.at( attIndex ).type() ) { case QVariant::String: { if ( encoding ) value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) ); else value = QVariant( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) ); break; } case QVariant::Int: value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) ); break; #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000 case QVariant::LongLong: value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) ); break; #endif case QVariant::Double: value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) ); break; case QVariant::Date: case QVariant::DateTime: case QVariant::Time: { int year, month, day, hour, minute, second, tzf; OGR_F_GetFieldAsDateTime( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf ); if ( fields.at( attIndex ).type() == QVariant::Date ) value = QDate( year, month, day ); else if ( fields.at( attIndex ).type() == QVariant::Time ) value = QTime( hour, minute, second ); else value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) ); } break; default: Q_ASSERT_X( false, "QgsOgrUtils::getOgrFeatureAttribute", "unsupported field type" ); if ( ok ) *ok = false; } } else { value = QVariant( QString::null ); } return value; }