[Qgis-developer] New Vector API

Marco Hugentobler marco.hugentobler at sourcepole.ch
Mon Jan 7 02:45:02 PST 2013


Hi Martin

Finally I had a look at the vector changes and I really like the new 
architecture. I agree it is important to merge soon. Merging as soon as 
server and the remaining providers are ported would be good in my opinion.
Btw, there is a problem with postgis layers, probably related to the 
recent fix: After zooming to a new extent, I always need to refresh a 
second time to get the features (with the refresh button in the main 
window). Otherwise, no features are drawn.

Regards,
Marco




On 28.12.2012 17:03, Martin Dobias wrote:
> Hi everyone,
>
> it seems that now it is a good time to ask for a broader review of the
> work I have been doing during recent months: essentially making QGIS
> vector API more flexible and more ready for introduction of threading
> for rendering. That resulted in a greater refactoring of some parts of
> QgsVectorLayer class and QgsVectorDataProvider implementations.
> Everything is in new_vector_api branch in QGIS repository on GitHub
> [1].
>
> There are few things that are not finished, but should not take too
> much work to sort out:
> - disabled providers - mssql, osm, sqlanywhere, wfs - not yet updated to new API
> - disabled mapserver - there are few things to update
>
> If no serious problems will be found, I would like to merge the branch
> to master and continue working on that on master branch to avoid the
> possibility to drift (again) too much from the quick development that
> happens on master. In short term I plan to do some polishing and
> fixing bugs, then eventually start looking at the threading again.
>
> For more details about what happened in the branch, see the text below
> (long read!). A great help from early testers would be to compile the
> branch, try to do some "usual" stuff with vectors and see if things
> break apart (crashes? data corruption?).
>
> Looking forward to your comments!
>
> Regards
> Martin
>
> [1] https://github.com/qgis/Quantum-GIS/tree/new_vector_api
>
>
>
> QGIS VECTOR API CHANGES
>
> 1. QgsFeature (changes)
>
> a) access to attributes by name. Vector data providers and vector
> layer assign pointer to the fields in QgsFeature, so it is possible to
> set/get attributes by their name. This is not as efficient as with
> direct access by index, but often this convenience is useful for
> users.
>
> b) attributes are stored in a QVector container rather than a QMap.
> The major advantage is simplification of logic related to handling of
> attributes: it's not possible to have "holes" in the array of
> fields/attributes. Currently it is possible that for example layer
> with three fields returns indexes 0,1,3 - but it is not so common nor
> obvious, so it's a common source of errors. After refactoring there
> must not be any holes, so a layer with three fields always returns
> indexes 0,1,2. When iterating over layer's features, QgsFeature always
> contains a vector of all layer's attributes. In case the client has
> not requested attributes to be fetched, the attributes contain invalid
> values.
>
>
> 2. QgsFields (new class)
>
> Just like attributes within a feature are stored in a vector instead
> of map, also layer's fields are now stored in a vector. QgsFields is a
> new class that mimics QVector API and adds two more pieces of
> functionality:
>
> a) fast lookup of field index from name. When QgsFields is populated
> with fields, it creates a map of fields that facilitates fast lookups
>
> b) detection of field origin. When working with a vector layer, it is
> sometimes useful to find out origin of the field - whether it comes
> from provider, from a join or whether it is a newly added field (not
> committed). In the future we could add also expression-based fields,
> creating a field calculator that calculates the values on the fly.
>
>
> 3. QgsFeatureRequest (new class)
>
> Class that encapsulates requests for features to a vector layer or
> vector data provider. Right now in master branch, the request is
> defined by arguments to select() method. That's not very flexible nor
> simple to use. Feature request class allows easier extensibility in
> future (support generic expression filter, native provider's SQL
> filter...).
>
> Without any customization, the request will ask for all features with
> geometries and attributes - somehow better default that the current
> one that does not fetch attributes if their list is not explicitly
> given.
>
> (I'm not yet completely happy with the API of this class, so it may be
> changed to some degree. Suggestions are welcome.)
>
> Examples:
> - fetch all features:
>      QgsFeatureRequest()
> - fetch all features, only one attribute
>      QgsFeatureRequest().setSubsetOfAttributes(QStringList("myfield"),
> provider->fields())
> - fetch all features, without geometries
>      QgsFeatureRequest().setFlags(QgsFeatureRequest::NoGeometry)
> - fetch only features from particular extent
>      QgsFeatureRequest().setFilterRect(QgsRectangle(0,0,1,1))
> - fetch only one feature
>      QgsFeatureRequest().setFilterFid(45)
>
>
>
> 4. QgsFeatureIterator (new class)
>
> The iterator class allows iteration over features of a vector layer or
> a provider. It contains the usual nextFeature() method that fills
> given QgsFeature class with data.
>
> Internally, this class is a wrapper around QgsAbstractFeatureIterator
> interface that is implemented by each vector data provider and by
> vector layer. In theory we could use directly
> QgsAbstractFeatureIterator pointers, but this wrapper allows us to use
> it as a local variable, so it gets destroyed automatically when it
> gets out of scope, not requiring an explicit "delete" call that would
> be necessary with a pointer (easy to forget, right?)
>
>
> 5. Access to features
>
> Vector layer and providers implement one important method call:
> getFeatures(). It takes single argument (QgsFeatureRequest) and
> returns QgsFeatureIterator. This replaces select(), nextFeature(),
> rewind() and featureAtId() methods.
>
> This approach allows users to create multiple iterators over a vector
> layer (or a vector data provider). But currently that's not supported
> because this needs support in the providers. At some point, we could
> add support for simultaneous iterators - something that old API does
> not allow at all.
>
> When QgsFeatureIterator instance of a particular layer is closed (by
> calling close() or destructed), then a new getFeatures() call may be
> issued.
>
>
> 6. QgsVectorLayerEditBuffer (new class)
>
> All editing functionality of vector layer has been moved out of
> QgsVectorLayer into a new class that stores everything related to
> editing: added features, removed features, changed geometries, changed
> attribute values, added attributes, removed attributes. This class is
> accessible from QgsVectorLayer, but it exists only when the layer is
> in editing mode - it is deleted once features are rolled back or
> committed.
>
> The undo/redo support has been completely rewritten and greatly
> simplified: instead of one undo command that gathers changes within
> the edit buffer, there is now one undo command implementation for each
> action. The undo commands can be grouped together with QUndoStack
> macros. The new implementation ensures that the undo stack does not
> get out of sync, because all editing changes are stored onto undo
> stack (unlike current implementation in master branch where
> begin/end-UndoCommand() methods must be called before/after edit
> operations to ensure correct behavior of undo).
>
>
> 7. QgsVectorLayerEditUtils (new class)
>
> Advanced editing operations that operate on vector layers (e.g. add
> part) that can be composed from one or more simple edit operations
> have been moved out of QgsVectorLayer and its edit buffer, so that the
> vector layer API is not polluted by methods that do not need access to
> its private members.
>
>
> 8. QgsVectorLayerCache (new class)
>
> To speed up geometry editing, QGIS keeps a cache of geometries
> currently shown in map canvas. This cache has been decoupled from
> editing operations and moved to a separate class to keep things tidy.
> In the future we should be able to add more general caching scheme to
> allow faster rendering of vectors. Also, this might be a good place to
> store index of feature ID -> row number that is calculated every time
> when attribute table is opened.
>
>
> 9. Python
>
> Python API has been updated to support functionality from the points
> above, that is access by attribute name and support for python
> iterators, e.g.:
>
> for feature in layer.getFeatures(request):
>    print feature["road_id"]
> _______________________________________________
> Qgis-developer mailing list
> Qgis-developer at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/qgis-developer


-- 
Dr. Marco Hugentobler
Sourcepole -  Linux & Open Source Solutions
Weberstrasse 5, CH-8004 Zürich, Switzerland
marco.hugentobler at sourcepole.ch http://www.sourcepole.ch
Technical Advisor QGIS Project Steering Committee



More information about the Qgis-developer mailing list