[Gfoss] [New post] User defined expression functions for QGIS

Salve.
una nuova funzione in QGIS, che consente di utilizzare nel labelling e nel calcolatore non solo le funzioni preconfezionate, ma anche quelle definite dall’utente. Non proprio utilissima per chi e’ alle prime armi, ma per i power users e’ una ganzata.
Se qualcuno ci inventa utilizzi interessanti, per piacere dia notizia in lista.
Saluti, e buon divertimento.

-------- Messaggio originale --------

[if gte mso 12]> body { font-family: arial; font-size: 0.8em; } .post, .comment { background-color: white !important; line-height: 1.4em !important; } <![endif]
Nathan posted: "Ever since I added expression based labels, including the new expression builder UI, something that I always wanted to add is the ability to define custom user defined functions in Python (or C++) and use them in an expression. The expression engine is "

Respond to this post by replying above this line

New post on Nathans QGIS and GIS blog <img moz-do-not-send=“true” style="margin: 5px 20px 5px 0;

                                    vertical-align: middle;" class="head-avatar" src="http://s.wordpress.com/i/emails/blavatar-default.png" alt="" border="0"> 

## User defined expression functions for QGISby Nathan

Ever since I added expression based labels, including the new expression builder UI, something that I always wanted to add is the ability to define custom user defined functions in Python (or C++) and use them in an expression. The expression engine is used for labels, rule based rendering, layer actions, and atlas composer tags. Thanks to the all the awesome work on the expression engine by Martin all this cool stuff is now possible.

Today I pushed a commit into master that adds the ability to define a function in Python (or C++), register it in the expression engine, then use it anywhere expressions are used.

The good stuff

Lets take a use case from Ujaval Gandhi and his example of counting vertices for each feature.

First we need to import the new qgsfunction decorator function from qgis.utils. The qgsfunction decorator will take a normal Python function, wrap it up in the class used to define a function, and register it in the engine.

So what does an empty function look like:

from qgis.utils import qgsfunction
from qgis.core import QGis

@qgsfunction(0, "Python")
def vertices(values, feature, parent):
	pass

@qgsfunction(0, "Python") means we are defining a new vertices function that takes 0 args and lives in the “python” group in the expression builder UI. Any custom function must take (values, feature, parent) as python args. values is a list of QVariants passed into the function, feature is the current QgsFeature, and parent is expression engine node (you use this to raise errors).

Lets stick some more logic in there:

from qgis.utils import qgsfunction
from qgis.core import QGis

@qgsfunction(0, "Python")
def vertices(values, feature, parent):
	"""
		Returns the number of vertices for a features geometry
	"""
	count = None
	geom = feature.geometry()
	if geom is None: return None
	if geom.type() == QGis.Polygon:
		count = 0
		if geom.isMultipart():
		  polygons = geom.asMultiPolygon()
		else:
		  polygons = [ geom.asPolygon() ]
		for polygon in polygons:
		  for ring in polygon:
		    count += len(ring)
	return count

Pretty simple. Get the geometry from the feature, check if it’s a polygon, if it is then count the number of vertices and return that number.

Now that we have that all done we can save it into a file in our .qgis/python folder, lets call it userfunctions.py (note you don’t have to save it here, anywhere that QGIS can find it will do. Anywhere on PATH)

Lets open QGIS and run import userfunctions.py:

Importing functions from userfunctions.py

Now open the label properties for the layer:

The new function shown in the expression builder

Nice! Notice also that the function doc string is used as the function help. How cool is that. You can also see the $ sign in front of the function, this is because any functions that take no args are considered special and use the $ sign as a convention, this is all automatic when the function is registered.

And the result is:

The label using the new function

You can even use it in the rule based rendering:

Rule rendering using new function

Enjoy!

Notes- You must unregister a function once you are finished with it using QgsExpression.unregisterFunction(name). This mainly applies to plugins where the user might unload your plugin and the code is no longer available. In the above example we could import userfunctions and never unregister because we plan on using it for the whole session.

  • You can’t override the built-in methods.

Nathan | November 10, 2012 at 4:38 pm | Categories: Open Source | URL: http://wp.me/pjIwZ-jc

Comment See all comments

Unsubscribe or change your email settings at Manage Subscriptions.

Trouble clicking? Copy and paste this URL into your browser:
http://woostuff.wordpress.com/2012/11/10/user-defined-expression-functions-for-qgis/

Thanks for flying with WordPress.com