35 #include <QDomDocument> 38 #include <QMessageBox> 43 #include <spatialite.h> 50 #define CUSTOM_PROPERTY_IS_OFFLINE_EDITABLE "isOfflineEditable" 51 #define CUSTOM_PROPERTY_REMOTE_SOURCE "remoteSource" 52 #define CUSTOM_PROPERTY_REMOTE_PROVIDER "remoteProvider" 53 #define PROJECT_ENTRY_SCOPE_OFFLINE "OfflineEditingPlugin" 54 #define PROJECT_ENTRY_KEY_OFFLINE_DB_PATH "/OfflineDbPath" 87 if ( createSpatialiteDB( dbPath ) )
91 if ( rc != SQLITE_OK )
93 showWarning(
tr(
"Could not open the spatialite database" ) );
98 createLoggingTables( db );
105 for (
int i = 0; i < layerIds.
count(); i++ )
115 QgsVectorJoinList::iterator it = joins.
begin();
116 while ( it != joins.end() )
118 if (( *it ).prefix.isNull() )
123 ( *it ).prefix = vl->
name() +
'_';
127 joinInfoBuffer.
insert( vl->
id(), joins );
131 for (
int i = 0; i < layerIds.
count(); i++ )
144 layerIdMapping.
insert( origLayerId, newLayer );
163 if ( newJoinedLayer )
184 projectTitle +=
" (offline)";
217 offlineLayers << layer;
221 for (
int l = 0; l < offlineLayers.
count(); l++ )
244 copySymbology( offlineLayer, remoteLayer );
248 QString sql =
QString(
"SELECT \"id\" FROM 'log_layer_ids' WHERE \"qgis_id\" = '%1'" ).
arg( qgisLayerId );
249 int layerId = sqlQueryInt( db, sql, -1 );
255 int commitNo = getCommitNo( db );
256 for (
int i = 0; i < commitNo; i++ )
259 applyAttributesAdded( remoteLayer, db, layerId, i );
260 applyAttributeValueChanges( offlineLayer, remoteLayer, db, layerId, i );
261 applyGeometryChanges( remoteLayer, db, layerId, i );
264 applyFeaturesAdded( offlineLayer, remoteLayer, db, layerId );
265 applyFeaturesRemoved( remoteLayer, db, layerId );
270 updateFidLookup( remoteLayer, db, layerId );
273 sql =
QString(
"DELETE FROM 'log_added_attrs' WHERE \"layer_id\" = %1" ).
arg( layerId );
275 sql =
QString(
"DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
277 sql =
QString(
"DELETE FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
279 sql =
QString(
"DELETE FROM 'log_feature_updates' WHERE \"layer_id\" = %1" ).
arg( layerId );
281 sql =
QString(
"DELETE FROM 'log_geometry_updates' WHERE \"layer_id\" = %1" ).
arg( layerId );
285 QString sql =
QString(
"UPDATE 'log_indices' SET 'last_index' = 0 WHERE \"name\" = 'commit_no'" );
315 void QgsOfflineEditing::initializeSpatialMetadata(
sqlite3 *sqlite_handle )
318 if ( !sqlite_handle )
323 int ret = sqlite3_get_table( sqlite_handle,
"select count(*) from sqlite_master", &results, &rows, &columns,
nullptr );
324 if ( ret != SQLITE_OK )
329 for (
int i = 1; i <= rows; i++ )
330 count = atoi( results[( i * columns ) + 0] );
333 sqlite3_free_table( results );
338 bool above41 =
false;
339 ret = sqlite3_get_table( sqlite_handle,
"select spatialite_version()", &results, &rows, &columns,
nullptr );
340 if ( ret == SQLITE_OK && rows == 1 && columns == 1 )
344 if ( parts.
size() >= 1 )
347 above41 = verparts.
size() >= 2 && ( verparts[0].toInt() > 4 || ( verparts[0].toInt() == 4 && verparts[1].toInt() >= 1 ) );
351 sqlite3_free_table( results );
354 char *errMsg =
nullptr;
355 ret = sqlite3_exec( sqlite_handle, above41 ?
"SELECT InitSpatialMetadata(1)" :
"SELECT InitSpatialMetadata()",
nullptr,
nullptr, &errMsg );
357 if ( ret != SQLITE_OK )
359 QString errCause =
tr(
"Unable to initialize SpatialMetadata:\n" );
361 showWarning( errCause );
362 sqlite3_free( errMsg );
365 spatial_ref_sys_init( sqlite_handle, 0 );
368 bool QgsOfflineEditing::createSpatialiteDB(
const QString& offlineDbPath )
372 char *errMsg =
nullptr;
373 QFile newDb( offlineDbPath );
393 QString errCause =
tr(
"Could not create a new database\n" );
395 sqlite3_close( sqlite_handle );
396 showWarning( errCause );
400 ret = sqlite3_exec( sqlite_handle,
"PRAGMA foreign_keys = 1",
nullptr,
nullptr, &errMsg );
401 if ( ret != SQLITE_OK )
403 showWarning(
tr(
"Unable to activate FOREIGN_KEY constraints" ) );
404 sqlite3_free( errMsg );
408 initializeSpatialMetadata( sqlite_handle );
416 void QgsOfflineEditing::createLoggingTables(
sqlite3* db )
419 QString sql =
"CREATE TABLE 'log_indices' ('name' TEXT, 'last_index' INTEGER)";
422 sql =
"INSERT INTO 'log_indices' VALUES ('commit_no', 0)";
425 sql =
"INSERT INTO 'log_indices' VALUES ('layer_id', 0)";
429 sql =
"CREATE TABLE 'log_layer_ids' ('id' INTEGER, 'qgis_id' TEXT)";
433 sql =
"CREATE TABLE 'log_fids' ('layer_id' INTEGER, 'offline_fid' INTEGER, 'remote_fid' INTEGER)";
437 sql =
"CREATE TABLE 'log_added_attrs' ('layer_id' INTEGER, 'commit_no' INTEGER, ";
438 sql +=
"'name' TEXT, 'type' INTEGER, 'length' INTEGER, 'precision' INTEGER, 'comment' TEXT)";
442 sql =
"CREATE TABLE 'log_added_features' ('layer_id' INTEGER, 'fid' INTEGER)";
446 sql =
"CREATE TABLE 'log_removed_features' ('layer_id' INTEGER, 'fid' INTEGER)";
450 sql =
"CREATE TABLE 'log_feature_updates' ('layer_id' INTEGER, 'commit_no' INTEGER, 'fid' INTEGER, 'attr' INTEGER, 'value' TEXT)";
454 sql =
"CREATE TABLE 'log_geometry_updates' ('layer_id' INTEGER, 'commit_no' INTEGER, 'fid' INTEGER, 'geom_wkt' TEXT)";
474 for (
int idx = 0; idx < fields.
count(); ++idx )
477 QVariant::Type type = fields[idx].type();
478 if ( type == QVariant::Int || type == QVariant::LongLong )
480 dataType =
"INTEGER";
482 else if ( type == QVariant::Double )
486 else if ( type == QVariant::String )
492 showWarning(
tr(
"%1: Unknown data type %2. Not using type affinity for the field." ).arg( fields[idx].
name(),
QVariant::typeToName( type ) ) );
495 sql += delim +
QString(
"'%1' %2" ).
arg( fields[idx].
name(), dataType );
500 int rc = sqlExec( db, sql );
512 geomType =
"MULTIPOINT";
515 geomType =
"LINESTRING";
518 geomType =
"MULTILINESTRING";
521 geomType =
"POLYGON";
524 geomType =
"MULTIPOLYGON";
527 showWarning(
tr(
"QGIS wkbType %1 not supported" ).arg( layer->
wkbType() ) );
530 QString sqlAddGeom =
QString(
"SELECT AddGeometryColumn('%1', 'Geometry', %2, '%3', 2)" )
536 QString sqlCreateIndex =
QString(
"SELECT CreateSpatialIndex('%1', 'Geometry')" ).
arg( tableName );
538 if ( rc == SQLITE_OK )
540 rc = sqlExec( db, sqlAddGeom );
541 if ( rc == SQLITE_OK )
543 rc = sqlExec( db, sqlCreateIndex );
548 if ( rc == SQLITE_OK )
551 QString connectionString =
QString(
"dbname='%1' table='%2'%3 sql=" )
555 layer->
name() +
" (offline)",
"spatialite" );
576 copySymbology( layer, newLayer );
582 if ( layerTreeLayer )
585 if ( parentTreeGroup )
590 if ( newLayerTreeLayer )
604 copySymbology( layer, newLayer );
617 int featureCount = 1;
622 remoteFeatureIds << f.
id();
629 for (
int it = 0; it < attrs.
count(); ++it )
631 newAttrs[column++] = attrs.
at( it );
645 int layerId = getOrCreateLayerId( db, newLayer->
id() );
651 offlineFeatureIds << f.
id();
655 sqlExec( db,
"BEGIN" );
656 int remoteCount = remoteFeatureIds.
size();
657 for (
int i = 0; i < remoteCount; i++ )
660 if ( i < offlineFeatureIds.count() )
662 addFidLookup( db, layerId, offlineFeatureIds.at( i ), remoteFeatureIds.
at( i ) );
666 showWarning(
tr(
"Feature cannot be copied to the offline layer, please check if the online layer '%1' is still accessible." ).arg( layer->
name() ) );
671 sqlExec( db,
"COMMIT" );
683 void QgsOfflineEditing::applyAttributesAdded(
QgsVectorLayer* remoteLayer,
sqlite3* db,
int layerId,
int commitNo )
685 QString sql =
QString(
"SELECT \"name\", \"type\", \"length\", \"precision\", \"comment\" FROM 'log_added_attrs' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2" ).
arg( layerId ).
arg( commitNo );
693 for (
int i = 0; i < nativeTypes.
size(); i++ )
701 for (
int i = 0; i < fields.
size(); i++ )
705 if ( typeNameLookup.contains( field.
type() ) )
713 showWarning(
QString(
"Could not add attribute '%1' of type %2" ).arg( field.
name() ).arg( field.
type() ) );
722 QString sql =
QString(
"SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
723 QList<int> newFeatureIds = sqlQueryInts( db, sql );
728 for (
int i = 0; i < remoteFlds.
count(); ++i )
736 for (
int i = 0; i < newFeatureIds.
size(); i++ )
756 QMap<int, int> attrLookup = attributeLookup( offlineLayer, remoteLayer );
759 for (
int it = 0; it < attrs.
count(); ++it )
761 newAttrs[ attrLookup[ it ] ] = attrs.
at( it );
766 for (
int k = 0; k < newAttrs.
count(); ++k )
768 if ( newAttrs.
at( k ).isNull() && !defaultValues.at( k ).isNull() )
769 newAttrs[k] = defaultValues.
at( k );
780 void QgsOfflineEditing::applyFeaturesRemoved(
QgsVectorLayer* remoteLayer,
sqlite3* db,
int layerId )
782 QString sql =
QString(
"SELECT \"fid\" FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
799 QString sql =
QString(
"SELECT \"fid\", \"attr\", \"value\" FROM 'log_feature_updates' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2 " ).
arg( layerId ).
arg( commitNo );
804 QMap<int, int> attrLookup = attributeLookup( offlineLayer, remoteLayer );
806 for (
int i = 0; i < values.
size(); i++ )
816 void QgsOfflineEditing::applyGeometryChanges(
QgsVectorLayer* remoteLayer,
sqlite3* db,
int layerId,
int commitNo )
818 QString sql =
QString(
"SELECT \"fid\", \"geom_wkt\" FROM 'log_geometry_updates' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2" ).
arg( layerId ).
arg( commitNo );
823 for (
int i = 0; i < values.
size(); i++ )
848 if ( offlineFid( db, layerId, f.
id() ) == -1 )
850 newRemoteFids[ f.
id()] =
true;
858 QString sql =
QString(
"SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
859 QList<int> newOfflineFids = sqlQueryInts( db, sql );
861 if ( newRemoteFids.size() != newOfflineFids.
size() )
869 sqlExec( db,
"BEGIN" );
872 addFidLookup( db, layerId, newOfflineFids.
at( i++ ), it.key() );
874 sqlExec( db,
"COMMIT" );
890 showWarning( error );
900 QMap <
int ,
int > attrLookup;
902 for (
int i = 0; i < remoteAttrs.
size(); i++ )
904 attrLookup.
insert( offlineAttrs.
at( i ), remoteAttrs.
at( i ) );
910 void QgsOfflineEditing::showWarning(
const QString& message )
912 emit
warning(
tr(
"Offline Editing Plugin" ), message );
915 sqlite3* QgsOfflineEditing::openLoggingDb()
923 if ( rc != SQLITE_OK )
925 showWarning(
tr(
"Could not open the spatialite logging database" ) );
933 int QgsOfflineEditing::getOrCreateLayerId(
sqlite3* db,
const QString& qgisLayerId )
935 QString sql =
QString(
"SELECT \"id\" FROM 'log_layer_ids' WHERE \"qgis_id\" = '%1'" ).
arg( qgisLayerId );
936 int layerId = sqlQueryInt( db, sql, -1 );
940 sql =
"SELECT \"last_index\" FROM 'log_indices' WHERE \"name\" = 'layer_id'";
941 int newLayerId = sqlQueryInt( db, sql, -1 );
944 sql =
QString(
"INSERT INTO 'log_layer_ids' VALUES (%1, '%2')" ).
arg( newLayerId ).
arg( qgisLayerId );
949 sql =
QString(
"UPDATE 'log_indices' SET 'last_index' = %1 WHERE \"name\" = 'layer_id'" ).
arg( newLayerId + 1 );
952 layerId = newLayerId;
958 int QgsOfflineEditing::getCommitNo(
sqlite3* db )
960 QString sql =
"SELECT \"last_index\" FROM 'log_indices' WHERE \"name\" = 'commit_no'";
961 return sqlQueryInt( db, sql, -1 );
964 void QgsOfflineEditing::increaseCommitNo(
sqlite3* db )
966 QString sql =
QString(
"UPDATE 'log_indices' SET 'last_index' = %1 WHERE \"name\" = 'commit_no'" ).
arg( getCommitNo( db ) + 1 );
972 QString sql =
QString(
"INSERT INTO 'log_fids' VALUES ( %1, %2, %3 )" ).
arg( layerId ).
arg( offlineFid ).
arg( remoteFid );
978 QString sql =
QString(
"SELECT \"remote_fid\" FROM 'log_fids' WHERE \"layer_id\" = %1 AND \"offline_fid\" = %2" ).
arg( layerId ).
arg( offlineFid );
979 return sqlQueryInt( db, sql, -1 );
984 QString sql =
QString(
"SELECT \"offline_fid\" FROM 'log_fids' WHERE \"layer_id\" = %1 AND \"remote_fid\" = %2" ).
arg( layerId ).
arg( remoteFid );
985 return sqlQueryInt( db, sql, -1 );
990 QString sql =
QString(
"SELECT COUNT(\"fid\") FROM 'log_added_features' WHERE \"layer_id\" = %1 AND \"fid\" = %2" ).
arg( layerId ).
arg( fid );
991 return ( sqlQueryInt( db, sql, 0 ) > 0 );
997 int rc = sqlite3_exec( db, sql.
toUtf8(),
nullptr,
nullptr, &errmsg );
998 if ( rc != SQLITE_OK )
1000 showWarning( errmsg );
1005 int QgsOfflineEditing::sqlQueryInt(
sqlite3* db,
const QString& sql,
int defaultValue )
1007 sqlite3_stmt* stmt =
nullptr;
1008 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1010 showWarning( sqlite3_errmsg( db ) );
1011 return defaultValue;
1014 int value = defaultValue;
1015 int ret = sqlite3_step( stmt );
1016 if ( ret == SQLITE_ROW )
1018 value = sqlite3_column_int( stmt, 0 );
1020 sqlite3_finalize( stmt );
1029 sqlite3_stmt* stmt =
nullptr;
1030 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1032 showWarning( sqlite3_errmsg( db ) );
1036 int ret = sqlite3_step( stmt );
1037 while ( ret == SQLITE_ROW )
1039 values << sqlite3_column_int( stmt, 0 );
1041 ret = sqlite3_step( stmt );
1043 sqlite3_finalize( stmt );
1052 sqlite3_stmt* stmt =
nullptr;
1053 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1055 showWarning( sqlite3_errmsg( db ) );
1059 int ret = sqlite3_step( stmt );
1060 while ( ret == SQLITE_ROW )
1062 QgsField field(
QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 0 ) ) ),
1063 static_cast< QVariant::Type >( sqlite3_column_int( stmt, 1 ) ),
1065 sqlite3_column_int( stmt, 2 ),
1066 sqlite3_column_int( stmt, 3 ),
1067 QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 4 ) ) ) );
1070 ret = sqlite3_step( stmt );
1072 sqlite3_finalize( stmt );
1081 sqlite3_stmt* stmt =
nullptr;
1082 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1084 showWarning( sqlite3_errmsg( db ) );
1088 int ret = sqlite3_step( stmt );
1089 while ( ret == SQLITE_ROW )
1091 values << sqlite3_column_int( stmt, 0 );
1093 ret = sqlite3_step( stmt );
1095 sqlite3_finalize( stmt );
1104 sqlite3_stmt* stmt =
nullptr;
1105 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1107 showWarning( sqlite3_errmsg( db ) );
1111 int ret = sqlite3_step( stmt );
1112 while ( ret == SQLITE_ROW )
1114 AttributeValueChange change;
1115 change.fid = sqlite3_column_int( stmt, 0 );
1116 change.attr = sqlite3_column_int( stmt, 1 );
1117 change.value =
QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 2 ) ) );
1120 ret = sqlite3_step( stmt );
1122 sqlite3_finalize( stmt );
1131 sqlite3_stmt* stmt =
nullptr;
1132 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1134 showWarning( sqlite3_errmsg( db ) );
1138 int ret = sqlite3_step( stmt );
1139 while ( ret == SQLITE_ROW )
1141 GeometryChange change;
1142 change.fid = sqlite3_column_int( stmt, 0 );
1143 change.geom_wkt =
QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 1 ) ) );
1146 ret = sqlite3_step( stmt );
1148 sqlite3_finalize( stmt );
1153 void QgsOfflineEditing::committedAttributesAdded(
const QString& qgisLayerId,
const QList<QgsField>& addedAttributes )
1155 sqlite3* db = openLoggingDb();
1160 int layerId = getOrCreateLayerId( db, qgisLayerId );
1161 int commitNo = getCommitNo( db );
1166 QString sql =
QString(
"INSERT INTO 'log_added_attrs' VALUES ( %1, %2, '%3', %4, %5, %6, '%7' )" )
1170 .arg( field.
type() )
1177 increaseCommitNo( db );
1178 sqlite3_close( db );
1181 void QgsOfflineEditing::committedFeaturesAdded(
const QString& qgisLayerId,
const QgsFeatureList& addedFeatures )
1183 sqlite3* db = openLoggingDb();
1188 int layerId = getOrCreateLayerId( db, qgisLayerId );
1195 QString sql =
QString(
"SELECT ROWID FROM '%1' ORDER BY ROWID DESC LIMIT %2" ).
arg( uri.
table() ).arg( addedFeatures.
size() );
1196 QList<int> newFeatureIds = sqlQueryInts( db, sql );
1197 for (
int i = newFeatureIds.
size() - 1; i >= 0; i-- )
1199 QString sql =
QString(
"INSERT INTO 'log_added_features' VALUES ( %1, %2 )" )
1201 .
arg( newFeatureIds.
at( i ) );
1205 sqlite3_close( db );
1208 void QgsOfflineEditing::committedFeaturesRemoved(
const QString& qgisLayerId,
const QgsFeatureIds& deletedFeatureIds )
1210 sqlite3* db = openLoggingDb();
1215 int layerId = getOrCreateLayerId( db, qgisLayerId );
1219 if ( isAddedFeature( db, layerId, *it ) )
1222 QString sql =
QString(
"DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1 AND \"fid\" = %2" ).
arg( layerId ).
arg( *it );
1227 QString sql =
QString(
"INSERT INTO 'log_removed_features' VALUES ( %1, %2)" )
1234 sqlite3_close( db );
1239 sqlite3* db = openLoggingDb();
1244 int layerId = getOrCreateLayerId( db, qgisLayerId );
1245 int commitNo = getCommitNo( db );
1247 for ( QgsChangedAttributesMap::const_iterator cit = changedAttrsMap.
begin(); cit != changedAttrsMap.
end(); ++cit )
1250 if ( isAddedFeature( db, layerId, fid ) )
1256 for ( QgsAttributeMap::const_iterator it = attrMap.
begin(); it != attrMap.
end(); ++it )
1258 QString sql =
QString(
"INSERT INTO 'log_feature_updates' VALUES ( %1, %2, %3, %4, '%5' )" )
1263 .arg( it.value().toString() );
1268 increaseCommitNo( db );
1269 sqlite3_close( db );
1272 void QgsOfflineEditing::committedGeometriesChanges(
const QString& qgisLayerId,
const QgsGeometryMap& changedGeometries )
1274 sqlite3* db = openLoggingDb();
1279 int layerId = getOrCreateLayerId( db, qgisLayerId );
1280 int commitNo = getCommitNo( db );
1282 for ( QgsGeometryMap::const_iterator it = changedGeometries.
begin(); it != changedGeometries.
end(); ++it )
1285 if ( isAddedFeature( db, layerId, fid ) )
1291 QString sql =
QString(
"INSERT INTO 'log_geometry_updates' VALUES ( %1, %2, %3, '%4' )" )
1301 increaseCommitNo( db );
1302 sqlite3_close( db );
1305 void QgsOfflineEditing::startListenFeatureChanges()
1324 void QgsOfflineEditing::stopListenFeatureChanges()
1343 void QgsOfflineEditing::layerAdded(
QgsMapLayer* layer )
1349 connect( vLayer, SIGNAL( editingStarted() ),
this, SLOT( startListenFeatureChanges() ) );
1350 connect( vLayer, SIGNAL( editingStopped() ),
this, SLOT( stopListenFeatureChanges() ) );
virtual QString subsetString()
Get the string (typically sql) used to define a subset of the layer.
Layer tree group node serves as a container for layers and further groups.
Wrapper for iterator of features from vector data provider or vector layer.
void layerProgressUpdated(int layer, int numLayers)
Emit a signal that the next layer of numLayers has started processing.
bool addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.
Base class for all map layer types.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
QString comment() const
Returns the field comment.
QgsAttributes attributes() const
Returns the feature's attributes.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=nullptr) const
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
#define PROJECT_ENTRY_KEY_OFFLINE_DB_PATH
bool convertToOfflineProject(const QString &offlineDataPath, const QString &offlineDbFile, const QStringList &layerIds)
Convert current project for offline editing.
bool deleteFeature(QgsFeatureId fid)
Delete a feature from the layer (but does not commit it)
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
#define CUSTOM_PROPERTY_IS_OFFLINE_EDITABLE
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
bool commitChanges()
Attempts to commit any changes to disk.
bool startEditing()
Make layer editable.
const_iterator constBegin() const
const T & at(int i) const
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
#define Q_NOWARN_DEPRECATED_PUSH
#define CUSTOM_PROPERTY_REMOTE_SOURCE
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group. The node will be deleted.
void removeMapLayers(const QStringList &theLayerIds)
Remove a set of layers from the registry.
int precision() const
Gets the precision of the field.
QgsLayerTreeGroup * layerTreeRoot() const
Return pointer to the root (invisible) node of the project's layer tree.
bool addFeature(QgsFeature &f, bool alsoUpdateExtent=true)
Adds a feature.
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
QString join(const QString &separator) const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QString & remove(int position, int n)
const QList< QgsVectorJoinInfo > vectorJoins() const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
int count() const
Return number of items.
QString tr(const char *sourceText, const char *disambiguation, int n)
static int sqlite3_close(sqlite3 *)
QString name() const
Gets the name of the field.
QgsMapLayer * mapLayer(const QString &theLayerId)
Retrieve a pointer to a loaded layer by id.
QgsFields fields() const
Returns the list of fields of this layer.
int indexOf(const T &value, int from) const
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
bool isOfflineProject()
Return true if current project is offline.
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
long featureCount(QgsSymbolV2 *symbol)
Number of features rendered with specified symbol.
static int sqlite3_open(const char *filename, sqlite3 **ppDb)
const char * name() const
bool writeEntry(const QString &scope, const QString &key, bool value)
void progressUpdated(int progress)
Emit a signal with the progress of the current mode.
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
int count(const T &value) const
QString fromUtf8(const char *str, int size)
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
void progressStopped()
Emit a signal that processing of all layers has finished.
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer *> &theMapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
Q_DECL_DEPRECATED void title(const QString &title)
Every project has an associated title string.
void setTypeName(const QString &typeName)
Set the field type.
static int sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs)
QgsLayerTreeNode * parent()
Get pointer to the parent. If parent is a null pointer, the node is a root node.
const_iterator constEnd() const
const char * constData() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
virtual long featureCount() const =0
Number of features in the layer.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
This class is a base class for nodes in a layer tree.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())=0
Query the provider for features specified in request.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key.
QgsAttributeList attributeList() const
Returns list of attribute indexes.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
Change feature's geometry.
QString exportToWkt(int precision=17) const
Exports the geometry to WKT.
Encapsulate a field in an attribute table or data source.
virtual bool importNamedStyle(QDomDocument &doc, QString &errorMsg)
Import the properties of this layer from a QDomDocument.
const QList< NativeType > & nativeTypes() const
Returns the names of the supported types.
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
bool isValid()
Return the status of the layer.
#define PROJECT_ENTRY_SCOPE_OFFLINE
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &value, bool emitSignal)
Changes an attribute value (but does not commit it)
const QStringList & commitErrors()
QgsFeatureId id() const
Get the feature ID for this feature.
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
virtual void reload() override
Synchronises with changes in the datasource.
QgsLayerTreeLayer * findLayer(const QString &layerId) const
Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tr...
const char * typeToName(Type typ)
#define Q_NOWARN_DEPRECATED_POP
const Key key(const T &value) const
long toLong(bool *ok, int base) const
virtual void exportNamedStyle(QDomDocument &doc, QString &errorMsg)
Export the properties of this layer as named style in a QDomDocument.
const T & at(int i) const
void warning(const QString &title, const QString &message)
Emitted when a warning needs to be displayed.
QString name() const
Get the display name of the layer.
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QString mid(int position, int n) const
virtual QVariant defaultValue(int fieldId)
Returns the default value for field specified by fieldId.
void insertChildNode(int index, QgsLayerTreeNode *node)
Insert existing node at specified position. The node must not have a parent yet. The node will be own...
QString source() const
Returns the source for the layer.
QString absolutePath() const
void synchronize()
Synchronize to remote layers.
static QgsProject * instance()
access to canonical QgsProject instance
QString table() const
Returns the table.
int count(const T &value) const
void setTitle(const QString &title)
Set project title.
int length() const
Gets the length of the field.
QString absoluteFilePath(const QString &fileName) const
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
virtual bool setSubsetString(const QString &subset)
Set the string (typically sql) used to define a subset of the layer.
void progressModeSet(QgsOfflineEditing::ProgressMode mode, int maximum)
Emit a signal that sets the mode for the progress of the current operation.
QString readPath(QString filename) const
Turn filename read from the project file to an absolute path.
iterator insert(const Key &key, const T &value)
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
static QgsGeometry * fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
QString providerType() const
Return the provider type for this layer.
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
Q_DECL_DEPRECATED bool hasLabelsEnabled() const
Label is on.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
virtual void invalidateConnections(const QString &connection)
Invalidate connections corresponding to specified name.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
#define CUSTOM_PROPERTY_REMOTE_PROVIDER
QString joinLayerId
Source layer.
void progressStarted()
Emit a signal that processing has started.
virtual QgsLayerTreeLayer * clone() const override
Create a copy of the node. Returns new instance.
QString authid() const
Returns the authority identifier for the CRS, which includes both the authority (eg EPSG) and the CRS...
bool mkpath(const QString &dirPath) const
Layer tree node points to a map layer.
const T value(const Key &key) const
QByteArray toUtf8() const