bool QgsOSMDatabase::exportSpatiaLite( ExportType type, const QString& tableName, const QStringList& tagKeys, const QStringList& notNullTagKeys ) { mError.clear(); // create SpatiaLite table QString geometryType; if ( type == Point ) geometryType = "POINT"; else if ( type == Polyline ) geometryType = "LINESTRING"; else if ( type == Polygon ) geometryType = "POLYGON"; else Q_ASSERT( false && "Unknown export type" ); if ( !createSpatialTable( tableName, geometryType, tagKeys ) ) return false; // import data int retX = sqlite3_exec( mDatabase, "BEGIN", nullptr, nullptr, nullptr ); Q_ASSERT( retX == SQLITE_OK ); Q_UNUSED( retX ); if ( type == Polyline || type == Polygon ) exportSpatiaLiteWays( type == Polygon, tableName, tagKeys, notNullTagKeys ); else if ( type == Point ) exportSpatiaLiteNodes( tableName, tagKeys, notNullTagKeys ); else Q_ASSERT( false && "Unknown export type" ); int retY = sqlite3_exec( mDatabase, "COMMIT", nullptr, nullptr, nullptr ); Q_ASSERT( retY == SQLITE_OK ); Q_UNUSED( retY ); if ( !createSpatialIndex( tableName ) ) return false; return mError.isEmpty(); }
QgsMemoryProvider::QgsMemoryProvider( QString uri ) : QgsVectorDataProvider( uri ) , mSpatialIndex( 0 ) { // 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( "geometry" ) ) { geometry = url.queryItemValue( "geometry" ); } else { geometry = url.path(); } geometry = geometry.toLower(); if ( geometry == "point" ) mWkbType = QGis::WKBPoint; else if ( geometry == "linestring" ) mWkbType = QGis::WKBLineString; else if ( geometry == "polygon" ) mWkbType = QGis::WKBPolygon; else if ( geometry == "multipoint" ) mWkbType = QGis::WKBMultiPoint; else if ( geometry == "multilinestring" ) mWkbType = QGis::WKBMultiLineString; else if ( geometry == "multipolygon" ) mWkbType = QGis::WKBMultiPolygon; else mWkbType = QGis::WKBUnknown; if ( url.hasQueryItem( "crs" ) ) { QString crsDef = url.queryItemValue( "crs" ); mCrs.createFromString( crsDef ); } mNextFeatureId = 1; mNativeTypes << QgsVectorDataProvider::NativeType( tr( "Whole number (integer)" ), "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)" ), "double", QVariant::Double, 0, 32, 0, 30 ) << QgsVectorDataProvider::NativeType( tr( "Text (string)" ), "string", QVariant::String, 0, 255 ) // date type << QgsVectorDataProvider::NativeType( tr( "Date" ), "date", QVariant::Date, -1, -1, -1, -1 ) // integer types << QgsVectorDataProvider::NativeType( tr( "Whole number (smallint - 16bit)" ), "int2", QVariant::Int, -1, -1, 0, 0 ) << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 32bit)" ), "int4", QVariant::Int, -1, -1, 0, 0 ) << QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 64bit)" ), "int8", QVariant::LongLong, -1, -1, 0, 0 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), "numeric", QVariant::Double, 1, 20, 0, 20 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), "decimal", QVariant::Double, 1, 20, 0, 20 ) // floating point << QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), "real", QVariant::Double, -1, -1, -1, -1 ) << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), "double precision", QVariant::Double, -1, -1, -1, -1 ) // string types << QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), "text", QVariant::String, -1, -1, -1, -1 ) ; if ( url.hasQueryItem( "field" ) ) { QList<QgsField> attributes; QRegExp reFieldDef( "\\:" "(int|integer|real|double|string|date)" // type "(?:\\((\\d+)" // length "(?:\\,(\\d+))?" // precision "\\))?" "$", Qt::CaseInsensitive ); QStringList fields = url.allQueryItemValues( "field" ); for ( int i = 0; i < fields.size(); i++ ) { QString name = fields.at( i ); QVariant::Type type = QVariant::String; QString typeName( "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 == "int" || typeName == "integer" ) { type = QVariant::Int; typeName = "integer"; length = 10; } else if ( typeName == "real" || typeName == "double" ) { type = QVariant::Double; typeName = "double"; length = 20; precision = 5; } else if ( typeName == "date" ) { type = QVariant::Date; typeName = "date"; length = 10; } if ( reFieldDef.cap( 2 ) != "" ) { length = reFieldDef.cap( 2 ).toInt(); } if ( reFieldDef.cap( 3 ) != "" ) { precision = reFieldDef.cap( 3 ).toInt(); } } if ( name != "" ) attributes.append( QgsField( name, type, typeName, length, precision ) ); } addAttributes( attributes ); } if ( url.hasQueryItem( "index" ) && url.queryItemValue( "index" ) == "yes" ) { createSpatialIndex(); } }
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(); } }