3

I am working in c++/QT 4.5 with the QGis 2.8.2 API. I had to change the geometry of features in a layer each second. Each second new data comes from the Ethernet connection, the application gets the data and calls a function with parameters.

It looks like a real time tracker. It works only if I put lLayer->startEditing and lLayer->commitChanges but it was too slow.

Here is my code (just an extract. Complete code is too long for the post.)

QgsVectorLayer * lLayer = mMapLayer.value(TRACKS);
lLayer->startEditing();
QgsVectorDataProvider * lDataProvider;
lDataProvider = lLayer->dataProvider();

//calc new random X and Y
PosX =(qrand()%(Xmax-Xmin)+Xmin);
PosY =(qrand()%(Ymin-Ymax)+Ymax);
//create point
QgsGeometry *MyPoint;
MyPoint=QgsGeometry::fromPoint(QgsPoint(PosX,PosY));
QgsGeometryMap MyGeometryMap;
//get the feature of the specify Id
QgsFeatureIterator MyFeatIter;
MyFeatIter = lDataProvider->getFeatures();
QgsFeature MyFeature;
QgsFeatureId MyFeatureId;
while ( MyFeatIter.nextFeature(MyFeature)) {
    if (pTrackId == MyFeature.attribute("TrackId")) {
        MyFeatureId=MyFeature.id();
        MyFeature.setGeometry(*MyPoint);
        MyFeature.setAttribute(Longitude,PosY);
        MyFeature.setAttribute(Latitude,PosX);
    }
}

MyGeometryMap.insert(MyFeatureId,*MyPoint);
bool lResult;
lResult=lDataProvider->changeGeometryValues(MyGeometryMap);
lLayer->commitChanges();

With the startEditing and commitChanges it works, but very slow. Without the startEditing and commitChanges, the coordinate seems to be modified, but on the layer the feature doesn't move.

4
  • Can you name your variables starting with a lower-case letter, so they don't look like class names?
    – das-g
    Commented Aug 28, 2015 at 15:25
  • ok, for the future post all my variable will start with a lower case letter
    – ainardi
    Commented Aug 28, 2015 at 16:42
  • Can you elaborate on which dataprovider you are using and what exactly you expect from your application (i.e. an animated canvas and/or persistent data) Commented Aug 28, 2015 at 16:43
  • i want an animated canvas that why i need to update the geometry with the new position, I am using the dataprovider from the vectorlayer where the change is needed, My layer contains up to 20 features with different symbology based on the position and differents caracteristics that change during the execution of the application, perhaps i use the wrong dataprovider
    – ainardi
    Commented Aug 28, 2015 at 17:12

1 Answer 1

4

Data Provider vs Vector Layer

A vector layer has a data provider which (normally [1]) is used to store data persistently.

If you edit something on the layer with a normal edit session, your changes will be saved in the vector layer until you commit them, then they will be sent to the data provider.

Edit Sessions

In your example you start an edit session on the layer but then write directly to the data provider. Instead you should either

  • Not use an edit session and only use QgsDataProvider(lDataProvider)

    Working directly on the data provider has the significant drawback, that there is no signal sent to the canvas (and other parts of the application) about the fact that data has changed. So whenever you use the approach of directly writing to the data provider you take the responsibility of signalling changes to all affected parts of the application that may be interested in being notified of these changes.

  • Work with edit sessions and never use lDataProvider but QgsVectorLayer(lLayer) instead

    QgsVectorLayer has the appropriate methods to get a feature iterator, to change geometries or attributes and delete or add features itself and will emit signals about changed data to which interested parties (like the map canvas or attribute table) can subscribe and react.

Performance

The performance of commitChanges is determined by the data provider which the layer uses (and the number/complexity of operations it needs to perform).

If you are happy with an animated canvas and do not need persistent storage, you may use a memory provider or just not commit changes (so they will be rendered from the edit buffer).

If you need to have persistent storage, make sure you choose a good data provider and have proper I/O resources (network, disk...).

Qt Version

Please update to Qt 4.8

[1] Memory Layer is an exception to this

1
  • sorry i am in QT 4.8.5 not 4.5 it is a mistake from me
    – ainardi
    Commented Aug 28, 2015 at 17:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.