2

Instead of two shapefiles that are saved in fcList in this loop I would like to do KernelDensity on the unique values of one shapefile.

Does anyone have an idea how this might work?

import arcpy,os
from arcpy import env
env.workspace = r'C:\Users\lhark\Desktop\SHK\ArcGis_Proj_Canada\shapefiles'
outworkspace = r'C:\Users\lhark\Desktop\SHK\ArcGis_Proj_Canada\KernelDensity'

fcList = arcpy.ListFeatureClasses ()
for fc in fcList:
outKDens = KernelDensity(fc,"NONE",4670)
outKDens.save(outworkspace + "/" + os.path.splitext(fc)[0] + "_kd.tif"
  • Could you please describe your feature data? – Aaron Feb 18 '18 at 15:33
  • The layer i want to create a KD loop with has a column in its attribute table that is called "Symbol". In this column are different facilities listet (i.e. : 'Bar', 'Full-Service-Restaurants' etc.) Now i want to do a KernelDensity analysis on each one of the facilities by including these into my loop. – Lasse Feb 18 '18 at 15:47
  • Do your shapefiles have the same categories/facilities in each? For example in your shapefilefolder, does the Full-Service-Restaurants value appear in more than one shapefile? – fatih_dur Feb 19 '18 at 6:05
5

Although Hornbydd is absolutely correct (+1 for that by the way), the first part of the question is to loop through all the unique values in a field.. this snippet should be usable in your existing code:

FieldToUse = "Field" # change this to your field name with the unique values
for fc in fcList:
    uVals = [] # new empty list
    # loop through each feature with a searchcursor
    with arcpy.da.SearchCursor(fc,FieldToUse) as SCur:
        for row in SCur:
            # check if the value is already in the list
            if row[0] not in uVals:
                uVals.append(row[0]) # add new value to list

    #loop through each unique field value
    for FieldValue in uVals:
        # create a layer with a where clause, this is for numeric fields
        arcpy.MakeFeatureLayer_management(fc,"Layer","{} = {}".format(FieldToUse,FieldValue))
        # use "{} = \'{}\'".format(FieldToUse,FieldValue) to quote the value
        # if the input field is a string field
        OutTIFFname = "{}_{}_kd.tif".format(os.path.splitext(fc)[0],FieldValue)
        outKDens = KernelDensity("Layer","NONE",4670)
        outKDens.save(os.path.join(outWorkspace,OutTIFFname))
        del "Layer" # clean up when you're done
        del outKDens

The process is fairly straightforward:

  1. Start with a new empty list: uVals = []. This instructs python that the new variable will be a list containing no elements.
  2. Open a search cursor on your feature class and loop through each feature; because you're not changing anything this is surprisingly quick.
  3. If the value of your field is not already in the list then add (append) it to the list, that way there is only one instance of each unique value. Note that the list is not sorted and can appear in any order.
  4. Loop through the unique value list and for each unique field value create a feature layer with a where clause. I am using string.format to create the where clause which I find tidier than simple concatenation (with '+' operator). I have changed the name of the outputs to include the unique value of the field that was used for each raster. I have also used os.path.join to concatenate your output path and file name; join uses the correct character required by your operating system when appending which makes the script more robust.
  • 1
    I would use uVals = set() with add method to avoid complications (and it is more pythonic, they say). – fatih_dur Feb 19 '18 at 6:02
  • I´m getting this Error now: ExecuteError: ERROR 000725: Output Layer: Dataset out_VHQ_5 already exists and the Loop stops ("out_VHQ_5" is what i put into "Layer") – Lasse Feb 19 '18 at 14:43
  • If you've changed the name of the layer from "layer" to "out_VHQ_5" you should also change del "layer" to del "out_VHQ_5". You could also set your environment overwriteOutput to True to stop getting the error - though sometimes you don't want to overwrite automatically to ensure you're not wiping existing data erroneously. – Michael Stimson Feb 19 '18 at 21:37
3

If you read the help file for this tool and look at the syntax section what does it takes as input? A Feature Layer. Unlike a Feature Class, you can do selections on Feature Layers. As all geo-processing tools honour selections first all you need to do is select the points of interest and have that selection feed into the Kernel Density tool.

  1. So you need to convert you FeatureClass to a FeatureLayer using the Make FeatureLayer tool
  2. Select by Atttibute to create the selection of interest
  3. Feed the layer with it's selection into Kernel Density tool.
  • KD also accepts feature classes and shapefiles in addition to feature layers. – Aaron Feb 18 '18 at 17:00
  • 1
    True but @Lasse wants to process subsets of their data and passing selections into the tool is a way of doing it without having to create intermediate datasets. They can wrap all that up in their loop. – Hornbydd Feb 18 '18 at 18:35

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.