Related Plugins and Tags

QGIS Planet

QGIS 64bit for Windows is ready to test

faunaliagis

Welcome to New QGIS PSC Members

Nominations for the QGIS PSC closed at 00:00 UTC on August 25, 2013 [1].

With only one nominee for each role, the PSC unanimously moved to accept each without election.

The QGIS PSC welcomes new members Anita Graser, Richard Duivenvoorde, and Jürgen Fischer.

The PSC is now composed of:

  • Chair - Gary Sherman
  • Community Advisor - Otto Dassau
  • Design Advisor - Anita Graser
  • Financial and Marketing Advisor - Paolo Cavallini
  • Infrastructure Manager - Richard Duivenvoorde
  • Release Manager - Jürgen Fischer
  • Technical Advisor - Marco Hugentobler
  • Testing/QA Manager - Tim Sutton

The new PSC members begin their terms immediately.

[1] http://hub.qgis.org/projects/quantum-gis/wiki/Call_for_Nominations_August_2013

Comparison of SOM Classification and Unsupervised KMeans image classification in SEXTANTE

faunaliagis

Detecting tree canopies with Unsupervised Classification in SEXTANTE

faunaliagis

Creating a simple habitat selection model in QGIS/SEXTANTE

faunaliagis

Generate series of maps with Python script

Sometimes you need to produce a series of similar thematic maps. The only difference is the field used to colour areas or show graduated symbols. Classifications or maximal symbol sizes are identical. For large numbers of maps it is quite annoying to repeat the same actions in QGIS over and over again. Moreover, mistakes are […]

There has never been a better time to sponsor QGIS

FOSS4G2013 is starting in just over a month and we (the QGIS project) are really hoping to make QGIS 2.0 available for the event. Its going to be a huge splash as 2.0 is a giant leap forward over version 1.8. However there is a hitch: We have 15 blocker issues holding up the release.... Read more »

QGIS PSC Call for Nominations

The QGIS Project Steering Committee (PSC) has announced a call for nominations to fill three vacant positions:

  • Design Advisor
  • Infrastructure Manager
  • Release Manager

Nominations are open until August 24, 2013. For details on the PSC, vacancies, and how to nominate someone, see:

http://hub.qgis.org/projects/quantum-gis/wiki/Call_for_Nominations_August_2013

Death to the message box! Use the QGIS messagebar

The good ol' message box. So easy to use. Yet such as stab in the users user experience metaphorical heart. Nothing like working along and getting a nice dialog to tell you can't do something or that the operation has finished

dave.png

info.png

You might think. "Well there isn't really anything wrong with that. I needed to tell the user everything is done". Sure but what you didn't need to do was stop the user and make them acknowledge it. Consider if your car made you OK something you each time your speed changed.

speed.png

speed2.png

speed3.png

Pretty annoying.

What is the alternative then?

Introducing the QGIS message bar

errorbar.png

infobar.png

warningbar.png

If you have been using QGIS 1.9 (the dev version for 2.0) you might have noticed it already. It's a great new way for us to let the user know about something without blocking their work or getting in the way. The best part is your can even access the message bar to post messages from your plugins.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, I'm afraid I can't do that", level=QgsMessageBar.CRITICAL)

errorbar.png

It even has timer to show a message for a limited time.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, ..", level=QgsMessageBar.CRITICAL, duration=3)

errorbar-timed.png

or showing a button for more info

def showError():
    pass

widget = iface.messageBar().createMessage("Missing Layers", "Show Me")
button = QPushButton(widget)
button.setText("Show Me")
button.pressed.connect(showError)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)

bar-button.png

In your own widgets

You can even use a message bar in your own dialog so you don't have to show a message box or if it doesn't make sense to show it in the main QGIS window.

class MyDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
        self.setLayout(QGridLayout())
        self.layout().setContentsMargins(0,0,0,0)
        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
        self.buttonbox.accepted.connect(self.run)
        self.layout().addWidget(self.buttonbox , 0,0,2,1)
        self.layout().addWidget(self.bar, 0,0,1,1)
        
    def run(self):
        self.bar.pushMessage("Hello", "World", level=QgsMessageBar.INFO)

dialog-with-bar.png

