2

I have a folder of photos named with a building ID that corresponds to a building ID in a building footprints feature class. Not all rows in the footprints feature class have a corresponding photo. So, I want to use an update cursor to calculate a photofile field in the footprints feature class if there is a photo in the folder.

I've gotten this to work with both arcpy.UpdateCursor [getValue(), setValue()] and arcpy.da.UpdateCursor, but I don't think it's the most efficient method due to the time it takes to run (new cursor for each value in the list?). Here is the working method using da, but again, it takes forever to run.

import arcpy

photos = arcpy.GetParameterAsText(0) #photos folder
fc = arcpy.GetParameterAsText(1) #feature class

arcpy.env.workspace = photos
photoList = arcpy.ListRasters()

fields = ('BLDG_ID','PHOTOFILE')

with arcpy.da.UpdateCursor(fc,fields) as uc:
    for row in uc:
        for photo in photoList:
            if (row[0] == photo[:-4]):
                row[1] = photo
            else:
                pass
            uc.updateRow(row)
del row, uc

That's probably not the most Pythonic way. I want to use something like:

with arcpy.da.UpdateCursor(fc,fields) as uc:
    for row in uc:
        if row[0] in photoList:
            row[1] = value in list
        uc.updateRow(row)
del row, uc

The problem is that the values in the photoList have ".jpg" after the BLDG_ID, so it is not equal without removing ".jpg" from each value in the list or concatenating ".jpg" to the BLDG_ID value in the row (row[0]+".jpg" ... I don't think that works). I'm also not sure how to update the row in the field as the value in the list without iterating through the list, and I need to retain the ".jpg" in the PHOTOFILE field as well.

Example:

Photo in folder = 12345.jpg

BLDG_ID in fc = 12345

PHOTOFILE in fc = 12345.jpg

1 Answer 1

7

Well, there are a few ways to go about this.

Here is one approach:

import arcpy
from os.path import splitext
#Use splitext, as slicing is hardcoded for extension length

photos = arcpy.GetParameterAsText(0) #photos folder
fc = arcpy.GetParameterAsText(1) #feature class

arcpy.env.workspace = photos
#Create list of image names without extension
nameList = [splitext(p)[0] for p in arcpy.ListRasters()]

fields = ('BLDG_ID','PHOTOFILE')

with arcpy.da.UpdateCursor(fc, fields) as uc:
    for row in uc:
        if row[0] in nameList:
            #str.format will append .jpg to BLDG_ID value
            row[1] = "{0}.jpg".format(row[0])
        uc.updateRow(row)

If you're interested in different raster types (PNG, TIFF, GIF, etc.), it's similar, though accounting for two files with the same basename and different extensions is interesting (image.png and image.jpg).

2
  • Excellent! Just to show how inefficient my code was, I had a folder with 1,044 photos that needed to be calculated on a feature class with 170,832 records. My original method took 3 hours and 50 minutes to run, while @Paul code took 1 minute and 15 seconds. Also, the uc.updateRow(row) needs to be unindented in the example above.
    – dubch87
    Aug 27, 2015 at 23:31
  • @dubch87, hmm I guessed wrong about .updateRow(). Thanks for responding1
    – Paul
    Aug 27, 2015 at 23:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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