Exemple #1
0
QgsMemoryProvider::QgsMemoryProvider( const QString &uri, const ProviderOptions &options )
  : QgsVectorDataProvider( uri, options )
{
  // Initialize the geometry with the uri to support old style uri's
  // (ie, just 'point', 'line', 'polygon')
  QUrl url = QUrl::fromEncoded( uri.toUtf8() );
  QString geometry;
  if ( url.hasQueryItem( QStringLiteral( "geometry" ) ) )
  {
    geometry = url.queryItemValue( QStringLiteral( "geometry" ) );
  }
  else
  {
    geometry = url.path();
  }

  if ( geometry.toLower() == QLatin1String( "none" ) )
  {
    mWkbType = QgsWkbTypes::NoGeometry;
  }
  else
  {
    mWkbType = QgsWkbTypes::parseType( geometry );
  }

  if ( url.hasQueryItem( QStringLiteral( "crs" ) ) )
  {
    QString crsDef = url.queryItemValue( QStringLiteral( "crs" ) );
    mCrs.createFromString( crsDef );
  }

  mNextFeatureId = 1;

  setNativeTypes( QList< NativeType >()
                  << QgsVectorDataProvider::NativeType( tr( "Whole number (integer)" ), QStringLiteral( "integer" ), QVariant::Int, 0, 10 )
                  // Decimal number from OGR/Shapefile/dbf may come with length up to 32 and
                  // precision up to length-2 = 30 (default, if width is not specified in dbf is length = 24 precision = 15)
                  // We know that double (QVariant::Double) has only 15-16 significant numbers,
                  // but setting that correct limits would disable the use of memory provider with
                  // data from Shapefiles. In any case, the data are handled as doubles.
                  // So the limits set here are not correct but enable use of data from Shapefiles.
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "double" ), QVariant::Double, 0, 32, 0, 30 )
                  << QgsVectorDataProvider::NativeType( tr( "Text (string)" ), QStringLiteral( "string" ), QVariant::String, 0, 255 )

                  // date type
                  << QgsVectorDataProvider::NativeType( tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 )
                  << QgsVectorDataProvider::NativeType( tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 )
                  << QgsVectorDataProvider::NativeType( tr( "Date & Time" ), QStringLiteral( "datetime" ), QVariant::DateTime, -1, -1, -1, -1 )

                  // integer types
                  << QgsVectorDataProvider::NativeType( tr( "Whole number (smallint - 16bit)" ), QStringLiteral( "int2" ), QVariant::Int, -1, -1, 0, 0 )
                  << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 32bit)" ), QStringLiteral( "int4" ), QVariant::Int, -1, -1, 0, 0 )
                  << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 64bit)" ), QStringLiteral( "int8" ), QVariant::LongLong, -1, -1, 0, 0 )
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 20, 0, 20 )
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 20, 0, 20 )

                  // floating point
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double, -1, -1, -1, -1 )
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double precision" ), QVariant::Double, -1, -1, -1, -1 )

                  // string types
                  << QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String, -1, -1, -1, -1 )
                );

  if ( url.hasQueryItem( QStringLiteral( "field" ) ) )
  {
    QList<QgsField> attributes;
    QRegExp reFieldDef( "\\:"
                        "(int|integer|long|int8|real|double|string|date|time|datetime)" // type
                        "(?:\\((\\-?\\d+)"                // length
                        "(?:\\,(\\d+))?"                  // precision
                        "\\))?(\\[\\])?"                  // array
                        "$", Qt::CaseInsensitive );
    QStringList fields = url.allQueryItemValues( QStringLiteral( "field" ) );
    for ( int i = 0; i < fields.size(); i++ )
    {
      QString name = QUrl::fromPercentEncoding( fields.at( i ).toUtf8() );
      QVariant::Type type = QVariant::String;
      QVariant::Type subType = QVariant::Invalid;
      QString typeName( QStringLiteral( "string" ) );
      int length = 255;
      int precision = 0;

      int pos = reFieldDef.indexIn( name );
      if ( pos >= 0 )
      {
        name = name.mid( 0, pos );
        typeName = reFieldDef.cap( 1 ).toLower();
        if ( typeName == QLatin1String( "int" ) || typeName == QLatin1String( "integer" ) )
        {
          type = QVariant::Int;
          typeName = QStringLiteral( "integer" );
          length = -1;
        }
        else if ( typeName == QLatin1String( "int8" ) || typeName == QLatin1String( "long" ) )
        {
          type = QVariant::LongLong;
          typeName = QStringLiteral( "int8" );
          length = -1;
        }
        else if ( typeName == QLatin1String( "real" ) || typeName == QLatin1String( "double" ) )
        {
          type = QVariant::Double;
          typeName = QStringLiteral( "double" );
          length = 20;
          precision = 5;
        }
        else if ( typeName == QLatin1String( "date" ) )
        {
          type = QVariant::Date;
          typeName = QStringLiteral( "date" );
          length = -1;
        }
        else if ( typeName == QLatin1String( "time" ) )
        {
          type = QVariant::Time;
          typeName = QStringLiteral( "time" );
          length = -1;
        }
        else if ( typeName == QLatin1String( "datetime" ) )
        {
          type = QVariant::DateTime;
          typeName = QStringLiteral( "datetime" );
          length = -1;
        }

        if ( !reFieldDef.cap( 2 ).isEmpty() )
        {
          length = reFieldDef.cap( 2 ).toInt();
        }
        if ( !reFieldDef.cap( 3 ).isEmpty() )
        {
          precision = reFieldDef.cap( 3 ).toInt();
        }
        if ( !reFieldDef.cap( 4 ).isEmpty() )
        {
          //array
          subType = type;
          type = ( subType == QVariant::String ? QVariant::StringList : QVariant::List );
        }
      }
      if ( !name.isEmpty() )
        attributes.append( QgsField( name, type, typeName, length, precision, QLatin1String( "" ), subType ) );
    }
    addAttributes( attributes );
  }

  if ( url.hasQueryItem( QStringLiteral( "index" ) ) && url.queryItemValue( QStringLiteral( "index" ) ) == QLatin1String( "yes" ) )
  {
    createSpatialIndex();
  }

}
QgsDelimitedTextProvider::QgsDelimitedTextProvider( const QString& uri )
    : QgsVectorDataProvider( uri )
    , mLayerValid( false )
    , mValid( false )
    , mFile( nullptr )
    , mGeomRep( GeomNone )
    , mFieldCount( 0 )
    , mXFieldIndex( -1 )
    , mYFieldIndex( -1 )
    , mWktFieldIndex( -1 )
    , mWktHasPrefix( false )
    , mXyDms( false )
    , mSubsetString( QLatin1String( "" ) )
    , mSubsetExpression( nullptr )
    , mBuildSubsetIndex( true )
    , mUseSubsetIndex( false )
    , mMaxInvalidLines( 50 )
    , mShowInvalidLines( true )
    , mRescanRequired( false )
    , mCrs()
    , mWkbType( QgsWkbTypes::NoGeometry )
    , mGeometryType( QgsWkbTypes::UnknownGeometry )
    , mBuildSpatialIndex( false )
    , mSpatialIndex( nullptr )
{

  // Add supported types to enable creating expression fields in field calculator
  setNativeTypes( QList< NativeType >()
                  << QgsVectorDataProvider::NativeType( tr( "Whole number (integer)" ), QStringLiteral( "integer" ), QVariant::Int, 0, 10 )
                  << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 64 bit)" ), QStringLiteral( "int8" ), QVariant::LongLong )
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double precision" ), QVariant::Double, -1, -1, -1, -1 )
                  << QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String, -1, -1, -1, -1 )
                );

  QgsDebugMsg( "Delimited text file uri is " + uri );

  QUrl url = QUrl::fromEncoded( uri.toLatin1() );
  mFile = new QgsDelimitedTextFile();
  mFile->setFromUrl( url );

  QString subset;

  if ( url.hasQueryItem( QStringLiteral( "geomType" ) ) )
  {
    QString gtype = url.queryItemValue( QStringLiteral( "geomType" ) ).toLower();
    if ( gtype == QLatin1String( "point" ) ) mGeometryType = QgsWkbTypes::PointGeometry;
    else if ( gtype == QLatin1String( "line" ) ) mGeometryType = QgsWkbTypes::LineGeometry;
    else if ( gtype == QLatin1String( "polygon" ) ) mGeometryType = QgsWkbTypes::PolygonGeometry;
    else if ( gtype == QLatin1String( "none " ) ) mGeometryType = QgsWkbTypes::NullGeometry;
  }

  if ( mGeometryType != QgsWkbTypes::NullGeometry )
  {
    if ( url.hasQueryItem( QStringLiteral( "wktField" ) ) )
    {
      mWktFieldName = url.queryItemValue( QStringLiteral( "wktField" ) );
      mGeomRep = GeomAsWkt;
      QgsDebugMsg( "wktField is: " + mWktFieldName );
    }
    else if ( url.hasQueryItem( QStringLiteral( "xField" ) ) && url.hasQueryItem( QStringLiteral( "yField" ) ) )
    {
      mGeomRep = GeomAsXy;
      mGeometryType = QgsWkbTypes::PointGeometry;
      mXFieldName = url.queryItemValue( QStringLiteral( "xField" ) );
      mYFieldName = url.queryItemValue( QStringLiteral( "yField" ) );
      QgsDebugMsg( "xField is: " + mXFieldName );
      QgsDebugMsg( "yField is: " + mYFieldName );

      if ( url.hasQueryItem( QStringLiteral( "xyDms" ) ) )
      {
        mXyDms = ! url.queryItemValue( QStringLiteral( "xyDms" ) ).toLower().startsWith( 'n' );
      }
    }
    else
    {
      mGeometryType = QgsWkbTypes::NullGeometry;
    }
  }

  if ( url.hasQueryItem( QStringLiteral( "decimalPoint" ) ) )
    mDecimalPoint = url.queryItemValue( QStringLiteral( "decimalPoint" ) );

  if ( url.hasQueryItem( QStringLiteral( "crs" ) ) )
    mCrs.createFromString( url.queryItemValue( QStringLiteral( "crs" ) ) );

  if ( url.hasQueryItem( QStringLiteral( "subsetIndex" ) ) )
  {
    mBuildSubsetIndex = ! url.queryItemValue( QStringLiteral( "subsetIndex" ) ).toLower().startsWith( 'n' );
  }

  if ( url.hasQueryItem( QStringLiteral( "spatialIndex" ) ) )
  {
    mBuildSpatialIndex = ! url.queryItemValue( QStringLiteral( "spatialIndex" ) ).toLower().startsWith( 'n' );
  }

  if ( url.hasQueryItem( QStringLiteral( "subset" ) ) )
  {
    // We need to specify FullyDecoded so that %25 is decoded as %
    subset = QUrlQuery( url ).queryItemValue( QStringLiteral( "subset" ) , QUrl::FullyDecoded );
    QgsDebugMsg( "subset is: " + subset );
  }

  if ( url.hasQueryItem( QStringLiteral( "quiet" ) ) ) mShowInvalidLines = false;

  // Do an initial scan of the file to determine field names, types,
  // geometry type (for Wkt), extents, etc.  Parameter value subset.isEmpty()
  // avoid redundant building indexes if we will be building a subset string,
  // in which case indexes will be rebuilt.

  scanFile( subset.isEmpty() );

  if ( ! subset.isEmpty() )
  {
    setSubsetString( subset );
  }
}
Exemple #3
0
QgsDb2Provider::QgsDb2Provider( const QString &uri )
  : QgsVectorDataProvider( uri )
  , mNumberFeatures( 0 )
  , mFidColIdx( -1 )
  , mEnvironment( ENV_LUW )
  , mWkbType( QgsWkbTypes::Unknown )
{
  QgsDebugMsg( "uri: " + uri );
  QgsDataSourceUri anUri = QgsDataSourceUri( uri );
  if ( !anUri.srid().isEmpty() )
    mSRId = anUri.srid().toInt();
  else
    mSRId = -1;

  if ( 0 != anUri.wkbType() )
  {
    mWkbType = anUri.wkbType();
  }
  QgsDebugMsg( QString( "mWkbType: %1" ).arg( mWkbType ) );
  QgsDebugMsg( QString( "new mWkbType: %1" ).arg( anUri.wkbType() ) );

  mValid = true;
  mSkipFailures = false;
  int dim; // Not used
  db2WkbTypeAndDimension( mWkbType, mGeometryColType, dim ); // Get DB2 geometry type name

  mFidColName = anUri.keyColumn().toUpper();
  QgsDebugMsg( "mFidColName " + mFidColName );
  mExtents = anUri.param( QStringLiteral( "extents" ) );
  QgsDebugMsg( "mExtents " + mExtents );

  mUseEstimatedMetadata = anUri.useEstimatedMetadata();
  QgsDebugMsg( QString( "mUseEstimatedMetadata: '%1'" ).arg( mUseEstimatedMetadata ) );
  mSqlWhereClause = anUri.sql();
  QString errMsg;
  mDatabase = getDatabase( uri, errMsg );
  mConnInfo = anUri.connectionInfo();
  QgsCoordinateReferenceSystem layerCrs = crs();
  QgsDebugMsg( "CRS: " + layerCrs.toWkt() );

  if ( !errMsg.isEmpty() )
  {
    setLastError( errMsg );
    QgsDebugMsg( mLastError );
    mValid = false;
    return;
  }

  // Create a query for default connection
  mQuery = QSqlQuery( mDatabase );

  mSchemaName = anUri.schema();

  mTableName = anUri.table().toUpper();
  QStringList sl = mTableName.split( '.' );
  if ( sl.length() == 2 )  // Never seems to be the case
  {
    mSchemaName = sl[0];
    mTableName = sl[1];
  }
  if ( mSchemaName.isEmpty() )
  {
    mSchemaName = anUri.username().toUpper();
  }

  QgsDebugMsg( "mSchemaName: '" + mSchemaName + "; mTableName: '" + mTableName );

  if ( !anUri.geometryColumn().isEmpty() )
    mGeometryColName = anUri.geometryColumn().toUpper();

  loadFields();
  updateStatistics();

  if ( mGeometryColName.isEmpty() )
  {
    // table contains no geometries
    mWkbType = QgsWkbTypes::NoGeometry;
    mSRId = 0;
  }

  //fill type names into sets
  setNativeTypes( QList< NativeType >()
                  // integer types
                  << QgsVectorDataProvider::NativeType( tr( "8 Bytes integer" ), QStringLiteral( "bigint" ), QVariant::Int )
                  << QgsVectorDataProvider::NativeType( tr( "4 Bytes integer" ), QStringLiteral( "integer" ), QVariant::Int )
                  << QgsVectorDataProvider::NativeType( tr( "2 Bytes integer" ), QStringLiteral( "smallint" ), QVariant::Int )
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 31, 0, 31 )
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 31, 0, 31 )

                  // floating point
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double )
                  << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double" ), QVariant::Double )

                  // date/time types
                  << QgsVectorDataProvider::NativeType( tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 )
                  << QgsVectorDataProvider::NativeType( tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 )
                  << QgsVectorDataProvider::NativeType( tr( "Date & Time" ), QStringLiteral( "datetime" ), QVariant::DateTime, -1, -1, -1, -1 )

                  // string types
                  << QgsVectorDataProvider::NativeType( tr( "Text, fixed length (char)" ), QStringLiteral( "char" ), QVariant::String, 1, 254 )
                  << QgsVectorDataProvider::NativeType( tr( "Text, variable length (varchar)" ), QStringLiteral( "varchar" ), QVariant::String, 1, 32704 )
                  << QgsVectorDataProvider::NativeType( tr( "Text, variable length large object (clob)" ), QStringLiteral( "clob" ), QVariant::String, 1, 2147483647 )
                  //DBCLOB is for 1073741824 double-byte characters, data length should be the same as CLOB (2147483647)?
                  << QgsVectorDataProvider::NativeType( tr( "Text, variable length large object (dbclob)" ), QStringLiteral( "dbclob" ), QVariant::String, 1, 1073741824 )
                );
}