Don't abuse it

Like anything the message bar can be abused if not careful. Avoid dumping debugging messages to it as this will annoy users rather then help. Use QgsMessageLog.logMessage() if you need to write debugging information. Also consider which messages you post there as posting too many messages will mean the user might just ignore it like they do with message boxes.

Death to the message box! Use the QGIS messagebar

The good ol' message box. So easy to use. Yet such as stab in the users user experience metaphorical heart. Nothing like working along and getting a nice dialog to tell you can't do something or that the operation has finished

Alt Text

Alt Text

You might think. "Well there isn't really anything wrong with that. I needed to tell the user everything is done". Sure but what you didn't need to do was stop the user and make them acknowledge it. Consider if your car made you OK something you each time your speed changed.

Alt Text

Alt Text

Alt Text

Pretty annoying.

What is the alternative then?

Introducing the QGIS message bar

Alt Text

Alt Text

Alt Text

If you have been using QGIS 1.9 (the dev version for 2.0) you might have noticed it already. It's a great new way for us to let the user know about something without blocking their work or getting in the way. The best part is your can even access the message bar to post messages from your plugins.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, I'm afraid I can't do that", level=QgsMessageBar.CRITICAL)

Alt Text

It even has timer to show a message for a limited time.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, ..", level=QgsMessageBar.CRITICAL, duration=3)

Alt Text

or showing a button for more info

def showError():
    pass

widget = iface.messageBar().createMessage("Missing Layers", "Show Me")
button = QPushButton(widget)
button.setText("Show Me")
button.pressed.connect(showError)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)

Alt Text

In your own widgets

You can even use a message bar in your own dialog so you don't have to show a message box or if it doesn't make sense to show it in the main QGIS window.

class MyDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
        self.setLayout(QGridLayout())
        self.layout().setContentsMargins(0,0,0,0)
        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
        self.buttonbox.accepted.connect(self.run)
        self.layout().addWidget(self.buttonbox , 0,0,2,1)
        self.layout().addWidget(self.bar, 0,0,1,1)

    def run(self):
        self.bar.pushMessage("Hello", "World", level=QgsMessageBar.INFO)

Alt Text

Don't abuse it

Like anything the message bar can be abused if not careful. Avoid dumping debugging messages to it as this will annoy users rather then help. Use QgsMessageLog.logMessage() if you need to write debugging information. Also consider which messages you post there as posting too many messages will mean the user might just ignore it like they do with message boxes.

Death to the message box! Use the QGIS messagebar

The good ol' message box. So easy to use. Yet such as stab in the users user experience metaphorical heart. Nothing like working along and getting a nice dialog to tell you can't do something or that the operation has finished

Alt Text

Alt Text

You might think. "Well there isn't really anything wrong with that. I needed to tell the user everything is done". Sure but what you didn't need to do was stop the user and make them acknowledge it. Consider if your car made you OK something you each time your speed changed.

Alt Text

Alt Text

Alt Text

Pretty annoying.

What is the alternative then?

Introducing the QGIS message bar

Alt Text

Alt Text

Alt Text

If you have been using QGIS 1.9 (the dev version for 2.0) you might have noticed it already. It's a great new way for us to let the user know about something without blocking their work or getting in the way. The best part is your can even access the message bar to post messages from your plugins.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, I'm afraid I can't do that", level=QgsMessageBar.CRITICAL)

Alt Text

It even has timer to show a message for a limited time.

iface.messageBar().pushMessage("Error", "I'm sorry Dave, ..", level=QgsMessageBar.CRITICAL, duration=3)

Alt Text

or showing a button for more info

def showError():
    pass

widget = iface.messageBar().createMessage("Missing Layers", "Show Me")
button = QPushButton(widget)
button.setText("Show Me")
button.pressed.connect(showError)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)

Alt Text

In your own widgets

You can even use a message bar in your own dialog so you don't have to show a message box or if it doesn't make sense to show it in the main QGIS window.

class MyDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
        self.setLayout(QGridLayout())
        self.layout().setContentsMargins(0,0,0,0)
        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
        self.buttonbox.accepted.connect(self.run)
        self.layout().addWidget(self.buttonbox , 0,0,2,1)
        self.layout().addWidget(self.bar, 0,0,1,1)

    def run(self):
        self.bar.pushMessage("Hello", "World", level=QgsMessageBar.INFO)

