1

I want to run the following script in QGIS

from qgis.core import *
from qgis.utils import *
from PyQt4.QtCore import *

inLayer = iface.activeLayer()

with open('iso_codes.txt') as f:
  codes = f.readlines()

for isoCode in codes:
  #exp = QgsExpression('"ISO_CODE" = \'AF\'') # THIS WORKS
  exp = QgsExpression('"ISO_CODE" = \'%s\'' % isoCode) # THIS DOES NOT WORK
  request = QgsFeatureRequest( exp )
  fipsCode = ''
  for feature in inLayer.getFeatures( request ):
    fips = feature['FIPS_CODE']
    if fipsCode != fips:
      fipsCode = fips
      print '%s, %s' % (isoCode, fipsCode)

Using '"ISO_CODE" = \'AF\'' as argument the script works till the end.

Using '"ISO_CODE" = \'%s\'' % isoCode as argument the script doesn't go into the for loop.

I've tried to use inLayer.setSelectedFeatures([]) at the end of the for loop, but this did not help.

  • 1
    Did you try lower case s? '"ISO_CODE" = \'%s\'' % isoCode – Richard Morgan Mar 17 '16 at 17:20
  • The '%s' as upper case has been a type mistake. I've corrected the example code. Thanks. – user1638045 Mar 18 '16 at 13:03
1

readlines() does not strip newline characters (\n) or carriage return characters (\r) from the read string. What you have read is most likely not the string 'AF' but 'AF\n', and that's why equality is not true for any feature in your layer.

Instead of:

# line with newline character
with open('e:\iso_codes.txt') as f:
    codes = f.readlines()
    for code in codes:
        print code

DE

AF

US

Try something like that:

with open('e:\iso_codes.txt') as f:
    codes = f.read().splitlines()
    for code in codes:
        print code

# line with newline character stripped off
with open('e:\iso_codes.txt') as f:
    codes = f.readlines()
    for code in codes:
        print code[:-1]

# line splitted manually, skipping the last newline
with open('e:\iso_codes.txt') as f:
    contents = f.read()
    codes = contents.split('\n')
    for code in codes[:-1]:
        print code

DE
AF
US
1

As Richard Morgan suggest you, try a lower case for the 's' (s instead of S). But a another suggestion if it's still doesn't work. Try to use the format method of the string class. It's available since Python 2.7 :

with open('iso_codes.txt') as f:
    codes = f.readlines()

    for isoCode in codes:
        #exp = QgsExpression('"ISO_CODE" = \'AF\'') # THIS WORKS
        exp = QgsExpression('"ISO_CODE" = \'{}\''.format(isoCode)) # THIS SHOULD WORK

        try:
            if exp.hasParserError :
                raise Exception(exp.parserErrorString())
            if exp.hasEvalError:
                raise ValueError(exp.evalErrorString())
            request = QgsFeatureRequest(exp)
            fipsCode = ''
            for feature in inLayer.getFeatures( request ):
                fips = feature['FIPS_CODE']
                if fipsCode != fips:
                    fipsCode = fips
                    print '{}, {}'.format(isoCode, fipsCode) # I ALSO EDIT HERE
        except Exception as e:
            print "it has an error in expression :  {}".format(e)
        except ValueError as v:
            print "The expression is good but it can't be evaluate error : {}".format(v)

-- EDIT --

I update the code so you can handle errors I suspect that some lines can raise errors but not all of them. And you can see what happen with error lines.

  • Thank you SIGIS for the advice, but does not work. I've tried differents combinations, but nothing seams to work :( Something is wrong with QgsExpression() ??? – user1638045 Mar 18 '16 at 16:52
  • Have you tried to validate your expression ? QgsExpression() has a method called hasParserError() – SIGIS Mar 18 '16 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.