Skip to main content
Added code for checking if field name exists first before adding field
Source Link
Jason Miller
  • 1.5k
  • 1
  • 12
  • 25

Using a spatial join is the easiest, but it creates an additional layer...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# USING SPATIAL JOIN
inputFC = "C:/YourFolder/Bakeries.shp"
joinFC = "C:/YourFolder/States.shp"
outputFC = "C:/YourFolder/BakeriesWithStates.shp"
arcpy.SpatialJoin_analysis(inputFC, joinFC, outputFC)

However, sometimes it's not desirable to create an additional layer. Maybe you just want to create another field in your original layer (bakeries.shp in this case) and store the "located state". Here is how that is done...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
# Create FeatureLayers
arcpy.MakeFeatureLayer_management("C:/YourFolder/Bakeries.shp", "lyr_Bakeries")
arcpy.MakeFeatureLayer_management("C:/YourFolder/States.shp", "lyr_States")

# Add an "LOCATED_ST" field
if "LOCATED_ST" not in [f.name for f in arcpy.ListFields("lyr_Bakeries")]:
    arcpy.AddField_management("lyr_Bakeries", "LOCATED_ST", "TEXT", "", "", "20")

# Create a search cursor for the states
rows = arcpy.SearchCursor("lyr_States")
for row in rows:
    # What you'll do is select each state one at a time, and then select all the bakeries in that state and calculate the LOCATED_ST 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_States", "NEW_SELECTION", "\"FID\" = " + str(row.getValue("FID")))
    arcpy.SelectLayerByLocation_management("lyr_Bakeries", "INTERSECT", "lyr_States", "", "NEW_SELECTION")
    arcpy.CalculateField_management("lyr_Bakeries", "LOCATED_ST", "'{0}'".format(str(row.getValue("STATEFIELD"))), "PYTHON_9.3", "")
    print "Finished processing " + str(row.getValue("STATEFIELD"))

Obviously you'll have to substitute your layer paths as needed... and if you are using a file geodatabase instead of a shapefile, then you'll need to change the FID to OBJECTID (as commented...) When you're done, any empty values in the LOCATED_ST field means that it was outside of all of the states.

You'll note that I used forward slashes in my path which looks "wierd" for windows users, but I like it better that way because you don't need to escape the backslashes... (the forward slash works that same way that you would expect a backslash to work...)

Using a spatial join is the easiest, but it creates an additional layer...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# USING SPATIAL JOIN
inputFC = "C:/YourFolder/Bakeries.shp"
joinFC = "C:/YourFolder/States.shp"
outputFC = "C:/YourFolder/BakeriesWithStates.shp"
arcpy.SpatialJoin_analysis(inputFC, joinFC, outputFC)

However, sometimes it's not desirable to create an additional layer. Maybe you just want to create another field in your original layer (bakeries.shp in this case) and store the "located state". Here is how that is done...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
# Create FeatureLayers
arcpy.MakeFeatureLayer_management("C:/YourFolder/Bakeries.shp", "lyr_Bakeries")
arcpy.MakeFeatureLayer_management("C:/YourFolder/States.shp", "lyr_States")

# Add an "LOCATED_ST" field
arcpy.AddField_management("lyr_Bakeries", "LOCATED_ST", "TEXT", "", "", "20")

# Create a search cursor for the states
rows = arcpy.SearchCursor("lyr_States")
for row in rows:
    # What you'll do is select each state one at a time, and then select all the bakeries in that state and calculate the LOCATED_ST 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_States", "NEW_SELECTION", "\"FID\" = " + str(row.getValue("FID")))
    arcpy.SelectLayerByLocation_management("lyr_Bakeries", "INTERSECT", "lyr_States", "", "NEW_SELECTION")
    arcpy.CalculateField_management("lyr_Bakeries", "LOCATED_ST", "'{0}'".format(str(row.getValue("STATEFIELD"))), "PYTHON_9.3", "")
    print "Finished processing " + str(row.getValue("STATEFIELD"))

Obviously you'll have to substitute your layer paths as needed... and if you are using a file geodatabase instead of a shapefile, then you'll need to change the FID to OBJECTID (as commented...) When you're done, any empty values in the LOCATED_ST field means that it was outside of all of the states.

You'll note that I used forward slashes in my path which looks "wierd" for windows users, but I like it better that way because you don't need to escape the backslashes... (the forward slash works that same way that you would expect a backslash to work...)

