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 );
}
Example #2
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;
}
Example #3
0
bool QgsOgrFeatureIterator::readFeature( gdal::ogr_feature_unique_ptr fet, QgsFeature &feature ) const
{
  feature.setId( OGR_F_GetFID( fet.get() ) );
  feature.initAttributes( mSource->mFields.count() );
  feature.setFields( mSource->mFields ); // allow name-based attribute lookups

  bool useIntersect = !mRequest.filterRect().isNull();
  bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown;
  if ( mFetchGeometry || useIntersect || geometryTypeFilter )
  {
    OGRGeometryH geom = OGR_F_GetGeometryRef( fet.get() );

    if ( geom )
    {
      QgsGeometry g = QgsOgrUtils::ogrGeometryToQgsGeometry( geom );

      // Insure that multipart datasets return multipart geometry
      if ( QgsWkbTypes::isMultiType( mSource->mWkbType ) && !g.isMultipart() )
      {
        g.convertToMultiType();
      }

      feature.setGeometry( g );
    }
    else
      feature.clearGeometry();

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

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

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

  return true;
}