0

I'm working on a python script for ArcGIS 10.2/10.3. What I want is to automatically fill in a field of a point layer based on the location of that point in relation to a polygon layer.

Say I have a two layers: cities and regions in a database, and the cities layer has a field called "region_name". Then all I want is that I can fill in this field "region_name" based on the location of the city points within the regions. I know this question has been asked before but I'm stuck at a specific point: I know I can either use Select by location or a Spatial Join but what bothers me is that this means that I get a new layer with the result while what I need is the same "cities" layer (without additional fields) just having the field "region" filled-in.

It sounds so simple so I'm wondering whether I have just missed something. Also since I have a lot of cities and regions it really needs to be done programmatically (not manually) but if you tell me it's easier if I use something else than Python (I'm working with an enterprise geodatabase) I'm happy to change.

8
  • 1
    There are several possible approaches to solving this, but your question (the title, at least) focuses on the hardest potential route (cursors) while stating that you know about the easiest (spatial join). Have you tried using the field calculator through a spatial join? What specific problem have you encountered?
    – Vince
    Commented Dec 7, 2015 at 14:31
  • Well if I use the spatial join in a script I create a new feature class as output which is precisely what I don't want.
    – oddpodm
    Commented Dec 7, 2015 at 14:34
  • To be precise I don't mind to create an additional feature class as intermediate result but then would need to know how to use that layer to update my initial cities layer
    – oddpodm
    Commented Dec 7, 2015 at 15:06
  • Spatial join does not create a new feature class, just a dynamically joined layer. The Identity tool creates a new feature class.
    – Vince
    Commented Dec 7, 2015 at 15:36
  • 2
    You need to configure the options of the Spatial Join so that you preserve the FID of the points in the output feature class, since the points have the field you want to fill in. Generally that means the points are the target and the polygons are the join features. Then do a standard attribute Join of the original points ObjectID to the FID value field in the Spatial Join and use the field calculator to transfer the values in the region field to the original points. Commented Dec 7, 2015 at 16:24

2 Answers 2

1

Thanks Richard Fairhurst, I think we just had the same idea (just posting it as answer as it works):

I can use the SpatialJoin approach to create a new layer with the results. This layer has a field target_fid (which contains the original FID of each city-point) and obviously the name of the region it falls inside. So I can use it to create a list containing the target_FIDs of all cities joined to region x. This allows me to then use the update Cursor on the city layer to write the region name into the field for the cities where the FID is in the list of target_FIDs. Then I have to do the same for all cities which have a region name of y,z ...

But maybe there is an easier approach

1

have you consider this type of solution using Search and Update Cursors? I've make this script, but I've not try it.

import arcpy
# set workspace and variables
arcpy.env.workspace = "workspace"
regions = "regions.shp"
cities = "cities.shp"

# set search cursor for regions
cursor_regions = arcpy.da.SearchCursor(regions, ["FieldWithRegionName"])
for row_regions in cursor_regions:
    # select cities that lays in current region
    arcpy.SelectLayerByLocation_management(cities, "INTERSECT", regions, "", "NEW_SELECTION")
    # set update cursor for selectet cities
    cursor_cities = arcpy.da.UpdateCursor(cities, ["FieldWithRegionNameInCities"])
    for row_cities in cursor_cities:
        # update name value
        row_cities[0] = row_regions[0]
        cursor_cities.updateCursor(row_cities)

    del row_cities
    del cursor_cities

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.