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])
  • 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 '16 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 '16 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 '16 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 '16 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 '16 at 23:20
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.

  • 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 '16 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, privacy policy and cookie policy

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