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

High level wrapper over QgsFeatureRequest #69

Open
NathanW2 opened this issue Dec 7, 2016 · 2 comments
Open

High level wrapper over QgsFeatureRequest #69

NathanW2 opened this issue Dec 7, 2016 · 2 comments

Comments

@NathanW2
Copy link
Member

NathanW2 commented Dec 7, 2016

The layer iterators are fantastic however the API is pretty raw I think a higher level wrapper to make it a bit more approachable would be nice.

Here is an example in Python that I have done in one my projects:

points = query.From(mylayer).where("valid = True").select("ID", "COL2")

Can be used in line quite nicely in a for loop:

for point in query.From(mylayer).where("valid = True").select("ID", "COL2"):
    pass

Under the hood this just wraps QgsFeatureRequest and handles any of building:

Compared to:

rq = QgsFeatureRequest()
rq.setFilterExpression("valid = True')
rq.setSubsetOfAttributes(["ID", "COL2"], mylayer.pendingFIelds())
for point in mylayer.getFeatures(rq):
    pass

Python version:

class Query(object):
    def __init__(self, layer):
        self.rq = QgsFeatureRequest()
        self.layer = layer

    def where(self, expression):
        self.rq.setFilterExpression(expression)
        return self

    def in_(self, *ids):
        self.rq.setFilterFids(ids)
        return self

    def extent(self, rect):
        self.rq.setFilterRect(rect)
        return self

    def no_geometry(self):
        self.rq.setFlags(QgsFeatureRequest.NoGeometry)
        return self

    def limit(self, top):
        self.rq.setLimit(top)
        return self

    def select(self, *fields, **kwargs):
        if fields:
            self.rq.setSubsetOfAttributes(fields, self.layer.pendingFields())
        if "geometry" in kwargs and not kwargs['geometry']:
            self.no_geometry()

        return self.layer.getFeatures(self.rq)
@wonder-sk
Copy link
Member

QgsFeatureRequest could get some love to make it less verbose... but rather than building a wrapper on top of it, maybe better to try to improve existing API...? Something like:

for f in layer.query().filter("x=1").limit(5):
    print f

So layer.query() would replace layer.getFeatures(...) and it would just return QgsFeatureRequest initialized to the given layer, which could have further chained method calls. Then we would just make QgsFeatureRequest an iterable class (in both c++ and python).

Possibly the class name of QgsFeatureRequest could be also changed to QgsFeatureQuery ?

@NathanW2
Copy link
Member Author

NathanW2 commented Dec 7, 2016 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants