Stacked Label Expression

04-10-2017 10:48 AM
New Contributor II

Hi y'all, I've got a quick question.  I'm trying to create a label reminiscent of a bygone era of maps and plats in the Forest Service regarding USA Tract numbers.  The label was a simple circle with "USA" written above a circle, and inside the circle the actual tract number would have been written.  I've got the circle and USA down.  The trick is, the label used to place the prefixing letter above the number, and if there were any trailing letters they would appear below the number.  The data in the attribute table looks like this:



or maybe


I would like these to appear like this: (centered)







The Tract number will always begin with a letter, and it may or may not end with a letter (or letters).  Is there a way to make it display like this?  I'd need to kill the hyphen too.  The number itself could be a 1 digit number to a 4 digits.  My thinking is that there's a way to make it take this data and display letters on first line, remove the hyphen, numbers on second line, and any follow-on letters on the third line.

Is this possible?

0 Kudos
4 Replies
New Contributor II


0 Kudos
Esri Notable Contributor

What about building your own label expression?  You can add as much logic as you need to to parse the string and move characters around as you need to.  You'll probably need to determine the length of the string to know where which characters to put where using the index of the characters:

>>> myString1 = "G-1320Ab"
>>> myString2 = "G-1320"
>>> def label(string):
...   if len(string) == 8:
...     print("{0}\n{1}\n{2}".format(string[:1],string[2:6],string[-2:]))
...   else:
...     print("{0}\n{1}".format(string[:1],string[2:6]))
>>> label(myString1)
>>> label(myString2)

You'll know your data more than I do so your logic will be different.

0 Kudos
New Contributor II

Man, I've tried, but I'm lost.  It's been a long time since I've taken a programming class (and it was an intro to C++).

Is that expression JScript, Python, or VBScript?

The attribute table that I'm trying to display is called [SURVEYNUMBER], and there's over 43,000 objects.  They'll always start with a letter, followed by a dash, then 1-4 numbers, then maybe another letter (but not always).  This is a picture of how I'd love to get it to display:

That would look like this in the attribute table:  A-3035a

I've got the symbol down, it's the pesky expression that I have no idea how to write.  This is what it looks like now without an expression:

I just realized that there's the possibility of another dash too, where a tract number like A-3035-I or A-3035-II may exist.  What a pain. I'm far from a programmer, but if I can get this to print correctly then our GIS will be getting much cooler!

0 Kudos
Esri Notable Contributor

That's written in Python.  It sounds like there's some variability in the value, which will make your logic a bit complex.  It's too bad the SURVEYNUMBER values aren't spread across three separate fields, which would make it easy to concatenate into one label expression.  Anyway, here's something that has worked for a few of the examples you provided:

def label(string):
    firstLine = string.split("-")[0]
    intVals = []
    for x in range(2,len(string)):
        if string[x] in ["0","1","2","3","4","5","6","7","8","9"]:
    start = min(intVals)
    end = max(intVals) + 1
    secondLine = string[start:end]
    if len(string.split("-")) > 2:
        thirdLine = string.split("-")[2]
    elif len(string.split("-")) == 2:
        thirdLine = string.split(secondLine)[1]
        thirdLine = ""
    returnLabel = "{0}\n{1}\n{2}".format(firstLine,secondLine,thirdLine).rstrip("\n")
    return returnLabel

I tried the following labels:

myString1 = "G-1320Ab"
myString2 = "G-1320"
myString3 = "G-132"
myString4 = "A-3035-I"
myString5 = "A-3035-II"

All came back as I think you'd like.

The function is the equivalent of the FindLabel function in the examples.  You won't need the print statement on line 17, I was just doing that to verify what was returned.

0 Kudos