Can't select using a custom function in QGIS 2.18.3

Interesting, this also worked for me before (I used it several times) but it also fails for me on QGIS 2.18.2.

Anyway, an alternative is to instead create a field which contains the zones for each feature and then use this field in your select expression. You can do this by creating a script which you can add by going to:

Processing Toolbox > Scripts > Tools > Create new script

The following is code taken from your link but slightly modified to run from the processing toolbox:

##Example=name
##Layer=vector point
##Field_Name=string

from qgis.core import QgsField
from math import floor
from PyQt4.QtCore import QVariant

layer = processing.getObject(Layer)
layer.dataProvider().addAttributes([QgsField(str(Field_Name), QVariant.String)])
layer.updateFields()
idx = layer.fieldNameIndex(str(Field_Name))
layer.startEditing()

for feat in layer.getFeatures():
    pt = feat.geometry().centroid().asPoint()
    longitude = pt.x()
    latitude = pt.y()
    zone_number = floor(((longitude + 180) / 6) % 60) + 1
    if latitude >= 0:
        zone_letter = 'N'
    else:
        zone_letter = 'S'
    layer.changeAttributeValue(feat.id(), idx, '%d%s' % (int(zone_number), zone_letter))

layer.commitChanges()

Example:

  1. Populated dataset from your link:

    Populated dataset

  2. Script interface:

    Running script

  3. New attribute field added containing zones

    New attributes

  4. Result of selecting the zones by expression (highlighted in yellow):

    Result


There are two things worth noting in this tutorial with respect to QGIS 2.18:

  • The code that is written in this exercise is a function (and not a variable). Functions are called with brackets (and parameters where applicable), so one needs to write GetUtmZone(). Do not reference it as a variable with a $ prefix.

  • This expression requires the geometry of the feature to calculate and return the result (it's hard to determine the correct UTM zone without a geometry, right ;) ). QGIS tries to reduce the amount of data it fetches (for performance reasons) and doesn't fetch the geometry if it's not explicitly required. Therefore you need to tell QGIS, that your function requires a geometry. How you do that?

-

@qgsfunction(args=0, group='Custom', usesgeometry=True)