Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the function setId in qgsfeature is not working #44898

Closed
1 of 2 tasks
jaredhan opened this issue Aug 31, 2021 · 3 comments
Closed
1 of 2 tasks

the function setId in qgsfeature is not working #44898

jaredhan opened this issue Aug 31, 2021 · 3 comments
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter!

Comments

@jaredhan
Copy link

What is the bug or the crash?

function "void setId( QgsFeatureId id );" is not work, when i create a feature, i use "setAttribute" and "setId" to set attribute and id ,but when i add the feature to layer and commit it to data provider , i fond the id is not what i set. it was data provider generated.

Steps to reproduce the issue

void TSMapWidget::DrawPolygon(QString polystring)
{
if (QgsVectorLayer * veclay = qobject_cast<QgsVectorLayer *>(GetOrCreateQgsPolygonMapLayer(5520)))
{
QgsProject::instance()->addMapLayer(veclay);

	veclay->startEditing();

	QgsSimpleFillSymbolLayer * fill = new QgsSimpleFillSymbolLayer();
	fill->setStrokeColor(QColor(253,191,204,50));
	fill->setFillColor(QColor(163,96,35,50));
	fill->setStrokeStyle(Qt::SolidLine);
	fill->setStrokeWidth(0.26);

	QgsSymbolLayerList symbolList;
	symbolList << fill;

	QgsFillSymbol *mFillSymbol = new QgsFillSymbol(symbolList);
	mFillSymbol->changeSymbolLayer(0, fill);
	
	QgsSingleSymbolRenderer *mSymbolRenderer = new QgsSingleSymbolRenderer(mFillSymbol);
	veclay->setRenderer(mSymbolRenderer);

	QgsFeatureList flist;

	QgsFeature f1;

	f1.setGeometry(QgsGeometry::fromWkt(polystring));
	f1.setId(112);//test code
	flist << f1;
	
	veclay->dataProvider()->addFeatures(flist);


	veclay->commitChanges();


	veclay->updateExtents();


	QList<QgsMapLayer *> ss = _p->_MapCanvas->layers();
	ss.push_front(veclay);
	_p->_MapCanvas->setLayers(ss);
	_p->_MapCanvas->setCurrentLayer(veclay);

	//test code
	qint64 ssid = f1.id();
	auto sdaa = veclay->getFeature(ssid);
	bool sssqq = sdaa.isValid();

	veclay->selectAll();
	auto ssqqqd = veclay->selectedFeatureIds().begin();

	qDebug() << "id:" << ssid << ";" << "valid:" << sssqq << "real:" << (*ssqqqd);
}

_p->_MapCanvas->refresh();

}

Versions

QGIS version
3.16.7-Hannover
QGIS code revision
acdcfc3
Compiled against Qt
5.11.2
Running against Qt
5.11.2
Compiled against GDAL/OGR
3.4.0dev
Running against GDAL/OGR
3.4.0dev
Compiled against GEOS
3.8.1-CAPI-1.13.3
Running against GEOS
3.8.1-CAPI-1.13.3
Compiled against SQLite
3.29.0
Running against SQLite
3.29.0
PostgreSQL Client Version
11.5
SpatiaLite Version
4.3.0
QWT Version
6.1.3
QScintilla2 Version
2.10.8
Compiled against PROJ
8.1.0
Running against PROJ
Rel. 8.1.0, July 1st, 2021
OS Version
Windows 10 (10.0)
This copy of QGIS writes debugging output.
Active python plugins
db_manager;
MetaSearch;
processing

Supported QGIS version

  • I'm running a supported QGIS version according to the roadmap.

New profile

  • I tried with a new QGIS profile

Additional context

No response

@jaredhan jaredhan added the Bug Either a bug report, or a bug fix. Let's hope for the latter! label Aug 31, 2021
@jaredhan jaredhan changed the title the function setId in qgsfeature is not useful the function setId in qgsfeature is not work Aug 31, 2021
@Joonalai
Copy link
Contributor

Joonalai commented Sep 17, 2021

I could replicate this bug with QGIS 3.20.2 on Arch. This also happens with PyQGIS:

feature = QgsFeature()
# Also happens when setting geometry or attributes
feature.setId(112)
print(feature.id())
layer = QgsVectorLayer("Point", "foo", "memory")
with edit(layer):
    succeeded = layer.addFeature(feature)
    assert succeeded
print(feature.id())

@gioman gioman changed the title the function setId in qgsfeature is not work the function setId in qgsfeature is not working Sep 17, 2021
@lbartoletti
Copy link
Member

I think there is a misunderstanding of what this method should do.

QgsFeature::setId seems to work:

feature = QgsFeature()
print(feature.id())
# -9223372036854775808
feature.setId(1)
print(feature.id())
# 1
feature.setId(1234)
print(feature.id())
# 1234

However, it's true that the id is no longer the same when integrated into the vector layer:

layer = QgsVectorLayer("Point", "foo", "memory")
with edit(layer):
    succeeded = layer.addFeature(feature)
    assert succeeded
print(feature.id())
# -27

And the feature from the layer is:

print( layer.getFeature(1).id() )
# 1

So, why?
The simplified workflow to add a feature is:
QgsVectorLayer::addFeature -> QgsVectorLayerEditBuffer::addFeature -> QgsVectorLayerUndoCommandAddFeature::QgsVectorLayerUndoCommandAddFeature

In this class, you have a comment about this change:

Force a feature ID (to keep other functions in QGIS happy,
providers will use their own new feature ID when we commit the new feature)
and add to the known added features.

@nyalldawson
Copy link
Collaborator

I think this is a documentation gap -- we should have a note in QgsFeature::setId along the lines "\warning Feature IDs will be automatically changed whenever a feature is added to vector layer or data provider. This method is not designed to allow a specific feature ID to be assigned to a feature which will be added to a layer or data provider, and the results will be unpredictable".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter!
Projects
None yet
Development

No branches or pull requests

4 participants