void QgsAttributeTypeLoadDialog::loadDataToValueMap()
{
  mValueMap.clear();
  int idx = keyComboBox->itemData( keyComboBox->currentIndex() ).toInt();
  int idx2 = valueComboBox->itemData( valueComboBox->currentIndex() ).toInt();
  QgsMapLayer* dataLayer = QgsMapLayerRegistry::instance()->mapLayer( layerComboBox->currentText() );
  QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer *>( dataLayer );
  if ( vLayer == NULL )
  {
    return;
  }

  QgsVectorDataProvider* dataProvider = vLayer->dataProvider();
  dataProvider->enableGeometrylessFeatures( true );

  QgsAttributeList attributeList = QgsAttributeList();
  attributeList.append( idx );
  attributeList.append( idx2 );
  vLayer->select( attributeList, QgsRectangle(), false );

  QgsFeature f;
  while ( vLayer->nextFeature( f ) )
  {
    QVariant val = f.attributeMap()[idx];
    if ( val.isValid() && !val.isNull() && !val.toString().isEmpty() )
    {
      mValueMap.insert( f.attributeMap()[idx2].toString(), val );
    }
  }
  dataProvider->enableGeometrylessFeatures( false );
}
void QgsDualView::columnBoxInit()
{
  // load fields
  QList<QgsField> fields = mLayerCache->layer()->pendingFields().toList();

  // default expression: saved value
  QString displayExpression = mLayerCache->layer()->displayExpression();

  // if no display expression is saved: use display field instead
  if ( displayExpression == "" )
  {
    displayExpression = mLayerCache->layer()->displayField();
  }

  // if neither diaplay expression nor display field is saved...
  if ( displayExpression == "" )
  {
    QgsAttributeList pkAttrs = mLayerCache->layer()->pendingPkAttributesList();

    if ( pkAttrs.size() > 0 )
    {
      // ... If there are primary key(s) defined
      QStringList pkFields;

      foreach ( int attr, pkAttrs )
      {
        pkFields.append( "\"" + fields[attr].name() + "\"" );
      }
void QgsVectorLayerFeatureIterator::prepareJoins()
{
  QgsAttributeList fetchAttributes = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : L->pendingAllAttributesList();
  QgsAttributeList sourceJoinFields; // attributes that also need to be fetched from this layer in order to have joins working

  mFetchJoinInfo.clear();

  QgsVectorLayerJoinBuffer* joinBuffer = L->mJoinBuffer;
  const QgsFields& fields = L->pendingFields();

  for ( QgsAttributeList::const_iterator attIt = fetchAttributes.constBegin(); attIt != fetchAttributes.constEnd(); ++attIt )
  {
    if ( !fields.exists( *attIt ) )
      continue;

    if ( fields.fieldOrigin( *attIt ) != QgsFields::OriginJoin )
      continue;

    int sourceLayerIndex;
    const QgsVectorJoinInfo* joinInfo = joinBuffer->joinForFieldIndex( *attIt, fields, sourceLayerIndex );
    Q_ASSERT( joinInfo );

    QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
    Q_ASSERT( joinLayer );

    if ( !mFetchJoinInfo.contains( joinLayer ) )
    {
      FetchJoinInfo info;
      info.joinInfo = joinInfo;
      info.joinLayer = joinLayer;

      if ( joinInfo->targetFieldName.isEmpty() )
        info.targetField = joinInfo->targetFieldIndex;    //for compatibility with 1.x
      else
        info.targetField = fields.indexFromName( joinInfo->targetFieldName );

      if ( joinInfo->joinFieldName.isEmpty() )
        info.joinField = joinInfo->joinFieldIndex;      //for compatibility with 1.x
      else
        info.joinField = joinLayer->pendingFields().indexFromName( joinInfo->joinFieldName );

      info.indexOffset = *attIt - sourceLayerIndex;
      if ( info.joinField < sourceLayerIndex )
        info.indexOffset++;

      // for joined fields, we always need to request the targetField from the provider too
      if ( !fetchAttributes.contains( info.targetField ) )
        sourceJoinFields << info.targetField;

      mFetchJoinInfo.insert( joinLayer, info );
    }

    // store field source index - we'll need it when fetching from provider
    mFetchJoinInfo[ joinLayer ].attributes.push_back( sourceLayerIndex );
  }

  // add sourceJoinFields if we're using a subset
  if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
    mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() + sourceJoinFields );
}
void QgsVectorLayerFeatureIterator::prepareExpressions()
{
  const QList<QgsExpressionFieldBuffer::ExpressionField> exps = mSource->mExpressionFieldBuffer->expressions();

  for ( int i = 0; i < mSource->mFields.count(); i++ )
  {
    if ( mSource->mFields.fieldOrigin( i ) == QgsFields::OriginExpression )
    {
      // Only prepare if there is no subset defined or the subset contains this field
      if ( !( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
           || mRequest.subsetOfAttributes().contains( i ) )
      {
        int oi = mSource->mFields.fieldOriginIndex( i );
        QgsExpression* exp = new QgsExpression( exps[oi].expression );
        exp->prepare( mSource->mFields );
        mExpressionFieldInfo.insert( i, exp );

        if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
        {
          QgsAttributeList attrs;
          Q_FOREACH( const QString& col, exp->referencedColumns() )
          {
            attrs.append( mSource->mFields.fieldNameIndex( col ) );
          }

          mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() + attrs );
        }

        if ( exp->needsGeometry() )
        {
          mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
        }
      }
    }
Exemple #5
0
void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest& request )
{
  mFallbackStatement.clear();
  mStatement.clear();

  bool limitAtProvider = ( mRequest.limit() >= 0 );

  // build sql statement

  // note: 'SELECT ' is added later, to account for 'SELECT TOP...' type queries
  mStatement += QString( "[%1]" ).arg( mSource->mFidColName );
  mFidCol = mSource->mFields.indexFromName( mSource->mFidColName );
  mAttributesToFetch.append( mFidCol );

  bool subsetOfAttributes = mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes;
  QgsAttributeList attrs = subsetOfAttributes ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();

  // ensure that all attributes required for expression filter are being fetched
  if ( subsetOfAttributes && request.filterType() == QgsFeatureRequest::FilterExpression )
  {
    Q_FOREACH ( const QString& field, request.filterExpression()->referencedColumns() )
    {
      int attrIdx = mSource->mFields.fieldNameIndex( field );
      if ( !attrs.contains( attrIdx ) )
        attrs << attrIdx;
    }
  }
Exemple #6
0
QgsAttributeList QgsFields::allAttributesList() const
{
  QgsAttributeList lst;
  for ( int i = 0; i < d->fields.count(); ++i )
    lst.append( i );
  return lst;
}
void QgsSearchQueryBuilder::getFieldValues( int limit )
{
  if ( !mLayer )
  {
    return;
  }
  // clear the values list
  mModelValues->clear();

  // determine the field type
  QString fieldName = mModelFields->data( lstFields->currentIndex() ).toString();
  int fieldIndex = mFieldMap[fieldName];
  QgsField field = mLayer->pendingFields()[fieldIndex];//provider->fields()[fieldIndex];
  bool numeric = ( field.type() == QVariant::Int || field.type() == QVariant::Double );

  QgsFeature feat;
  QString value;

  QgsAttributeList attrs;
  attrs.append( fieldIndex );

  mLayer->select( attrs, QgsRectangle(), false );

  lstValues->setCursor( Qt::WaitCursor );
  // Block for better performance
  mModelValues->blockSignals( true );
  lstValues->setUpdatesEnabled( false );

  /**MH: keep already inserted values in a set. Querying is much faster compared to QStandardItemModel::findItems*/
  QSet<QString> insertedValues;

  while ( mLayer->nextFeature( feat ) &&
          ( limit == 0 || mModelValues->rowCount() != limit ) )
  {
    const QgsAttributeMap& attributes = feat.attributeMap();
    value = attributes[fieldIndex].toString();

    if ( !numeric )
    {
      // put string in single quotes and escape single quotes in the string
      value = "'" + value.replace( "'", "''" ) + "'";
    }

    // add item only if it's not there already
    if ( !insertedValues.contains( value ) )
    {
      QStandardItem *myItem = new QStandardItem( value );
      myItem->setEditable( false );
      mModelValues->insertRow( mModelValues->rowCount(), myItem );
      insertedValues.insert( value );
    }
  }
  // Unblock for normal use
  mModelValues->blockSignals( false );
  lstValues->setUpdatesEnabled( true );
  // TODO: already sorted, signal emit to refresh model
  mModelValues->sort( 0 );
  lstValues->setCursor( Qt::ArrowCursor );
}
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
    : QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
    , mEditGeometrySimplifier( 0 )
{

  // prepare joins: may add more attributes to fetch (in order to allow join)
  if ( mSource->mJoinBuffer->containsJoins() )
    prepareJoins();

  prepareExpressions();

  // by default provider's request is the same
  mProviderRequest = mRequest;

  if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    // prepare list of attributes to match provider fields
    QgsAttributeList providerSubset;
    QgsAttributeList subset = mProviderRequest.subsetOfAttributes();
    int nPendingFields = mSource->mFields.count();
    for ( int i = 0; i < subset.count(); ++i )
    {
      int attrIndex = subset[i];
      if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
      if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
        providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
    }
    mProviderRequest.setSubsetOfAttributes( providerSubset );
  }

  if ( mSource->mHasEditBuffer )
  {
    mChangedFeaturesRequest = mProviderRequest;
    mChangedFeaturesRequest.setFilterFids( mSource->mChangedAttributeValues.keys().toSet() );
  }

  if ( request.filterType() == QgsFeatureRequest::FilterFid )
  {
    mFetchedFid = false;
  }
  else // no filter or filter by rect
  {
    if ( mSource->mHasEditBuffer )
    {
      mChangedFeaturesIterator = mSource->mProviderFeatureSource->getFeatures( mChangedFeaturesRequest );
    }
    else
    {
      mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );
    }

    rewindEditBuffer();
  }

  if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression )
  {
    mRequest.filterExpression()->prepare( mSource->mFields );
  }
}
Exemple #9
0
int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsVectorLayer* vlayer )
{
  if ( !layerItem || !vlayer )
  {
    return 1;
  }

  int opacity = vlayer->getTransparency();

  const QgsRenderer* vectorRenderer = vlayer->renderer();
  if ( !vectorRenderer )
  {
    return 3;
  }

  //text field that describes classification attribute?
  QSettings settings;
  if ( settings.value( "/qgis/showLegendClassifiers", false ).toBool() )
  {
    QgsFieldMap layerFields = vlayer->pendingFields();
    QgsAttributeList attributes = vectorRenderer->classificationAttributes();
    QgsAttributeList::const_iterator att_it = attributes.constBegin();
    for ( ; att_it != attributes.constEnd(); ++att_it )
    {
      QgsFieldMap::const_iterator fieldIt = layerFields.find( *att_it );
      if ( fieldIt != layerFields.constEnd() )
      {
        QString attributeName = vlayer->attributeDisplayName( fieldIt.key() );
        QStandardItem* attributeItem = new QStandardItem( attributeName );
        attributeItem->setData( QgsLegendModel::ClassificationItem, Qt::UserRole + 1 ); //first user data stores the item type
        attributeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
        layerItem->setChild( layerItem->rowCount(), 0, attributeItem );
      }
    }
  }

  const QList<QgsSymbol*> vectorSymbols = vectorRenderer->symbols();
  QList<QgsSymbol*>::const_iterator symbolIt = vectorSymbols.constBegin();

  for ( ; symbolIt != vectorSymbols.constEnd(); ++symbolIt )
  {
    if ( !( *symbolIt ) )
    {
      continue;
    }

    QStandardItem* currentSymbolItem = itemFromSymbol( *symbolIt, opacity, vlayer->id() );
    if ( !currentSymbolItem )
    {
      continue;
    }

    layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem );

  }

  return 0;
}
QgsVectorLayer *QgsFeatureSource::materialize( const QgsFeatureRequest &request, QgsFeedback *feedback )
{
  QgsWkbTypes::Type outWkbType = request.flags() & QgsFeatureRequest::NoGeometry ? QgsWkbTypes::NoGeometry : wkbType();
  QgsCoordinateReferenceSystem crs = request.destinationCrs().isValid() ? request.destinationCrs() : sourceCrs();

  QgsAttributeList requestedAttrs = request.subsetOfAttributes();

  QgsFields outFields;
  if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    int i = 0;
    const QgsFields sourceFields = fields();
    for ( const QgsField &field : sourceFields )
    {
      if ( requestedAttrs.contains( i ) )
        outFields.append( field );
      i++;
    }
  }
  else
  {
    outFields = fields();
  }

  std::unique_ptr< QgsVectorLayer > layer( QgsMemoryProviderUtils::createMemoryLayer(
        sourceName(),
        outFields,
        outWkbType,
        crs ) );
  QgsFeature f;
  QgsFeatureIterator it = getFeatures( request );
  int fieldCount = fields().count();
  while ( it.nextFeature( f ) )
  {
    if ( feedback && feedback->isCanceled() )
      break;

    if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes )
    {
      // remove unused attributes
      QgsAttributes attrs;
      for ( int i = 0; i < fieldCount; ++i )
      {
        if ( requestedAttrs.contains( i ) )
        {
          attrs.append( f.attributes().at( i ) );
        }
      }

      f.setAttributes( attrs );
    }

    layer->dataProvider()->addFeature( f, QgsFeatureSink::FastInsert );
  }

  return layer.release();
}
bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) const
{
  feature.setFeatureId( OGR_F_GetFID( fet ) );
  feature.initAttributes( mSource->mFields.count() );
  feature.setFields( mSource->mFields ); // allow name-based attribute lookups

  bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect;
  bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown;
  if ( mFetchGeometry || useIntersect || geometryTypeFilter )
  {
    OGRGeometryH geom = OGR_F_GetGeometryRef( fet );

    if ( geom )
    {
      feature.setGeometry( QgsOgrUtils::ogrGeometryToQgsGeometry( geom ) );
    }
    else
      feature.clearGeometry();

    if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection &&
         geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection )
    {
      // OK
    }
    else if (( useIntersect && ( !feature.hasGeometry() || !feature.geometry().intersects( mRequest.filterRect() ) ) )
             || ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
    {
      OGR_F_Destroy( fet );
      return false;
    }
  }

  if ( !mFetchGeometry )
  {
    feature.clearGeometry();
  }

  // fetch attributes
  if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    QgsAttributeList attrs = mRequest.subsetOfAttributes();
    for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it )
    {
      getFeatureAttribute( fet, feature, *it );
    }
  }
  else
  {
    // all attributes
    for ( int idx = 0; idx < mSource->mFields.count(); ++idx )
    {
      getFeatureAttribute( fet, feature, idx );
    }
  }

  return true;
}
QgsVirtualLayerDefinition QgsVirtualLayerDefinitionUtils::fromJoinedLayer( QgsVectorLayer *layer )
{
  QgsVirtualLayerDefinition def;

  QStringList leftJoins;
  QStringList columns;

  // add the geometry column if the layer is spatial
  if ( layer->isSpatial() )
    columns << "t.geometry";

  // look for the uid
  QgsFields fields = layer->dataProvider()->fields();
  {
    QgsAttributeList pk = layer->dataProvider()->pkAttributeIndexes();
    if ( pk.size() == 1 )
    {
      def.setUid( fields.field( pk[0] ).name() );
    }
    else
    {
      // find an uid name
      QString uid = QStringLiteral( "uid" );
      while ( fields.lookupField( uid ) != -1 )
        uid += QLatin1String( "_" ); // add "_" each time this name already exists

      // add a column
      columns << "t.rowid AS " + uid;
      def.setUid( uid );
    }
  }
  const QgsFields providerFields = layer->dataProvider()->fields();
  for ( const auto &f : providerFields )
  {
    columns << "t.\"" + f.name() + "\"";
  }

  int joinIdx = 0;
  Q_FOREACH ( const QgsVectorLayerJoinInfo &join, layer->vectorJoins() )
  {
    QString joinName = QStringLiteral( "j%1" ).arg( ++joinIdx );
    QgsVectorLayer *joinedLayer = join.joinLayer();
    if ( !joinedLayer )
      continue;
    QString prefix = join.prefix().isEmpty() ? joinedLayer->name() + "_" : join.prefix();

    leftJoins << QStringLiteral( "LEFT JOIN \"%1\" AS %2 ON t.\"%5\"=%2.\"%3\"" ).arg( joinedLayer->id(), joinName, join.joinFieldName(), join.targetFieldName() );
    if ( join.joinFieldNamesSubset() )
    {
      Q_FOREACH ( const QString &f, *join.joinFieldNamesSubset() )
      {
        columns << joinName + ".\"" + f + "\" AS \"" + prefix + f + "\"";
      }
    }
    else
    {
QgsAttributeList QgsVectorDataProvider::attributeIndexes()
{
  uint count = fieldCount();
  QgsAttributeList list;

  for ( uint i = 0; i < count; i++ )
    list.append( i );

  return list;
}
void QgsAttributeTypeLoadDialog::createPreview( int fieldIndex, bool full )
{
  previewTableWidget->clearContents();

  for ( int i = previewTableWidget->rowCount() - 1; i > 0; i-- )
  {
    previewTableWidget->removeRow( i );
  }
  if ( layerComboBox->currentIndex() < 0 || fieldIndex < 0 )
  {
    //when nothing is selected there is no reason for preview
    return;
  }
  int idx = keyComboBox->itemData( keyComboBox->currentIndex() ).toInt();
  int idx2 = valueComboBox->itemData( valueComboBox->currentIndex() ).toInt();
  QgsMapLayer* dataLayer = QgsMapLayerRegistry::instance()->mapLayer( layerComboBox->currentText() );
  QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer *>( dataLayer );
  if ( vLayer == NULL )
  {
    return;
  }

  QgsVectorDataProvider* dataProvider = vLayer->dataProvider();
  dataProvider->enableGeometrylessFeatures( true );

  QgsAttributeList attributeList = QgsAttributeList();
  attributeList.append( idx );
  attributeList.append( idx2 );
  vLayer->select( attributeList, QgsRectangle(), false );

  QgsFeature f;
  QMap<QString, QVariant> valueMap;
  while ( vLayer->nextFeature( f ) )
  {
    QVariant val1 = f.attributeMap()[idx];
    QVariant val2 = f.attributeMap()[idx2];
    if ( val1.isValid() && !val1.isNull() && !val1.toString().isEmpty()
         && val2.isValid() && !val2.isNull() && !val2.toString().isEmpty() )
    {
      valueMap.insert( val1.toString(), val2.toString() );
    }
    if ( !full && valueMap.size() > 8 )
      break; //just first entries all on button
  }
  int row = 0;
  for ( QMap<QString, QVariant>::iterator mit = valueMap.begin(); mit != valueMap.end(); mit++, row++ )
  {
    previewTableWidget->insertRow( row );
    previewTableWidget->setItem( row, 0, new QTableWidgetItem( mit.value().toString() ) );
    previewTableWidget->setItem( row, 1, new QTableWidgetItem( mit.key() ) );
  }

  dataProvider->enableGeometrylessFeatures( false );
}
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
    : QgsAbstractFeatureIteratorFromSource<QgsOgrFeatureSource>( source, ownSource, request )
    , mFeatureFetched( false )
    , mConn( nullptr )
    , ogrLayer( nullptr )
    , mSubsetStringSet( false )
    , mFetchGeometry( false )
    , mExpressionCompiled( false )
    , mFilterFids( mRequest.filterFids() )
    , mFilterFidsIt( mFilterFids.constBegin() )
{
  mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mProvider->dataSourceUri() );
  if ( !mConn->ds )
  {
    return;
  }

  if ( mSource->mLayerName.isNull() )
  {
    ogrLayer = OGR_DS_GetLayer( mConn->ds, mSource->mLayerIndex );
  }
  else
  {
    ogrLayer = OGR_DS_GetLayerByName( mConn->ds, TO8( mSource->mLayerName ) );
  }
  if ( !ogrLayer )
  {
    return;
  }

  if ( !mSource->mSubsetString.isEmpty() )
  {
    ogrLayer = QgsOgrProviderUtils::setSubsetString( ogrLayer, mConn->ds, mSource->mEncoding, mSource->mSubsetString );
    if ( !ogrLayer )
    {
      return;
    }
    mSubsetStringSet = true;
  }

  mFetchGeometry = ( !mRequest.filterRect().isNull() ) || !( mRequest.flags() & QgsFeatureRequest::NoGeometry );
  QgsAttributeList attrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();

  // ensure that all attributes required for expression filter are being fetched
  if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && request.filterType() == QgsFeatureRequest::FilterExpression )
  {
    Q_FOREACH ( const QString& field, request.filterExpression()->referencedColumns() )
    {
      int attrIdx = mSource->mFields.fieldNameIndex( field );
      if ( !attrs.contains( attrIdx ) )
        attrs << attrIdx;
    }
    mRequest.setSubsetOfAttributes( attrs );
  }
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayer* layer, const QgsFeatureRequest& request )
    : QgsAbstractFeatureIterator( request ), L( layer )
{
  QgsVectorLayerJoinBuffer* joinBuffer = L->mJoinBuffer;

  if ( L->editBuffer() )
  {
    mAddedFeatures = QgsFeatureMap( L->editBuffer()->addedFeatures() );
    mChangedGeometries = QgsGeometryMap( L->editBuffer()->changedGeometries() );
    mDeletedFeatureIds = QgsFeatureIds( L->editBuffer()->deletedFeatureIds() );
    mChangedAttributeValues = QgsChangedAttributesMap( L->editBuffer()->changedAttributeValues() );
    mAddedAttributes = QList<QgsField>( L->editBuffer()->addedAttributes() );
    mDeletedAttributeIds = QgsAttributeList( L->editBuffer()->deletedAttributeIds() );
  }

  // prepare joins: may add more attributes to fetch (in order to allow join)
  if ( joinBuffer->containsJoins() )
    prepareJoins();

  // by default provider's request is the same
  mProviderRequest = mRequest;

  if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    // prepare list of attributes to match provider fields
    QgsAttributeList providerSubset;
    QgsAttributeList subset = mProviderRequest.subsetOfAttributes();
    const QgsFields &pendingFields = L->pendingFields();
    int nPendingFields = pendingFields.count();
    for ( int i = 0; i < subset.count(); ++i )
    {
      int attrIndex = subset[i];
      if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
      if ( L->pendingFields().fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
        providerSubset << L->pendingFields().fieldOriginIndex( attrIndex );
    }
    mProviderRequest.setSubsetOfAttributes( providerSubset );
  }

  if ( request.filterType() == QgsFeatureRequest::FilterFid )
  {
    mFetchedFid = false;
  }
  else // no filter or filter by rect
  {
    mProviderIterator = L->dataProvider()->getFeatures( mProviderRequest );

    rewindEditBuffer();
  }
}
Exemple #17
0
QString QgsMemoryProvider::dataSourceUri( bool expandAuthConfig ) const
{
  Q_UNUSED( expandAuthConfig )

  QUrl uri( QStringLiteral( "memory" ) );
  QString geometry = QgsWkbTypes::displayString( mWkbType );
  uri.addQueryItem( QStringLiteral( "geometry" ), geometry );

  if ( mCrs.isValid() )
  {
    QString crsDef( QLatin1String( "" ) );
    QString authid = mCrs.authid();
    if ( authid.startsWith( QLatin1String( "EPSG:" ) ) )
    {
      crsDef = authid;
    }
    else
    {
      int srid = mCrs.postgisSrid();
      if ( srid )
      {
        crsDef = QStringLiteral( "postgis:%1" ).arg( srid );
      }
      else
      {
        crsDef = QStringLiteral( "wkt:%1" ).arg( mCrs.toWkt() );
      }
    }
    uri.addQueryItem( QStringLiteral( "crs" ), crsDef );
  }
  if ( mSpatialIndex )
  {
    uri.addQueryItem( QStringLiteral( "index" ), QStringLiteral( "yes" ) );
  }

  QgsAttributeList attrs = const_cast<QgsMemoryProvider *>( this )->attributeIndexes();
  for ( int i = 0; i < attrs.size(); i++ )
  {
    QgsField field = mFields.at( attrs[i] );
    QString fieldDef = field.name();
    fieldDef.append( QStringLiteral( ":%2(%3,%4)" ).arg( field.typeName() ).arg( field.length() ).arg( field.precision() ) );
    uri.addQueryItem( QStringLiteral( "field" ), fieldDef );
  }

  return QString( uri.toEncoded() );

}
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
    : QgsAbstractFeatureIteratorFromSource<QgsVectorLayerFeatureSource>( source, ownSource, request )
    , mFetchedFid( false )
    , mEditGeometrySimplifier( 0 )
{
  prepareExpressions();

  // prepare joins: may add more attributes to fetch (in order to allow join)
  if ( mSource->mJoinBuffer->containsJoins() )
    prepareJoins();

  mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty();

  // by default provider's request is the same
  mProviderRequest = mRequest;

  if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    // prepare list of attributes to match provider fields
    QgsAttributeList providerSubset;
    QgsAttributeList subset = mProviderRequest.subsetOfAttributes();
    int nPendingFields = mSource->mFields.count();
    for ( int i = 0; i < subset.count(); ++i )
    {
      int attrIndex = subset[i];
      if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
      if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
        providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
    }
    mProviderRequest.setSubsetOfAttributes( providerSubset );
  }

  if ( mProviderRequest.filterType() == QgsFeatureRequest::FilterExpression )
  {
    Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() )
    {
      int idx = source->mFields.fieldNameIndex( field );

      // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
      // In this case we disable the expression filter.
      if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider )
      {
        mProviderRequest.disableFilter();
      }
    }
  }
