Eagle Pipeline GIS Blog

In the last post we learned a bit about GUIDs, and how and why they are used in the APDM and PODS ESRI Spatial. Now, let's make some!

GUIDs can, of course, be generated using VB Script. But given the gradual deemphasis of VB Script by ESRI, we’ll perform GUID generation in ArcMap using the ninth wonder of the world, Python. For those of you not already in the know, Python is God’s gift to inveterate GIS hackers. My advice: Learn it! Live it! Love it!

Perhaps the coolest thing about Python in ArcMap is that you can use any Python module in the Field Calculator tool. In this case, we’ll rely on a Python module called UUID. UUID stands for Universally Unique ID. You guessed it; UUID = GUID. (“Universally Unique” hints of hubris; I prefer GUID.) The UUID Python module defines the Python UUID object and provides functions that let you generate GUIDs nine ways from Sunday. And the good news is that the UUID module is a standard Python 2.6 module; no additional downloads are necessary.

So let’s get to it. Suppose we have a polyline feature class containing pipeline features; let’s call it Raw Pipeline Polylines. We’ll add two fields to our feature class: LineGUID and StringGUID. LineGUID has a data type of GUID; StringGUID has a data type of String, with Length = 38. The ArcMap table document for our feature class looks something like this:

Having both fields present is for illustrative purposes; it turns out the Field Calculator expects GUIDs to be expressed as strings, so we can use the same expression in the Field Calculator to calculate both proper GUIDs and string versions of the same. We’ll start with LineGUID. A right-click on the LineGUID column header in the table document brings up the context menu:

Selecting the context menu Field Calculator... option opens the Field Calculator tool, where we enter the following Python code:

This is the ArcGIS 10 version of the tool; note the Parser control panel at the top. At ArcGIS 10 you can choose whether to use Python or VB Script in the Field Calculator. We, of course, select Python. (Prior to ArcGIS 10 only VB Script is available in the Field Calculator. But never fear, 9.x users, the ArcToolbox Calculate Field tool lets you pick your parser, too. We’ll cover that at the end.) To do the heavy lifting of GUID generation, we define our own little Python function, CalcGUID. The code for this function is entered into the Pre-Logic Script Code text block:

Let’s deconstruct this code. The first line defines our function. In Python, definition of functions has the following syntax:

def <your function>(argument1, argument2, argumentn)

In many cases you might choose to pass an existing field (or fields) from your table to the function for processing. In our CalcGUID example we are generating GUIDs from whole cloth, so no arguments are necessary.

The second line of code imports the UUID Python module, which gives us access to the Python UUID object and functions.

The third line of code generates the GUID and returns it as the result of the CalcGUID function. The .uuid4() function is what actually generates the GUID. (.uuid4() is just one of four ways the UUID module can generate GUIDs.) Python returns GUIDs as 16-byte integer values. This does not suit our purposes, so we turn the GUID into a string using the built-in Python str() function. The .upper() string function just makes sure everything is upper case; this is for cosmetics only. Our GUID string lacks the curly brackets ({ }) expected by ArcMap, so we do a little string concatenation to add those. And that’s it.

We use our CalcGUID function in the LineGUID = text block to actually perform the calculation. Pressing the OK button in the Field Calculator tool should render results that look something like this:

We can use the exact same logic to generate GUIDs for our StringGUID field, with results like this:

Those of you who are not yet migrated to ArcGIS 10 can use the ArcToolbox --> Data Management Tools --> Fields --> Calculate Field tool:

The Expression Type (optional) pull-down let's you select the parser. Either PYTHON or PYTHON_9.3 may be selected; the differences between the two affect mainly shape operations and have no impact here.

This is exactly what I needed. You saved me an undetermined amount of time banging my head against this problem (and my cubicle wall)... Thank you for sharing!

Alwyn

We have a geodatabase on the server and a few people are capturing checking data in and out. What I want to do is to create a unique ID for every feature captured but I want to make it automatic so people do not have to do it themselves with each feature captured and eliminate the chance of mistakes that way. The number in that field should increment by itself each time a new feature is added, almost like the FID field but more user controlled and defined according to our needs. Is this posible and how will it work? I see python can handle something like this but I have Arc 9.3.1 and see python is only available for Arc10? Can anybody help or give advice? Thanks Alwyn

Tracy Thorleifson

Alwyn, Python is available in 9.3.1, so you can do it in your environment. However, your only option with Python is a manually run ArcToolbox tool. To do it automatically, the best option for a versioned geodatabase is to create a feature class extension that implements your automatic ID generation logic. This option requires knowledge of .NET and ArcObjects. If your geodatabase is not versioned, you could do the same thing in the underlying database using a sequence and an insert trigger in Oracle, or an identity field with an auto increment in SQL Server. Best regards, Tracy

Tracy Thorleifson

Alwyn, Also, if you don't mind using GUIDs, you can just add a GlobaID field to your feature class. GlobalID fields automatically generate a GUID when a row/feature is added. - T.

Jason Balmut

Just FYI, in 9.3.1, GUID field types do not show up in the Calculate Field tool. The screenshots above are all from 10.x which does not have that limitation.

Rahul Rakshit

This is exactly what I was looking for. Thanks a lot for the wonderful posts throughout this blog.