1
  • The data: PL_Fac -point file - facilities used in service area analysis - contains PNTID in Add_PNTID field PD - polygon - catchment areas assigned to a facility (there can be many polygons assigned to one point. the polygon file contains a PNTID that corresponds to the PNTID of the facility. The PNTID is also in the feature name Civic - point file - civic addresses of people who live in the PD polygon areas. The PNTID is in the feature name
  • The Purpose: I'm trying to determine if the civic point fall within the service areas they area assigned to. Thus far the civic points do not contain a PNTID but I may need to add one. The script below searches for similar names of the features.
  • The Problem: I'm working with the below script to iterate through over 600 points. It finds PNTIDs that are similar if I fill in the ROW section with the PNTID however, I want the script to automatically grab the PNTID from the Add_PNTID field in the Facilities PL_Fac point file. After the search cursor finds features I then want to select the two found features (one PD_polygon and one Civic_point) and feed them into separate tools. Currently I can't get MakeFeatureLayer from the output from the search cursor. Not sure if some other method might work?

I'm using ArcGIS 10.2 Desktop

import arcpy, os, sys

### #UpdateCursor(dataset, {where_clause}, {spatial_reference}, {fields}, {sort_fields})
arcpy.env.overwriteOutput = True
arcpy.env.workspace = r"F:\PL_DriveTime\PL_DriveTime.gdb"
fcPNTID = r"F:\PL_DriveTime\PL_DriveTime.gdb\EG\PL_Facilities"
fcPNTID_lyr = "fcPNTID_lyr"
flds = ('Add_PNTID')

try:

    with arcpy.da.SearchCursor(fcPNTID, flds) as cursor:
        row = cursor.next()
        print(row)
        commonSearchText = ['ROW']
        for nameX in commonSearchText:
            foundFCList = []
            walk = arcpy.da.Walk(arcpy.env.workspace, datatype="FeatureClass")
            for dirpath, dirnames, filenames in walk:
                for filename in filenames:
                    found = filename.find(nameX)
                    if found >-1:
                        foundFCList.append(os.path.join(filename))
                        print foundFCList
except StopIteration:
    print("no rows")
except arcpy.ExecuteError:    
    print arcpy.GetMessages(2)
    arcpy.AddError(arcpy.GetMessages(2))
except Exception as e:
    print e.args[0]
    arcpy.AddError(e.args[0])
6
  • row[0] should return the value of the first field in flds. row[1] the second field etc (if you had a list of more fields)
    – Midavalo
    Feb 29, 2016 at 17:23
  • when I enter anything but a numeric value in commonSearchText = ['ROW'] nothing happens. there is no output. I'd like the script to pull values from the field and run the process for each row
    – MMcInnis
    Feb 29, 2016 at 18:22
  • I am still unclear on what you're trying to do. Are you trying to iterate through a point feature class, then for each point select an intersected polygon and run another pair of tools: one for the point and one for the polygon?
    – Zack
    Feb 29, 2016 at 19:20
  • Are you planning to run this in an ArcMap session, or does it need to be a stand alone script? If in ArcMap session, I have an idea. Also, what is your polygon layer called, and what is its corresponding field name to be matched with the point ID?
    – Priscilla
    Feb 29, 2016 at 21:42
  • Hi Pricilla and @Zack. Thanks for your comments. I've added some detail that was requested. I'm planning to run this as a stand alone script at the moment.
    – MMcInnis
    Feb 29, 2016 at 23:20

2 Answers 2

1

My understanding of the problem statement is this:

"For every unique point ID, which is also found in the polygon layer, find the overlap with civic points, and update civic's PNTID field accordingly" (If I'm misunderstanding, please let me know, and I'll update my answer.)

My preferred approach is within an ArcMap session, which keeps everything clean, using selections on the participating layers, and without creating intermediate data:

import arcpy
# in-map layers
Points = "PL_Facilities"
Polygons = "PL_Areas"
Civic = "PL_Civic"

pointIDList = list(arcpy.da.SearchCursor(Points, 'Add_PNTID')) 
setOfUniqePointIDs = {x[0] for x in pointIDList} 
for ID in setOfUniqePointIDs:
    expression = 'PNTID =' + str(ID)
    arcpy.SelectLayerByAttribute_management(Polygons, "NEW_SELECTION", expression)
    desc = arcpy.Describe(Polygons)
    if len(desc.FIDset) > 0:
        arcpy.SelectLayerByLocation_management(Civic, "INTERSECT", Polygons)
        desc2 = arcpy.Describe(Civic)
        if len(desc2.FIDset) > 0:
            arcpy.CalculateField_management(Civic, "PNTID", ID)
    else: 
        continue

However, for a stand-alone python script, I don't think you can use layer selections, so intermediate data are sent to 'in_memory':

import arcpy
# feature classes on disk
Points = r"F:\PL_DriveTime\PL_DriveTime.gdb\EG\PL_Facilities"
Polygons = r"F:\PL_DriveTime\PL_DriveTime.gdb\EG\PL_Areas"
Civic = r"F:\PL_DriveTime\PL_DriveTime.gdb\EG\PL_Civic"

pointIDList = list(arcpy.da.SearchCursor(Points, 'Add_PNTID')) 
setOfUniqePointIDs = {x[0] for x in pointIDList} 
SQLList = []
for ID in setOfUniqePointIDs:
    SQLList.append('"PNTID" =' + str(ID))
SQLexpression = " OR ".join(SQLList)
selectPoly = arcpy.FeatureClassToFeatureClass_conversion(Polygons, 'in_memory', "pLayer", SQLexpression)
intersectPolyCivic = arcpy.Intersect_analysis([selectPoly, Civic], 'in_memory\interPC', "ALL", "", "POINT")
arcpy.AddJoin_management(Civic, "OBJECTID", intersectPolyCivic, "FID_Civic")
arcpy.CalculateField_management(Civic, "PNTID", "PNTID_1")
arcpy.RemoveJoin_management(Civic)
# join and calculate field take precise field names, so augment accordingly

There are numerous ways to solve this problem, but these are workflows I might employ on my own data.

1
  • I updated my answer, swapping GetCount for the Describe object method of FIDset. This is a better way to test for selections on feature classes, especially when there are no selections.
    – Priscilla
    Mar 3, 2016 at 14:23
0

Now that I've learned more about arcpy I've found what was giving me trouble. I can use the field from the PDrow[1] by adding str(PDrow[1]) and making it a variable to use later in the script. Specifically in the MakeFeatureLayer using a where clause. Thanks to everyone who posted. I've learned a lot from these posts.

import os
import sys
import arcpy

#set workspace
arcpy.env.overwriteOutput = True
arcpy.env.workspace = r"C:\PollLocation_DriveTime.gdb"
#Local variables for PD:
PD_ED ="PD_ED"
PD_ED_PNTID_Lay = "PD_ED_PNTID_Lay"
PD_ED_fld = ['First_ED_NO', 'Add_PNTID']

NullwhereClause = 'Add_PNTID IS NOT ' 'NULL'
try:
    # Process: SearchCursor returns an iterator of tuples
    with arcpy.da.SearchCursor(PD_ED, PD_ED_fld, NullwhereClause) as PDcursor:
        for PDrow in PDcursor:
            #print('{0}'.format(PDrow[0]))
            # Returns string values for the field names specified
            PDPNTIDrow = str(PDrow[1])
            PD_NOrow = str(PDrow[0])

            # where statement to select a single PNTID value from the field 
            PDwhereClause = 'Add_PNTID =' +PDPNTIDrow

            # Process: Make Feature Layer
            arcpy.MakeFeatureLayer_management(PD_ED, PD_ED_PNTID_Lay, PDwhereClause)
except arcpy.ExecuteError:
    print arcpy.GetMessages(2)
    arcpy.AddError(arcpy.GetMessages(2))
except Exception as e:
    print e.args[0]
    arcpy.AddError(e.args[0])

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.