Alt Text

Don't abuse it

Like anything the message bar can be abused if not careful. Avoid dumping debugging messages to it as this will annoy users rather then help. Use QgsMessageLog.logMessage() if you need to write debugging information. Also consider which messages you post there as posting too many messages will mean the user might just ignore it like they do with message boxes.

4th GRASS GIS Community Sprint: Exciting achievements

The GRASS GIS community is delighted to present the outcome of the 4th Community Sprint that took place in a warm and sunny Prague, Czech Republic, from July 12 to July 18, 2013. The event happened after the Geoinformatics conference at the Czech Technical University in Prague. The Community Sprint was once more a creative gathering of both long-term and new developers, as well as users.
This meeting was held in the light of 30 YEARS OF GRASS GIS!

30 YEARS OF GRASS GIS!
We wish to cordially thank the Department of Mapping and Cartography, Faculty of Civil Engineering, Czech Technical University in Prague for hosting and technical support. In particular, we gratefully acknowledge our association sponsors OSGeo  and FOSSGIS e.V., and many individual donors: Peter Löwe, Andrea Borruso, Massimo Di Stefano, Alessandro Sarretta, Joshua Campbell, Andreas Neumann, Jon Eiriksson, Luca Casagrande, Karyn O Newcomb, Holger Naumann, Anne Ghisla, Helena Mitasova and Lubos Mitas, Dimitris Tamp, Mark Seibel, Markus Metz, and Tawny Gapinski. These financial contributions were used to cover costs such as meals and to help reducing travelling and accommodation expenses for participants with far arrival who came on own expenses.

Developers and users who joined the event came from various countries like Italy, Czech Republic, Slovak Republic, Poland, Sri Lanka/France, USA and Germany.
The Community Sprint focused on:

  • testing/bugfixing of the upcoming GRASS 7 version,
  • backporting new functionalities to the stable GRASS 6.4 series,
  • testing/bugfixing related to Mac OS X, MS-Windows and Linux,
  • presenting and developing the new Temporal GIS Algebra in GRASS 7,
  • connecting GRASS 7 with the planetary science software ISIS,
  • discussing integration with rasdaman.org software, a powerful multidimensional raster processor,
  • creating 3D vector test data for 3D interpolation,
  • discussing vector conflation,
  • discussing Bundle Block Adjustments,
  • presenting the state of image processing in GRASS 7, and discussing its future,
  • improving documentation, with focus on image processing and Temporal GIS Algebra,
  • developing/refactoring and bugfixing several wxGUI’s components,
  • further developing customizable wxGUI Toolboxes concept,
  • improving translation in Polish and Romanian languages,
  • fixing v.krige in GRASS7 and proposing merge with the recently developed v.kriging module,
  • meeting between Google Summer of Code 2013 mentor and students.

A lot of topic oriented discussions happened among small groups of participants: for more detailed information, please visit the Wiki pages at http://grasswiki.osgeo.org/wiki/GRASS_Community_Sprint_Prague_2013 and the related discussion page at http://grasswiki.osgeo.org/wiki/Talk:GRASS_Community_Sprint_Prague_2013

About GRASS GIS
The Geographic Resources Analysis Support System, commonly referred to as GRASS GIS, is an Open Source Geographic Information System providing powerful raster, vector and geospatial processing capabilities in a single integrated software suite. GRASS GIS includes tools for spatial modeling, visualization of raster and vector data, management and analysis of geospatial data, and the processing of satellite and aerial  imagery. It also provides the capability to produce sophisticated presentation graphics and hardcopy maps. GRASS GIS has been translated into about twenty languages and supports a huge array of data formats. It is distributed freely under the terms of the GNU General Public License (GPL). GRASS GIS is an official project of the Open Source Geospatial Foundation (OSGeo).

GRASS GIS Development Team, July 2013

Vintage map design using QGIS

This post describes the three simple steps necessary to create a vintage-looking map using the blending feature in QGIS 2.0′s print composer. This is what we are aiming for:

alaska_oldpaper

1. Prepare the map

