Esempio n. 1
0
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;
}
Esempio n. 3
0
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 );
      }
    }
  }
}
Esempio n. 4
0
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 );
}
Esempio n. 5
0
void QgsFields::extend( const QgsFields &other )
{
  for ( int i = 0; i < other.count(); ++i )
  {
    append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) );
  }
}
Esempio n. 6
0
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();
}
Esempio n. 8
0
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;
  }
}
Esempio n. 10
0
QgsFeature::QgsFeature( const QgsFields &fields, QgsFeatureId id )
    : mFid( id )
    , mGeometry( 0 )
    , mOwnsGeometry( 0 )
    , mValid( false )
    , mFields( &fields )
{
  initAttributes( fields.count() );
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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();
}
Esempio n. 13
0
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() );
    }
}
Esempio n. 14
0
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 );
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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();
}
Esempio n. 18
0
void QgsAtlasComposition::setSortKeyAttributeIndex( int idx )
{
  if ( mCoverageLayer )
  {
    QgsFields fields = mCoverageLayer->fields();
    if ( idx >= 0 && idx < fields.count() )
    {
      mSortKeyAttributeName = fields.at( idx ).name();
      return;
    }
  }
  mSortKeyAttributeName = "";
}
Esempio n. 19
0
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 );
}
Esempio n. 20
0
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];
    }
  }
}
Esempio n. 21
0
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 );
}
Esempio n. 22
0
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 );
}
Esempio n. 23
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;
}
Esempio n. 24
0
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() );
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
void TestQgsFields::create()
{
    QgsFields fields;
    QCOMPARE( fields.count(), 0 );
}
Esempio n. 27
0
QVariantMap QgsJoinWithLinesAlgorithm::processAlgorithm( const QVariantMap &parameters, 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;
}
Esempio n. 29
0
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();
  }
}
Esempio n. 30
0
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;
}