2

I have two types of spatial data. One is a geodatabase of parcel data by county in Florida, and the other is a shapefile containing wind_zones through out Florida (used for enforcing certain building codes). I want to create and populate two fields in the parcel data based on which county and which wind_zone they are in. I have found a post here: Assigning field value based on location without join that answers a similar question and is what I am basing my code off of, but I need to iterate this process through an entire geodatabase that contains ~70 counties. Is there a line of code that can be added to iterate through the geodatabase so I do not have to manually run the code for each county?

Here is the code I have so far:

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
# Create FeatureLayers
arcpy.MakeFeatureLayer_management("C:/Data/HAAS/parc_join/parcels_1.gdb",    "lyr_parcels")
arcpy.MakeFeatureLayer_management("C:/wind_zones/All_WZs.shp", "lyr_windZones")

# Add a "LOCATED_WZ" & "WZ_CAT" field
arcpy.AddField_management("lyr_parcels", "Located_WZ", "TEXT", "", "", "20")
arcpy.AddField_management("lyr_parcels", "WZ_Cat", "SHORT")


# Create a search cursor for the WZs
rows = arcpy.SearchCursor("lyr_windZones")
for row in rows:
# What you'll do is select each WZ one at a time, and then select all the parcels in that WZ and calculate the "LOCATED_WZ" field 
# NOTE: If you are using not using shapefiles, then you'll have to change the FID in the line below to OBJECTID (or similar)
    arcpy.SelectLayerByAttribute_management("lyr_windZones", "NEW_SELECTION", "\"FID\" = " + str(row.getValue("FID")))
    arcpy.SelectLayerByLocation_management("lyr_Parcels", "INTERSECT", "lyr_windZones", "", "NEW_SELECTION")
    arcpy.CalculateField_management("lyr_parcels", "Located_WZ", "'{0}'".format(str(row.getValue("COUNTY"))), "PYTHON_9.3", "")
    print "Finished processing " + str(row.getValue("COUNTY"))

# Create a search cursor for the WZs
rows = arcpy.SearchCursor("lyr_windZones")
for row in rows:
# What you'll do is select each WZ one at a time, and then select all the parcels in that WZ and calculate the fields 
# NOTE: If you are using not using shapefiles, then you'll have to change the FID in the line below to OBJECTID (or similar)
    arcpy.SelectLayerByAttribute_management("lyr_windZones", "NEW_SELECTION", "\"FID\" = " + str(row.getValue("FID")))
    arcpy.SelectLayerByLocation_management("lyr_Parcels", "INTERSECT", "lyr_windZones", "", "NEW_SELECTION")
    arcpy.CalculateField_management("lyr_parcels", "WZ_Cat", "'{0}'".format(str(row.getValue("DESCRIPT"))), "PYTHON_9.3", "")
    print "Finished processing " + str(row.getValue("DESCRIPT"))

Because each county is it's own feature class, I suppose I don't need to add a new field to tell me county name, because I will already know which county it is in.

  • What if a parcel intersects several wind zones (I suppose a parcel can't intersect several counties, otherwise same question for counties)? – GISGe Mar 22 '17 at 15:18
  • You raise a good point and I must admit that II didn't think of that. The wind zones are relatively large, but with so many parcels I'm sure it could happen. Perhaps I should first take the centroid of each parcel and only allow it to fall completely within the wind zone? – Michael Mar 22 '17 at 15:21
  • That is a rule that is easy to implement (use "HAVE_THEIR_CENTER_IN" as overlap_type parameter in Select Layer By Location, instead of "INTERSECT"). But I don't know how you will use the wind zone info, so you should decide. You can also select the wind zone that covers most of the parcel, or add info from all intersecting wind zones. – GISGe Mar 22 '17 at 15:26
1

Regardless of the decision you take to choose how you'll add the information from the wind zones to your parcels in case a parcel intrsects more than one wind zone: you can use arcpy.ListFeatureClasses() to list all your parcels feature classes, then iterate over the feature classes with a for loop and run your code for each of them:

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# Define your workspace. This should be your database with parcels feature class
arcpy.env.workspace = r"C\Data\HAAS\parc_join\parcels.gdb"

# This can be done once for all iterations
arcpy.MakeFeatureLayer_management("C:/wind_zones/All_WZs.shp", "lyr_windZones")

for fc in arcpy.ListFeatureClasses():

    # KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
    # Create FeatureLayers
    arcpy.MakeFeatureLayer_management(fc, "lyr_parcels")
    ...

Be careful, there is an error in your code in this line:

arcpy.MakeFeatureLayer_management("C:/Data/HAAS/parc_join/parcels_1.gdb",    "lyr_parcels")

The input of MakeFeatureLayer is a feature class, not a gdb.

Other attention points:

  • use arcpy.da.Cursors with a with statement, not the old arcpy.Cursors, especially if you're overwriting them (using with deletes the cursor automatically when they've run).
  • you can calculate both fields with one cursor, no need to use 2.
  • Thank you, this is very helpful. However, now when trying to run I am getting error: "TypeError: 'NoneType' object is not iterable" for the wind_zone shapefile... – Michael Mar 22 '17 at 15:55
  • EDIT: fixed. The issue was that there was no colon in the file path. – Michael Mar 22 '17 at 16:57

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.