Like any other map, this one starts in the QGIS main window. Try to stick with earthy colors which will go well with the old paper look. For labels, try fonts which look like handwriting.

alaska_oldschool_overview

Once you are happy with your map

2. Prepare the composition background

To get that vintage feel, we need a background image with a great texture. You can find such textures on sites like lostandtaken.com. Download one you like and add it to an empty print composer. Make sure it covers the whole paper:

alaska_oldschool_bg

Lock the image by right-clicking it once – a small lock icon should appear in the upper left corner.

3. Finish the composition

The final step is to add the map on top of the background image. To make our nice background texture shine through, we enable the “multiply” blending mode in the map’s rendering options:

alaska_oldschool_print

Feel free to add north arrows or drawings of dragons as finishing touches.


Stable GRASS GIS 6.4.3 released

GRASS GIS 6.4.3 released – Birthday release for 30 years of GRASS GIS
http://grass.osgeo.org

30 YEARS OF GRASS GIS!

We are pleased to announce the release of a new stable version of GRASS GIS. This release fixes bugs discovered in 6.4.2 version of the program and adds a number of new features. This release includes over
830 updates to the source code since 6.4.2. As a stable release series, the 6.4 line will enjoy long-term support and incremental enhancements while preserving backwards-compatibility with the entire GRASS 6 line.

Key improvements of this release include some new functionality (assistance for topologically unclean vector data), major speedup for some vector modules, fixes in the vector network modules, fixes for the wxPython based portable graphical interface (attribute table management, wxNVIZ, and Cartographic Composer). A number of new modules have been added for processing LANDSAT and MODIS satellite data, and a new vector statistics module is also introduced. Many new symbols and north arrows are available, and the user will find an improved and easier to use wizard for creating custom project locations with precise map projection and datum support. Community-contributed add-on modules are now more easily and robustly installed from an online archive. Other major developments include enhancements to the Python scripting library and numerous software-compatibility fixes and translation updates. Important is the enhanced portability for MS-Windows (native support, fixes in case of missing system DLLs). And we welcome Romanian as our twenty-fourth language!

Source code download:

Binaries download:

  • … further packages will follow shortly.

To get the GRASS GIS 6.4.3 source code directly from SVN:
svn checkout http://svn.osgeo.org/grass/grass/tags/release_20130727_grass_6_4_3

See also our detailed announcement:

  http://trac.osgeo.org/grass/wiki/Release/6.4.3-NewsFirst time users should explore the first steps tutorial after installation.

Video of GRASS GIS 6.4 development visualization from 1999 to 2013 (with soundtrack)
GRASS GIS 6.4 development visualization from 1999 to 2013 (with soundtrack)
About GRASS GIS

GRASS (Geographic Resources Analysis Support System) is a free and open source Geographic Information System (GIS) software suite used for geospatial data management and analysis, image processing, graphics and map production, spatial modeling, and 3D visualization. GRASS GIS is currently used in academic and commercial settings around the world, as well as by many governmental agencies and environmental consulting companies. GRASS GIS can be used either as a stand-alone application or as backend for other software packages such as QGIS and R geostatistics. It is a founding member of the Open Source Geospatial Foundation (OSGeo).

PDF reports with embedded maps

Printing is always one of the more difficult parts in a web mapping application. There are solutions like the MapFish Print module or the built-in QGIS WYSIWYG PDF printing. But very often users do not want only a map on their print output, but collected information stored in a database with images, etc. - and a matching map. This is the domain of database reporting tools like JasperReports. They provide desktop tools for designing complex reports with texts, graphics, images, tables, etc. and server software for web applications. But how to include a matching map - a map with application parameters like the bounding box or a list of active layers, etc.?

Sourcepole is releasing the missing link between high-quality map printing and database reports, an extension for JasperReports/iReport. This extension makes it easy to embed maps served with the standardized Web Map Service (WMS) protocol.

With this extension installed as plugin for iReport Designer, you have all the reporting features of JapserReports plus a new toolbox component for embedding maps.

This allows you to create multi-page reports with embedded maps using parameters from your web mapping application and complex Jasper expressions.

Source and documentation of the WMS map extension for Jasper Reports is available on Github and binaries as Github downloads

