Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am working with a watershed map, and I was wondering if there is a function or a way that I can get ArcMap to number the watersheds. For instance, if we have watershed X numbered as 0, I want the watersheds that surround/or share a boundary with watershed X to be numbered 1, and the watersheds that surround/ or share a boundary with the number 1 watersheds to be numbered 2 and so on. Is there a way this can be done by building a model in Modelbuilder? I would like to save it so when I change a watershed layer and run the model it will do the same in a new watershed area.

Thanks, E

Image Link

PS: Sorry if the image is too small I did it really quickly using paint...

share|improve this question
Can you demonstrate with a picture what you're after? –  blah238 Jul 11 '12 at 20:34
Out of interest, given you're dealing with watersheds, would a numbering system such as Strahler or Pfafstetter be more appropriate as it deals with upstream and downstream directionality? –  om_henners Jul 12 '12 at 1:12
Well I'm only looking at the watersheds as a whole not going into the streams. I believe if i would use that if I was doing the analysis at stream level. –  user8759 Jul 12 '12 at 13:42
add comment

2 Answers

I'm thinking you could do something with Select by Location, Calculate Field and iteration in ModelBuilder... see this page for an example: Iteration using a count or Boolean condition


share|improve this answer
I think this may work. I will try it out. However do you know if it will assign it values? I looked at the example but does each Interaction give those boxes a new value and if so does it give them all the same values? –  user8759 Jul 11 '12 at 20:49
This answer is not meant to be a complete solution, only a starting point. The Calculate Field tool is what I would use assign the selected features values. Some care would need to be taken to ensure that the previously selected features are not also calculated with each iteration though. –  blah238 Jul 11 '12 at 21:09
The SelectByLocation tool gives you an option for NEW_SELECTION so you're not overwriting your last iteration. –  Roy Jul 12 '12 at 11:23
Thank you everyone who has answered I will be working on creating this and if I run into anything complicated I will ask for advice. –  user8759 Jul 12 '12 at 13:07
Hello, is there a way I can control the Select by Layer tool to interate, but when it interates for the second or third time to not include the previews times it interated? –  user8759 Jul 18 '12 at 18:29
show 1 more comment

A possible solution written in arcpy Python based on @blah238's solution above. If you wanted to stay in a model builder environment, you could just take the expression from the CalculateFieldManagement line and use that in model builder. Just note the extra setting of -1 and 0 to the original field in case the input is a shapefile.

import arcpy
import sys

def watershed_counter(watershed_lyr, calc_attribute):
    current_count = int(arcpy.GetCount_management(watershed_lyr).getOutput(0))
    assert current_count == 1, "Too many features selected!"

    watershed_value = 0

    arcpy.AddMessage("Calculating base watershed")

    #We calculate to -1 as if base file is shapefile it uses 0 instead of Null
    #as placeholders for no data, and that'a where we want to start the
    #watershed count
    arcpy.CalculateField_management(watershed_lyr, calc_attribute, -1)

    while watershed_value >= 0:
        arcpy.AddMessage("Selecting new watersheds")
        arcpy.SelectLayerByLocation_management(watershed_lyr, 'SHARE_A_LINE_SEGMENT_WITH', watershed_lyr)

        new_count = int(arcpy.GetCount_management(watershed_lyr).getOutput(0))
        if current_count == new_count:
            watershed_value = -1
            arcpy.AddMessage("No more watersheds")
            watershed_value += 1
            arcpy.AddMessage("At watershed level %i, %i new watersheds found" % (watershed_value, new_count - current_count))
            current_count = new_count

        data = {"val": watershed_value, "field": calc_attribute}
        arcpy.CalculateField_management(watershed_lyr, calc_attribute, "%(val)i if !%(field)s! is None or !%(field)s! == 0 else !%(field)s!" % data, "PYTHON_9.3")

    arcpy.AddMessage("Setting base watershed to 0")
    arcpy.SelectLayerByAttribute_management(watershed_lyr, "NEW_SELECTION", " %s = -1" % arcpy.AddFieldDelimiters(watershed_lyr, calc_attribute))
    arcpy.CalculateField_management(watershed_lyr, calc_attribute, 0)

if __name__ == '__main__':
    except Exception, e:

Note that each iteration of the loop in this solution is likely to take a longer amount of time as the size of select by location increases in complexity based on number of features, as well as the number of features to be calculated increasing.

Lastly if you're interested in having multiple possible starting points (ie, shortest destance), remove the assert in the script.

share|improve this answer
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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