0

I need help with some python in selecting correct input and near feature classes in Near Table analysis.

The project aim is to run Near Table Analysis (distance) on point locations collected at time 1[day] and time2[night].

I have managed to group the files I want to input into each iteration of the model based on filename and Year using groupby with the first 0:26 characters in the file name ​(all files are in the same directory).

My problem is I need to separate the inputs for the GenerateNearTable Tool into in_features (Day) and near_features (Night). So split each group again into Day and Night files.

Here is my code.

import arcpy, itertools, os

# Define the input and output workspaces
arcpy.env.workspace = r"C:\Users\Jenny\roos"
outws = r"C:\Users\Jenny\roos\gmehome.gdb"

# List the fcs in your workspace
my_pts = arcpy.ListFeatureClasses()

# Group the items based on first 26 characters
grouped = [list(g) for _, g in itertools.groupby(sorted(my_pts), lambda x: x[0:26])]

# Loop over the groups and perform the NearTable operation
for group in grouped:
    groupedDay = ?
    groupedNight = ?
    outname = group[0][:26] + "_DayNightDist"
    arcpy.GenerateNearTable_analysis(in_features=groupedDay, near_features=groupedNight, out_table= outname, search_radius="", location="NO_LOCATION", angle="NO_ANGLE", closest="ALL", closest_count="0", method="PLANAR")

Other useful information is the file names

[[Jenxxx_Annual_HR_Poly_Yr1Day_SCV, Jenxxx_Annual_HR_Poly_Yr1Night_SCV] [Jenxxx_Annual_HR_Poly_Yr2Day_SCV, Jenxxx_Annual_HR_Poly_Yr2Night_SCV], [Barry_Annual_HR_Poly_Yr1Day_SCV, Barry_Annual_HR_Poly_Yr1Night_SCV]] (and so on)

UPDATE: SCREENSHOT OF ITERATION ISSUE

enter image description here

2
  • So, for every Day there is a matching night? Perhaps first go through the folder first finding all the days, checking there is a matching night and put them in a list then iterate the days to nights... does that sound like what you want to do? Commented Jul 11, 2016 at 2:12
  • Or do you just need a if / else clause for each group? What is the actual question?
    – BradHards
    Commented Jul 11, 2016 at 2:54

1 Answer 1

1

I think this is what you're trying to do:

import arcpy, itertools, os

# Define the input and output workspaces
arcpy.env.workspace = r"C:\Users\Jenny\roos"
outws = r"C:\Users\Jenny\roos\gmehome.gdb"

# List the fcs in your workspace
my_pts = arcpy.ListFeatureClasses()

DayList = [] # a shiny new empty list..

for ThisFC in my_pts:
    if ThisFC.upper().find('DAY_SCV') > 0: # edited here
        # This is a 'day' feature class
        NightFC = ThisFC.upper().replace("DAY_SCV","NIGHT_SCV") # we'll do this again..

        if not arcpy.Exists(os.path.join(arcpy.env.workspace,NightFC)):
            # do something here if there is no matching night to your day
            arcpy.AddWarning("Oh dear, {0} has no matching night".format(ThisFC))
        else:
            # a 'night' matches a 'day'
            DayList.append(ThisFC) # add it to the list of days to process.

# Group the items based on first 26 characters
# I don't know what you're trying to do here..
# grouped = [list(g) for _, g in itertools.groupby(sorted(my_pts), lambda x: x[0:26])]

# Loop over the groups and perform the NearTable operation
for groupedDay in DayList:
    #groupedDay = ?
    groupedNight = groupedDay.upper().replace("DAY_SCV","NIGHT_SCV") 
    outname = groupedDay[:26] + "_DayNightDist" # I don't like this method, try outname = groupedDay.split('_')[0] to get the first part, not a fixed length
    # you don't need to supply parameters that are 'as default'
    arcpy.GenerateNearTable_analysis(groupedDay,
                                    groupedNight,
                                    outname,
                                    closest = "ALL")#, the rest of this isn't required because they're default

##                                   search_radius="",
##                                   location="NO_LOCATION",
##                                   angle="NO_ANGLE",
##                                   closest="ALL",
##                                   closest_count="0",
##                                   method="PLANAR")

When specifying parameters for a function you only need the parameter name if you're going to skip optional parameters or putting them in a different sequence.. Have a close look at how I edited your Generate Near Table, the only parameter that is implicitly specified is closest = "ALL", that is because I skip 3 optional parameters, accepting the default values.

6
  • Thanks so much Michael. There is a 'day' for every 'night' FC so I just need to iterate between both lists. When I enter groupedNight = = groupedDay.upper().replace("DAY_SCV","NIGHT_SCV") - I get a SyntaxError: invalid syntax on the double = =. Any ideas? Commented Jul 12, 2016 at 0:07
  • DOH! it should be =, I mis-typed it or rather when I did the copy/paste I failed to overwrite the first =. Having no data to test it on I did not run the script but I should have syntax checked it first... I'll edit that now. Commented Jul 12, 2016 at 0:12
  • Thank you so much for your help. I understand how difficult it is when you can't do it with data! The code executed and produced an output (the first step!) EXCEPT the output isn't right...It seems to be iterating over itself - in the first iteration it selects a Day and Night input. But then repeats with a Night Night input and overwrites the output. I'll try and attach a screenshot. I have copied your code exactly but can post it again if necessary. Commented Jul 12, 2016 at 2:10
  • Actually @Michael Miles-Stimson its ok because if I specify the outname as outname = groupedDay.split('_SCV')[0] then it creates a separate output for the Night:Night files. And I can just delete them. A messy workaround but works! Thanks again. Commented Jul 12, 2016 at 2:58
  • It shouldn't, the first step is creating a list of just 'day' feature classes unless 'DAY_SCV' appears in the night feature classes as well. What's the contents of DayList at the end of the first loop? hint: arcpy.AddMessage(','.join(DayList)) will print the whole list with commas separating. Oh I see, it's on the line if ThisFC.upper().find('DAY_SCV'): should be if ThisFC.upper().find('DAY_SCV') > 0:, I wrote this one in a hurry but that's a sloppy mistake. Commented Jul 12, 2016 at 3:29

Your Answer

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

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