Many thanks to Mika from Panter for implementing the Java stuff and the Canton of Zurich for sponsoring this useful piece of Open Source software.

@PirminKalberer

PDF reports with embedded maps

Printing is always one of the more difficult parts in a web mapping application. There are solutions like the MapFish Print module or the built-in QGIS WYSIWYG PDF printing. But very often users do not want only a map on their print output, but collected information stored in a database with images, etc. - and a matching map. This is the domain of database reporting tools like JasperReports. They provide desktop tools for designing complex reports with texts, graphics, images, tables, etc. and server software for web applications. But how to include a matching map - a map with application parameters like the bounding box or a list of active layers, etc.?

Sourcepole is releasing the missing link between high-quality map printing and database reports, an extension for JasperReports/iReport. This extension makes it easy to embed maps served with the standardized Web Map Service (WMS) protocol.

With this extension installed as plugin for iReport Designer, you have all the reporting features of JapserReports plus a new toolbox component for embedding maps.

This allows you to create multi-page reports with embedded maps using parameters from your web mapping application and complex Jasper expressions.

Source and documentation of the WMS map extension for Jasper Reports is available on Github and binaries as Github downloads

Many thanks to Mika from Panter for implementing the Java stuff and the Canton of Zurich for sponsoring this useful piece of Open Source software.

@PirminKalberer

Generate a series of maps 2 (Linux)

In a previous article I described how you can let QGIS generate a series of thematic maps with a batch file. This method was meant for the Windows version of QGIS. Now I have written a similar shell script for Linux (‘projectsnapshots’). You can find it in the ZIP file included with this article. It […]

The little pyqgis query engine

Sean Gillies has managed to get me addicted to using generators, itertools, map, filter, and a generally more declarative style of programming.

What has this got to do with anything? Well let me explain. A little project I have recently started working on in my free time is a mini query engine for pyqgis to make fetching features easier. The goals are simple.

  • Use a query style syntax to say what I need, not how to get it. The basics of declarative programming.
  • Use generators to save on memory unless the user asks.

Before we go any further, just note that this is just a hobby project of mine. Not feature complete nor bug free but it's evolving.

The code can be found on github or its homepage.

What good is a mini query engine? Lets try with some examples.

Get all the features that match the condition `postcode > 6164 OR postcode < 6167'. We will use QgsExpression because that provides a nice where clause type base for us to use.

exp = QgsExpression("postcode > 6164 OR postcode < 6167")
fields = layer.pendingFields()
exp.prepare(fields)
for feature in layer.getFeatures():
    if exp.evaluate(feature):
        print "Pass"

at best you can reduce it to this:

exp = QgsExpression("postcode > 6164 OR postcode < 6167")
fields = layer.pendingFields()
exp.prepare(fields)
features = filter(exp.evaluate, layer.getFeatures())

Not too bad. But still. it's a bit of a pain because you have to care about QgsExpression and looping all the features to check.

How about something like this?

q = query(layer).where("postcode > 6164 OR postcode < 6167")
for feature in q():
    print feature

Define a query on layer and return only the features that match the .where() condition. Sounds pretty descriptive to me.

Nothing is executed until you call the query object itself q() and the return result is a generator so it will only serve up records as we ask. The return type is a Python dict because they are simple, fast, and work well for a return type.

>>> from query import query
>>> q = query(layer).where("postcode > 6164 OR postcode < 6167")
>>> type(q)
<class 'query.Query'>
>>> results = q()
>>> type(results)
<generator object <genexpr> at 0x1A8DDD78>
>>> results.next()
{
u'old': u'http://www.seabreeze.com.au|mylink', 
u'pin_string': u'286633', 
'qgs_geometry': <qgis.core.QgsGeometry object at 0x1A8DF588>, 
u'bool': u'F', 
u'location': None, 
u'lot': u'LOT 79', 
'qgs_feature': <qgis.core.QgsFeature object at 0x1A8DF0C0>
}

Select support

What is the point of a query if you can't ask it to give you just what you need?

>>> q = (query(layer).where("postcode > 6164 OR postcode < 6167")
                     .select('assessment','address', 'lot',
                              geom = lambda f: f.geometry().buffer(20,3),
                              mylot = lambda f: int(f['house_numb']) * 100))
>>> q().next()
{
'geom': <qgis.core.QgsGeometry object at 0x1A8E64B0>, 
'assessment': u'4309719', 
'mylot': 7900, 
'lot': u'LOT 79', 
'address': u'BIRCHLEY RD'
}

You can use "colname" or any Python callable in the select statement. Using keyword arguments is the same as "Col" AS MyName in SQL.

On the TODO list

I would really like to have some kind of index support in the future to make queries run faster. I had basic index support working using a dict however it was nothing smart and was hard coded. QgsExpression does provide support to walk the generated tree see what the expression includes. In "theory" it would involve walking the expression tree and calculating what should be used for index lookup.

Join support would also be nice. Attribute and spatial.

Helpers welcome

Like I said at the start, this is just a hobby project and it's still only in early days however I am always happy for help if you have ideas, or know how to improve something. If you find it handy that would be cool to know too.

Installing

  • Just download the code from here.
  • Add the files to your Python project
  • from query import query

The little pyqgis query engine

Sean Gillies has managed to get me addicted to using generators, itertools, map, filter, and a generally more declarative style of programming.

What has this got to do with anything? Well let me explain. A little project I have recently started working on in my free time is a mini query engine for pyqgis to make fetching features easier. The goals are simple.

  • Use a query style syntax to say what I need, not how to get it. The basics of declarative programming.
  • Use generators to save on memory unless the user asks.

Before we go any further, just note that this is just a hobby project of mine. Not feature complete nor bug free but it's evolving.

The code can be found on github or its homepage.

What good is a mini query engine? Lets try with some examples.

Get all the features that match the condition `postcode > 6164 OR postcode < 6167'. We will use QgsExpression because that provides a nice where clause type base for us to use.

