1

I have to trasform a script (which I didn't write myself) from QGIS to ArcMap.

In the script a filter by expression is used. The function has the input inl (= the layer with the data that should be filtered) and filter (a string e.g. 'HQ_SZEN<=30' / '"HQ_SZEN"<=30'). This filter is a user input and in QGIS one has to use the second form. I think ArcMap requires the same input but it didn't seem to work so I tried to use arcpy.AddFieldDelimiters with the first form like mentioned in example 4 here https://pro.arcgis.com/en/pro-app/arcpy/data-access/searchcursor-class.htm. To use this I had to split the attributename from the actual expression and my reasoning was that there would always be a strange character between the name and the expression. So that is the reason why the arcpy code is kind of ugly with the chars_allowed_in_layername.

I was thinking of solving it by using arcpy.da.SearchCursor with a where clause but I can't get the filter to work. As filter i use 'HQ_SZEN <=30', the output I get is:

HQ_SZEN
<=30
"HQ_SZEN"<=30
No filter - filtering skipped

Main code:

fifeatures = addAttrFactory().FilterInput(fl, filter)
        try:
            arcpy.AddMessage("Filter returned {0} rows".format(len(fifeatures)))
        except:
            arcpy.AddMessage("No filter - filtering skipped")

QGIS code:

    def FilterInput(self,inl, filter):    
        ftext = ''
        if not filter or not filter.strip():
            #print "FilterInput()..." 
            featureIterator = inl.getFeatures()            
        else:     
            ftext = filter
            #print "FilterInput(%s) ..." % (ftext)
            featureIterator = inl.getFeatures(QgsFeatureRequest().setFilterExpression ( ftext))          

        #print "FilterInput(%s) done" % (ftext)
        return featureIterator

My ArcPy code:

    def FilterInput(self, inl, filter):
        ftext = ''
        if not filter or not filter.strip():
            featureIterator = arcpy.da.SearchCursor(inl, '*')
        else:
            chars_allowed_in_layername = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789"
            for char in filter:
                if char not in chars_allowed_in_layername:
                    end_layername = filter.index(char)-1
            name = filter[:end_layername].strip(' ')
            arcpy.AddMessage(name) #with input HQ_SZEN<=30: HQ_SZEN
            filter_expr = filter[end_layername:]
            arcpy.AddMessage(filter_expr) #with input HQ_SZEN<=30: <=30
            ftext = u'{0}'.format(arcpy.AddFieldDelimiters(inl, name)) + filter_expr
            arcpy.AddMessage(ftext) #with input HQ_SZEN<=30: "HQ_SZEN"<=30
            featureIterator = arcpy.da.SearchCursor(inl, '*', where_clause=ftext)

        return featureIterator
  • Please Edit the question to contain the exact filter contents and the error or other result which makes it not work. – Vince Aug 8 at 11:52
  • Suggested edits done – Jan-Pieter Van Parys Aug 8 at 12:04
  • No, you stripped out the error message with the try/except. Take out the try block and you'll know what the error is. – Vince Aug 8 at 12:24
1

Off course after I've asked the question I know the answer. After using Searchcursor I still have to iterate through it. Changed the last line in the else to this and it works:

            with arcpy.da.SearchCursor(inl, '*', where_clause=ftext) as feats:
                featureIterator = []
                for f in feats:
                    featureIterator.append(f)

EDIT: just using quotation marks in the input (so filter = '"HQ_SZEN"<=30') is acceptable in my script and it makes the code a lot cleaner because all the stuff about extracting the fieldname from the filter becomes unnecessary.

This is the ArcPy result:

    def FilterInput(self, inl, filter):
        if not filter or not filter.strip():
            featureIterator = arcpy.da.SearchCursor(inl, '*')
        else:
            with arcpy.da.SearchCursor(inl, '*', where_clause=filter) as feats:
                featureIterator = []
                for f in feats:
                    featureIterator.append(f)

        return featureIterator

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.