Exemplo n.º 1
0
QgsCachedFeatureIterator::QgsCachedFeatureIterator( QgsVectorLayerCache *vlCache, const QgsFeatureRequest &featureRequest )
  : QgsAbstractFeatureIterator( featureRequest )
  , mVectorLayerCache( vlCache )
{
  if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mVectorLayerCache->sourceCrs() )
  {
    mTransform = QgsCoordinateTransform( mVectorLayerCache->sourceCrs(), mRequest.destinationCrs() );
  }
  try
  {
    mFilterRect = filterRectToSourceCrs( mTransform );
  }
  catch ( QgsCsException & )
  {
    // can't reproject mFilterRect
    close();
    return;
  }
  if ( !mFilterRect.isNull() )
  {
    // update request to be the unprojected filter rect
    mRequest.setFilterRect( mFilterRect );
  }

  switch ( featureRequest.filterType() )
  {
    case QgsFeatureRequest::FilterFids:
      mFeatureIds = featureRequest.filterFids();
      break;

    case QgsFeatureRequest::FilterFid:
      mFeatureIds = QgsFeatureIds() << featureRequest.filterFid();
      break;

    default:
      mFeatureIds = mVectorLayerCache->mCache.keys().toSet();
      break;
  }

  mFeatureIdIterator = mFeatureIds.constBegin();

  if ( mFeatureIdIterator == mFeatureIds.constEnd() )
    close();
}
Exemplo n.º 2
0
QgsCachedFeatureIterator::QgsCachedFeatureIterator( QgsVectorLayerCache *vlCache, QgsFeatureRequest featureRequest )
    : QgsAbstractFeatureIterator( featureRequest )
    , mVectorLayerCache( vlCache )
{
  switch ( featureRequest.filterType() )
  {
    case QgsFeatureRequest::FilterFids:
      mFeatureIds = featureRequest.filterFids();
      break;

    case QgsFeatureRequest::FilterFid:
      mFeatureIds = QgsFeatureIds() << featureRequest.filterFid();
      break;

    default:
      mFeatureIds = mVectorLayerCache->mCache.keys().toSet();
      break;
  }

  mFeatureIdIterator = mFeatureIds.begin();
}
Exemplo n.º 3
0
QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresProvider* p, const QgsFeatureRequest& request )
    : QgsAbstractFeatureIterator( request ), P( p )
    , mFeatureQueueSize( sFeatureQueueSize )
{
    mCursorName = QString( "qgisf%1_%2" ).arg( P->mProviderId ).arg( P->mIteratorCounter++ );

    P->mActiveIterators << this;

    QString whereClause;

    if ( request.filterType() == QgsFeatureRequest::FilterRect && !P->mGeometryColumn.isNull() )
    {
        whereClause = whereClauseRect();
    }
    else if ( request.filterType() == QgsFeatureRequest::FilterFid )
    {
        whereClause = P->whereClause( request.filterFid() );
    }
    else if ( request.filterType() == QgsFeatureRequest::FilterFids )
    {
        whereClause = P->whereClause( request.filterFids() );
    }

    if ( !P->mSqlWhereClause.isEmpty() )
    {
        if ( !whereClause.isEmpty() )
            whereClause += " AND ";

        whereClause += "(" + P->mSqlWhereClause + ")";
    }

    if ( !declareCursor( whereClause ) )
    {
        mClosed = true;
        return;
    }

    mFetched = 0;
}
Exemplo n.º 4
0
bool QgsCacheIndexFeatureId::getCacheIterator( QgsFeatureIterator &featureIterator, const QgsFeatureRequest &featureRequest )
{
  switch ( featureRequest.filterType() )
  {
    case QgsFeatureRequest::FilterFid:
    {
      if ( C->isFidCached( featureRequest.filterFid() ) )
      {
        featureIterator = QgsFeatureIterator( new QgsCachedFeatureIterator( C, featureRequest ) );
        return true;
      }
      break;
    }
    case QgsFeatureRequest::FilterFids:
    {
      if ( C->cachedFeatureIds().contains( featureRequest.filterFids() ) )
      {
        featureIterator = QgsFeatureIterator( new QgsCachedFeatureIterator( C, featureRequest ) );
        return true;
      }
      break;
    }
    case QgsFeatureRequest::FilterNone:
    case QgsFeatureRequest::FilterExpression:
    {
      if ( C->hasFullCache() )
      {
        featureIterator = QgsFeatureIterator( new QgsCachedFeatureIterator( C, featureRequest ) );
        return true;
      }
      break;
    }
  }

  return false;
}
QgsVirtualLayerFeatureIterator::QgsVirtualLayerFeatureIterator( QgsVirtualLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request )
  : QgsAbstractFeatureIteratorFromSource<QgsVirtualLayerFeatureSource>( source, ownSource, request )
{

  // NOTE: this is really bad and should be removed.
  // it's only here to guard mSource->mSqlite - because if the provider is removed
  // then mSqlite will be meaningless.
  // this needs to be totally reworked so that mSqlite no longer depends on the provider
  // and can be fully encapsulated in the source
  if ( !mSource->mProvider )
  {
    close();
    return;
  }

  if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mSource->mCrs )
  {
    mTransform = QgsCoordinateTransform( mSource->mCrs, mRequest.destinationCrs(), mRequest.transformContext() );
  }
  try
  {
    mFilterRect = filterRectToSourceCrs( mTransform );
  }
  catch ( QgsCsException & )
  {
    // can't reproject mFilterRect
    close();
    return;
  }

  try
  {
    QString tableName = mSource->mTableName;

    QStringList wheres;
    QString offset;
    QString subset = mSource->mSubset;
    if ( !subset.isEmpty() )
    {
      wheres << subset;
    }

    if ( !mSource->mDefinition.uid().isNull() )
    {
      // filters are only available when a column with unique id exists
      if ( mSource->mDefinition.hasDefinedGeometry() && !mFilterRect.isNull() )
      {
        bool do_exact = request.flags() & QgsFeatureRequest::ExactIntersect;
        QString mbr = QStringLiteral( "%1,%2,%3,%4" ).arg( mFilterRect.xMinimum() ).arg( mFilterRect.yMinimum() ).arg( mFilterRect.xMaximum() ).arg( mFilterRect.yMaximum() );
        wheres << quotedColumn( mSource->mDefinition.geometryField() ) + " is not null";
        wheres <<  QStringLiteral( "%1Intersects(%2,BuildMbr(%3))" )
               .arg( do_exact ? "" : "Mbr",
                     quotedColumn( mSource->mDefinition.geometryField() ),
                     mbr );
      }
      else if ( request.filterType() == QgsFeatureRequest::FilterFid )
      {
        wheres << QStringLiteral( "%1=%2" )
               .arg( quotedColumn( mSource->mDefinition.uid() ) )
               .arg( request.filterFid() );
      }
      else if ( request.filterType() == QgsFeatureRequest::FilterFids )
      {
        QString values = quotedColumn( mSource->mDefinition.uid() ) + " IN (";
        bool first = true;
        const auto constFilterFids = request.filterFids();
        for ( QgsFeatureId v : constFilterFids )
        {
          if ( !first )
          {
            values += QLatin1String( "," );
          }
          first = false;
          values += QString::number( v );
        }
        values += QLatin1String( ")" );
        wheres << values;
      }
    }
    else
    {
      if ( request.filterType() == QgsFeatureRequest::FilterFid )
      {
        if ( request.filterFid() >= 0 )
          offset = QStringLiteral( " LIMIT 1 OFFSET %1" ).arg( request.filterFid() );
        else // never return a feature if the id is negative
          offset = QStringLiteral( " LIMIT 0" );
      }
      else if ( !mFilterRect.isNull() &&
                mRequest.flags() & QgsFeatureRequest::ExactIntersect )
      {
        // if an exact intersection is requested, prepare the geometry to intersect
        QgsGeometry rectGeom = QgsGeometry::fromRect( mFilterRect );
        mRectEngine.reset( QgsGeometry::createGeometryEngine( rectGeom.constGet() ) );
        mRectEngine->prepareGeometry();
      }
    }

    if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes )
    {
      // copy only selected fields
      const auto subsetOfAttributes = request.subsetOfAttributes();
      for ( int idx : subsetOfAttributes )
      {
        mAttributes << idx;
      }

      // ensure that all attributes required for expression filter are being fetched
      if ( request.filterType() == QgsFeatureRequest::FilterExpression )
      {
        const auto constReferencedColumns = request.filterExpression()->referencedColumns();
        for ( const QString &field : constReferencedColumns )
        {
          int attrIdx = mSource->mFields.lookupField( field );
          if ( !mAttributes.contains( attrIdx ) )
            mAttributes << attrIdx;
        }
      }

      // also need attributes required by order by
      if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && !mRequest.orderBy().isEmpty() )
      {
        const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
        for ( int attrIdx : usedAttributeIndices )
        {
          if ( !mAttributes.contains( attrIdx ) )
            mAttributes << attrIdx;
        }
      }
    }
    else
    {
      mAttributes = mSource->mFields.allAttributesList();
    }

    QString columns;
    {
      // the first column is always the uid (or 0)
      if ( !mSource->mDefinition.uid().isNull() )
      {
        columns = quotedColumn( mSource->mDefinition.uid() );
      }
      else
      {
        if ( request.filterType() == QgsFeatureRequest::FilterFid )
        {
          columns = QString::number( request.filterFid() );
        }
        else
        {
          columns = QStringLiteral( "0" );
        }
      }
      const auto constMAttributes = mAttributes;
      for ( int i : constMAttributes )
      {
        columns += QLatin1String( "," );
        QString cname = mSource->mFields.at( i ).name().toLower();
        columns += quotedColumn( cname );
      }
    }
    // the last column is the geometry, if any
    if ( ( !( request.flags() & QgsFeatureRequest::NoGeometry )
           || ( request.filterType() == QgsFeatureRequest::FilterExpression && request.filterExpression()->needsGeometry() ) )
         && !mSource->mDefinition.geometryField().isNull() && mSource->mDefinition.geometryField() != QLatin1String( "*no*" ) )
    {
      columns += "," + quotedColumn( mSource->mDefinition.geometryField() );
    }

    mSqlQuery = "SELECT " + columns + " FROM " + tableName;
    if ( !wheres.isEmpty() )
    {
      mSqlQuery += " WHERE " + wheres.join( QStringLiteral( " AND " ) );
    }

    if ( !offset.isEmpty() )
    {
      mSqlQuery += offset;
    }

    mQuery.reset( new Sqlite::Query( mSource->mSqlite, mSqlQuery ) );

    mFid = 0;
  }
  catch ( std::runtime_error &e )
  {
    QgsMessageLog::logMessage( e.what(), QObject::tr( "VLayer" ) );
    close();
  }
}
Exemplo n.º 6
0
QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleFeatureSource* source, bool ownSource, const QgsFeatureRequest &request )
    : QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
    , mRewind( false )
{
    mConnection = QgsOracleConn::connectDb( mSource->mUri.connectionInfo() );
    if ( !mConnection )
    {
        close();
        return;
    }

    mQry = QSqlQuery( *mConnection );

    if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
    {
        mAttributeList = mRequest.subsetOfAttributes();
        if ( mAttributeList.isEmpty() )
            mAttributeList = mSource->mFields.allAttributesList();
    }
    else
        mAttributeList = mSource->mFields.allAttributesList();

    QString whereClause;

    switch ( request.filterType() )
    {
    case QgsFeatureRequest::FilterExpression:
        break;

    case QgsFeatureRequest::FilterRect:
        if ( !mSource->mGeometryColumn.isNull() )
        {
            QgsRectangle rect( mRequest.filterRect() );
            QString bbox = QString( "mdsys.sdo_geometry(2003,%1,NULL,"
                                    "mdsys.sdo_elem_info_array(1,1003,3),"
                                    "mdsys.sdo_ordinate_array(%2,%3,%4,%5)"
                                    ")" )
                           .arg( mSource->mSrid < 1 ? "NULL" : QString::number( mSource->mSrid ) )
                           .arg( qgsDoubleToString( rect.xMinimum() ) )
                           .arg( qgsDoubleToString( rect.yMinimum() ) )
                           .arg( qgsDoubleToString( rect.xMaximum() ) )
                           .arg( qgsDoubleToString( rect.yMaximum() ) );

            if ( !mSource->mSpatialIndex.isNull() )
            {
                whereClause = QString( "sdo_filter(%1,%2)='TRUE'" ).arg( QgsOracleProvider::quotedIdentifier( mSource->mGeometryColumn ) ).arg( bbox );
#if 0
                if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect )
                {
                    whereClause += QString( " AND sdo_relate(%1,%2,'mask=ANYINTERACT')='TRUE'" )
                                   .arg( quotedIdentifier( P->mGeometryColumn ) )
                                   .arg( bbox );
                }
#endif
            }
        }
        break;

    case QgsFeatureRequest::FilterFid:
        whereClause = QgsOracleUtils::whereClause( request.filterFid(), mSource->mFields, mSource->mPrimaryKeyType, mSource->mPrimaryKeyAttrs, mSource->mShared );
        break;

    case QgsFeatureRequest::FilterFids:
        whereClause = QgsOracleUtils::whereClause( request.filterFids(), mSource->mFields, mSource->mPrimaryKeyType, mSource->mPrimaryKeyAttrs, mSource->mShared );
        break;

    case QgsFeatureRequest::FilterNone:
        break;
    }

    if ( mSource->mRequestedGeomType != QGis::WKBUnknown && mSource->mRequestedGeomType != mSource->mDetectedGeomType )
    {
        if ( !whereClause.isEmpty() )
            whereClause += " AND ";

        whereClause += QgsOracleConn::databaseTypeFilter( "featureRequest", mSource->mGeometryColumn, mSource->mRequestedGeomType );
    }

    if ( !mSource->mSqlWhereClause.isEmpty() )
    {
        if ( !whereClause.isEmpty() )
            whereClause += " AND ";
        whereClause += "(" + mSource->mSqlWhereClause + ")";
    }

    if ( !openQuery( whereClause ) )
        return;
}
QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleProvider *p, const QgsFeatureRequest &request )
    : QgsAbstractFeatureIterator( request )
    , P( p )
    , mRewind( false )
{
  P->mActiveIterators << this;

  mQry = QSqlQuery( *P->mConnection );

  if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    mAttributeList = mRequest.subsetOfAttributes();
    if ( mAttributeList.isEmpty() )
      mAttributeList = P->attributeIndexes();
  }
  else
    mAttributeList = P->attributeIndexes();

  QString whereClause;

  switch ( request.filterType() )
  {
    case QgsFeatureRequest::FilterExpression:
      break;

    case QgsFeatureRequest::FilterRect:
      if ( !P->mGeometryColumn.isNull() )
      {
        QgsRectangle rect( mRequest.filterRect() );
        QString bbox = QString( "mdsys.sdo_geometry(2003,%1,NULL,"
                                "mdsys.sdo_elem_info_array(1,1003,3),"
                                "mdsys.sdo_ordinate_array(%2,%3,%4,%5)"
                                ")" )
                       .arg( P->mSrid < 1 ? "NULL" : QString::number( P->mSrid ) )
                       .arg( qgsDoubleToString( rect.xMinimum() ) )
                       .arg( qgsDoubleToString( rect.yMinimum() ) )
                       .arg( qgsDoubleToString( rect.xMaximum() ) )
                       .arg( qgsDoubleToString( rect.yMaximum() ) );

        if ( !P->mSpatialIndex.isNull() )
        {
          whereClause = QString( "sdo_filter(%1,%2)='TRUE'" ).arg( P->quotedIdentifier( P->mGeometryColumn ) ).arg( bbox );
#if 0
          if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect )
          {
            whereClause += QString( " AND sdo_relate(%1,%2,'mask=ANYINTERACT')='TRUE'" )
                           .arg( quotedIdentifier( P->mGeometryColumn ) )
                           .arg( bbox );
          }
#endif
        }
      }
      break;

    case QgsFeatureRequest::FilterFid:
      whereClause = P->whereClause( request.filterFid() );
      break;

    case QgsFeatureRequest::FilterFids:
      whereClause = P->whereClause( request.filterFids() );
      break;

    case QgsFeatureRequest::FilterNone:
      break;
  }

  if ( P->mRequestedGeomType != QGis::WKBUnknown && P->mRequestedGeomType != P->mDetectedGeomType )
  {
    if ( !whereClause.isEmpty() )
      whereClause += " AND ";

    whereClause += QgsOracleConn::databaseTypeFilter( "featureRequest", P->mGeometryColumn, P->mRequestedGeomType );
  }

  if ( !P->mSqlWhereClause.isEmpty() )
  {
    if ( !whereClause.isEmpty() )
      whereClause += " AND ";
    whereClause += "(" + P->mSqlWhereClause + ")";
  }

  if ( !openQuery( whereClause ) )
    return;
}