exp = QgsExpression("postcode > 6164 OR postcode < 6167")
fields = layer.pendingFields()
exp.prepare(fields)
for feature in layer.getFeatures():
    if exp.evaluate(feature):
        print "Pass"

at best you can reduce it to this:

exp = QgsExpression("postcode > 6164 OR postcode < 6167")
fields = layer.pendingFields()
exp.prepare(fields)
features = filter(exp.evaluate, layer.getFeatures())

Not too bad. But still. it's a bit of a pain because you have to care about QgsExpression and looping all the features to check.

How about something like this?

q = query(layer).where("postcode > 6164 OR postcode < 6167")
for feature in q():
    print feature

Define a query on layer and return only the features that match the .where() condition. Sounds pretty descriptive to me.

Nothing is executed until you call the query object itself q() and the return result is a generator so it will only serve up records as we ask. The return type is a Python dict because they are simple, fast, and work well for a return type.

>>> from query import query
>>> q = query(layer).where("postcode > 6164 OR postcode < 6167")
>>> type(q)
<class 'query.Query'>
>>> results = q()
>>> type(results)
<generator object <genexpr> at 0x1A8DDD78>
>>> results.next()
{
u'old': u'http://www.seabreeze.com.au|mylink', 
u'pin_string': u'286633', 
'qgs_geometry': <qgis.core.QgsGeometry object at 0x1A8DF588>, 
u'bool': u'F', 
u'location': None, 
u'lot': u'LOT 79', 
'qgs_feature': <qgis.core.QgsFeature object at 0x1A8DF0C0>
}

Select support

What is the point of a query if you can't ask it to give you just what you need?

>>> q = (query(layer).where("postcode > 6164 OR postcode < 6167")
                     .select('assessment','address', 'lot',
                              geom = lambda f: f.geometry().buffer(20,3),
                              mylot = lambda f: int(f['house_numb']) * 100))
>>> q().next()
{
'geom': <qgis.core.QgsGeometry object at 0x1A8E64B0>, 
'assessment': u'4309719', 
'mylot': 7900, 
'lot': u'LOT 79', 
'address': u'BIRCHLEY RD'
}

You can use "colname" or any Python callable in the select statement. Using keyword arguments is the same as "Col" AS MyName in SQL.

On the TODO list