Exemple #19
0
void TestQgsFields::allAttrsList()
{
    QgsFields fields;
    QgsAttributeList attrList = fields.allAttributesList();
    QVERIFY( attrList.isEmpty() );

    QgsField field( QString( "testfield" ) );
    fields.append( field );
    QgsField field2( QString( "testfield2" ) );
    fields.append( field2 );
    QgsField field3( QString( "testfield3" ) );
    fields.append( field3 );

    attrList = fields.allAttributesList();
    QCOMPARE( attrList.at( 0 ), 0 );
    QCOMPARE( attrList.at( 1 ), 1 );
    QCOMPARE( attrList.at( 2 ), 2 );
}
Exemple #20
0
void QgsLabel::addRequiredFields( QgsAttributeList& fields ) const
{
  for ( uint i = 0; i < LabelFieldCount; i++ )
  {
    if ( mLabelFieldIdx[i] == -1 )
      continue;
    bool found = false;
    for ( QgsAttributeList::iterator it = fields.begin(); it != fields.end(); ++it )
    {
      if ( *it == mLabelFieldIdx[i] )
      {
        found = true;
        break;
      }
    }
    if ( !found )
    {
      fields.append( mLabelFieldIdx[i] );
    }
  }
}
Exemple #21
0
void QgsDualView::columnBoxInit()
{
  // load fields
  QList<QgsField> fields = mLayerCache->layer()->fields().toList();

  QString defaultField;

  // default expression: saved value
  QString displayExpression = mLayerCache->layer()->displayExpression();

  // if no display expression is saved: use display field instead
  if ( displayExpression.isEmpty() )
  {
    if ( !mLayerCache->layer()->displayField().isEmpty() )
    {
      defaultField = mLayerCache->layer()->displayField();
      displayExpression = QString( "COALESCE(\"%1\", '<NULL>')" ).arg( defaultField );
    }
  }

  // if neither display expression nor display field is saved...
  if ( displayExpression.isEmpty() )
  {
    QgsAttributeList pkAttrs = mLayerCache->layer()->pkAttributeList();

    if ( !pkAttrs.isEmpty() )
    {
      if ( pkAttrs.size() == 1 )
        defaultField = pkAttrs.at( 0 );

      // ... If there are primary key(s) defined
      QStringList pkFields;

      Q_FOREACH ( int attr, pkAttrs )
      {
        pkFields.append( "COALESCE(\"" + fields[attr].name() + "\", '<NULL>')" );
      }

      displayExpression = pkFields.join( "||', '||" );
    }
void QgsVectorDataProvider::uniqueValues( int index, QList<QVariant> &values, int limit )
{
  QgsFeature f;
  QgsAttributeList keys;
  keys.append( index );
  QgsFeatureIterator fi = getFeatures( QgsFeatureRequest().setSubsetOfAttributes( keys ) );

  QSet<QString> set;
  values.clear();

  while ( fi.nextFeature( f ) )
  {
    if ( !set.contains( f.attribute( index ).toString() ) )
    {
      values.append( f.attribute( index ) );
      set.insert( f.attribute( index ).toString() );
    }

    if ( limit >= 0 && values.size() >= limit )
      break;
  }
}
void QgsVectorDataProvider::uniqueValues( int index, QList<QVariant> &values, int limit )
{
  QgsFeature f;
  QgsAttributeList keys;
  keys.append( index );
  select( keys, QgsRectangle(), false );

  QSet<QString> set;
  values.clear();

  while ( nextFeature( f ) )
  {
    if ( !set.contains( f.attributeMap()[index].toString() ) )
    {
      values.append( f.attributeMap()[index] );
      set.insert( f.attributeMap()[index].toString() );
    }

    if ( limit >= 0 && values.size() >= limit )
      break;
  }
}
void QgsAttributeTableModel::loadAttributes()
{
  if ( !layer() )
  {
    return;
  }

  bool ins = false, rm = false;

  QgsAttributeList attributes;
  const QgsFields &fields = layer()->fields();

  mWidgetFactories.clear();
  mAttributeWidgetCaches.clear();
  mWidgetConfigs.clear();

  for ( int idx = 0; idx < fields.count(); ++idx )
  {
    const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( layer(), fields[idx].name() );
    QgsEditorWidgetFactory *widgetFactory = QgsGui::editorWidgetRegistry()->factory( setup.type() );
    QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );

    mWidgetFactories.append( widgetFactory );
    mWidgetConfigs.append( setup.config() );
    mAttributeWidgetCaches.append( fieldFormatter->createCache( layer(), idx, setup.config() ) );
    mFieldFormatters.append( fieldFormatter );

    attributes << idx;
  }

  if ( mFieldCount + mExtraColumns < attributes.size() + mExtraColumns )
  {
    ins = true;
    beginInsertColumns( QModelIndex(), mFieldCount + mExtraColumns, attributes.size() - 1 );
  }
  else if ( attributes.size() + mExtraColumns < mFieldCount + mExtraColumns )
  {
    rm = true;
    beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount + mExtraColumns - 1 );
  }

  mFieldCount = attributes.size();
  mAttributes = attributes;

  for ( SortCache &cache : mSortCaches )
  {
    if ( cache.sortFieldIndex >= mAttributes.count() )
      cache.sortFieldIndex = -1;
  }

  if ( ins )
  {
    endInsertColumns();
  }
  else if ( rm )
  {
    endRemoveColumns();
  }
}
void QgsDb2FeatureIterator::BuildStatement( const QgsFeatureRequest &request )
{
  bool limitAtProvider = ( mRequest.limit() >= 0 );
  QString delim;

  // build sql statement
  mStatement = QStringLiteral( "SELECT " );

  if ( !mSource->mFidColName.isEmpty() )
  {
    mStatement += mSource->mFidColName;
    mFidCol = mSource->mFields.indexFromName( mSource->mFidColName );
    mAttributesToFetch.append( mFidCol );
    delim = QStringLiteral( "," );
  }

  bool subsetOfAttributes = mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes;
  QgsAttributeList attrs = subsetOfAttributes ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();

  // ensure that all attributes required for expression filter are being fetched
  if ( subsetOfAttributes && request.filterType() == QgsFeatureRequest::FilterExpression )
  {
    //ensure that all fields required for filter expressions are prepared
    QSet<int> attributeIndexes = request.filterExpression()->referencedAttributeIndexes( mSource->mFields );
    attributeIndexes += attrs.toSet();
    attrs = attributeIndexes.toList();
  }

  Q_FOREACH ( int i, attrs )
  {
    QString fieldname = mSource->mFields.at( i ).name();
    if ( mSource->mFidColName == fieldname )
      continue;
    mStatement += delim + fieldname;
    delim = QStringLiteral( "," );
    mAttributesToFetch.append( i );
    QgsDebugMsg( QString( "i: %1; name: %2" ).arg( i ).arg( fieldname ) );
  }
void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest &request )
{
  mFallbackStatement.clear();
  mStatement.clear();

  bool limitAtProvider = ( mRequest.limit() >= 0 );

  // build sql statement

  // note: 'SELECT ' is added later, to account for 'SELECT TOP...' type queries
  mStatement += QStringLiteral( "[%1]" ).arg( mSource->mFidColName );
  mFidCol = mSource->mFields.indexFromName( mSource->mFidColName );
  mAttributesToFetch.append( mFidCol );

  bool subsetOfAttributes = mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes;
  QgsAttributeList attrs = subsetOfAttributes ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();

  // ensure that all attributes required for expression filter are being fetched
  if ( subsetOfAttributes && request.filterType() == QgsFeatureRequest::FilterExpression )
  {
    //ensure that all fields required for filter expressions are prepared
    QSet<int> attributeIndexes = request.filterExpression()->referencedAttributeIndexes( mSource->mFields );
    attributeIndexes += attrs.toSet();
    attrs = attributeIndexes.toList();
  }

  Q_FOREACH ( int i, attrs )
  {
    QString fieldname = mSource->mFields.at( i ).name();
    if ( mSource->mFidColName == fieldname )
      continue;

    mStatement += QStringLiteral( ",[%1]" ).arg( fieldname );

    mAttributesToFetch.append( i );
  }
void QgsGrassFeatureIterator::setFeatureAttributes( int cat, QgsFeature *feature, const QgsAttributeList& attlist )
{
#if QGISDEBUG > 3
  QgsDebugMsg( QString( "setFeatureAttributes cat = %1" ).arg( cat ) );
#endif
  GLAYER& glayer = QgsGrassProvider::mLayers[mSource->mLayerId];

  if ( glayer.nColumns > 0 )
  {
    // find cat
    GATT key;
    key.cat = cat;
    GATT *att = ( GATT * ) bsearch( &key, glayer.attributes, glayer.nAttributes,
                                    sizeof( GATT ), QgsGrassProvider::cmpAtt );

    feature->initAttributes( glayer.nColumns );

    for ( QgsAttributeList::const_iterator iter = attlist.begin(); iter != attlist.end(); ++iter )
    {
      if ( att != NULL )
      {
        QByteArray cstr( att->values[*iter] );
        feature->setAttribute( *iter, QgsGrassProvider::convertValue( glayer.fields[*iter].type(), mSource->mEncoding->toUnicode( cstr ) ) );
      }
      else   /* it may happen that attributes are missing -> set to empty string */
      {
        feature->setAttribute( *iter, QVariant() );
      }
    }
  }
  else
  {
    feature->initAttributes( 1 );
    feature->setAttribute( 0, QVariant( cat ) );
  }
}
void QgsAttributeTableModel::loadAttributes()
{
  if ( !layer() )
  {
    return;
  }

  bool ins = false, rm = false;

  QgsAttributeList attributes;
  const QgsFields& fields = layer()->pendingFields();

  mWidgetFactories.clear();
  mAttributeWidgetCaches.clear();
  mWidgetConfigs.clear();

  for ( int idx = 0; idx < fields.count(); ++idx )
  {
    QgsEditorWidgetFactory* widgetFactory = QgsEditorWidgetRegistry::instance()->factory( layer()->editorWidgetV2( idx ) );
    if ( !widgetFactory || !layer() )
      continue;

    mWidgetFactories.append( widgetFactory );
    mWidgetConfigs.append( layer()->editorWidgetV2Config( idx ) );
    mAttributeWidgetCaches.append( widgetFactory->createCache( layer(), idx, mWidgetConfigs.last() ) );

    attributes << idx;
  }

  if ( mFieldCount < attributes.size() )
  {
    ins = true;
    beginInsertColumns( QModelIndex(), mFieldCount, attributes.size() - 1 );
  }
  else if ( attributes.size() < mFieldCount )
  {
    rm = true;
    beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount - 1 );
  }

  mFieldCount = attributes.size();
  mAttributes = attributes;

  if ( ins )
  {
    endInsertColumns();
  }
  else if ( rm )
  {
    endRemoveColumns();
  }
}
void QgsAttributeTableModel::loadAttributes()
{
  if ( !mLayer )
  {
    return;
  }

  bool ins = false, rm = false;

  QgsAttributeList attributes;
  for ( QgsFieldMap::const_iterator it = mLayer->pendingFields().constBegin(); it != mLayer->pendingFields().end(); it++ )
  {
    switch ( mLayer->editType( it.key() ) )
    {
      case QgsVectorLayer::Hidden:
        continue;

      case QgsVectorLayer::ValueMap:
        mValueMaps.insert( it.key(), &mLayer->valueMap( it.key() ) );
        break;

      default:
        break;
    }

    attributes << it.key();
  }

  if ( mFieldCount < attributes.size() )
  {
    ins = true;
    beginInsertColumns( QModelIndex(), mFieldCount, attributes.size() - 1 );
  }
  else if ( attributes.size() < mFieldCount )
  {
    rm = true;
    beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount - 1 );
  }

  mFieldCount = attributes.size();
  mAttributes = attributes;
  mValueMaps.clear();

  if ( ins )
  {
    endInsertColumns();
  }
  else if ( rm )
  {
    endRemoveColumns();
  }
}
void QgsPointDisplacementRenderer::createDisplacementGroups( QgsVectorLayer* vlayer, const QgsRectangle& viewExtent )
{
  if ( !vlayer || ( vlayer->wkbType() != QGis::WKBPoint && vlayer->wkbType() != QGis::WKBPoint25D ) )
  {
    return;
  }

  mDisplacementGroups.clear();
  mDisplacementIds.clear();

  //use a spatial index to check if there is already a point at a position
  QgsSpatialIndex spatialIndex;

  //attributes
  QgsAttributeList attList;
  QList<QString> attributeStrings = usedAttributes();
  QList<QString>::const_iterator attStringIt = attributeStrings.constBegin();
  for ( ; attStringIt != attributeStrings.constEnd(); ++attStringIt )
  {
    attList.push_back( vlayer->fieldNameIndex( *attStringIt ) );
  }

  QgsFeature f;
  QList<QgsFeatureId> intersectList;

  //Because the new vector api does not allow querying features by id within a nextFeature loop, default constructed QgsFeature() is
  //inserted first and the real features are created in a second loop

  QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( viewExtent ).setSubsetOfAttributes( attList ) );
  while ( fit.nextFeature( f ) )
  {
    intersectList.clear();

    //check, if there is already a point at that position
    if ( f.geometry() )
    {
      intersectList = spatialIndex.intersects( searchRect( f.geometry()->asPoint() ) );
      if ( intersectList.empty() )
      {
        spatialIndex.insertFeature( f );
      }
      else
      {
        //go through all the displacement group maps and search an entry where the id equals the result of the spatial search
        QgsFeatureId existingEntry = intersectList.at( 0 );
        bool found = false;
        QList< QMap<QgsFeatureId, QgsFeature> >::iterator it = mDisplacementGroups.begin();
        for ( ; it != mDisplacementGroups.end(); ++it )
        {
          if ( it->size() > 0 && it->contains( existingEntry ) )
          {
            found = true;
            QgsFeature feature;
            it->insert( f.id(), QgsFeature() );
            mDisplacementIds.insert( f.id() );
            break;
          }
        }

        if ( !found )//insert the already existing feature and the new one into a map
        {
          QMap<QgsFeatureId, QgsFeature> newMap;
          newMap.insert( existingEntry, QgsFeature() );
          mDisplacementIds.insert( existingEntry );
          newMap.insert( f.id(), QgsFeature() );
          mDisplacementIds.insert( f.id() );
          mDisplacementGroups.push_back( newMap );
        }
      }
    }
  }

  //insert the real features into mDisplacementGroups
  QList< QMap<QgsFeatureId, QgsFeature> >::iterator it = mDisplacementGroups.begin();
  for ( ; it != mDisplacementGroups.end(); ++it )
  {
    QMap<QgsFeatureId, QgsFeature>::iterator mapIt = it->begin();
    for ( ; mapIt != it->end(); ++mapIt )
    {
      QgsFeature fet;
      vlayer->getFeatures( QgsFeatureRequest().setFilterFid( mapIt.key() ) ).nextFeature( fet );
      mapIt.value() = fet;
    }
  }

}