Using a spatial join is the easiest, but it creates an additional layer...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# USING SPATIAL JOIN
inputFC = "C:/YourFolder/Bakeries.shp"
joinFC = "C:/YourFolder/States.shp"
outputFC = "C:/YourFolder/BakeriesWithStates.shp"
arcpy.SpatialJoin_analysis(inputFC, joinFC, outputFC)

However, sometimes it's not desirable to create an additional layer. Maybe you just want to create another field in your original layer (bakeries.shp in this case) and store the "located state". Here is how that is done...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
# Create FeatureLayers
arcpy.MakeFeatureLayer_management("C:/YourFolder/Bakeries.shp", "lyr_Bakeries")
arcpy.MakeFeatureLayer_management("C:/YourFolder/States.shp", "lyr_States")

# Add an "LOCATED_ST" field
if "LOCATED_ST" not in [f.name for f in arcpy.ListFields("lyr_Bakeries")]:
    arcpy.AddField_management("lyr_Bakeries", "LOCATED_ST", "TEXT", "", "", "20")

# Create a search cursor for the states
rows = arcpy.SearchCursor("lyr_States")
for row in rows:
    # What you'll do is select each state one at a time, and then select all the bakeries in that state and calculate the LOCATED_ST 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_States", "NEW_SELECTION", "\"FID\" = " + str(row.getValue("FID")))
    arcpy.SelectLayerByLocation_management("lyr_Bakeries", "INTERSECT", "lyr_States", "", "NEW_SELECTION")
    arcpy.CalculateField_management("lyr_Bakeries", "LOCATED_ST", "'{0}'".format(str(row.getValue("STATEFIELD"))), "PYTHON_9.3", "")
    print "Finished processing " + str(row.getValue("STATEFIELD"))

Obviously you'll have to substitute your layer paths as needed... and if you are using a file geodatabase instead of a shapefile, then you'll need to change the FID to OBJECTID (as commented...) When you're done, any empty values in the LOCATED_ST field means that it was outside of all of the states.

You'll note that I used forward slashes in my path which looks "wierd" for windows users, but I like it better that way because you don't need to escape the backslashes... (the forward slash works that same way that you would expect a backslash to work...)

Source Link
Jason Miller
  • 1.5k
  • 1
  • 12
  • 25

Using a spatial join is the easiest, but it creates an additional layer...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# USING SPATIAL JOIN
inputFC = "C:/YourFolder/Bakeries.shp"
joinFC = "C:/YourFolder/States.shp"
outputFC = "C:/YourFolder/BakeriesWithStates.shp"
arcpy.SpatialJoin_analysis(inputFC, joinFC, outputFC)

However, sometimes it's not desirable to create an additional layer. Maybe you just want to create another field in your original layer (bakeries.shp in this case) and store the "located state". Here is how that is done...

import arcpy

# Set overwrite option
arcpy.env.overwriteOutput = True

# KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
# Create FeatureLayers
arcpy.MakeFeatureLayer_management("C:/YourFolder/Bakeries.shp", "lyr_Bakeries")
arcpy.MakeFeatureLayer_management("C:/YourFolder/States.shp", "lyr_States")

# Add an "LOCATED_ST" field
arcpy.AddField_management("lyr_Bakeries", "LOCATED_ST", "TEXT", "", "", "20")

# Create a search cursor for the states
rows = arcpy.SearchCursor("lyr_States")
for row in rows:
    # What you'll do is select each state one at a time, and then select all the bakeries in that state and calculate the LOCATED_ST 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_States", "NEW_SELECTION", "\"FID\" = " + str(row.getValue("FID")))
    arcpy.SelectLayerByLocation_management("lyr_Bakeries", "INTERSECT", "lyr_States", "", "NEW_SELECTION")
    arcpy.CalculateField_management("lyr_Bakeries", "LOCATED_ST", "'{0}'".format(str(row.getValue("STATEFIELD"))), "PYTHON_9.3", "")
    print "Finished processing " + str(row.getValue("STATEFIELD"))

Obviously you'll have to substitute your layer paths as needed... and if you are using a file geodatabase instead of a shapefile, then you'll need to change the FID to OBJECTID (as commented...) When you're done, any empty values in the LOCATED_ST field means that it was outside of all of the states.

You'll note that I used forward slashes in my path which looks "wierd" for windows users, but I like it better that way because you don't need to escape the backslashes... (the forward slash works that same way that you would expect a backslash to work...)