I would really like to have some kind of index support in the future to make queries run faster. I had basic index support working using a dict however it was nothing smart and was hard coded. QgsExpression does provide support to walk the generated tree see what the expression includes. In "theory" it would involve walking the expression tree and calculating what should be used for index lookup.

Join support would also be nice. Attribute and spatial.

Helpers welcome

Like I said at the start, this is just a hobby project and it's still only in early days however I am always happy for help if you have ideas, or know how to improve something. If you find it handy that would be cool to know too.

Installing

  • Just download the code from here.
  • Add the files to your Python project
  • from query import query

The little pyqgis query engine

Sean Gillies has managed to get me addicted to using generators, itertools, map, filter, and a generally more declarative style of programming.

What has this got to do with anything? Well let me explain. A little project I have recently started working on in my free time is a mini query engine for pyqgis to make fetching features easier. The goals are simple.

  • Use a query style syntax to say what I need, not how to get it. The basics of declarative programming.
  • Use generators to save on memory unless the user asks.

Before we go any further, just note that this is just a hobby project of mine. Not feature complete nor bug free but it's evolving.

The code can be found on github or its homepage.

What good is a mini query engine? Lets try with some examples.

Get all the features that match the condition `postcode > 6164 OR postcode < 6167'. We will use QgsExpression because that provides a nice where clause type base for us to use.

exp = QgsExpression("postcode > 6164 OR postcode < 6167")
fields = layer.pendingFields()
exp.prepare(fields)
for feature in layer.getFeatures():
    if exp.evaluate(feature):
        print "Pass"

at best you can reduce it to this:

exp = QgsExpression("postcode > 6164 OR postcode < 6167")
fields = layer.pendingFields()
exp.prepare(fields)
features = filter(exp.evaluate, layer.getFeatures())

Not too bad. But still. it's a bit of a pain because you have to care about QgsExpression and looping all the features to check.

How about something like this?

q = query(layer).where("postcode > 6164 OR postcode < 6167")
for feature in q():
    print feature

Define a query on layer and return only the features that match the .where() condition. Sounds pretty descriptive to me.

Nothing is executed until you call the query object itself q() and the return result is a generator so it will only serve up records as we ask. The return type is a Python dict because they are simple, fast, and work well for a return type.

>>> from query import query
>>> q = query(layer).where("postcode > 6164 OR postcode < 6167")
>>> type(q)
<class 'query.Query'>
>>> results = q()
>>> type(results)
<generator object <genexpr> at 0x1A8DDD78>
>>> results.next()
{
u'old': u'http://www.seabreeze.com.au|mylink', 
u'pin_string': u'286633', 
'qgs_geometry': <qgis.core.QgsGeometry object at 0x1A8DF588>, 
u'bool': u'F', 
u'location': None, 
u'lot': u'LOT 79', 
'qgs_feature': <qgis.core.QgsFeature object at 0x1A8DF0C0>
}

Select support

What is the point of a query if you can't ask it to give you just what you need?

>>> q = (query(layer).where("postcode > 6164 OR postcode < 6167")
                     .select('assessment','address', 'lot',
                              geom = lambda f: f.geometry().buffer(20,3),
                              mylot = lambda f: int(f['house_numb']) * 100))
>>> q().next()
{
'geom': <qgis.core.QgsGeometry object at 0x1A8E64B0>, 
'assessment': u'4309719', 
'mylot': 7900, 
'lot': u'LOT 79', 
'address': u'BIRCHLEY RD'
}

You can use "colname" or any Python callable in the select statement. Using keyword arguments is the same as "Col" AS MyName in SQL.

On the TODO list

I would really like to have some kind of index support in the future to make queries run faster. I had basic index support working using a dict however it was nothing smart and was hard coded. QgsExpression does provide support to walk the generated tree see what the expression includes. In "theory" it would involve walking the expression tree and calculating what should be used for index lookup.

Join support would also be nice. Attribute and spatial.

Helpers welcome

Like I said at the start, this is just a hobby project and it's still only in early days however I am always happy for help if you have ideas, or know how to improve something. If you find it handy that would be cool to know too.

Installing

  • Just download the code from here.
  • Add the files to your Python project
  • from query import query

  • <<
  • Page 84 of 142 ( 2821 posts )
  • >>

Back to Top

Sustaining Members