36 #include <QDomDocument> 39 #include <QMessageBox> 44 #include <spatialite.h> 51 #define CUSTOM_PROPERTY_IS_OFFLINE_EDITABLE "isOfflineEditable" 52 #define CUSTOM_PROPERTY_REMOTE_SOURCE "remoteSource" 53 #define CUSTOM_PROPERTY_REMOTE_PROVIDER "remoteProvider" 54 #define PROJECT_ENTRY_SCOPE_OFFLINE "OfflineEditingPlugin" 55 #define PROJECT_ENTRY_KEY_OFFLINE_DB_PATH "/OfflineDbPath" 89 if ( createSpatialiteDB( dbPath ) )
93 if ( rc != SQLITE_OK )
95 showWarning(
tr(
"Could not open the spatialite database" ) );
100 createLoggingTables( db );
107 Q_FOREACH (
const QString& layerId, layerIds )
119 QgsVectorJoinList::iterator joinIt = joins.
begin();
120 while ( joinIt != joins.
end() )
122 if ( joinIt->prefix.isNull() )
127 joinIt->prefix = vl->
name() +
'_';
131 joinInfoBuffer.
insert( vl->
id(), joins );
135 for (
int i = 0; i < layerIds.
count(); i++ )
144 QgsVectorLayer* newLayer = copyVectorLayer( vl, db, dbPath, onlySelected );
148 layerIdMapping.
insert( origLayerId, newLayer );
167 if ( newJoinedLayer )
188 projectTitle +=
" (offline)";
224 offlineLayers << layer;
229 for (
int l = 0; l < offlineLayers.
count(); l++ )
260 copySymbology( offlineLayer, remoteLayer );
261 updateRelations( offlineLayer, remoteLayer );
262 updateVisibilityPresets( offlineLayer, remoteLayer );
267 QString sql =
QString(
"SELECT \"id\" FROM 'log_layer_ids' WHERE \"qgis_id\" = '%1'" ).
arg( qgisLayerId );
268 int layerId = sqlQueryInt( db, sql, -1 );
274 int commitNo = getCommitNo( db );
276 for (
int i = 0; i < commitNo; i++ )
280 applyAttributesAdded( remoteLayer, db, layerId, i );
282 applyAttributeValueChanges( offlineLayer, remoteLayer, db, layerId, i );
284 applyGeometryChanges( remoteLayer, db, layerId, i );
288 applyFeaturesAdded( offlineLayer, remoteLayer, db, layerId );
290 applyFeaturesRemoved( remoteLayer, db, layerId );
297 updateFidLookup( remoteLayer, db, layerId );
300 sql =
QString(
"DELETE FROM 'log_added_attrs' WHERE \"layer_id\" = %1" ).
arg( layerId );
302 sql =
QString(
"DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
304 sql =
QString(
"DELETE FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
306 sql =
QString(
"DELETE FROM 'log_feature_updates' WHERE \"layer_id\" = %1" ).
arg( layerId );
308 sql =
QString(
"DELETE FROM 'log_geometry_updates' WHERE \"layer_id\" = %1" ).
arg( layerId );
319 showWarning(
tr(
"Synchronization failed" ) );
324 QgsDebugMsg(
"Could not find the layer id in the edit logs!" );
347 QString sql =
QString(
"UPDATE 'log_indices' SET 'last_index' = 0 WHERE \"name\" = 'commit_no'" );
355 void QgsOfflineEditing::initializeSpatialMetadata(
sqlite3 *sqlite_handle )
358 if ( !sqlite_handle )
363 int ret = sqlite3_get_table( sqlite_handle,
"select count(*) from sqlite_master", &results, &rows, &columns,
nullptr );
364 if ( ret != SQLITE_OK )
369 for (
int i = 1; i <= rows; i++ )
370 count = atoi( results[( i * columns ) + 0] );
373 sqlite3_free_table( results );
378 bool above41 =
false;
379 ret = sqlite3_get_table( sqlite_handle,
"select spatialite_version()", &results, &rows, &columns,
nullptr );
380 if ( ret == SQLITE_OK && rows == 1 && columns == 1 )
384 if ( parts.
size() >= 1 )
387 above41 = verparts.
size() >= 2 && ( verparts[0].toInt() > 4 || ( verparts[0].toInt() == 4 && verparts[1].toInt() >= 1 ) );
391 sqlite3_free_table( results );
394 char *errMsg =
nullptr;
395 ret = sqlite3_exec( sqlite_handle, above41 ?
"SELECT InitSpatialMetadata(1)" :
"SELECT InitSpatialMetadata()",
nullptr,
nullptr, &errMsg );
397 if ( ret != SQLITE_OK )
399 QString errCause =
tr(
"Unable to initialize SpatialMetadata:\n" );
401 showWarning( errCause );
402 sqlite3_free( errMsg );
405 spatial_ref_sys_init( sqlite_handle, 0 );
408 bool QgsOfflineEditing::createSpatialiteDB(
const QString& offlineDbPath )
412 char *errMsg =
nullptr;
413 QFile newDb( offlineDbPath );
433 QString errCause =
tr(
"Could not create a new database\n" );
435 sqlite3_close( sqlite_handle );
436 showWarning( errCause );
440 ret = sqlite3_exec( sqlite_handle,
"PRAGMA foreign_keys = 1",
nullptr,
nullptr, &errMsg );
441 if ( ret != SQLITE_OK )
443 showWarning(
tr(
"Unable to activate FOREIGN_KEY constraints" ) );
444 sqlite3_free( errMsg );
448 initializeSpatialMetadata( sqlite_handle );
456 void QgsOfflineEditing::createLoggingTables(
sqlite3* db )
459 QString sql =
"CREATE TABLE 'log_indices' ('name' TEXT, 'last_index' INTEGER)";
462 sql =
"INSERT INTO 'log_indices' VALUES ('commit_no', 0)";
465 sql =
"INSERT INTO 'log_indices' VALUES ('layer_id', 0)";
469 sql =
"CREATE TABLE 'log_layer_ids' ('id' INTEGER, 'qgis_id' TEXT)";
473 sql =
"CREATE TABLE 'log_fids' ('layer_id' INTEGER, 'offline_fid' INTEGER, 'remote_fid' INTEGER)";
477 sql =
"CREATE TABLE 'log_added_attrs' ('layer_id' INTEGER, 'commit_no' INTEGER, ";
478 sql +=
"'name' TEXT, 'type' INTEGER, 'length' INTEGER, 'precision' INTEGER, 'comment' TEXT)";
482 sql =
"CREATE TABLE 'log_added_features' ('layer_id' INTEGER, 'fid' INTEGER)";
486 sql =
"CREATE TABLE 'log_removed_features' ('layer_id' INTEGER, 'fid' INTEGER)";
490 sql =
"CREATE TABLE 'log_feature_updates' ('layer_id' INTEGER, 'commit_no' INTEGER, 'fid' INTEGER, 'attr' INTEGER, 'value' TEXT)";
494 sql =
"CREATE TABLE 'log_geometry_updates' ('layer_id' INTEGER, 'commit_no' INTEGER, 'fid' INTEGER, 'geom_wkt' TEXT)";
516 QVariant::Type type = field.
type();
517 if ( type == QVariant::Int || type == QVariant::LongLong )
519 dataType =
"INTEGER";
521 else if ( type == QVariant::Double )
525 else if ( type == QVariant::String )
531 showWarning(
tr(
"%1: Unknown data type %2. Not using type affinity for the field." ).arg( field.
name(),
QVariant::typeToName( type ) ) );
534 sql += delim +
QString(
"'%1' %2" ).
arg( field.
name(), dataType );
539 int rc = sqlExec( db, sql );
551 geomType =
"MULTIPOINT";
554 geomType =
"LINESTRING";
557 geomType =
"MULTILINESTRING";
560 geomType =
"POLYGON";
563 geomType =
"MULTIPOLYGON";
566 showWarning(
tr(
"QGIS wkbType %1 not supported" ).arg( layer->
wkbType() ) );
571 showWarning(
tr(
"Will drop Z and M values from layer %1 in offline copy." ).
arg( layer->
name() ) );
573 QString sqlAddGeom =
QString(
"SELECT AddGeometryColumn('%1', 'Geometry', %2, '%3', 2)" )
579 QString sqlCreateIndex =
QString(
"SELECT CreateSpatialIndex('%1', 'Geometry')" ).
arg( tableName );
581 if ( rc == SQLITE_OK )
583 rc = sqlExec( db, sqlAddGeom );
584 if ( rc == SQLITE_OK )
586 rc = sqlExec( db, sqlCreateIndex );
591 if ( rc == SQLITE_OK )
594 QString connectionString =
QString(
"dbname='%1' table='%2'%3 sql=" )
598 layer->
name() +
" (offline)",
"spatialite" );
619 copySymbology( layer, newLayer );
625 if ( layerTreeLayer )
628 if ( parentTreeGroup )
633 if ( newLayerTreeLayer )
647 copySymbology( layer, newLayer );
650 updateRelations( layer, newLayer );
651 updateVisibilityPresets( layer, newLayer );
678 int featureCount = 1;
683 remoteFeatureIds << f.
id();
690 for (
int it = 0; it < attrs.
count(); ++it )
692 newAttrs[column++] = attrs.
at( it );
716 int layerId = getOrCreateLayerId( db, newLayer->
id() );
722 offlineFeatureIds << f.
id();
726 sqlExec( db,
"BEGIN" );
727 int remoteCount = remoteFeatureIds.
size();
728 for (
int i = 0; i < remoteCount; i++ )
731 if ( i < offlineFeatureIds.count() )
733 addFidLookup( db, layerId, offlineFeatureIds.at( i ), remoteFeatureIds.
at( i ) );
737 showWarning(
tr(
"Feature cannot be copied to the offline layer, please check if the online layer '%1' is still accessible." ).arg( layer->
name() ) );
742 sqlExec( db,
"COMMIT" );
754 void QgsOfflineEditing::applyAttributesAdded(
QgsVectorLayer* remoteLayer,
sqlite3* db,
int layerId,
int commitNo )
756 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 );
764 for (
int i = 0; i < nativeTypes.
size(); i++ )
772 for (
int i = 0; i < fields.
size(); i++ )
776 if ( typeNameLookup.contains( field.
type() ) )
788 showWarning(
QString(
"Could not add attribute '%1' of type %2" ).arg( field.
name() ).arg( field.
type() ) );
797 QString sql =
QString(
"SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
798 QList<int> newFeatureIds = sqlQueryInts( db, sql );
809 for (
int i = 0; i < newFeatureIds.
size(); i++ )
829 QMap<int, int> attrLookup = attributeLookup( offlineLayer, remoteLayer );
832 for (
int it = 0; it < attrs.
count(); ++it )
834 newAttrs[ attrLookup[ it ] ] = attrs.
at( it );
839 for (
int k = 0; k < newAttrs.
count(); ++k )
841 if ( !newAttrs.
at( k ).isNull() )
845 newAttrs[k] = remoteLayer->
defaultValue( k, f, &context );
862 void QgsOfflineEditing::applyFeaturesRemoved(
QgsVectorLayer* remoteLayer,
sqlite3* db,
int layerId )
864 QString sql =
QString(
"SELECT \"fid\" FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
885 QString sql =
QString(
"SELECT \"fid\", \"attr\", \"value\" FROM 'log_feature_updates' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2 " ).
arg( layerId ).
arg( commitNo );
890 QMap<int, int> attrLookup = attributeLookup( offlineLayer, remoteLayer );
892 for (
int i = 0; i < values.
size(); i++ )
906 void QgsOfflineEditing::applyGeometryChanges(
QgsVectorLayer* remoteLayer,
sqlite3* db,
int layerId,
int commitNo )
908 QString sql =
QString(
"SELECT \"fid\", \"geom_wkt\" FROM 'log_geometry_updates' WHERE \"layer_id\" = %1 AND \"commit_no\" = %2" ).
arg( layerId ).
arg( commitNo );
913 for (
int i = 0; i < values.
size(); i++ )
942 if ( offlineFid( db, layerId, f.
id() ) == -1 )
944 newRemoteFids[ f.
id()] =
true;
952 QString sql =
QString(
"SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).
arg( layerId );
953 QList<int> newOfflineFids = sqlQueryInts( db, sql );
955 if ( newRemoteFids.size() != newOfflineFids.
size() )
963 sqlExec( db,
"BEGIN" );
966 addFidLookup( db, layerId, newOfflineFids.
at( i++ ), it.key() );
968 sqlExec( db,
"COMMIT" );
984 showWarning( error );
1016 Q_FOREACH (
const QString& preset, visibilityPresets )
1047 QMap <
int ,
int > attrLookup;
1049 for (
int i = 0; i < remoteAttrs.
size(); i++ )
1051 attrLookup.
insert( offlineAttrs.
at( i ), remoteAttrs.
at( i ) );
1057 void QgsOfflineEditing::showWarning(
const QString& message )
1059 emit
warning(
tr(
"Offline Editing Plugin" ), message );
1062 sqlite3* QgsOfflineEditing::openLoggingDb()
1070 if ( rc != SQLITE_OK )
1072 QgsDebugMsg(
"Could not open the spatialite logging database" );
1073 showWarning(
tr(
"Could not open the spatialite logging database" ) );
1074 sqlite3_close( db );
1085 int QgsOfflineEditing::getOrCreateLayerId(
sqlite3* db,
const QString& qgisLayerId )
1087 QString sql =
QString(
"SELECT \"id\" FROM 'log_layer_ids' WHERE \"qgis_id\" = '%1'" ).
arg( qgisLayerId );
1088 int layerId = sqlQueryInt( db, sql, -1 );
1089 if ( layerId == -1 )
1092 sql =
"SELECT \"last_index\" FROM 'log_indices' WHERE \"name\" = 'layer_id'";
1093 int newLayerId = sqlQueryInt( db, sql, -1 );
1096 sql =
QString(
"INSERT INTO 'log_layer_ids' VALUES (%1, '%2')" ).
arg( newLayerId ).
arg( qgisLayerId );
1101 sql =
QString(
"UPDATE 'log_indices' SET 'last_index' = %1 WHERE \"name\" = 'layer_id'" ).
arg( newLayerId + 1 );
1104 layerId = newLayerId;
1110 int QgsOfflineEditing::getCommitNo(
sqlite3* db )
1112 QString sql =
"SELECT \"last_index\" FROM 'log_indices' WHERE \"name\" = 'commit_no'";
1113 return sqlQueryInt( db, sql, -1 );
1116 void QgsOfflineEditing::increaseCommitNo(
sqlite3* db )
1118 QString sql =
QString(
"UPDATE 'log_indices' SET 'last_index' = %1 WHERE \"name\" = 'commit_no'" ).
arg( getCommitNo( db ) + 1 );
1124 QString sql =
QString(
"INSERT INTO 'log_fids' VALUES ( %1, %2, %3 )" ).
arg( layerId ).
arg( offlineFid ).
arg( remoteFid );
1130 QString sql =
QString(
"SELECT \"remote_fid\" FROM 'log_fids' WHERE \"layer_id\" = %1 AND \"offline_fid\" = %2" ).
arg( layerId ).
arg( offlineFid );
1131 return sqlQueryInt( db, sql, -1 );
1136 QString sql =
QString(
"SELECT \"offline_fid\" FROM 'log_fids' WHERE \"layer_id\" = %1 AND \"remote_fid\" = %2" ).
arg( layerId ).
arg( remoteFid );
1137 return sqlQueryInt( db, sql, -1 );
1142 QString sql =
QString(
"SELECT COUNT(\"fid\") FROM 'log_added_features' WHERE \"layer_id\" = %1 AND \"fid\" = %2" ).
arg( layerId ).
arg( fid );
1143 return ( sqlQueryInt( db, sql, 0 ) > 0 );
1146 int QgsOfflineEditing::sqlExec(
sqlite3* db,
const QString& sql )
1149 int rc = sqlite3_exec( db, sql.
toUtf8(),
nullptr,
nullptr, &errmsg );
1150 if ( rc != SQLITE_OK )
1152 showWarning( errmsg );
1157 int QgsOfflineEditing::sqlQueryInt(
sqlite3* db,
const QString& sql,
int defaultValue )
1159 sqlite3_stmt* stmt =
nullptr;
1160 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1162 showWarning( sqlite3_errmsg( db ) );
1163 return defaultValue;
1166 int value = defaultValue;
1167 int ret = sqlite3_step( stmt );
1168 if ( ret == SQLITE_ROW )
1170 value = sqlite3_column_int( stmt, 0 );
1172 sqlite3_finalize( stmt );
1181 sqlite3_stmt* stmt =
nullptr;
1182 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1184 showWarning( sqlite3_errmsg( db ) );
1188 int ret = sqlite3_step( stmt );
1189 while ( ret == SQLITE_ROW )
1191 values << sqlite3_column_int( stmt, 0 );
1193 ret = sqlite3_step( stmt );
1195 sqlite3_finalize( stmt );
1204 sqlite3_stmt* stmt =
nullptr;
1205 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1207 showWarning( sqlite3_errmsg( db ) );
1211 int ret = sqlite3_step( stmt );
1212 while ( ret == SQLITE_ROW )
1214 QgsField field(
QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 0 ) ) ),
1215 static_cast< QVariant::Type >( sqlite3_column_int( stmt, 1 ) ),
1217 sqlite3_column_int( stmt, 2 ),
1218 sqlite3_column_int( stmt, 3 ),
1219 QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 4 ) ) ) );
1222 ret = sqlite3_step( stmt );
1224 sqlite3_finalize( stmt );
1233 sqlite3_stmt* stmt =
nullptr;
1234 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1236 showWarning( sqlite3_errmsg( db ) );
1240 int ret = sqlite3_step( stmt );
1241 while ( ret == SQLITE_ROW )
1243 values << sqlite3_column_int( stmt, 0 );
1245 ret = sqlite3_step( stmt );
1247 sqlite3_finalize( stmt );
1256 sqlite3_stmt* stmt =
nullptr;
1257 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1259 showWarning( sqlite3_errmsg( db ) );
1263 int ret = sqlite3_step( stmt );
1264 while ( ret == SQLITE_ROW )
1266 AttributeValueChange change;
1267 change.fid = sqlite3_column_int( stmt, 0 );
1268 change.attr = sqlite3_column_int( stmt, 1 );
1269 change.value =
QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 2 ) ) );
1272 ret = sqlite3_step( stmt );
1274 sqlite3_finalize( stmt );
1283 sqlite3_stmt* stmt =
nullptr;
1284 if ( sqlite3_prepare_v2( db, sql.
toUtf8().
constData(), -1, &stmt, nullptr ) != SQLITE_OK )
1286 showWarning( sqlite3_errmsg( db ) );
1290 int ret = sqlite3_step( stmt );
1291 while ( ret == SQLITE_ROW )
1293 GeometryChange change;
1294 change.fid = sqlite3_column_int( stmt, 0 );
1295 change.geom_wkt =
QString( reinterpret_cast< const char* >( sqlite3_column_text( stmt, 1 ) ) );
1298 ret = sqlite3_step( stmt );
1300 sqlite3_finalize( stmt );
1305 void QgsOfflineEditing::committedAttributesAdded(
const QString& qgisLayerId,
const QList<QgsField>& addedAttributes )
1307 sqlite3* db = openLoggingDb();
1312 int layerId = getOrCreateLayerId( db, qgisLayerId );
1313 int commitNo = getCommitNo( db );
1318 QString sql =
QString(
"INSERT INTO 'log_added_attrs' VALUES ( %1, %2, '%3', %4, %5, %6, '%7' )" )
1322 .arg( field.
type() )
1329 increaseCommitNo( db );
1330 sqlite3_close( db );
1333 void QgsOfflineEditing::committedFeaturesAdded(
const QString& qgisLayerId,
const QgsFeatureList& addedFeatures )
1335 sqlite3* db = openLoggingDb();
1340 int layerId = getOrCreateLayerId( db, qgisLayerId );
1347 QString sql =
QString(
"SELECT ROWID FROM '%1' ORDER BY ROWID DESC LIMIT %2" ).
arg( uri.
table() ).arg( addedFeatures.
size() );
1348 QList<int> newFeatureIds = sqlQueryInts( db, sql );
1349 for (
int i = newFeatureIds.
size() - 1; i >= 0; i-- )
1351 QString sql =
QString(
"INSERT INTO 'log_added_features' VALUES ( %1, %2 )" )
1353 .
arg( newFeatureIds.
at( i ) );
1357 sqlite3_close( db );
1360 void QgsOfflineEditing::committedFeaturesRemoved(
const QString& qgisLayerId,
const QgsFeatureIds& deletedFeatureIds )
1362 sqlite3* db = openLoggingDb();
1367 int layerId = getOrCreateLayerId( db, qgisLayerId );
1371 if ( isAddedFeature( db, layerId, *it ) )
1374 QString sql =
QString(
"DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1 AND \"fid\" = %2" ).
arg( layerId ).
arg( *it );
1379 QString sql =
QString(
"INSERT INTO 'log_removed_features' VALUES ( %1, %2)" )
1386 sqlite3_close( db );
1391 sqlite3* db = openLoggingDb();
1396 int layerId = getOrCreateLayerId( db, qgisLayerId );
1397 int commitNo = getCommitNo( db );
1399 for ( QgsChangedAttributesMap::const_iterator cit = changedAttrsMap.
begin(); cit != changedAttrsMap.
end(); ++cit )
1402 if ( isAddedFeature( db, layerId, fid ) )
1408 for ( QgsAttributeMap::const_iterator it = attrMap.
begin(); it != attrMap.
end(); ++it )
1410 QString sql =
QString(
"INSERT INTO 'log_feature_updates' VALUES ( %1, %2, %3, %4, '%5' )" )
1415 .arg( it.value().toString() );
1420 increaseCommitNo( db );
1421 sqlite3_close( db );
1424 void QgsOfflineEditing::committedGeometriesChanges(
const QString& qgisLayerId,
const QgsGeometryMap& changedGeometries )
1426 sqlite3* db = openLoggingDb();
1431 int layerId = getOrCreateLayerId( db, qgisLayerId );
1432 int commitNo = getCommitNo( db );
1434 for ( QgsGeometryMap::const_iterator it = changedGeometries.
begin(); it != changedGeometries.
end(); ++it )
1437 if ( isAddedFeature( db, layerId, fid ) )
1443 QString sql =
QString(
"INSERT INTO 'log_geometry_updates' VALUES ( %1, %2, %3, '%4' )" )
1453 increaseCommitNo( db );
1454 sqlite3_close( db );
1457 void QgsOfflineEditing::startListenFeatureChanges()
1476 void QgsOfflineEditing::stopListenFeatureChanges()
1495 void QgsOfflineEditing::layerAdded(
QgsMapLayer* layer )
1501 connect( vLayer, SIGNAL( editingStarted() ),
this, SLOT( startListenFeatureChanges() ) );
1502 connect( vLayer, SIGNAL( editingStopped() ),
this, SLOT( stopListenFeatureChanges() ) );
virtual QString subsetString()
Get the string (typically sql) used to define a subset of the layer.
static WkbType flatType(WkbType type)
Map 2d+ to 2d type.
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.
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
Filter using feature IDs.
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)
bool contains(const Key &key) const
#define PROJECT_ENTRY_KEY_OFFLINE_DB_PATH
bool deleteFeature(QgsFeatureId fid)
Delete a feature from the layer (but does not commit it)
QgsMapLayer * mapLayer(const QString &theLayerId) const
Retrieve a pointer to a registered layer by layer ID.
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.
void setReferencingLayer(const QString &id)
Set the referencing (child) layer id.
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.
void setGeometry(QgsAbstractGeometryV2 *geometry)
Sets the underlying geometry store.
#define Q_NOWARN_DEPRECATED_PUSH
#define CUSTOM_PROPERTY_REMOTE_SOURCE
FilterType filterType() const
Return the filter type which is currently set on this request.
Abstract base class for all geometries.
Container of fields for a vector layer.
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all registered layers by layer ID.
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 by layer ID.
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
QgsLayerTreeGroup * layerTreeRoot() const
Return pointer to the root (invisible) node of the project's layer tree.
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)
bool addFeature(QgsFeature &feature, bool alsoUpdateExtent=true)
Adds a feature.
QgsRelationManager * relationManager() const
const QList< QgsVectorJoinInfo > vectorJoins() const
bool isOfflineProject() const
Return true if current project is offline.
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 *)
virtual QString name() const =0
Return a provider name.
bool convertToOfflineProject(const QString &offlineDataPath, const QString &offlineDbFile, const QStringList &layerIds, bool onlySelected=false)
Convert current project for offline editing.
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 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)
void update(const QString &name, const PresetRecord &state)
Updates a preset within the collection.
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
void append(const T &value)
QList< QgsRelation > referencingRelations(QgsVectorLayer *layer=nullptr, int fieldIdx=-2) const
Get all relations where the specified layer (and field) is the referencing part (i.e.
QString fromUtf8(const char *str, int size)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
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.
bool rollBack(bool deleteBuffer=true)
Stop editing and discard the edits.
#define QgsDebugMsgLevel(str, level)
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer *> &theMapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
QMap< QString, QString > mPerLayerCurrentStyle
For layers that use multiple styles - which one is currently selected.
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)
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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
QStringList mVisibleLayerIDs
Ordered list of layers that are visible.
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.
QList< QgsRelation > referencedRelations(QgsVectorLayer *layer=nullptr) const
Get all relations where this layer is the referenced part (i.e.
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)
virtual QVariant defaultValue(int fieldId, bool forceLazyEval=false)
Returns the default value for field specified by fieldId.
const QStringList & commitErrors()
void setReferencedLayer(const QString &id)
Set the referenced (parent) layer id.
QgsFeatureId id() const
Get the feature ID for this feature.
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
bool contains(QChar ch, Qt::CaseSensitivity cs) const
virtual void reload() override
Synchronises with changes in the datasource.
QgsGeometry * geometry()
Get the geometry object associated with this feature.
QgsLayerTreeLayer * findLayer(const QString &layerId) const
Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tr...
QString defaultValueExpression(int index) const
Returns the expression used when calculating the default value for a field.
const char * typeToName(Type typ)
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
#define Q_NOWARN_DEPRECATED_POP
const Key key(const T &value) const
long toLong(bool *ok, int base) const
PresetRecord presetState(const QString &name) const
Returns the recorded state of a preset.
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.
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.
QgsAbstractGeometryV2 * geometry() const
Returns the underlying geometry store.
QString mid(int position, int n) const
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Set feature IDs that should be fetched.
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...
Individual preset record of visible layers and styles.
QString source() const
Returns the source for the layer.
QString absolutePath() const
void synchronize()
Synchronize to remote layers.
This class manages a set of relations between layers.
QString readPath(QString filename, const QString &relativeBasePath=QString()) const
Turn filename read from the project file to an absolute path.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QString table() const
Returns the table.
int count(const T &value) const
void setTitle(const QString &title)
Sets the project's title.
QString absoluteFilePath(const QString &fileName) const
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.
Container class that allows storage of visibility presets consisting of visible map layers and layer ...
QString name
Read property of QString layerName.
iterator insert(const Key &key, const T &value)
void removeRelation(const QString &id)
Remove a relation.
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
static QgsGeometry * fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
QString providerType() const
Return the provider type for this layer.
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
virtual QgsAbstractGeometryV2 * clone() const =0
Clones the geometry by performing a deep copy.
QMap< QString, QSet< QString > > mPerLayerCheckedLegendSymbols
For layers that have checkable legend symbols and not all symbols are checked - list which ones are...
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)
QStringList presets() const
Returns a list of existing preset names.
QgsVisibilityPresetCollection * visibilityPresetCollection()
Returns pointer to the project's visibility preset collection.
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
bool removeOne(const T &value)
#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
QVariant defaultValue(int index, const QgsFeature &feature=QgsFeature(), QgsExpressionContext *context=nullptr) const
Returns the calculated default value for the specified field index.
int remove(const Key &key)
void addRelation(const QgsRelation &relation)
Add a relation.
QByteArray toUtf8() const